ImagingDataCommons / highdicom

High-level DICOM abstractions for the Python programming language
https://highdicom.readthedocs.io
MIT License
168 stars 35 forks source link

Referenced Images in MeasurementsAndQualitativeEvaluations (TID 1501) #169

Closed CPBridge closed 2 years ago

CPBridge commented 2 years ago

Address #164

By adding:

Note that in order to do this I had to add things to the MeasurementsAndQualitativeEvaluations class that should not be present on the PlanarROIMeasurementsAndQualitativeEvaluations and VolumetricROIMeasurementsAndQualitativeEvaluations classes, and we find ourselves up against our old friend the Liskhov Substitution Principle. Therefore I changed the class hierarchy from this:

MeasurementsAndQualitativeEvaluations
└── _ROIMeasurementsAndQualitativeEvaluations
    ├── PlanarROIMeasurementsAndQualitativeEvaluations
    └── VolumetricROIMeasurementsAndQualitativeEvaluations

to this:

_MeasurementsAndQualitativeEvaluations
├── MeasurementsAndQualitativeEvaluations
└── _ROIMeasurementsAndQualitativeEvaluations
    ├── PlanarROIMeasurementsAndQualitativeEvaluations
    └── VolumetricROIMeasurementsAndQualitativeEvaluations

Note that this is in a narrow way a break to the public API in that two public classes (Planar, Volumetric...) are no longer subclasses of another public class: MeasurementsAndQualitativeEvaluations.

CPBridge commented 2 years ago

Tagging @fedorov who first suggested this as an issue

hackermd commented 2 years ago

Thanks @CPBridge. Let me think about the subclassing issue. It's conceptually nice for instances of all three classes to be an instance of MeasurementsAndQualitativeEvaluations. The templates have some differences, but they are all included in the same Content Sequence.

hackermd commented 2 years ago

@CPBridge I would prefer keeping the old class hierarchy. Couldn't the new parameters for get_image_measurement_groups() be supported in a more dynamic way without having to change class inheritance?

CPBridge commented 2 years ago

Couldn't the new parameters for get_image_measurement_groups() be supported in a more dynamic way without having to change class inheritance?

The parameters for get_image_measurement_groups() are fine, there's no need to change the class hierarchy for these.

The issue is these two things:

I'm not especially keen on one solution over the other, they are both a little ugly in my opinion. On balance I thought I'd go with changing the hierarchy, but we can go with the above instead if you prefer.

hackermd commented 2 years ago

I see. Thanks for the clarification. I agree with your notion of following it unless we have a very strong reason not to.

Maybe we should move away from inheritance and start using Protocol. The class that defines the protocol (interface) can be decorated with @runtime_checkable and can be used as a common type.

hackermd commented 2 years ago

What do you think about calling the base class or protocol class ImagingMeasurements (that's the name of the parent content item)?

CPBridge commented 2 years ago

Maybe we should move away from inheritance and start using Protocol. The class that defines the protocol (interface) can be decorated with @runtime_checkable and can be used as a common type.

Are you talking about for future parts of the library, or for this PR? I'm a little reluctant to completely restructure this part (and only this part) of the templates code. The main reason for inheritance here is reducing code duplication, and Protocol doesn't help there, right?

What do you think about calling the base class or protocol class ImagingMeasurements (that's the name of the parent content item)?

Sure, but we don't want it to be a public class, do we? So _ImagingMeasurements?

hackermd commented 2 years ago

Are you talking about for future parts of the library, or for this PR? I'm a little reluctant to completely restructure this part (and only this part) of the templates code. The main reason for inheritance here is reducing code duplication, and Protocol doesn't help there, right?

It doesn't help with that. However, it would give us a type so that we woulnd't have to write Union[MeasurementsAndQualitativeEvaluations, PlanarROIMeasurementsAndQualitativeEvaluations, VolumetricMeasurementsAndQualitativeEvaluations] to refer to them collectively.

Sure, but we don't want it to be a public class, do we? So _ImagingMeasurements?

I was thinking to make it public to be able to refer to these "groups" collectively. They are very similar (at least conceptually) and (should) share a common interface (finding type, finding site, etc.).

hackermd commented 2 years ago

@CPBridge as discussed, let's keep the base class private for the time being.

CPBridge commented 2 years ago

@hackermd Shall we merge this so that @fedorov can use it for his purposes on #164 ?