Skip to content

BUG: Throw on repeated slice positions in DCMTKSeriesFileNames - #7064

Open
hjmjohnson wants to merge 2 commits into
InsightSoftwareConsortium:mainfrom
hjmjohnson:bug-dcmtk-series-duplicate-position
Open

hjmjohnson wants to merge 2 commits into
InsightSoftwareConsortium:mainfrom
hjmjohnson:bug-dcmtk-series-duplicate-position

Conversation

@hjmjohnson

@hjmjohnson hjmjohnson commented Nov 1, 2026 •

Copy link
Copy Markdown
Member

DCMTKSeriesFileNames now throws when slice positions repeat, matching GDCMSeriesFileNames, and gains FailOnAmbiguousOrdering and DidUseAmbiguousOrdering. GDCM's DidUseAmbiguousOrdering no longer resets when a later series orders cleanly.

A series with repeated positions (multi-volume DWI, for example) has no geometric order and is not one 3D volume. DCMTK sorted it by position anyway and silently returned a position-major interleave, which mis-paired gradients in BRAINSTools DWIConvert.

Related: #6463, #6464, #6466, #6468

Behavior
  • GetFileNames() and GetInputFileNames() throw for a series whose positions along the slice normal repeat (tolerance 1e-3 mm). GetSeriesUIDs() still enumerates without throwing.
  • With FailOnAmbiguousOrdering off, the series comes back in InstanceNumber order when every slice has one and they are unique, else in file name order. This is the GDCM fallback, and also the DCMTK order in ITK 5.4.
  • DidUseAmbiguousOrdering is true when any series returned since the last directory parse was ambiguous. GDCM assigned it per series, so ordering a later, well-ordered series cleared it; it is now OR-ed and cleared only on a new parse.
  • Series without orientation or position keep the existing InstanceNumber, then file name, fallback and do not throw.
Local testing

Linux, GCC 13.3, Release. A minimal build with ITKIODCMTK, IOTransformDCMTK, and ITKIOGDCM: all 36 DCMTKSeriesFileNames*, GDCMSeriesFileNamesContract*, and GDCMSeriesDirection* GTests pass.

New tests:

  • DCMTKSeriesFileNamesParity.RepeatedPositionsThrowByDefault
  • DCMTKSeriesFileNamesParity.RepeatedPositionsFallBackWhenAllowed
  • DCMTKSeriesFileNamesParity.AmbiguityFlagIsSticky
  • DCMTKSeriesFileNamesParity.MissingInstanceNumberFallsBackToFileNames
  • GDCMSeriesFileNamesContract.AmbiguityFlagIsSticky (fails on the unfixed GDCM code, passes with the fix)

Downstream: BRAINSTools DWIConvert, built against this branch, passes all 52 of its tests (GE, Siemens, Philips, and Hitachi DWI series, several with repeated positions).

pre-commit run --all-files passes.

AI assistance

Claude Code researched how dcm2niix, dicm2nii, MRtrix3, and GDCM order DWI series, wrote the change and tests, and ran the builds above. I directed the design (throw by default, sticky flag) and reviewed the change.

🤖 Generated with Claude Code

@github-actions github-actions Bot added type:Bug Inconsistencies or issues which will cause an incorrect result under some or all circumstances type:Testing Ensure that the purpose of a class is met/the results on a wide set of test cases are correct area:IO Issues affecting the IO module labels Nov 1, 2026
@hjmjohnson
hjmjohnson marked this pull request as ready for review November 1, 2026 13:26
@greptile-apps

greptile-apps Bot commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no actionable new issues remain.

Summary

DCMTKSeriesFileNames now rejects repeated slice positions by default and offers an explicit fallback.

  • DCMTK series requests reject repeated slice positions unless callers opt into a fallback.
  • GDCM keeps its ambiguity flag set across later series requests.

Reviews (2) · Last reviewed commit: "BUG: Keep GDCMSeriesFileNames DidUseAmbi..." · Reviewed by Greptile

@hjmjohnson
hjmjohnson force-pushed the bug-dcmtk-series-duplicate-position branch from 93c0472 to 4dac4a9 Compare November 1, 2026 15:13
@hjmjohnson

Copy link
Copy Markdown
Member Author

@greptileai review

A series whose slice positions repeat (a multi-volume acquisition such
as DWI) has no geometric order, so it cannot be one 3D volume.
DCMTKSeriesFileNames sorted it by position anyway and silently returned
a position-major interleave, unlike GDCMSeriesFileNames, which throws.

Detect repeated positions along the slice normal and throw from
GetFileNames() and GetInputFileNames() by default. Add
FailOnAmbiguousOrdering and DidUseAmbiguousOrdering, matching
GDCMSeriesFileNames. With the exception disabled, the series is
returned in InstanceNumber order when the numbers are unique, else in
file name order, which is the GDCM fallback and the DCMTK order before
geometric sorting. GetSeriesUIDs() still enumerates without throwing.

Assisted-by: Claude Code — surveyed dcm2niix, GDCM, and DICOM ordering; wrote the change and tests
OrderSeries() assigned the flag for each series it ordered, so ordering
a later series with a valid geometry cleared the record of an earlier
ambiguous one. Set it with OR and clear it only when the directory is
parsed again.

Assisted-by: Claude Code — found the reset while testing DCMTK parity; wrote the fix and test
@hjmjohnson
hjmjohnson force-pushed the bug-dcmtk-series-duplicate-position branch from 4dac4a9 to b95470c Compare November 2, 2026 18:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:IO Issues affecting the IO module type:Bug Inconsistencies or issues which will cause an incorrect result under some or all circumstances type:Testing Ensure that the purpose of a class is met/the results on a wide set of test cases are correct

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant