diff --git a/bartfire.py b/bartfire.py index d527693..1dda4d3 100755 --- a/bartfire.py +++ b/bartfire.py @@ -12,6 +12,11 @@ # Folder for debug output files debugFolder = "/tmp/share/debug" +# Don't write to /tmp/share in cfl +os.environ["TMPDIR"] = "/tmp" + +use_nlinv = False + def process(connection, config, metadata): logging.info("Config: \n%s", config) @@ -45,7 +50,7 @@ def process(connection, config, metadata): if isinstance(item, ismrmrd.Acquisition): # Accumulate all imaging readouts in a group if (not item.is_flag_set(ismrmrd.ACQ_IS_NOISE_MEASUREMENT) and - not item.is_flag_set(ismrmrd.ACQ_IS_PARALLEL_CALIBRATION) and + (use_nlinv or not item.is_flag_set(ismrmrd.ACQ_IS_PARALLEL_CALIBRATION)) and not item.is_flag_set(ismrmrd.ACQ_IS_PHASECORR_DATA)): acqGroup.append(item) @@ -131,19 +136,26 @@ def process_raw(group, config, metadata): logging.debug("Raw data is size %s" % (data.shape,)) np.save(debugFolder + "/" + "raw.npy", data) - # Fourier Transform with BART - logging.info("Calling BART FFT") - data = bart(1, 'fft -u -i 3', data) + # Reconstruction with BART. + if use_nlinv: + logging.info("Calling BART NLINV") + + # coil compression to 8 channels + data = bart(1, "cc -p8", data) + + # nlinv with debug level 4 and 13 gauss-newton steps. + data = bart(1, "nlinv -d4 -i13", data) + + data = np.atleast_3d(abs(data)) + + else: + logging.info("Calling BART FFT") + data = bart(1, 'fft -u -i 3', data) - # Re-format as [cha row col phs] - data = data.transpose((3, 0, 1, 2)) + # RSS with BART + data = bart(1, 'rss 8', data) - # Sum of squares coil combination - # Data will be [PE RO phs] - data = np.abs(data) - data = np.square(data) - data = np.sum(data, axis=0) - data = np.sqrt(data) + data = np.atleast_3d(data.real) logging.debug("Image data is size %s" % (data.shape,)) np.save(debugFolder + "/" + "img.npy", data) diff --git a/docker/bart/Dockerfile b/docker/bart/Dockerfile index a28e446..1c7e4be 100644 --- a/docker/bart/Dockerfile +++ b/docker/bart/Dockerfile @@ -1,5 +1,5 @@ # ----- First stage to build BART ----- -FROM python:3.9-slim AS bart_build +FROM python:3.12.0-slim AS bart_build ARG DEBIAN_FRONTEND=noninteractive ENV TZ=America/Chicago @@ -8,15 +8,17 @@ RUN mkdir -p /opt/code # BART (static linked) RUN cd /opt/code && \ - git clone https://github.com/mrirecon/bart.git --branch v0.7.00 && \ + git clone https://github.com/mrirecon/bart.git --branch v0.9.00 && \ cd bart && \ - make SLINK=1 -j $(nproc) && \ + make -j $(nproc) && \ make install # ----- Main stage without build dependencies ----- # Re-use already built Docker image, but the contents of \docker\Dockerfile can also be # recapitulated here instead to ensure the latest build FROM kspacekelvin/fire-python + +# this does *not* work in the chroot image! ENV PYTHONPATH=/opt/code/bart/python # Copy BART from previous stage @@ -24,3 +26,6 @@ COPY --from=bart_build /usr/local/bin/bart /usr/local/bin/ COPY --from=bart_build /usr/local/lib/bart/commands /usr/local/lib/bart/commands COPY --from=bart_build /usr/local/share/doc/bart /usr/local/share/doc/bart COPY --from=bart_build /opt/code/bart /opt/code/bart + +# Install BART runtime dependencies +RUN apt-get update && apt-get install -y libfftw3-single3 libgomp1 liblapacke libpng16-16 libblas3 libunwind8 diff --git a/docker/docker_tar_to_chroot.sh b/docker/docker_tar_to_chroot.sh index 6ba4080..bffe71b 100755 --- a/docker/docker_tar_to_chroot.sh +++ b/docker/docker_tar_to_chroot.sh @@ -2,6 +2,8 @@ # This script takes a Docker container export (.tar) creates a chroot image (.img) # Note that root privileges are required to mount the loopback images +set -eu + # Syntax: ./docker_tar_to_chroot.sh docker-export.tar chroot.img EXPORT_FILE=${1} @@ -40,6 +42,7 @@ tar -xf ${EXPORT_FILE} --directory=/mnt/chroot --totals df -h umount /mnt/chroot +rmdir /mnt/chroot echo Finished! Verify that no errors have occured and that available space on the echo last row of the above df output is greater than 100 MB diff --git a/start-fire-python-server.sh b/start-fire-python-server.sh index 1df0d1d..7c93a7b 100755 --- a/start-fire-python-server.sh +++ b/start-fire-python-server.sh @@ -9,6 +9,10 @@ # it's less likely to accidentally fill up the chroot export TMPDIR=/tmp/share +# This is needed for the chroot-images to run BART. +export PYTHONPATH=/opt/code/bart/python:${PYTHONPATH} + + if [ $# -eq 1 ]; then LOG_FILE=${1} python3 /opt/code/python-ismrmrd-server/main.py -v -r -H=0.0.0.0 -p=9002 -l=${LOG_FILE} &