Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should the Bruker reco_map_slope parameter be multiplied or divided? #29

Closed
r03ert0 opened this issue Aug 16, 2017 · 9 comments
Closed

Comments

@r03ert0
Copy link

r03ert0 commented Aug 16, 2017

the function slope_corrector applies the slope like data[]=data[]*slope, however
Here, the slope is applied as data[]=data[]/slope+offset
In my own data, applying the reco_map_slope values by dividing produces reasonable results: the values in the diffusion directions are smaller that those for b0 (the images look 'darker').

@SebastianoF
Copy link
Owner

SebastianoF commented Aug 17, 2017

Thanks your help in improving bruker2nifti, your feedback is very useful!

Thanks for the link. Please check the screenshot (page D2-66)
to the ParaVision manual (let me know if you need more pages and how can I send the to you).

The code parses the offset parameter but it does not apply it to correct the intensity as it has no impact. Adding a "correct_offset" would have been even more confusing, as it has no visual effect. Do you think I should add it?

About the intensity, to my understanding the b0 should have a lower intensity than the others, being the magnetic field some Tesla less stronger. Please correct me if I am wrong.

@r03ert0
Copy link
Author

r03ert0 commented Aug 17, 2017

Thank you for bruker2nifti! I had started hacking my own converter just by reading the reco, etc, files (here). I'm very happy that you are doing it right :D

You are correct about the b0. I had a vague image of an exponential decrease in image intensity, but this is the first dwi data i analyse, i'm just starting to learn about it : )

I just realised that the value you are using for correcting the slope is not the same I was using! You use VisuCoreDataSlope from visu_pars and I used RECO_map_slope from reco. I started using the RECO_map_slope correction because without it the tensor fitting produced values >1. The problem is what was describe here: http://community.mrtrix.org/t/using-bruker-2dseq-file-beware-reco-slope/613
The RECO_map_slope also comes with a RECO_map_offset, but that offset value seems to be always set to 0.

@r03ert0
Copy link
Author

r03ert0 commented Aug 17, 2017

[and i'd be happy to have the complete format definition if it's ok!]

@SebastianoF
Copy link
Owner

I'm starting to learn about it too.
Initially also this converter was based on the RECO param-file. Using only the visu_pars solved more issues that the one it created, so it may be a better option.

For the complete format definition let me know where I can send you some files.

@r03ert0
Copy link
Author

r03ert0 commented Aug 19, 2017

I tried multiplying the slope factor in RECO_map_slope, and the results are really awful. I continued to the tensor fitting, and the result were also abnormal.

I think that in fact the values are ment to be divided to recover the original image. In fact, in the manual (D-7-25) when they talk about reconstruction it's not the reconstruction of the original data, but the reconstruction of the data that's saved into the file:

Image Mapping 7.17
Image mapping is the phrase which is used to describe the way in which the final image data are generated. Since the reconstruction uses a floating point data representation internally and since all of the currently fully supported image formats use some integer representation of the data, a mapping function of some kind must always be used to generate the final images. The mapping function which is used is always a linear function, but the way in which it is selected is determined primarily by two parameters, the RECO_wordtype and the RECO_map_mode.

The conversion formula is like this:

m = RECO_map_min[i]
M = RECO_map_max[i]
b = RECO_map_offset[i]
s = RECO_map_slope[i]
x = floating point internal value
y = image pixel value

y = (M-b) if x>=M
y = (x-b)*s if m<x<M
y = (m-b)*s if x<=m

The important point is that the y values are the values stored in the file, and the x values are the original, floating point, internal values. So, to recover the original data, the transformation has to be inverted to:

x = y/s+b

Where b is most of the time zero, so that the transformation is basically x=y/s. When I use that transformation in the code, the tensor fitting and the FA make sense.

@SebastianoF SebastianoF reopened this Aug 19, 2017
@SebastianoF
Copy link
Owner

SebastianoF commented Aug 19, 2017

Interesting!
For my data, both PV version 5.1 and 6, the conversion worked well as in the version proposed, i.e. by multiplying for the visu_pars slope.

What is the ParaVision version used to create the files (do you have the parameter VisuCreatorVersion)?
Do we have to assume this depends on the PV version or on something else?

Would be helpful to have a copy of the RECO and visu_pars of your data.

For what I understood, the visu_pars is filled from the reco file and other parameter files (method and acqp) to provide a stand-alone parameter file to convert to DICOM.

My guess, that needs further investigations, is that the translation from reco+method+acqp to visu_pars for the DICOM conversion has not always been successful, in particular for old versions (check for example issue #11).

Integrating this ParaVision "feature" into the converter may be not that straight.

Probably @neurolabusc may have encountered this before.

@r03ert0
Copy link
Author

r03ert0 commented Aug 19, 2017

@SebastianoF
Copy link
Owner

Thanks, I see that the VisuCreatorVersion is 5.1 and the VisuCorePosition is HeadSupine.
So we can't rely on these variables as criteria to discriminate between datasets to change orientation and slope correction function.

And I agree the salt and pepper artefact can be caused by a mis-correction of the slope.

Time-points between 163 and 165 seems problematic, as if the problem was also in the slice reconstruction other than the slope (in particular 165 slice z=41).

Interestingly enough the protocol you used for the acquisition is a 2D (VisuAcqSize as dimension 2), while for my dataset is a 3D.
As a consequence the VisuCorePosition is in your case a matrix (n_slices x 3) , increasing from the y coordinate (stack are left to right), mine is a 1 x 3 matrix for the DWI with 3D protocol.

More interestingly, in the data I have, acquired with a 2D protocol (that are correctly converted), the VisuCorePosition is again a (n_slices x 3) increasing from the z coordinate (stacks are inferior to superior).

I think the "stack-direction" (x, y or z) when the acquisition protocol is 2D needs to be taken into account as a new variable. And this has an impact both on the orientation and the slope correction.

Need to do more tests and will let you know! Thanks again for the data.

@SebastianoF
Copy link
Owner

Function get_stack_direction_from_VisuCorePosition in _getters implemented. It will be integrated (in the next patch release) in the compute_affine_from_visu_pars as an additional information to decode the orientation matrix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants