Package: warpkit
warpkitA python library for neuroimaging transformsIf you've landed here, you're probably interested in the Multi-Echo DIstortion Correction (MEDIC) algorithm, which this
library implements.You can find the pre-print for MEDIC here:https://www.biorxiv.org/content/10.1101/2023.11.28.568744v1.See below for usage details.InstallationJuliawarpkitrequiresjuliainstalled on your system ensure that you have thejuliaexecutable in your path, and
thejulialibraries correctly setup in yourld.so.conf. See the below instructions for both Linux and macOS.LinuxIf you installed julia via a package manager, library configuration should be done for you (most of the time) already.
However, if you installed Julia manually, you may need to tellldconfigwhere the julia libraries are. For example,
on debian based systems you can do this with:# /path to julia installation (the lib folder will have libjulia.so)echo/path/to/julia/lib>/etc/ld.so.conf.d/julia.conf
ldconfigIf you have done this correctly, you should seelibjulia.soin your ldconfig:ldconfig-p|grepjulialibjulia.so.1(libc6,x86-64)=>/usr/lib/libjulia.so.1libjulia.so(libc6,x86-64)=>/usr/lib/libjulia.soThe above may require root privileges. The alternative to the above is to set theLD_LIBRARY_PATHenvironment
variable to the path of the julia libraries.# /path to julia installation (the lib folder will have libjulia.so)exportLD_LIBRARY_PATH=/path/to/julia/lib:$LD_LIBRARY_PATHNote however, that you must type the above each time you open a new terminal. To make this permanent, you can add the
above line to your shell's profile file.macOSIf you installed julia throughbrew, this should be done for you already.However, if you get an error saying thatlibjuliacannot be found, you may need to add the julia libraries via yourDYLD_LIBRARY_PATHenvironment variable. For example, if you installed julia to/Applications/Julia-1.6.app, you
would add the following to your shell's profile file:exportDYLD_LIBRARY_PATH=/Applications/Julia-1.6.app/Contents/Resources/julia/lib:$DYLD_LIBRARY_PATHInstalling through pipAssuming you havejuliainstalled and configured correctly, you can installwarpkitthroughpip:pipinstallwarpkitIf you encounter any errors during the installation process, please report them to the issue tracker with the logs
reported frompip install warpkit -v.Installing through condaAnother way to installwarpkitis through acondaenvironment. Currently,warpkitis not uploaded to anycondachannels, so you will need to build it from source (Looking for help on thisissue).[!NOTE]For advanced users onlyAmeta.yamlfile is present in thecondafolder in the root of the repo. If you are familiar withconda-buildyou should be able to build this with your existingcondainstall.Fortunately, there is an automated script that will downloadmicromamba(acondavariant), create a new
environment, and build/installwarpkitfor you automagically. To do this, clone this repo and run the following:# switch to conda directory in repocdconda# run the install script (use -p or --path to specify an install prefix)# by default this is set to ~/micromamba./warpkit-conda-install.sh# in your shell profile add the following lines# or just execute them in your current shell# but it won't be permanentexportMAMBA_ROOT_PREFIX=/whatever/path/you/installed/micromamba/prefix/aboveeval"$(/whatever/path/you/installed/micromamba/prefix/above/bin/micromambashellhook-sposix)"# if you added the above to your profile# restart your shell then activate the environment## unless you have already executed the above in your current shell# then you don't need to restart it and can just activate the environmentmicromambaactivatebase# you should now be able to import/use warpkitpython-c"import warpkit"# should return no errorsmedic--help# should return helpAfter installing and configuring everything, you must typemicromamba activate baseeach time you open a new terminal
to get back into thecondaenvironment to usewarpkit. To make this permanent, you can add the above line to your
shell's profile file.Installing through dockerIf you are familiar withdocker, you can also installwarpkitthrough adockercontainer.dockerrun-it--rmghcr.io/vanandrew/warpkit:latestNote that the default entrypoint is themedicCLI script, so you can runmedic --helpto get the help message.Building and installing from sourceTo build and install from source, clone this repo and run the following in the repo directory.
I highly recommend installing it in editable mode (with the strict option, seehere):pip install -e ./[dev] -v --config-settings editable_mode=strictYou will need a C++ compiler with C++17 support, as well as Julia pre-installed on your system. See theJuliasection for more details.The build process uses CMake to build the C++/Python Extension. If you encounter an error during the build process,
please report the full logs of the build process using the-vflag to thepipcommand above.What is MEDIC?MEDIC takes your ME-EPI phase data from this:to this:for each frame of your data. You can then use these field maps to distortion correct your data.MEDIC UsageThewarpkitlibrary is meant for integration into a larger neuroimaging pipeline/software package.An example of how to call MEDIC from python is provided below:importnibabelasnibfromwarpkit.distortionimportmedicfromwarpkit.utilitiesimportdisplacement_map_to_warp# load phase and magnitude images into lists# each element in list is a different echophases=[nib.load(p)forpinphases_paths]magnitudes=[nib.load(p)forpinmagnitude_paths]TEs=[TE1,TE2,...]# in millisecondseffective_echo_spacing=...# in secondsphase_encoding_direction=eitheri,j,k,i-,j-,k-,x,y,z,x-,y-,z-# call the medic functionfield_maps_native,displacement_maps,field_maps=medic(phases,magnitudes,TEs,effective_echo_spacing,phase_encoding_direction)# field_maps_native are returned in the distorted space (Hz) (mainly for reference/debugging purposes)# you shouldn't need to use these probably???# displacement_maps are returned in the undistorted space (mm) (see below for usage)# field_maps are returned in the undistorted space (Hz) (same field map output as topup/fugue, but framewise)# returns are nibabel Nifti1Image objects, so they can be saved to file by:# displacement_maps to filedisplacement_maps.to_filename("/path/to/save.nii.gz")# these should be converted to displacement fields# by the displacement_map_to_field function# and specifying the appropriate type (i.e. itk, ants, afni, fsl)displacement_field=displacement_map_to_field(displacement_maps,axis="y",format="itk",frame=0)# where axis specifies the phase encoding direction, format is the desired output format, and frame is the index of# displacement map to convert to a displacement field# the displacement field can then be saved to file by the to_filename method# Each file can be applied with the respective software's displacement field application tool:# itk: the internal format warpkit uses. See utilities.resample_image# ants: antsApplyTransforms (note that even though ants also uses itk, warpkit's itk warp format is NOT equivalent)# afni: 3dNwarpApply# fsl: applywarp# if you are using fsl and instead want to use fugue to distortion correction, you can use the field_maps outputs# (these are the equivalent field maps of that you would get from fugue, but with multiple frames)You can also use the provided CLI scriptmedicto run MEDIC from the command line. The script is installed to yourPATHwhen you install the package.medictakes the following arguments:usage:medic[-h]--magnitudeMAGNITUDE[MAGNITUDE...]--phasePHASE[PHASE...]--metadataMETADATA[METADATA...][--out_prefixOUT_PREFIX][-fNOISEFRAMES][-nN_CPUS][--debug][--wrap_limit]Multi-EchoDIstortionCorrection

options:-h,--helpshowthishelpmessageandexit--magnitudeMAGNITUDE[MAGNITUDE...]Magnitudedata--phasePHASE[PHASE...]Phasedata--metadataMETADATA[METADATA...]JSONsidecarforeachecho--out_prefixOUT_PREFIXPrefixtooutputfieldmapsanddisplacmentmaps.-fNOISEFRAMES,--noiseframesNOISEFRAMESNumberofnoiseframes-nN_CPUS,--n_cpusN_CPUSNumberofCPUstouse.--debugDebugmode--wrap_limitTurnsoffsomeheuristicsforphaseunwrapping

VahdetaSuljic<suljic@wustl.edu>,AndrewVan<vanandrew@wustl.edu>12/09/2022