-
Notifications
You must be signed in to change notification settings - Fork 49
Auto Seg - fix loading from/into patient dictionary and patch ROI numbers #395
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
Conversation
…nt dictionary Refactored NiftiToRtstructConverter.py to load rtss from patient dictionary Add ROI number patch to fix/avoid "overwrite" when existing ROI numbers are greater than the length of the StructureSetROISequence
Move nifti file clean up to ensure proper removal
Removed debug print statement Add try catch to dcmread to log error
Updated RTStructFileLoader.py to load new rtss dataset into the patient dictionary - was inhibiting DVH calculations of segments Refactored NiftiToRtstructConverter.py to load rtss from patient dictionary Add ROI number patch to fix/avoid "overwrite" when existing ROI numbers are greater than the length of the StructureSetROISequence Added check for existing rtstruct file in NiftiToRtstructConverter.py Move Nifti file clean up to ensure proper removal of segmentation files
Reviewer's GuideThis PR refactors RTStruct handling by loading and saving from a patient dictionary, patches ROI numbering to avoid duplicates, adds existence checks for RTStruct files, reorders cleanup steps for robust file removal, and updates UI messaging and logging formatting. Sequence diagram for loading and saving RTStruct via patient dictionarysequenceDiagram
participant "AutoSegmentation"
participant "PatientDictContainer"
participant "RTStructBuilder"
participant "RTStructFileLoader"
"AutoSegmentation"->>"PatientDictContainer": Prepare output paths
"AutoSegmentation"->>"RTStructBuilder": Convert Nifti to RTStruct
alt RTStruct file exists in patient dictionary
"RTStructBuilder"->>"PatientDictContainer": Load rtss path
"RTStructBuilder"->>"RTStructBuilder": Load existing RTStruct from rtss path
else RTStruct file does not exist
"RTStructBuilder"->>"RTStructBuilder": Create new RTStruct
end
"RTStructBuilder"->>"PatientDictContainer": Save RTStruct to rtss path
"RTStructFileLoader"->>"PatientDictContainer": Load rtss file to patient dictionary
"RTStructFileLoader"->>"PatientDictContainer": Set dataset['rtss'] with dcmread(rtss_path)
ER diagram for RTStruct ROI number patchingerDiagram
RTStruct {
ROINumber int
StructureSetROISequence list
ROIContourSequence list
RTROIObservationsSequence list
}
StructureSetROISequence {
ROINumber int
}
ROIContourSequence {
ReferencedROINumber int
}
RTROIObservationsSequence {
ReferencedROINumber int
}
RTStruct ||--o{ StructureSetROISequence : contains
RTStruct ||--o{ ROIContourSequence : contains
RTStruct ||--o{ RTROIObservationsSequence : contains
StructureSetROISequence }o--|| RTStruct : references
ROIContourSequence }o--|| RTStruct : references
RTROIObservationsSequence }o--|| RTStruct : references
Class diagram for PatientDictContainer and RTStructBuilder changesclassDiagram
class PatientDictContainer {
+filepaths: dict
+dataset: dict
+set(key, value)
}
class RTStructBuilder {
+create_from(rt_struct_path, dicom_series_path)
+create_new(dicom_series_path)
+save(path)
+add_roi(mask, name)
}
PatientDictContainer "1" o-- "1" RTStructBuilder : uses rtss path
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
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.
Hey there - I've reviewed your changes - here's some feedback:
- The converter sets a new rtss_path when creating a fresh RTStruct but doesn’t update patient_dict_container.filepaths['rtss'], so the patient dictionary may still point to the old path—please sync the container path after creation.
- Before patching the last ROI’s ROINumber, add guards to ensure StructureSetROISequence, ROIContourSequence, and RTROIObservationsSequence exist and contain elements to avoid potential index errors.
- Consider renaming rtss_dataset to something more descriptive (e.g. rtstruct_ds) to clearly distinguish between the DICOM dataset object and the rtss file path variable.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The converter sets a new rtss_path when creating a fresh RTStruct but doesn’t update patient_dict_container.filepaths['rtss'], so the patient dictionary may still point to the old path—please sync the container path after creation.
- Before patching the last ROI’s ROINumber, add guards to ensure StructureSetROISequence, ROIContourSequence, and RTROIObservationsSequence exist and contain elements to avoid potential index errors.
- Consider renaming rtss_dataset to something more descriptive (e.g. rtstruct_ds) to clearly distinguish between the DICOM dataset object and the rtss file path variable.
## Individual Comments
### Comment 1
<location> `src/Model/AutoSegmentation/AutoSegmentation.py:66-75` </location>
<code_context>
self._copy_temp_dicom_dir()
self._run_totalsegmentation(task, roi_subset, output_dir)
self._convert_to_rtstruct(output_dir, output_rt)
- self._cleanup_nifti_dir(output_dir)
self.signals.finished.emit()
except Exception as e:
</code_context>
<issue_to_address>
**suggestion:** Moving cleanup to finally block may remove files needed for error analysis.
Consider making cleanup conditional or logging the output directory location before removal to support error analysis after failures.
```suggestion
self._copy_temp_dicom_dir()
self._run_totalsegmentation(task, roi_subset, output_dir)
self._convert_to_rtstruct(output_dir, output_rt)
self.signals.finished.emit()
cleanup_output_dir = True
except Exception as e:
self.signals.error.emit(str(e))
logger.exception("Segmentation workflow failed")
logger.info(f"Segmentation failed. Output directory retained for error analysis: {output_dir}")
cleanup_output_dir = False
finally:
if cleanup_output_dir:
self._cleanup_nifti_dir(output_dir)
self._cleanup_temp_dir()
```
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Set new rtss path when creating new file Change variable name rtss_dataset to rtstruct_ds
Pin fetch_cache to ubuntu-24.04
sjswerdloff
left a comment
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.
Excellent work. Surgical fixes.
AJB-BigA
left a comment
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.
Lgtm
Nowhere4Nothing
left a comment
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.
Legend, looks good 🤘
Updated RTStructFileLoader.py to load new rtss dataset into the patient dictionary - was inhibiting DVH calculations of segments
Refactored NiftiToRtstructConverter.py to load rtss from patient dictionary
Add ROI number patch to fix/avoid "overwrite" when existing ROI numbers are greater than the length of the StructureSetROISequence
Added check for existing rtstruct file in NiftiToRtstructConverter.py
Move Nifti file clean up to ensure proper removal of segmentation files
Summary by Sourcery
Refine auto-segmentation pipeline to better integrate RTStruct files via the patient dictionary, prevent ROI numbering collisions, and ensure proper cleanup and messaging.
Enhancements: