Code Monkey home page Code Monkey logo

nifti_mrs_tools's Introduction

Python Tools for NIfTI-MRS

PyPI PyPI - Python Version DOI PyPI - License

This package contains python-based tools for representing, validating, and manipulating the NIfTI-MRS format. NIfTI-MRS is a standardised format for storing Magnetic Resonance Spectroscopy data.

These tools are used extensively in the spec2nii format conversion program and the FSL-MRS analysis software. However, this library can also be used as a stand-alone set of tools.

If you use these tools please cite: Clarke, WT, Bell, TK, Emir, UE, et al. NIfTI-MRS: A standard data format for magnetic resonance spectroscopy. Magn Reson Med. 2022; 88: 2358- 2370. doi:10.1002/mrm.29418

Installation

Installation is via conda(-forge) or Pypi.

conda install -c conda-forge nifti-mrs

or

pip install nifti-mrs

Note this package is a requirement of spec2nii (>v0.4.9) and FSL-MRS (>v2.0.9) and will automatically be installed with them.

Using the package

Command-line tool - mrs_tools

MRS data stored in NIfTI-MRS format can contain multiple higher dimensions. For example it might contain dimensions encoding multiple receive coils, multiple temporal averages, or even a spectral editing dimension.

Data might need to be manipulated within the NIfTI-MRS storage framework before, after, or during preprocessing. For this, FLS-MRS provides the mrs_tools command line script. mrs_tools has the ability to merge and split NIfTI-MRS files along the higher encoding dimensions. It can also reorder the higher dimensions, or create a new singleton dimension for further manipulation.

mrs_tools split takes a single file and splits it along a specified dimension e.g. --dim DIM_DYN, at a single point (--index 8) or extracting multiple elements into a second file (--indices 8 9 10).

mrs_tools merge takes two or more files and merges them along a specified dimension e.g. --dim DIM_EDIT. Use --newaxis if that dimension doesn't exist in the files already.

mrs_tools reorder permutes the dimensions of an existing NIfTI-MRS file. For example, the 5th through 7th dimensions can be changed from DIM_COIL, DIM_DYN, DIM_EDIT to DIM_DYN, DIM_EDIT, DIM_COIL using --dim_order DIM_DYN DIM_EDIT DIM_COIL. Reorder can be used to add a tag to a singleton dimension.

mrs_tools reshape allows Numpy-style reshaping of the higher dimensions. For example if two editing conditions are interleaved you can reshape a file from (32, 128) to (32, 64, 2), and by specifying -d6 DIM_DYN -d7 DIM_EDIT you can tag the new dimensions appropriately.

mrs_tools also contains the mrs_tools vis and mrs_tools info options to provide quick visualisation and information on the command line. See the FSL-MRS Visualisation documentation for more information on mrs_tools vis/info.

Note: visualisation of NIfTI-MRS data using mrs_tools requires the installation of the FSL-MRS package

As a code library

The command-line tools presents an interface to the underlying code library. The library can be used directly in interactive or scripted python. For example:

from nifti_mrs.nifti_mrs import NIFTI_MRS
from nifti_mrs import tools

obj = NIFTI_MRS('path/to/data.nii.gz')

# Split the object at index 16 (1-16, 17-N) along the dynamics dimension
part_1, part_2 = tools.split(obj, 'DIM_DYN', 15)

# Save the first part
part_1.save('output/location/part_1.nii.gz')

See the API documentation for details.

Contributing and tests

Contributions to improve or extend these tools via pull requests are extremely welcome. Contributors, please take time to develop tests to continually validate new features or changes.

Acknowledgements

Contributors

William Clarke, University of Oxford

Funding acknowledgments

This work was funded by the Wellcome Trust [225924/Z/22/Z, 203139/Z/16/Z and 203139/A/16/Z].

nifti_mrs_tools's People

Contributors

dc-3t avatar dimitripapadopoulos avatar musicinmybrain avatar wtclarke avatar

Watchers

 avatar

nifti_mrs_tools's Issues

Tests fail when file endianness does not match host endianness

While packaging this for Fedora Linux, for which the big-endian s390x is a primary architecture, I found that the routines assume the file endianness and host endianness match. This results in six test failures:

=========================== short test summary info ============================
FAILED tests/test_nifti_mrs.py::test_nifti_mrs_save - nifti_mrs.validator.nif...
FAILED tests/test_script_mrs_tools.py::test_merge - subprocess.CalledProcessE...
FAILED tests/test_script_mrs_tools.py::test_split - subprocess.CalledProcessE...
FAILED tests/test_script_mrs_tools.py::test_reorder - subprocess.CalledProces...
FAILED tests/test_script_mrs_tools.py::test_reshape - subprocess.CalledProces...
FAILED tests/test_script_mrs_tools.py::test_conjugate - subprocess.CalledProc...
=================== 6 failed, 44 passed, 1 skipped in 1.96s ====================

I have attached the full build log.

This StackOverflow question suggests one way of detecting endianness in a NIfTI file.

I would understand if you chose not to support NIfTI files that don’t match the host endianness, but I thought I should at least report the issue.

