-
Notifications
You must be signed in to change notification settings - Fork 2
Description
3D Slicer Extension Review: CrossSegmentationExplorer
Summary
This review identifies issues in the CrossSegmentationExplorer extension that may cause problems with Slicer integration, non-compliance with Slicer conventions, or incorrect/undesirable API usage.
Critical Issues
1. Module Naming Mismatch (Build Failure)
Severity: CRITICAL
The CMakeLists.txt in CrossSegmentationExplorer/ specifies:
set(MODULE_NAME CrossSegmentationExplorer)
set(MODULE_PYTHON_SCRIPTS ${MODULE_NAME}.py)However, the actual Python file is named SegmentationComparison.py, not CrossSegmentationExplorer.py.
Impact: The extension will fail to build because CMake will look for a non-existent file.
Files affected:
Fix: Either rename SegmentationComparison.py to CrossSegmentationExplorer.py OR change MODULE_NAME to SegmentationComparison.
2. UI Resource Mismatch (Build Failure)
Severity: CRITICAL
The CMakeLists.txt references:
Resources/UI/${MODULE_NAME}.uiThis expands to Resources/UI/CrossSegmentationExplorer.ui, but the actual file is named SegmentationComparison.ui.
Impact: Build will fail due to missing UI resource file.
Files affected:
3. Icon Resource Mismatch
Severity: CRITICAL
The CMakeLists.txt references:
Resources/Icons/${MODULE_NAME}.pngThis expands to Resources/Icons/CrossSegmentationExplorer.png, but the available icons are:
SegmentationComparison.pnglogo.pngSlicerVisible.png, etc.
Impact: Module icon will not be displayed; may cause build warnings or errors.
4. Class Name Does Not Match Module Convention
Severity: HIGH
In Slicer's ScriptedLoadableModule convention, the main class names should match the module name:
- Module file:
CrossSegmentationExplorer.py - Expected classes:
CrossSegmentationExplorer,CrossSegmentationExplorerWidget,CrossSegmentationExplorerLogic,CrossSegmentationExplorerTest
Current classes are named SegmentationComparison*, which breaks the convention.
Files affected:
High Priority Issues
5. Module-Level Observer Registration
Severity: HIGH
Location: SegmentationComparison.py:35
slicer.mrmlScene.AddObserver(slicer.mrmlScene.EndImportEvent, _restoreCustomLayout)This observer is registered at module import time (not within a class), which:
- Persists even after the module is unloaded
- Can cause issues during module reload/development
- Is not properly cleaned up
Recommendation: Move observer registration to the Widget's setup() method and ensure cleanup in cleanup().
6. Project Name Inconsistency
Severity: MEDIUM
Location: CMakeLists.txt:3
The top-level CMakeLists.txt declares:
project(SegmentationVerification)But the extension is named CrossSegmentationExplorer. This inconsistency can cause confusion and may affect extension identification.
7. Extension Dependency Added
Severity: INFO
Location: CMakeLists.txt:11
The extension now declares a dependency on QuantitativeReporting:
set(EXTENSION_DEPENDS "QuantitativeReporting")This dependency should be verified - ensure QuantitativeReporting is actually required. If the module only uses standard Slicer modules (DICOM, Segmentations), this dependency may be unnecessary and could prevent installation on systems without QuantitativeReporting.
API Usage Issues
8. Deprecated VTK Pattern for Mutable Strings
Severity: MEDIUM
Locations: Multiple occurrences, e.g., SegmentationComparison.py:1240
tag = vtk.mutable('')
if segment.GetTag('TerminologyEntry', tag):The vtk.mutable() pattern is older and less intuitive. Consider using the more modern approach with direct return value checking where available.
9. Missing MRML Scene Connection in UI
Severity: MEDIUM
Location: SegmentationComparison.py:97-99
The comment states:
# Set scene in MRML widgets. Make sure that in Qt designer the top-level qMRMLWidget's
# "mrmlSceneChanged(vtkMRMLScene*)" signal in is connected to each MRML widget's.
# "setMRMLScene(vtkMRMLScene*)" slot.But the UI file SegmentationComparison.ui has no connections defined:
<connections/>The code manually sets the scene for volumeNodeComboBox at line 101, but the recommended pattern is to use Qt Designer signal/slot connections.
10. Using slicer.util.getNode with Wildcard Pattern
Severity: MEDIUM
Locations:
layoutNode = slicer.util.getNode('*LayoutNode*')Using wildcards in getNode() is fragile and can return unexpected nodes. Use the proper API:
layoutNode = slicer.app.layoutManager().layoutLogic().GetLayoutNode()11. Incomplete Error Handling in DICOM Operations
Severity: MEDIUM
Locations:
DICOM database operations can fail for various reasons (no database, missing files, etc.), but many paths exit silently with return or return None without logging or user feedback.
Example:
def onLoadSegmentations(self):
volumeNode = self.ui.volumeNodeComboBox.currentNode()
instanceUIDsString = volumeNode.GetAttribute("DICOM.instanceUIDs") # Could be None
if instanceUIDsString:
firstInstanceUID = instanceUIDsString.split()[0] # Could fail if empty12. Direct Print Statements Instead of Logging
Severity: LOW
Locations:
print(e)
print(segmentation_series)Use the logging module imported at line 1 instead:
logging.error(f"Error: {e}")
logging.debug(f"Segmentation series: {segmentation_series}")13. Unused Import
Severity: LOW
Location: SegmentationComparison.py:8
import randomThe random module is imported but never used.
14. Typo in Comment
Severity: LOW
Location: SegmentationComparison.py:197
# Do not react to parameter node changes (GUI wlil be updated when the user enters into the module)"wlil" should be "will".
Code Quality Issues
15. Mixed Naming Conventions in Comments
Severity: LOW
Various comments use German spelling/terms like "Funktions" instead of "Functions":
- Line 290:
Initiliazes the Layout and the Funktions - Line 503:
#Funktions for the pop up/Dialog - Line 637:
#Funktions for both pop ups - Line 682:
showNeighboring Funktion - Line 846:
Calls funktion to initilize - Line 851:
diable funktions
16. Inconsistent String Comparison for Boolean Parameters
Severity: LOW
The code uses string comparisons for boolean parameters stored in the parameter node:
if value is not None:
widget.setChecked(value == "True")This is fragile - consider using a helper function or slicer.util.toBool().
17. Empty Test Case
Severity: MEDIUM
Location: SegmentationComparison.py:1861-1881
The test_SegmentationComparison1 method contains only initialization and a pass message:
def test_SegmentationComparison1(self):
self.delayDisplay("Starting the test")
logic = SegmentationComparisonLogic()
self.delayDisplay("Test passed")This does not actually test any functionality.
18. Module Dependencies Mismatch
Severity: MEDIUM
Location: SegmentationComparison.py:50
The Python module declares no dependencies:
self.parent.dependencies = []But the CMakeLists.txt declares:
set(EXTENSION_DEPENDS "QuantitativeReporting")These should be consistent. If QuantitativeReporting is required, it should be listed in the Python module's dependencies array as well.
Recommendations Summary
| Priority | Action |
|---|---|
| Critical | Fix module/file naming to match CMake expectations |
| Critical | Update UI and icon resource paths in CMakeLists.txt |
| High | Move module-level observer to widget lifecycle |
| Medium | Verify QuantitativeReporting dependency is needed |
| Medium | Synchronize Python module dependencies with CMake |
| Medium | Add proper error handling for DICOM operations |
| Medium | Implement meaningful unit tests |
| Low | Replace print statements with logging |
| Low | Remove unused imports |
Files Reviewed
CMakeLists.txt(root)CrossSegmentationExplorer/CMakeLists.txtCrossSegmentationExplorer/SegmentationComparison.pyCrossSegmentationExplorer/Resources/UI/SegmentationComparison.uiCrossSegmentationExplorer/Resources/UI/SegmentationModelsDialog.uiCrossSegmentationExplorer/Resources/UI/SegmentationGroupsDialog.uiCrossSegmentationExplorer/Testing/CMakeLists.txtCrossSegmentationExplorer/Testing/Python/CMakeLists.txt
Review generated on 2026-01-29