Skip to content

Modernize itk::GDCMSeriesFileNames onto gdcm::IPPSorter/Scanner (drop deprecated gdcm::SerieHelper) #6467

Description

@hjmjohnson

Summary

itk::GDCMSeriesFileNames is built entirely on gdcm::SerieHelper, which GDCM itself documents as deprecated backward-compatibility code that should not be used in new code. This issue tracks reimplementing GDCMSeriesFileNames on GDCM's supported modern API (gdcm::Scanner for series grouping + gdcm::IPPSorter for geometric ordering).

Split out of #2735 (the GDCM-side concern); the DCMTK-side concerns from that issue are tracked there and addressed by #6466.

Evidence that SerieHelper is deprecated

Modules/ThirdParty/GDCM/src/gdcm/Source/MediaStorageAndFileFormat/gdcmSerieHelper.h:

// line 48: Backward only class do not use in newer code
// line 63: DO NOT USE this class, it is only a temporary solution for ITK
//          migration from GDCM 1.x to GDCM 2.x
// line 66: Instead see ImageHelper or IPPSorter

This is the documentation the original reporter referenced:

image

The "situation the authors are aware of" is the deprecation, not a memory leak — see the leak analysis in #2735 (verified: gdcm::FileList is std::vector<SmartPointer<FileWithName>>, Clear()/~SerieHelper() free everything, no leak).

Current dependency surface

itk::GDCMSeriesFileNames is the only ITK consumer of SerieHelper (Modules/IO/GDCM/src/itkGDCMSeriesFileNames.cxx). Calls used:

SerieHelper call Purpose
SetDirectory(dir, recursive) scan input dir
SetUseSeriesDetails / AddRestriction / CreateDefaultUniqueSeriesIdentifier series-detail grouping
GetFirstSingleSerieUIDFileSet / GetNextSingleSerieUIDFileSet iterate distinct series
CreateUniqueSeriesIdentifier(file) series id
OrderFileList(flist) geometric slice ordering (IPP on slice normal)
SetLoadMode (LD_NOSEQ / LD_NOSHADOW) load-sequences / private-tags toggles
Clear reset between directories

Proposed implementation (modern GDCM API)

Replace the SerieHelper member with:

  1. gdcm::DirectoryLoad(dir, recursive) to enumerate files (replaces SetDirectory).
  2. gdcm::ScannerAddTag() for SeriesInstanceUID (0020,000e) plus the detail/restriction tags; Scan(filenames); then group files by the concatenated tag values to form unique series identifiers (replaces GetFirst/NextSingleSerieUIDFileSet + CreateUniqueSeriesIdentifier). Default detail tags match CreateDefaultUniqueSeriesIdentifier: 0020,0011 / 0018,0024 / 0018,0050 / 0028,0010 / 0028,0011.
  3. gdcm::IPPSorterSort(filesOfOneSeries) for geometric ordering (replaces OrderFileList). API: SetComputeZSpacing, SetZSpacingTolerance, SetDirectionCosinesTolerance, SetDropDuplicatePositions, GetZSpacing.

Compatibility risks (must be handled / pinned by tests)

gdcm::IPPSorter is stricter than SerieHelper::OrderFileList:

  • Fails on duplicate IPP (returns false). SerieHelper tolerated it. Need a fallback (ImageNumber / file-name ordering, matching SerieHelper's fallback chain) when IPPSorter::Sort fails, or opt into SetDropDuplicatePositions — but dropping changes the returned file count, a behavior change.
  • Gantry tilt is treated as an error by IPPSorter (documented \bug).
  • Non-image SOP classes — IPPSorter assumes sortable image datasets.
  • LD_NOSEQ / LD_NOSHADOW load-mode performance hints have no direct Scanner equivalent; evaluate scan cost.

Because of these, the rewrite must preserve GDCMSeriesFileNames's current observable contract (ordering, file counts, multi-series separation) — pin it with regression tests over existing multi-series fixtures before swapping the backend.

Acceptance

  • itk::GDCMSeriesFileNames no longer references gdcm::SerieHelper.
  • Existing GDCMSeriesFileNames / ImageSeriesReader tests pass unchanged (ordering, UIDs, restrictions, recursive).
  • Fallback path covered when IPP ordering is not possible (duplicate IPP / missing IPP).

Provenance

GDCM-side content extracted from #2735 (reported by @PHLF). Related: the DCMTK analog of this geometric ordering shipped in #6464 (issue #6463) and the DCMTK parity items in #6466 — useful reference for the IPP-on-normal algorithm and the series-detail identifier construction.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions