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

Unable to load DICOM Segmentations from Siemens #280

Open
511photon opened this issue Mar 17, 2025 · 8 comments
Open

Unable to load DICOM Segmentations from Siemens #280

511photon opened this issue Mar 17, 2025 · 8 comments

Comments

@511photon
Copy link

Dear Quantitative Reporting Developers,

Thank you for all of your working in developing and maintaining this excellent extension. I have used it over many versions to import Segmentations for PET CT scans from Siemens Syngo Via workstations, However, in recent versions (the last working version is for 3DSlicer 5.2.2) it reports and error "Could not load: Unknown as a DICOM Segmentation". Consequently, I am stuck using version 5.2.2. Could this error be corrected in future versions of the extensions?

Best regards,

Ivan

@pieper
Copy link
Member

pieper commented Mar 17, 2025

Could you provide some sample data (no PHI please) that demonstrates the issue?

@fedorov
Copy link
Member

fedorov commented Mar 17, 2025

If you like, I can easily point you to a de-identified sample of a PET/CT scan so you could annotate it using your workstation and share the resulting segmentation that does not load.

Slicer 5.2.2 is really old, it is very difficult to say what is going on without a sample to reproduce the problem.

@511photon
Copy link
Author

25031806.zip

Dear Dr Pieper and Dr Fedorov,

Thanks both for the prompt reply. Phantom data (PET CT) with 1 segmentatation (for the PET data) created on Siemens Syngo Via attached. The segment loads correctly on 5.2.2 but not 5.8.1.

Best regards,

Ivan

@511photon
Copy link
Author

511photon commented Mar 18, 2025 via email

@fedorov
Copy link
Member

fedorov commented Mar 19, 2025

@511photon thank you for sharing the sample - this was super helpful.

For the sake of completeness, here's the error log from Slicer:

Convert DICOM Segmentation Image into ITK image(s) standard error:

W: DeviceSerialNumber (0018,1000) absent in EnhancedGeneralEquipmentModule (type 1)
W: SegmentedPropertyCategoryCodeSequence (0062,0003) absent in SegmentDescriptionMacro (type 1)
W: SegmentedPropertyTypeCodeSequence (0062,000f) absent in SegmentDescriptionMacro (type 1)
WARNING: SliceThickness is present and is 1. using it!
E: ensureFramesAreParallel(): Image Orientation Patient is per-frame, frames are probably not parallel
ERROR: Failed to convert DICOM SEG to ITK image: Frames are not parallel

Convert DICOM Segmentation Image into ITK image(s) completed with errors

Given that error, I checked your sample, and confirmed that it contains (identical) ImageOrientationPatient per-frame, in the PerFrameFunctionalGroups. If you are not familiar with how those objects are organized, DICOM attributes that are shared (identical) for all frames are expected to be in the SharedFunctionalGroups section and not duplicated per-frame. While providing them in the per-frame section is not forbidden, it makes interpretation more difficult.

I then checked the latest segimage2itkimage binary from the latest dcmqi release here https://github.com/QIICR/dcmqi/releases/tag/latest, and confirmed that your segmentation object can be converted without errors. dcmqi is the library that is used by Slicer QuantitativeReporting extension for conversion.

$ segimage2itkimage --inputDICOM ./1_3_12_2_1107_5_8_15_131453_30000025031816471323900000509.dcm --outputDirectory .
dcmqi repository URL: https://github.com/QIICR/dcmqi revision: 011237d tag:
Loading DICOM SEG file ./1_3_12_2_1107_5_8_15_131453_30000025031816471323900000509.dcm
W: DeviceSerialNumber (0018,1000) absent in EnhancedGeneralEquipmentModule (type 1)
W: SegmentedPropertyCategoryCodeSequence (0062,0003) absent in SegmentDescriptionMacro (type 1)
W: SegmentedPropertyTypeCodeSequence (0062,000f) absent in SegmentDescriptionMacro (type 1)
Row direction: 1 0 0
Col direction: 0 1 0
Z direction: 0 0 1
Total frames: 66
Total frames with unique IPP: 66
Total overlapping frames: 0
Origin: [-286.586, -172.986, 472.2]
Slice extent: 260
Slice spacing: 4
WARNING: SliceThickness is present and is 1. using it!
Will not merge segments: Splitting segments into 1 groups
Failed to get CIELab values - initializing to default 43803,26565,37722
Writing itk image to ./1.nrrd ... done

My guess is that the error is triggered in DCMTK (a dependency of dcmqi). The reason it works with the dcmqi binary, but does not work in Slicer is because Slicer builds dcmqi with a more recent version of DCMTK (3.6.8), while standalone dcmqi is still using 2-year old 3.6.6 version (there is on-going work to upgrade in QIICR/dcmqi#500).

I believe the error in DCMTK is a regression. In this case, values of ImageOrientationPatient appear to be identical, and I would expect DCMTK to check those if provided in PerFrameFunctionalGroups with some tolerance. @michaelonken what do you think?

@511photon you have the following options:

  1. use dcmqi segimage2itkimage command-line converter directly
  2. fix your DICOM SEG to put ImageOrientationPatient into SharedFunctionalGroups (either as a post-processing patch operation, or by fixing the software that generates it)
  3. wait for a fix in DCMTK, next stable release of DCMTK after fix, and following upgrade of DCMTK in Slicer

Option 1 is most practical, if it is feasible for you.

@michaelonken
Copy link
Member

I think I didn't change anything about how this works in DCMTK in the past. It depends on how the DCMTK API is used when getting the related Plane Orientation (Patient) functional group that contains Image Orientation Patient.

I see that in the current dcmqi the call seems to be always fgInterface.get(0, DcmFGTypes::EFG_PLANEORIENTPATIENT, isPerFrame)) which will get you the functional group (and therefore PlaneOrientationPatient eventually) always for the first frame. So dcmqi asssumes implicitly that the value is equal for all frames anyway. DCMTK just gives it to you for the desired frame (here: frame 0), no matter whether its shared or per-frame.

This method is used in framesorter.h, ConverterBase.h and OverlapUtil.cpp. The latter has been added in recent years in dcmqi but I think is not relevant when loading DICOM segmentation objects. I don't know about the rest of the occurrences.

Based on this "frame 0" usage pattern used in current dcmqi, my guess is that something changed in dcmqi.

@michaelonken
Copy link
Member

michaelonken commented Mar 19, 2025

P.S: The related error message comes from dcmqi, more specifically in OverlapUtil.cpp which has not been existing in early versions of dcmqi. Which probably does not really help to identify the problem ...

@fedorov
Copy link
Member

fedorov commented Mar 19, 2025

@michaelonken thank you for investigating this! I don't recall anything changing in dcmqi, and that is why I assumed DCMTK version change is the only change that could trigger this. I will need to investigate on dcmqi side. Unfortunately, I cannot compile dcmqi standalone with the latest DCMTK, and the error only happens with the latest DCMTK in Slicer.

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

4 participants