-
Notifications
You must be signed in to change notification settings - Fork 34
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
Segmentation Parsing #74
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks nice @CPBridge. I have added a few suggestions and comments here and there, but my two main concerns are:
- Handling of single-frame and multi-frame source images: The main question is whether we should try to take a general approach that would work for both cases, or implement specific methods for each case. I am ambivalent and see pros and cons for either approach.
- Types of return value of properties: Several of the properties assume that the values stored on the corresponding attributes have a specific highdicom type (e.g., CodedConcept). The type is enforced by the constructor methods (either via
__init__()
orfrom_dataset()
/from_sequence()
). However, I am wondering whether the properties should ensure that the returned values have the expected type (if it doesn't introduce too much overhead), because it's easy to miss the type casting in the alternative constructor methods and because the objects are mutable. We may also want to revisit the SR pull request.
Co-authored-by: Markus D. Herrmann <hackermd@users.noreply.github.com>
de81889
to
77ea145
Compare
@hackermd I have added full tests and this is ready for a full review. A couple of things to note since you last looked:
|
I'm not sure why the travis pipeline isn't running, and I can't see how to trigger it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice @CPBridge! I only have a couple of suggestions for your consideration, but am also fine with merging as is.
categories = [] | ||
for desc in self.SegmentSequence: | ||
if desc.segmented_property_category not in categories: | ||
categories.append(desc.segmented_property_category) | ||
|
||
return categories |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to rewrite this into a list comprehension for (potentially) improved performance?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can't be written as a list comprehension because the check is applied to the list that is being constructed. It appends the segmented property to the list only if it is not already in the list.
(It is also not possible to use a set here because CodedConcept is not hashable).
I think we are stuck with it the way it is, even if it's a bit ugly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can't be written as a list comprehension because the check is applied to the list that is being constructed. It appends the segmented property to the list only if it is not already in the list.
Right...
It is also not possible to use a set here because CodedConcept is not hashable
This is something we should consider adding. We may also want to add __hash__
to pydicom.sr.coding.Code
so that we can use instances as dictionary keys..
Co-authored-by: Markus D. Herrmann <hackermd@users.noreply.github.com>
@hackermd a few changes since the last review:
I think all previous comments have now been addressed and I don't have plans at the moment to add any more functionality in this PR. |
Actually, since it seems like there are still a few potentially gnarly things to resolve on #69, I think I recommend holding this here until we finalize both PRs. We may make some decisions on #69 with broad implications for this PR too, and we should aim for consistency of approach between the two. |
Merging into dev branch to continue refinement there alongside #69 |
Implementation of substantial parts of the planned segmentation parsing.
This begins with implementation of
from_dataset
/from_sequence
classmethods and "getter" properties for several classes:In order to check each of the above sequences for the required attributes in a less verbose, manual way, I implemented checks that a dataset contains the required attributes from a certain module automatically using the module definitions contained within highdicom. For now this functionality is private and lives in
highdicom._module_utils
.Beyond this, there are several new methods on the Segmentation class that allow users to get various properties of the segmentation image, search for segments and tracking id/uids using filters, and get pixel arrays. There are currently three different public methods for constructing pixel arrays:
get_pixels_by_source_instance
- This is intended for segmentations derived from (multiple) single-frame instances, where frames are indexed by the SOP Instance UID of the source frame.get_pixels_by_source_frame
- This is intended for segmentations derived from multiple-frame intances, where frames are indexed by the the frame number of the source frame.get_pixels_by_dimension_index_values
- Allows users to index by arbitrary dimension index values. This allows for a more general case where the segmentation may de derived from resampled source images.Considered out of scope for this PR but planned for future work:
from_dataset
method for DimensionIndexSequence - awaiting changes to the encoding behaviour in light of recent discussions around dimension organization uids.Everything seems to be working fine but this PR is currently provisional until tests are written.
@hackermd could you please comment on the general approach and the interface before tests are written?