MagneticResonanceImaging / MRIReco.jl

Julia Package for MRI Reconstruction
https://magneticresonanceimaging.github.io/MRIReco.jl/latest/
Other
85 stars 22 forks source link

Loading a MRD converted from Bruker in python, missing encoding header fields #33

Open rajramasawmy opened 2 years ago

rajramasawmy commented 2 years ago

I was testing out this example https://magneticresonanceimaging.github.io/MRIReco.jl/latest/filehandling/#Conversion to convert the example Bruker data at http://media.tuhh.de/ibi/mrireco/brukerfileCart.zip to MRD/ISMRMRD

However, I cannot open the converted data using python's ismrmrd package,

File "/home/parallels/.local/lib/python3.8/site-packages/ismrmrd/hdf5.py", line 200, in read_acquisition
    acq.data[:] = self._dataset['data'][acqnum]['data'].view(np.complex64).reshape((acq.active_channels, acq.number_of_samples))[:]
ValueError: cannot reshape array of size 96 into shape (0,0)

I can open the data in matlab, but a few fields are missing in the header structure - though I can reconstruct the dataset with some workarounds.

MRD header encoding sub-structure:

 |--- encoding
   |       |    
   |       |--- encodedSpace
   |       |       |    
   |       |       |--- fieldOfView_mm
   |       |       |       |    
   |       |       |       |-- x : 0.027
   |       |       |       |-- y : 0.027
   |       |       |       |-- z : 0.0125
   |       |       |    
   |       |       |--- matrixSize
   |       |       |       |    
   |       |       |       |-- x : 96
   |       |       |       |-- y : 96
   |       |       |       |-- z : 1
   |       |       |    
   |       |    
   |       |--- encodingLimits
   |       |       |    **missing**
   |       |    
   |       |--- parallelImaging
   |       |       |    **missing**
   |       |    
   |       |--- reconSpace
   |       |       |   **missing**
   |       |--- trajectoryDescription
   |       |       |    
   |       |    
   |       |------------- trajectory : 'cartesian'
   |       |-------- echoTrainLength : [ ]
tknopp commented 2 years ago

Hi @rajramasawmy, thank you for the bug report!

I fixed the missing reconSpace on master so that you can test this out. I also added a dummy entry for parallelImaging. The reconSize of the data is 128x128. I am not sure if that reconSize I get from BrukerFile is the same as the one we have in the ISMRMRD file.

encodingLimits are still missing. Not sure if the python software requires that. If yes: could you say what entries within encodingLimits are actually used?

tknopp commented 2 years ago

I also added the encoding limits (at least partially).

rajramasawmy commented 2 years ago

Hey @tknopp sorry for the delay!

Here is a printout of the encoding structure (for spiral, showing userParameter options too):

|--- encodedSpace
   |       |    
   |       |--- fieldOfView_mm
   |       |       |    
   |       |       |-- x : 240
   |       |       |-- y : 240
   |       |       |-- z : 5
   |       |    
   |       |--- matrixSize
   |       |       |    
   |       |       |-- x : 320
   |       |       |-- y : 320
   |       |       |-- z : 1
   |       |    
   |    
   |--- encodingLimits
   |       |    
   |       |--- average
   |       |       |    
   |       |       |--- center : 0
   |       |       |-- maximum : 5
   |       |       |-- minimum : 0
   |       |    
   |       |--- contrast
   |       |       |    
   |       |       |--- center : 0
   |       |       |-- maximum : 0
   |       |       |-- minimum : 0
   |       |    
   |       |--- kspace_encoding_step_1
   |       |       |    
   |       |       |--- center : 160
   |       |       |-- maximum : 79
   |       |       |-- minimum : 0
   |       |    
   |       |--- kspace_encoding_step_2
   |       |       |    
   |       |       |--- center : 0
   |       |       |-- maximum : 0
   |       |       |-- minimum : 0
   |       |    
   |       |--- phase
   |       |       |    
   |       |       |--- center : 0
   |       |       |-- maximum : 0
   |       |       |-- minimum : 0
   |       |    
   |       |--- repetition
   |       |       |    
   |       |       |--- center : 0
   |       |       |-- maximum : 0
   |       |       |-- minimum : 0
   |       |    
   |       |--- segment
   |       |       |    
   |       |       |--- center : 0
   |       |       |-- maximum : 0
   |       |       |-- minimum : 0
   |       |    
   |       |--- set
   |       |       |    
   |       |       |--- center : 0
   |       |       |-- maximum : 0
   |       |       |-- minimum : 0
   |       |    
   |       |--- slice
   |       |       |    
   |       |       |--- center : 0
   |       |       |-- maximum : 10
   |       |       |-- minimum : 0
   |       |    
   |    
   |--- parallelImaging
   |       |    
   |       |--- accelerationFactor
   |       |       |    
   |       |       |-- kspace_encoding_step_1 : 1
   |       |       |-- kspace_encoding_step_2 : 1
   |       |    
   |       |----- calibrationMode : 'other'
   |    
   |--- reconSpace
   |       |    
   |       |--- fieldOfView_mm
   |       |       |    
   |       |       |-- x : 240
   |       |       |-- y : 240
   |       |       |-- z : 5
   |       |    
   |       |--- matrixSize
   |       |       |    
   |       |       |-- x : 320
   |       |       |-- y : 320
   |       |       |-- z : 1
   |       |    
   |    
   |--- trajectoryDescription
   |       |    
   |       |--- userParameterDouble(1)
   |       |       |    
   |       |       |--- name : 'example1'
   |       |       |-- value : 1
   |       |    
   |       |--- userParameterDouble(2)
   |       |       |    
   |       |       |--- name : 'example2'
   |       |       |-- value : 2
   |       |    
   |       |--- userParameterLong(1)
   |       |       |    
   |       |       |--- name : 'interleaves'
   |       |       |-- value : 40
   |       |    
   |       |--- userParameterLong(2)
   |       |       |    
   |       |       |--- name : 'example3'
   |       |       |-- value : 3
   |       |    
   |       |----------- identifier : 'example4'
   |    
   |------------- trajectory : 'spiral'
   |-------- echoTrainLength : [ ]
rajramasawmy commented 2 years ago

The encoding-limits are the overall experiment dimensions, which can be extracted from the data>acquisition header as well (which was my workaround). I was using the xml header to grab the experimental dimensions to set-up my kspace object.

tknopp commented 2 years ago
tknopp commented 2 years ago

https://github.com/MagneticResonanceImaging/MRIReco.jl/blob/master/src/IO/Brukerfile.jl#L330

Here you can see how I extract the encoding limit data from the headers of the profiles.

rajramasawmy commented 2 years ago

Thanks, I'll test it out! I dont work with Bruker data right now, but I was using the toolbox as demonstration of bruker to mrd conversion using open-source software: https://github.com/rajramasawmy/mri_together_mrd

aTrotier commented 2 years ago

@rajramasawmy Did you manage to make it works ?