FSL-MRS spec2nii twix conversion issue

Hi!

I’ve just begun using FSL-MRS (v1.1.12) and I’m running into some issues trying to convert my multiraid twix files acquired from a 3T Siemens Prisma with spec2nii (v0.4.2).

My multiraid file contains a “noise” dataset (-m 1):

spec2nii twix -v meas_MID01821_FID13842_Fus_Prep2_Ref2NoInline_SaveEach.dat -m 1
pymapVBVD version 0.4.8
Software version: VD
Contents of file meas_MID01821_FID13842_Fus_Prep2_Ref2NoInline_SaveEach.dat:  
Multiraid file, 2 files found.
Selecting file 1. Use -m option to change.
The file contains these evalinfo flags with dimensions and sizes as follows:
noise          :	Col, Cha, Lin, Ave  	[512  32 128   2]

and also my main “image” dataset (-m 2):

spec2nii twix -v meas_MID01821_FID13842_Fus_Prep2_Ref2NoInline_SaveEach.dat -m 2
pymapVBVD version 0.4.8
Software version: VD
Contents of file meas_MID01821_FID13842_Fus_Prep2_Ref2NoInline_SaveEach.dat:  
Multiraid file, 2 files found.
Selecting file 2. Use -m option to change.
The file contains these evalinfo flags with dimensions and sizes as follows:
image          :	Col, Cha, Ave, Phs  	[2080   32  150    2]

I was able to convert the main dataset “image”:

spec2nii twix -e image -m 2 -f Fus_run1 -j meas_MID01821_FID13842_Fus_Prep2_Ref2NoInline_SaveEach.dat
pymapVBVD version 0.4.8
Software version: VD
Converting twix file meas_MID01821_FID13842_Fus_Prep2_Ref2NoInline_SaveEach.dat.
Looking for evalinfo flag image.
Found data of size (2080, 32, 150, 2).                                       
Header extension validated!

However, I’m having trouble interpreting what it’s reading in here as the data size. The data are supposed to be 2048-point FIDs, collected on 32 channels, with 150 averages… but instead, the data size shown here shows that I have 2080-point FIDs, and I’m unclear about the 4th value of 2 represents here.

> pymapVBVD version 0.4.8
> Software version: VD
> 
> Converting twix file meas_MID01821_FID13842_Fus_Prep2_Ref2NoInline_SaveEach.dat.                                                                                                                   
> Looking for evalinfo flag image.
> Found data of size (2080, 32, 150, 2).                                                                                                                                                            
> Header extension validated!

Further, I’m unclear about the nature of the data stored in -m 1 has this datasize (512, 32, 128, 2), but I suspect this is my water unsuppressed data where 2 averages were acquired. I’d like to take a look at this after converting to .nii, but spec2nii fails:

spec2nii twix -e noise meas_MID01821_FID13842_Fus_Prep2_Ref2NoInline_SaveEach.dat -m 1 -f Fus_run1_wref
pymapVBVD version 0.4.8
Software version: VD
                                                                                                                                                                                                 Converting twix file meas_MID01821_FID13842_Fus_Prep2_Ref2NoInline_SaveEach.dat.                                                                                                                   
