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

Philips scaling with when RW units present not including scale slope ? #493

Closed
drmclem opened this issue Mar 11, 2021 · 10 comments
Closed

Comments

@drmclem
Copy link

drmclem commented Mar 11, 2021

I have had a query from one of our users - It looks as if there is a problem with the scaling logic when the real world tags are present for the rescale slope and rescale intercept. For the "precise" conversion (FP in Philips terminology) the scale slope needs to also be taken into consideration but I think even though displayed in the logs only the RS and RI are being used leading to a conversion to the displayed value (matching the scanner console display) rather than the FP value.

Using RWVSlope:RWVIntercept = 0.596581:0
Philips Scaling Values RS:RI:SS = 0.596581:0:1.6765 (see PMC3998685)
Convert 20 DICOM as DICOM\DICOM_pCASL_rest_20210309125250_201a (128x128x20x1)

To Reproduce
Compare the nii output from data with and without the real world scaling tags but with identical conventional rescale tags - the scaling is different

Expected behavior
For FP output the results should be the same.

Chris Rorden's dcm2niiX version v1.0.20190902 (JP2:OpenJPEG) (JP-LS:CharLS) MSC1900 (64-bit Windows)
Found 4 DICOM file(s)
Philips Scaling Values RS:RI:SS = 0.596581:0:1.6765 (see PMC3998685)
Convert 1 DICOM as Z:\mjf_head\PCASL_ENHANCED_DICOM\DICOM\20210309125250_pCASL_rest_201_real (128x128x20x1)

Further info -
It looks like for this system that the real-world tags are present when the export is in classic dicom but are not present when the export is enhanced (no idea why this decision was made) but the conventional rescale tags are present in both versions.

Matthew

@neurolabusc
Copy link
Collaborator

@drmclem I propose changing the Image Scaling section of the Philips conversion notes. The new text is now explicit that precedence is given to the real world scaling. Further, the alternative scaling factors are available in the BIDS sidecar. The variation described by the user appears to describe differences in image export between Classic and Enhanced DICOM data. As you are one of the experts in this topic, I would be grateful if you could proof the text below and suggest edits.

Image Scaling

dcm2niix losslessy copies the raw data from DICOM to NIfTI format. These values are typically stored as 16-bit integers in the range -32768..32767. Both the DICOM and NIfTI formats describe how scaling intercept and slope values can be used to convert these raw values into calibrated values. For example, with an intercept of 0 and slope of 0.01 the raw value of 50 would be converted to 0.5.

The NIfTI header provides the scl_slope and scl_inter fields so each voxel value in the dataset is scaled as:

I = scl_slope * R + scl_inter

where R is the voxel value stored and I is the "true" transformed voxel intensity.

For all manufacturers except Philips, the scl_slope and scl_inter correspond to the DICOM tags 0028,1053 and 0028,1052, respectively.

Philips has three possible intensity transforms for their DICOM images (world (W), display (D), precise (P)). All of these transforms might be provided in a single DICOM image, while the NIfTI standard only designates a single scl_slope and scl_inter for each image. dcm2niix will retain the raw value (R) and sets the NIfTI scl_inter and scl_slope values for the desired intensity transform. dcm2niix will use W if possible. If this is not possible it will use P unless the user specifies -p n to disable the precise calculation resulting in D.

The formulas are provided below. The DICOM tags are in brackets (e.g. (0040,9225)) and the BIDS tag is in double quotes (e.g. "PhilipsRWVSlope"). Since all the scaling values are stored in the BIDS sidecar, you can always use these to generate your preferred intensity transform.

Inputs:
 R = raw stored value of voxel in DICOM without scaling
 WS = RealWorldValue slope (0040,9225) "PhilipsRWVSlope"
 WI = RealWorldValue intercept (0040,9224) "PhilipsRWVIntercept"
 RS = rescale slope (0028,1053) "PhilipsRescaleSlope"
 RI = rescale intercept (0028,1052) "PhilipsRescaleIntercept"
 SS = scale slope (2005,100E) "PhilipsScaleSlope"
Outputs:
 W = real world value
 P = precise value
 D = displayed value
Formulas:
 W = R * WS + WI
 D = R * RS + RI
 P = D / (RS * SS)

@drmclem
Copy link
Author

drmclem commented Mar 11, 2021 via email

neurolabusc added a commit that referenced this issue Mar 11, 2021
@drmclem
Copy link
Author

drmclem commented Mar 11, 2021

HI

I still think there may be a bug, or at least surprising behaviour. The problem is that the real world scaling with no units is not sufficient for cross scan comparison - either the scale slope needs to be included as well, or the user needs a third option - just using real world produces scans which can't be compared.

Essentially - the expected behaviour for users is to use all three values (RI,RS,SS) with RI and RS either coming from the traditional values or the RW values. I'll check on the edge case where RW has units .

Matthew

@neurolabusc
Copy link
Collaborator

neurolabusc commented Mar 11, 2021

So do you recommend the default behavior be to provide the transforms for P, and save the D if the user explicitly requests -p n? In other words, the W values are not desired? Alternatively, should W transform be applied if the units are known, e.g. Fieldmap in Hz?

@drmclem
Copy link
Author

drmclem commented Mar 11, 2021 via email

@neurolabusc
Copy link
Collaborator

neurolabusc commented Mar 11, 2021

You can find a Philips Fieldmap here. The stored values range from 18..4084 (~12 bit). For this example, you get the same rescale regardless of if you choose W,D,P intensity transforms:

BIDS JSON:

	"PhilipsRWVSlope": 0.2442,
	"PhilipsRWVIntercept": -500,
	"PhilipsRescaleSlope": 0.2442,
	"PhilipsRescaleIntercept": -500,
	"PhilipsScaleSlope": 4.095,

Derived NIfTI rescales:

W = scl_slope 0.24420, scl_intercept -500
D = scl_slope 0.24420, scl_intercept -500
P = scl_slope 0.24420, scl_intercept -499.99994

@drmclem
Copy link
Author

drmclem commented Mar 15, 2021

Hi

Think I have got to the bottom of this with some limited testings (so caveats etc.). To summarise the summary - if the image derives from a quantitaive method, or inline subtractions (ASL) then DV and FP scalings are identical - in otherwords applying the Scale Slope modification to the scaling is a NULL operation (give or take rounding error).

If however the dataset is an unaltered stream the applying the SS correction is needed to enable cross scan comparsion. So as of the moment (probably since release 5.6 and current 5.7)- adding the SS correction to the real world scaling values if present is required for normal scans for cross scan comparison (DV!=FP) and has no effect if the images are quantitive (DV==FP).

If you wanted to avoid the unecessary additional correction for on quantitive images (and not require the private tag 2005,100e in that case) it may be possible to identify them through the tag (0028,1054) RescaleType. Based on very limited checking so far this has the value "normalized" for images where DV!=FP and somthing else (US,Hz etc) when DV=FP.

This is only applicable for the most recent releases (5.6+) and applies whether the Realworld block is present or not.

Hope this is clear

Matthew

@neurolabusc
Copy link
Collaborator

@drmclem thanks. So are you happy for dcm2niix to provide the Precise scaling values (P, aka FP) by default and the Display values (D, aka DV) if the user selected -p n. In no case will dcm2niix provide the RealWorldValue scaling. Regardless of selection, the operands will be provided in the BIDS JSON file so a user can select any scaling factor they prefer later.

 D = R * RS + RI
 P = D / (RS * SS)

@drmclem
Copy link
Author

drmclem commented Mar 16, 2021

Hi - as an aside I think I assumed that that -p n did no conversion at all and returned the raw integers from the file.

I think also conceptually this isn't an issue with RealWorldValue per se as it it is currently an alternative location to the standard rescale values - in the cases I have seen if RWorld is present so have been the rescale tags - but I know cases in the wild where rescale has been missing (due to other software) but the RWorld has been the alternative.

I think the issue is whether it is desirable to always apply the SS value - at the moment it deosn't matter as it is either a null operation (SS=1/RS) when units/subtractions have been applied or it is isn't when the FP conversion is necessary. Just thinking to the future proof it - ideally you wouldn't apply the SS if not required but detecting the units or the equivalence of the reciprocal is error prone. The problem may be in the future if multiple RW blocks are added, or the private tag being set to the reciprocal is lost in the RW case.

M

@neurolabusc
Copy link
Collaborator

The raw pixel data values is always losslessly copied from the DICOM to the NIfTI. The only thing that changes is the NIfTI scl_slope and scl_inter values. With -p n' these are set to the rescale slope (0028,1053)and rescale intercept (0028,1052) , identical to behavior to the other manufacturers. One the other hand, the precise values adjust scl_slopeandscl_inter` based on the Philips precise scale slope (2005,100E). This does not matter for most MRI data that uses relative signal, but can matter for sequences like ASL, see PMC3998685.

yarikoptic added a commit to neurodebian/dcm2niix that referenced this issue Apr 6, 2021
* tag 'v1.0.20210317': (23 commits)
  CI: Travis updates submodules always from remote.
  Update dcm_qa_nih submodule.
  Remove diagnostic message
  help should describe accession number (rordenlab#496)
  Describe and provide kludge for mangled Canon DICOMs (rordenlab#495)
  Update Philips notes (rordenlab#493)
  Update dcm_qa submodule.
  Support Canon Enhanced DICOM (rordenlab#491)
  Use first recognized manufacturer tag (rordenlab#487)
  If mosaics where ANY volume is non-planar, save ALL volumes as 3D(rordenlab#481)
  Add notes
  Kludge to separate vNav files as 3D (rordenlab#481)
  Tell user to override merging (-m o) to separate coils, specific with fmrib usage that disrupts Siemens DCE processing (rordenlab#187)
  Forbid semicolon in filenames as Linux uses this for command concatenation and Windows function GetOpenFileName will truncate (rordenlab#425)
  report totalReadoutTime once
  EstimatedEffectiveEchoSpacing -> EffectiveEchoSpacing (rordenlab#480)
  GE Round factor for Total Readout Time
  Update explicit naming of DICOMs (rordenlab#252), GE file naming changes (rordenlab#476)
  Update issue templates
  GE TotalReadouTime, BEP009 fixes (rordenlab#476)
  ...
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