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

BF+ENH: Fixes to DICOM scaling, make frame filtering explicit #1342

Merged
merged 2 commits into from
Sep 5, 2024

Conversation

moloney
Copy link
Contributor

@moloney moloney commented Aug 12, 2024

Fixes how we handle DICOM scaling, particularly for Philips and multi-frame files. For Philips data scale factors without defined units should be avoided, and instead a private tag should be used to make image intensities comparable across series. For multi-frame DICOM, it is possible to have different scale factors (potentially coming from different tags) per-frame. We also prefer scale factors from a RealWorldValueMapping provided they have defined units.

The base Wrapper class now has a few new attributes and methods to support this functionality. In particular an attribute scale_factors that provides an array of slope/intercept pairs, and a method get_unscaled_data that will return the reordered/reshaped data but without the scaling applied. A vendor attribute was also added to better support vendor-specific implementation details.

For the MultiFrameWrapper I also added an attribute frame_order which exposes the order used to sort the frames, and use this to return the scale_factors in sorted order. While implementing this I kept bumping into issues due to the (implicit) frame filtering that was happening in the image_shape property, so I made this filtering explicit and configurable and moved it into the class initialization.

Fixes how we handle DICOM scaling, particularly for Philips and
multi-frame files. For Philips data scale factors without defined
units should be avoided, and instead a private tag should be used
to make image intensities comparable across series. For multi-frame
DICOM, it is possible to have different scale factors (potentially
coming from different tags) per-frame. We also prefer scale factors
from a RealWorldValueMapping provided they have defined units.

The base Wrapper class now has a few new attributes and methods to
support this functionality. In particular an attribute `scale_factors`
that provides an array of slope/intercept pairs, and a method
`get_unscaled_data` that will return the reordered/reshaped data but
without the scaling applied. A `vendor` attribute was also added
to better support vendor-specific implementation details.

For the MultiFrameWrapper I also added an attribute `frame_order`
which exposes the order used to sort the frames, and use this
to return the `scale_factors` in sorted order. While implementing
this I kept bumping into issues due to the (implicit) frame filtering
that was happening in the `image_shape` property, so I made this
filtering explicit and configurable and moved it into the class
initialization.
Copy link

codecov bot commented Aug 12, 2024

Codecov Report

Attention: Patch coverage is 94.45844% with 22 lines in your changes missing coverage. Please review.

Project coverage is 95.34%. Comparing base (33c6721) to head (f0264ab).
Report is 3 commits behind head on master.

Files with missing lines Patch % Lines
nibabel/nicom/dicomwrappers.py 91.53% 8 Missing and 8 partials ⚠️
nibabel/nicom/tests/test_dicomwrappers.py 97.96% 2 Missing and 2 partials ⚠️
nibabel/nicom/utils.py 81.81% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1342      +/-   ##
==========================================
- Coverage   95.35%   95.34%   -0.01%     
==========================================
  Files         207      207              
  Lines       29238    29481     +243     
  Branches     4905     4981      +76     
==========================================
+ Hits        27881    28110     +229     
- Misses        925      930       +5     
- Partials      432      441       +9     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@moloney
Copy link
Contributor Author

moloney commented Aug 12, 2024

Also, this allows us to get data out of multi-frame files with more than one StackID. By default the lowest StackID will be used and a warning will be issued, but a user can pass in a frame filter that explicitly selects the StackID. I haven't run into this situation yet but it is mentioned here.

@effigies
Copy link
Member

effigies commented Sep 5, 2024

@moloney Thanks for this (and thanks for your patience)!

@effigies effigies merged commit d15ec58 into nipy:master Sep 5, 2024
48 of 49 checks passed
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

Successfully merging this pull request may close these issues.

2 participants