Creating streamlined workflows in Slicer
Add ideas for discussion here!
Discussion topics:
CART (Collaborative Annotation and Review Tool) provides a set of abstract base classes for creating streamlined annotation workflows in 3D Slicer. The framework enables efficient iteration through medical imaging cohorts with customizable tasks and flexible data loading strategies.
With inspiration from SlicerCART, mpReview, and CaseIterator
The framework enforces only one requirement:
uid
column for unique case identificationWe chose CSV for its simplicity and universal usage - it’s human-readable, version-controllable, and supported by every data processing tool.
The key innovation is the DataUnit abstraction layer that decouples data sources from task logic:
CSV (uid + metadata) → DataUnit → Task Logic
↓ ↓ ↓
Universal Pluggable Reusable
Interface Loaders Tasks
This design enables multiple data loading strategies:
class VolumeOnlyDataUnit(DataUnitBase):
# Loads .nrrd files from local filesystem
# Supports relative paths with configurable base directory
class DICOMDataUnit(DataUnitBase):
# Query DICOM database by SeriesInstanceUID
# Automatic series type detection and loading
# Built-in de-identification handling
class CloudDataUnit(DataUnitBase):
# Download from S3, Google Cloud, or IDC
# Automatic caching and prefetching
# Authentication handling
Tasks don’t need to know whether data comes from local files, DICOM databases, or cloud storage. They simply request resources through the standard get_resource(key)
interface.
Switch from local NIfTI files to a DICOM database by changing only the DataUnit type - no task code changes required.
Data engineers can optimize loading strategies while UI developers focus on annotation workflows, all working against the same abstract interface.
Tasks can define sophisticated view layouts and multi-volume displays without coupling to specific data formats.
The framework is designed to support prefetching multiple scenes for improved performance:
Tasks can implement sophisticated display logic:
class MultiContrastTask(TaskBaseClass):
def setup(self, data_unit):
# Custom layout: T1w background, T2w foreground, FLAIR in separate view
volumes = [data_unit.get_resource(key) for key in ['T1w', 'T2w', 'FLAIR']]
self.layoutLogic.viewerPerVolume(volumes, background=volumes[0])
The only requirement is a uid
column.
All other columns are interpreted as resource identifiers.
We support saving to the Input CSV or a separate output CSV.:
uid,T1w,T2w,segmentation,notes
patient_001,/data/001/t1.nrrd,/data/001/t2.nrrd,,needs_review
patient_002,/data/002/t1.nrrd,/data/002/t2.nrrd,/segs/002.nrrd,complete
class MyDataUnit(DataUnitBase):
def _validate(self):
# Ensure your data meets requirements
def _initialize_resources(self):
# Load data into Slicer scene
def to_dict(self):
# Export for saving back to CSV
class MyTask(TaskBaseClass):
def buildGUI(self, container):
# Build your annotation interface
def setup(self, data_unit):
# Configure views and load data
def save(self):
# Save annotations/results
uid
column with unique identifiersGet Started by simply selecting your CSV file in the module interface.
And Select your “User” or add a new one.
You can Then navigate through your data using the “Next” and “Previous” buttons.
Select your task from the dropdown menu.
And complete the “Action” you want to perform. And you can still use the same
“Next” and “Previous” buttons to navigate through your data.