Skip to content

Conversation

@CPBridge
Copy link
Collaborator

Working PR to update legacy conversion, building on the work done by @afshinmessiah in #34. Supersedes #34

@CPBridge CPBridge self-assigned this Jan 23, 2026
"""
self.mixed_frames = single_frame_list
self.mixed_frames_copy = self.mixed_frames[:]
self._distinguishing_attribute_keywords = [
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fedorov see here

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR revamps the legacy conversion functionality for DICOM images, building on work from PR #34. It introduces a comprehensive framework for converting single-frame legacy DICOM images (CT, MR, PET) to multi-frame enhanced images, inspired by David Clunie's PixelMed implementation.

Changes:

  • Complete rewrite of the legacy conversion module with new class architecture (_FrameSet, _FrameSetCollection, _CommonLegacyConvertedEnhancedImage)
  • Enhanced test suite with new DicomGenerator helper class for generating test DICOM datasets
  • Support for frame set detection, shared/per-frame attribute classification, and modular conversion through build blocks

Reviewed changes

Copilot reviewed 1 out of 2 changed files in this pull request and generated 19 comments.

File Description
tests/test_legacy.py Adds comprehensive test infrastructure with DicomGenerator class and new test cases for conversion, frame set detection, and attribute handling
src/highdicom/legacy/sop.py Complete rewrite introducing new architecture for legacy-to-enhanced DICOM conversion with frame set management and modular attribute copying

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

setattr(pffg, seq_kw, [inner_item])

def _add_composite_instance_contex_module(self) -> None:
"""Copies/adds a `composite_instance_contex` multiframe module to
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in docstring: "composite_instance_contex" should be "composite_instance_context" (missing 't' in 'context').

Suggested change
"""Copies/adds a `composite_instance_contex` multiframe module to
"""Copies/adds a `composite_instance_context` multiframe module to

Copilot uses AI. Check for mistakes.
tmp_dataset.PhotometricInterpretation = 'MONOCHROME2'
tmp_dataset.PixelData = pixel_array
tmp_dataset.PositionReferenceIndicator = 'XY'
tmp_dataset.ProtocolName = 'some protocole'
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: 'protocole' should be 'protocol' (extra 'e').

Suggested change
tmp_dataset.ProtocolName = 'some protocole'
tmp_dataset.ProtocolName = 'some protocol'

Copilot uses AI. Check for mistakes.
)
setattr(pffg, seq_kw, [inner_item])

def _add_composite_instance_contex_module(self) -> None:
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in method name: "_add_composite_instance_contex_module" should be "_add_composite_instance_context_module" (missing 't' in 'context').

Copilot uses AI. Check for mistakes.
self._build_blocks.extend(
[
[self._add_image_pixel_module, None],
[self._add_composite_instance_contex_module, None],
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in method name reference: "_add_composite_instance_contex_module" should be "_add_composite_instance_context_module" (missing 't' in 'context').

Suggested change
[self._add_composite_instance_contex_module, None],
[self._add_composite_instance_context_module, None],

Copilot uses AI. Check for mistakes.
self.PerFrameFunctionalGroupsSequence,
self._legacy_datasets
):
self._add_referenced_image_module_to_dataset(legacy, item)
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The method is calling "_add_referenced_image_module_to_dataset" instead of "_add_pixel_value_transformation_module_to_dataset". This appears to be a copy-paste error. The loop should be calling the pixel value transformation method, not the referenced image method.

Suggested change
self._add_referenced_image_module_to_dataset(legacy, item)
self._add_pixel_value_transformation_module_to_dataset(
legacy,
item,
)

Copilot uses AI. Check for mistakes.
tmp_dataset.AdditionalPatientHistory = 'UTERINE CA PRE-OP EVAL'
tmp_dataset.ContentDate = date_
tmp_dataset.ContentTime = datetime.now().time()
tmp_dataset.Manufacturer = 'Mnufacturer'
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: 'Mnufacturer' should be 'Manufacturer' (missing 'a').

Suggested change
tmp_dataset.Manufacturer = 'Mnufacturer'
tmp_dataset.Manufacturer = 'Manufacturer'

Copilot uses AI. Check for mistakes.
Parameters
----------
source: pydicom.Dataset
Source fataset from which the module's attribute values are copied
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in docstring: 'fataset' should be 'dataset' (incorrect letter 'f').

Suggested change
Source fataset from which the module's attribute values are copied
Source dataset from which the module's attribute values are copied

Copilot uses AI. Check for mistakes.
legacy_datasets
)

super(_Image, self).__init__(
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First argument to super() should be _CommonLegacyConvertedEnhancedImage.

Suggested change
super(_Image, self).__init__(
super(_CommonLegacyConvertedEnhancedImage, self).__init__(

Copilot uses AI. Check for mistakes.
def _find_per_frame_and_shared_tags(self) -> None:
"""Detects and collects all shared and perframe attributes"""
rough_shared: Dict[BaseTag, List[DataElement]] = defaultdict(list)
sh_tgs = set()
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assignment to 'sh_tgs' is unnecessary as it is redefined before this value is used.

Suggested change
sh_tgs = set()

Copilot uses AI. Check for mistakes.
ratio = fr_ds.LossyImageCompressionRatio
try:
sum_compression_ratio += float(ratio)
except BaseException:
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Except block directly handles BaseException.

Suggested change
except BaseException:
except (TypeError, ValueError):

Copilot uses AI. Check for mistakes.
@CPBridge CPBridge mentioned this pull request Jan 23, 2026
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.

3 participants