File I/O Instruction ==================== Read ASCII Data --------------- - PyAMARES does not have a proprietary MRS data format. Instead, it provides a simple file I/O module, ``pyAMARES.fileio.readmat.readmrs``, which can read 2-column ASCII data from TXT files, Numpy arrays, or Matlab MAT-files. For a simple example, see `fid.txt `_ .. code-block:: none 6.847809 1.216094 4.828833 3.156816 4.034658 1.782253 1.330667 -0.451028 -1.733149 -0.407579 -0.897316 1.419248 2.927123 1.590987 6.410198 -1.603970 6.767128 -5.662707 4.205815 -6.782638 1.651590 -4.380638 0.669085 -1.487109 0.771935 -0.740095 4.094533 2.889353 6.077999 -0.541224 5.933486 -2.790893 5.309414 -2.072833 ........ ......... ........ ......... ........ ......... 0.034993 -0.000327 -0.036540 0.000899 0.340343 0.002208 0.157346 0.003399 -0.131407 0.004274 0.818836 0.004679 The first column represents the real part, while the second column represents the imaginary part of the MRS FID data. Here is how to read it: .. code-block:: python :emphasize-lines: 3 import pyAMARES import matplotlib.pyplot as plt fid = pyAMARES.readmrs('fid.txt') # Load MRS data print(f"{fid.shape}=") plt.plot(fid.real) plt.title("The real part of input FID") plt.show() | Output: | Try to load 2-column ASCII data | data.shape= (1024,) | (1024,)= .. image:: images/fid_real.png :width: 300 :alt: The real part of the FID Read GE MNS Research Pack fidall Data ------------------------------------- - The GE MNS Research Pack `fidall` files (``rhrecon=2600, 2700, 2701, 2702``) reconstructed MAT-files can be read using ``pyAMARES.read_fidall(filename)``: .. code-block:: python :emphasize-lines: 2 import pyAMARES header, fid = pyAMARES.read_fidall('20210608_170823_P34816.mat') print(f"{header.MHz=}") print(f"{header.sw=}") print(f"{header.deadtime=}") print(f"{fid.shape=} {fid.dtype=}") | Output: | header.MHz=51.720748 | header.sw=5000.0 | header.deadtime=0.000887 | fid.shape=(720, 256) fid.dtype=dtype('complex128') Although ``fid`` can be a 2D array (e.g., MRSI), note that ``pyAMARES.initialize_FID`` only supports 1D data. MRSI data can be processed either by looping through each FID or using the ``pyAMARES.run_parallel_fitting_with_progress`` API. Read NifTI-MRS Data ------------------- - It is not within pyAMARES's scope to reconstruct and post-process the MRS spectrum from vendor-specific formats. Existing tools such as `jMRUI `_, `MRSpa `_, and `FSL-MRS `_ are already well-equipped for these tasks. - We recommend using the `spec2nii `_ tool from FSL-MRS to convert vendor-specific formats to NifTI format because FSL-MRS is also developed in Python. Refer to its `documentation `_ for details. You will need to install ``spec2nii`` with the command ``pip install spec2nii`` first. - You can load the NifTI-MRS files generated by FSL-MRS following this `example `_. Alternatively, PyAMARES provides a simple wrapper for this example, utilizing `NiBabel `_. You will need to install ``nibabel`` with the command ``pip install nibabel`` first. .. code-block:: python :emphasize-lines: 2 import pyAMARES header, fid = pyAMARES.read_nifti('TE04_cleanMM_ForFItting.nii.gz') print(f"{header.MHz=}") print(f"{header.dwelltime=}") print(f"{header.sw=}") print(f"{fid.shape=} {fid.dtype=}") | Output: | There is no AcqusitionStartTime! | header.MHz=400.2654061 | header.dwelltime=0.0002 | header.sw=5000.0 | fid.shape=(4096,) fid.dtype=dtype('complex64') - The advantage of using NifTI-MRS is that it allows us to read the required arguments for AMARES fitting (MHz, sw) directly from the file. However, ``deadtime``, or ``AcquisitionStartTime``, may not always be available in NifTI files. If these parameters are not present in the header, pyAMARES requires the user to manually input them into ``pyAMARES.initialize_FID``. .. note:: It is always a good idea to check if the loaded FID needs to be conjugated (i.e., invert the frequency axis for the Fourier Transformed spectrum). To our knowledge, the frequency axes for certain nuclei may be inverted in some vendor scanners (e.g., 1.5T/7T with MNS), and converting to NifTI-MRS format might also invert the frequency axis. ``pyAMARES.initialize_FID`` provides an argument ``flip_axis`` to easily flip the axis. Read Binary jMRUI Data ---------------------- - Alternatively, ``spec2nii`` can be used to read MRS data directly from various formats without requiring conversion to NifTI-MRS. Below is an example of how to load data processed by jMRUI: .. code-block:: python :emphasize-lines: 2 from spec2nii import jmrui # Loda jmrui module fid, header, str_info = jmrui.read_mrui('./Data_PK_forSubmission/Metabolite_removal_PK_SV/TE02_MMspectrum.mrui') # The spectral parameters required by AMARES can be obtained from the header: sw = 1.0 / (header['sampling_interval'] * 1e-3) # Hz, 1/dwell MHz = header['transmitter_frequency'] * 1e-6 # MHz deadtime = header['begin_time '] # second print(f"{fid.shape=} {fid.dtype=}") print(f"{sw=} Hz {MHz=} MHz {deadtime=} s") | Output: | fid.shape=(4096,) fid.dtype=dtype('complex128') | sw=5000.0 Hz MHz=400.2654061 MHz deadtime=0.0 s .. note:: It is recommended to post-processing your data using MRS software first, such as FSL-MRS. Save MRS Data for pyAMARES Using Python --------------------------------------- - If you are using Python and want to use pyAMARES for quantification, you can save your MRS FID data in either 2-column `NPY` or `CSV` format: .. code-block:: python import numpy as np # Import Numpy # `FID` is a 1D Numpy array in complex format # Check the data type and the shape of this 1D Numpy array print(fid.dtype, fid.shape) # The above line will print `fid.dtype=dtype('complex128'), fid.shape=(4096,)` # Save the complex 1D array FID to NPY format np.save('fid.npy', fid) # Convert the complex 1D array FID into a 2-column float Numpy array (i.e., 2D array) and save it as txt fid2 = np.column_stack((fid.real, fid.imag)) np.savetxt('fid.txt', fid2) # The same 2D float array fid2 can also be saved as a CSV np.savetxt('fid.csv', fid2, delimiter=',') # The saved `fid.npy`, `fid.txt`, and `fid.csv` can all be read by the same API: f1 = pyAMARES.readmrs('fid.npy') f2 = pyAMARES.readmrs('fid.txt') f3 = pyAMARES.readmrs('fid.csv') # f1, f2, and f3 are identical Save MRS Data for pyAMARES Using Matlab --------------------------------------- - If you are using MATLAB and want to use pyAMARES for quantification, you can save your MRS FID to a MAT-file. .. code-block:: matlab % If the MRS FID data variable is 'fid' save('fid1.mat', 'fid'); % If the MRS FID data variable is 'data' save('fid2.mat', 'data'); The saved MRS data can be read by pyAMARES using the following commands: .. code-block:: python fid1 = pyAMARES.readmrs('fid1.mat') fid2 = pyAMARES.readmrs('fid2.mat') .. note:: The jMRUI-exported Matlab FID and GE MNS Research Pack `fidall` (``rhrecon=2600, 2700, 2701, 2702``) reconstructed MAT-files can be read by this API. However, users will need to manually input necessary parameters such as MHz, sw, and deadtime.