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

    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:

    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,)=
    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):

    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.

    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:

    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:

    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.

    % 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:

    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.