Unnecessary file nifti_mrs/standard/explanatory_doc/conf.py

An unnecessary file nifti_mrs/standard/explanatory_doc/conf.py, the Doxygen configuration for the standard specification https://github.com/wtclarke/mrs_nifti_standard/, is included in both the sdists and wheels, when only nifti_mrs/standard/definitions.json is really needed or wanted. This isn’t particularly harmful, but it isn’t really right either.

$ python3.12 -m venv _e
$ . _e/bin/activate
(_e) $ pip install nifti-mrs
(_e) $ find _e/lib/python3.12/site-packages/nifti_mrs/standard/
_e/lib/python3.12/site-packages/nifti_mrs/standard/
_e/lib/python3.12/site-packages/nifti_mrs/standard/definitions.json
_e/lib/python3.12/site-packages/nifti_mrs/standard/explanatory_doc
_e/lib/python3.12/site-packages/nifti_mrs/standard/explanatory_doc/conf.py
_e/lib/python3.12/site-packages/nifti_mrs/standard/explanatory_doc/__pycache__
_e/lib/python3.12/site-packages/nifti_mrs/standard/explanatory_doc/__pycache__/conf.cpython-312.pyc
$ gh repo clone wtclarke/nifti_mrs_tools
$ cd nifti_mrs_tools
$ python3 -m build
$ tar -tzf dist/nifti_mrs-1.2.0.tar.gz | grep standard
nifti_mrs-1.2.0/src/nifti_mrs/standard/
nifti_mrs-1.2.0/src/nifti_mrs/standard/definitions.json
nifti_mrs-1.2.0/src/nifti_mrs/standard/explanatory_doc/
nifti_mrs-1.2.0/src/nifti_mrs/standard/explanatory_doc/conf.py

Expected:

$ python3.12 -m venv _e
$ . _e/bin/activate
(_e) $ pip install nifti-mrs
(_e) $ find _e/lib/python3.12/site-packages/nifti_mrs/standard/
_e/lib/python3.12/site-packages/nifti_mrs/standard/
_e/lib/python3.12/site-packages/nifti_mrs/standard/definitions.json
$ tar -tzf dist/nifti_mrs-1.2.0.tar.gz | grep standard
nifti_mrs-1.2.0/src/nifti_mrs/standard/
nifti_mrs-1.2.0/src/nifti_mrs/standard/definitions.json

FSL MRS issue traced back to ValueError in nifti_mrs

I am trying to use FSL MRS interactively and I've run into the following error:

Cell In[29], line 2
      1 # %%
----> 2 data = mrs_io.read_FID(path)
      3 mrs = data.mrs(basis_file=fsl_basis_file_path)                     
      4             #    ref_data=final_wref)

File ~/Documents/Repositories/fsl_mrs/fsl_mrs/utils/mrs_io/main.py:91, in read_FID(filename)
     88     filename = Path(filename).resolve()
     90 try:
---> 91     return fsl_nmrs.NIFTI_MRS(filename)
     92 except (NotNIFTI_MRS, fslpath.PathError):
     93     data_type, id_ext = _check_datatype(Path(filename))

File ~/Documents/Repositories/fsl_mrs/fsl_mrs/core/nifti_mrs.py:100, in NIFTI_MRS.__init__(self, *args, **kwargs)
     54 def __init__(self, *args, **kwargs):
     55     """Create a NIFTI_MRS object with the given image data or file name.
     56 
     57     This is a wrapper around the nifti_mrs.nifti_mrs.NIFTI_MRS class to
   (...)
     98     (if it is called).
     99     """
--> 100     super().__init__(*args, **kwargs)
...
    105         else:
--> 106             raise ValueError(f'User-defined key {key} must contain a "Description" field"')
    108 return obj

ValueError: User-defined key conversion_time must contain a "Description" field"

This happens with every input file, but we used FSL MRS to fit all of this data this summer, so I know it worked a few months ago.

I went through the data file using the following code:

img = nib.load(path)
data = img.get_fdata(dtype=np.complex64)
header = img.header
hdr_ext_codes = img.header.extensions.get_codes()
mrs_hdr_ext = json.loads(img.header.extensions[hdr_ext_codes.index(44)].get_content())
print(mrs_hdr_ext)

And got the following output showing that 'conversion_time' does in fact have a filled in value pair.

{'SpectrometerFrequency': [123.2],
 'ResonantNucleus': ['1H'],
 'EchoTime': 0.144,
 'RepetitionTime': 2.0,
 'DeviceSerialNumber': 'NA',
 'Manufacturer': 'simulated',
 'ManufacturersModelName': 'NA',
 'SoftwareVersions': 'NA',
 'PatientDoB': 'NA',
 'PatientName': 'NA',
 'PatientPosition': 'HFS',
 'PatientSex': 'NA',
 'PatientWeight': 0,
 'ConversionMethod': 'Manual',
 'ConversionTime': '2023-04-22T15:58:10.128',
 'OriginalFile': ['denoiser_physics_model_512_dataset.mat'],
 'conversion_time': '2023-06-02T09:04:55.836'}

Do you have any suggestions for what could be causing this and how to fix it or work around it?

Best,
John

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.