Looking for evalinfo flag noise.
Found data of size (512, 32, 128, 2).                                                                                                                                                             
Traceback (most recent call last):
  File "/mnt/hippocampus/starkdata1/Jess/anaconda3/bin/spec2nii", line 8, in <module>
    sys.exit(main())
  File "/mnt/hippocampus/starkdata1/Jess/anaconda3/lib/python3.8/site-packages/spec2nii/spec2nii.py", line 509, in main
    spec2nii(*args)
  File "/mnt/hippocampus/starkdata1/Jess/anaconda3/lib/python3.8/site-packages/spec2nii/spec2nii.py", line 260, in __init__
    args.func(args)
  File "/mnt/hippocampus/starkdata1/Jess/anaconda3/lib/python3.8/site-packages/spec2nii/spec2nii.py", line 333, in twix
    self.imageOut, self.fileoutNames = process_twix(twixObj,
  File "/mnt/hippocampus/starkdata1/Jess/anaconda3/lib/python3.8/site-packages/spec2nii/twixfunctions.py", line 95, in process_twix
    return process_svs(
  File "/mnt/hippocampus/starkdata1/Jess/anaconda3/lib/python3.8/site-packages/spec2nii/twixfunctions.py", line 162, in process_svs
    meta_obj = extractTwixMetadata(twixObj['hdr'], basename(twixObj[dataKey].filename))
  File "/mnt/hippocampus/starkdata1/Jess/anaconda3/lib/python3.8/site-packages/spec2nii/twixfunctions.py", line 440, in extractTwixMetadata
    return extractTwixMetadata_vx(mapVBVDHdr, original_file)
  File "/mnt/hippocampus/starkdata1/Jess/anaconda3/lib/python3.8/site-packages/spec2nii/twixfunctions.py", line 567, in extractTwixMetadata_vx
    obj = nifti_mrs.hdr_ext(mapVBVDHdr['Meas'][('Frequency')] / 1E6,
KeyError: 'Frequency'

Lastly, I actually cannot view the main dataset that successfully converted to .nii successfully with mrs_tools:

mrs_tools vis --no_mean Fus_run1.nii.gz 
Performing coil combination
/mnt/hippocampus/starkdata1/Jess/anaconda3/lib/python3.8/site-packages/fsl_mrs/utils/preproc/combine.py:46: RuntimeWarning:

divide by zero encountered in true_divide

/mnt/hippocampus/starkdata1/Jess/anaconda3/lib/python3.8/site-packages/fsl_mrs/utils/preproc/combine.py:46: RuntimeWarning:

invalid value encountered in matmul

Traceback (most recent call last):
  File "/mnt/hippocampus/starkdata1/Jess/anaconda3/bin/mrs_tools", line 357, in <module>
    main()
  File "/mnt/hippocampus/starkdata1/Jess/anaconda3/bin/mrs_tools", line 129, in main
    args.func(args)
  File "/mnt/hippocampus/starkdata1/Jess/anaconda3/bin/mrs_tools", line 240, in vis
    vis_nifti_mrs(p)
  File "/mnt/hippocampus/starkdata1/Jess/anaconda3/bin/mrs_tools", line 177, in vis_nifti_mrs
    data = nifti_mrs_proc.coilcombine(data)
  File "/mnt/hippocampus/starkdata1/Jess/anaconda3/lib/python3.8/site-packages/fsl_mrs/utils/preproc/nifti_mrs_proc.py", line 79, in coilcombine
    combinedc_obj[idx] = preproc.combine_FIDs(
  File "/mnt/hippocampus/starkdata1/Jess/anaconda3/lib/python3.8/site-packages/fsl_mrs/utils/preproc/combine.py", line 158, in combine_FIDs
    return svd_reduce(FIDlist, W)
  File "/mnt/hippocampus/starkdata1/Jess/anaconda3/lib/python3.8/site-packages/fsl_mrs/utils/preproc/combine.py", line 69, in svd_reduce
    U, S, V = np.linalg.svd(FIDs, full_matrices=False)
  File "<__array_function__ internals>", line 5, in svd
  File "/home/jess/.local/lib/python3.8/site-packages/numpy/linalg/linalg.py", line 1660, in svd
    u, s, vh = gufunc(a, signature=signature, extobj=extobj)
  File "/home/jess/.local/lib/python3.8/site-packages/numpy/linalg/linalg.py", line 97, in _raise_linalgerror_svd_nonconvergence
    raise LinAlgError("SVD did not converge")
numpy.linalg.LinAlgError: SVD did not converge

Has anyone run into this and might know how I could resolve these issues? Thanks so much in advance!

Jess

Hi @jnlingad,

Thanks for this detailed bug report and for trying these tools. Sorry it’s taken me a few days to pick this up. I think there are a couple things going on here:

  1. The 2080 vs 2048 time points is possibly expected. Sequences often add additional points to the ADC (read out event) before the centre of the echo is expected. This is so the artefacts seen at the beginning of the ADC don’t overlap the final data. Eventually you can discard these points with fsl_mrs_proc truncate ....

  2. Regarding the two dimensions. Is the data either from a MEGA edited sequence, or is it a Siemens product sequence? Do you know what baseline you are using? If the latter, I think there’s a new set of product sequence which encodes a single water reference scan. This means that all the points, except a single average which contains the water reference in the first element of the final (size-2) AVE dimension are zeros. This is why the mrs_tools vis call fails.
    I handle this for the new XA line of scanners (Vida etc) but perhaps this behaviour also occurs on some Prisma scanners.

  3. Those noise scans in the first twix file of the multiraid -m 1 is effectively from another (non-spectroscopy) scanner calibration scan. That means spec2nii isn’t set up to handle them. However it might be worth looking into as the noise scans are useful.

Ah, I figured out that I can use mrs_tools split here to separate out the single water reference average from the water-suppressed data. Very excited to move forward with this. Thanks so much for your help!

Jess