Modality and Classification Schema
Flywheel uses a structured, vocabulary-controlled classification scheme for labeling file content. Each modality (for example, MR, CT, or PET) specifies the valid classification aspects and values for files acquired with that modality.
Unlike free-form metadata in info, classification values are constrained by the modality vocabulary defined on the site.
Warning
Starting in Flywheel 21.4.0, when a gear outputs a file with a classification value that does not match the defined classification schema, Flywheel logs a warning in the job log. In a future major version, invalid classification output will cause the job to fail. Ensure that your site's schema is updated to match users' data workflow needs and that gear output is adhering to this schema. See Upcoming Change: Gear Output Classification Validation for additional information.
What the classification schema is
The classification schema organizes file content along multiple dimensions called aspects. The available aspects and their allowed values depend on the file's modality.
For example, the MR modality defines the following aspects:
Intent— Structural, Functional, Localizer, etc.Measurement— T1, T2, Diffusion, etc.Features— 2D, 3D, Multi-Echo, etc.Contrast- Contrast, No ContrastScan Orientation- Axial, Sagittal, Coronal, Oblique
A Custom aspect is always available for any file regardless of modality, and accepts arbitrary string values.
How classification differs from info metadata
| Feature | Classification | Info |
|---|---|---|
| Structure | Vocabulary-controlled aspect lists | Free-form JSON dict |
| Validation | Values validated against modality schema | No validation |
| Filtering | Supported via Finder queries | Supported via Finder queries |
| Purpose | Label file content type and intent | Store arbitrary key-value data |
Managing modality definitions
Modalities are site-wide objects that define which classification aspects and allowed values are available for a given imaging type. The SDK supports full create, read, update, and delete (CRUD) operations on modality definitions.
Modality fields
| Field | Type | Description |
|---|---|---|
id | str | Modality identifier (e.g., "MR", "CT") |
classification | dict[str, list[str]] | Aspect names mapped to lists of allowed values |
active | bool | Whether the modality is enabled on the site |
description | str | Optional human-readable description |
The classification dict maps each aspect name (e.g., "Measurement") to the list of vocabulary values allowed under that aspect.
Listing all modalities
modalities = fw.get_all_modalities()
for mod in modalities:
print(mod.id, mod.active)
Inspecting the classification vocabulary
The classification vocabulary for each modality is stored in the modality object.
Adding a modality
Use ModalityInput to create a new modality. The id field becomes the modality identifier used in file classification:
from flywheel.models.modality_input import ModalityInput
fw.add_modality(
ModalityInput(
id=modality_id,
description="Test modality for docs",
active=True,
classification={
"Anatomy": ["Chest", "Abdomen", "Extremity"],
"View": ["AP", "Lateral", "PA"],
},
)
)
Replacing a modality
fw.replace_modality() does a full replacement of the classification vocabulary. Use ModalityModify to supply the updated fields. Unlike ModalityInput, ModalityModify does not take an id — the modality to update is identified by the first argument:
from flywheel.models.modality_modify import ModalityModify
fw.replace_modality(
modality_id,
ModalityModify(
description="Test modality (updated)",
active=True,
classification={
"Anatomy": ["Chest", "Abdomen", "Extremity", "Spine"],
"View": ["AP", "Lateral", "PA", "Oblique"],
},
),
)
Note
replace_modality overwrites the entire classification dict. Any aspects or values not included in the new definition are removed.
Deleting a modality
Warning
Deleting a modality removes the classification vocabulary, but does not clear the modality and classification from files. Files already classified with the deleted modality retain their existing classification values and will raise validation errors on some file operations if the deleted modality is not cleared from the file metadata. See Metadata: File Classification for how to replace or remove classifications from files.
Upsert pattern
When syncing modality definitions from an external source, check whether each modality already exists before deciding to create or replace it:
from flywheel.models.modality_input import ModalityInput
from flywheel.models.modality_modify import ModalityModify
current_modalities = fw.get_all_modalities()
current_ids = [mod.id for mod in current_modalities]
if modality_id in current_ids:
fw.replace_modality(
modality_id,
ModalityModify(
classification=new_classification,
active=True,
description=new_description,
),
)
else:
fw.add_modality(
ModalityInput(
id=modality_id,
classification=new_classification,
active=True,
description=new_description,
)
)
Related pages
- Metadata: Info, Tags, and Notes — work with metadata on containers and files
- Data Classification product documentation - more information on data classification in Flywheel, including the default classification schema
- Upcoming Change: Gear Output Classification Validation - information on changes to how Flywheel handles files with invalid classification