Skip to content

DICOM Connector Hierarchy Mapping Guide

Introduction

This document explains how the DICOM Connector maps DICOM data structures to the Flywheel hierarchy.

Both DICOM and Flywheel use a 3-level hierarchy for organizing medical imaging data:

Level DICOM Flywheel
Level 1 Patient Subject
Level 2 Study Session
Level 3 Series Acquisition

While the hierarchies align conceptually, they use different identification approaches:

  • DICOM: Uses globally unique identifiers (UIDs) to identify objects
    • PatientID for patients
    • StudyInstanceUID for studies
    • SeriesInstanceUID for series
  • Flywheel: Uses human-readable labels to identify containers
    • subject.label for subjects
    • session.label for sessions
    • acquisition.label for acquisitions

The DICOM Connector's mapping challenge is deriving appropriate Flywheel labels from DICOM metadata, since DICOM UIDs are not suitable for human-readable labels.

For information about metadata processing mechanics, see the Metadata Extraction Guide. For advanced configuration options, see the Advanced Configuration Guide.

Default Field Mappings

The following table shows standard mappings from DICOM tags to Flywheel fields:

Flywheel Field DICOM Tag Notes
group._id Routing field (e.g., PatientComments) Based on routing string parsing
project.label Routing field (e.g., PatientComments) Based on routing string parsing
subject.label Routing field (e.g., PatientComments) Based on routing string parsing
subject.firstname PatientName See name parsing rules
subject.lastname PatientName See name parsing rules
session.uid StudyInstanceUID
session.label Configured routing field (e.g., PatientComments) or header mapping (e.g., StudyDescription by default) Can be based on routing string parsing or directly mapped from other DICOM headers.
session.operator OperatorsName
session.timestamp StudyDate / StudyTime See timestamp parsing
acquisition.uid SeriesInstanceUID See UID processing rules
acquisition.label SeriesDescription
acquisition.timestamp AcquisitionDate / AcquisitionTime See timestamp parsing

Site-Specific Configurations

These are default mappings. Individual sites may use different DICOM tags for Flywheel fields. Consult your Site Administrator for site-specific mappings.

Key Label Mappings

Subject Level:

  • subject.labelPatientID (not PatientName)
  • Subject identification uses the DICOM patient identifier

Session Level:

  • session.labelStudyDescription
  • Session identification uses the study description text, not StudyInstanceUID

Acquisition Level:

  • acquisition.labelSeriesDescription
  • Acquisition identification uses the series description text, not SeriesInstanceUID

Multiple DICOM Series to One Flywheel Acquisition

Because Flywheel uses SeriesDescription (not SeriesInstanceUID) for acquisition.label, multiple DICOM series with the same description become a single Flywheel acquisition.

Common Scenarios:

  • Localizer Scans: Some modalities create separate series for each plane (axial, sagittal, coronal) with identical descriptions
  • Multi-Echo Sequences: Multiple echoes may be stored as separate series with the same description
  • Dynamic Series: Time-series acquisitions may be split into multiple series

Example:

1
2
3
4
5
DICOM Series 1: SeriesInstanceUID=1.2.3.4.5, SeriesDescription="T1_MPRAGE"
DICOM Series 2: SeriesInstanceUID=1.2.3.4.6, SeriesDescription="T1_MPRAGE"

Both map to:
Flywheel Acquisition: acquisition.label="T1_MPRAGE"

Whether this grouping is appropriate depends on your use case. Some customers prefer all related series grouped together; others require separation.

SeriesInstanceUID Processing

To address cases where UIDs need to influence Flywheel organization, the Connector applies special processing to SeriesInstanceUID:

Derived Series Handling

DICOMs with ImageType values DERIVED\SECONDARY\SCREEN SAVE or DERIVED\SECONDARY\VXTL STATE receive a "decremented" UID:

  • Original: SeriesInstanceUID=4.5.6
  • Processed: acquisition.uid=4.5.5

This groups derived series with their source series in Flywheel.

AcquisitionNumber Suffix

For non-Siemens manufacturers, when AcquisitionNumber > 1, the UID is suffixed with _{AcquisitionNumber}:

SeriesInstanceUID ImageType Manufacturer AcquisitionNumber acquisition.uid
1.2.3.4 ORIGINAL... (any) (any) 1.2.3.4
1.2.3.4 DERIVED... (any) (any) 1.2.3.3
1.2.3.4 (any) SIEMENS 2 1.2.3.4
1.2.3.4 (any) GE 2 1.2.3.4_2
1.2.3.4 (any) GE 1 1.2.3.4

This separates multi-part acquisitions into distinct Flywheel acquisitions.

Container Creation Rules

Understanding how containers are created helps predict where data will appear:

  • Groups: Desired group should be manually created in advance.
    • Unknown group is automatically created if desired group does not exist or if mapping string is missing or cannot be parsed.
  • Projects: Created based on routing string.
    • Ideally, the desired project is manually created in advance with the preferred settings. Otherwise, the DICOM connector will create it with default settings.
    • Unsorted project is created if mapping string is missing or cannot be parsed.
  • Subjects: Created based on routing string or derived from DICOM metadata (e.g., PatientID)
  • Sessions: Created based on routing string or derived from DICOM metadata (e.g., StudyDescription)
  • Acquisitions: Always created for each unique SeriesDescription

Routing String Processing

Format Specification

Valid routing strings follow this format:

fw://group/project/subject/session

Processing Rules

The Connector parses routing strings according to these rules:

Routing String Pattern Result Notes
fw://group/project/subject/session Complete routing Ideal case - all containers specified
fw://group/project/subject Partial routing Session name derived from StudyDescription
fw://group/project Group + Project only Subject and session from DICOM metadata
fw://group Group only Data goes to Unsorted Project
Invalid format or missing Default routing Data goes to Unknown Group

Container Resolution Logic

The DICOM Connector uses two decision processes to determine where data is placed in Flywheel:

Routing String Parsing:

The following flowchart shows how routing strings are parsed to determine target containers:

flowchart TD
    start([Routing String Input]) --> parse{Parse Routing String}

    parse -->|"fw://group/project/subject/session"| complete[Complete Routing Specified]
    parse -->|"fw://group/project/subject"| partial_subject[Partial Routing]
    parse -->|"fw://group/project"| partial_project[Group + Project Only]
    parse -->|"fw://group"| group_only[Group Only]
    parse -->|Invalid or missing| invalid[Invalid/Missing]

    complete --> result_complete[Group, Project, Subject, Session all specified]

    partial_subject --> session_fallback[Derive Session from StudyDescription]
    session_fallback --> result_partial_subject[Specified Group, Project, Subject + Derived Session]

    partial_project --> subject_fallback[Derive Subject from PatientID]
    subject_fallback --> session_fallback2[Derive Session from StudyDescription]
    session_fallback2 --> result_partial_project[Specified Group, Project + Derived Subject, Session]

    group_only --> unsorted_project["Use 'Unsorted' Project"]
    unsorted_project --> subject_fallback2[Derive Subject from PatientID]
    subject_fallback2 --> session_fallback3[Derive Session from StudyDescription]
    session_fallback3 --> result_group_only[Specified Group + Default Project + Derived Subject, Session]

    invalid --> unknown_group["Use 'Unknown' Group"]
    unknown_group --> unsorted_project2["Use 'Unsorted' Project"]
    unsorted_project2 --> subject_fallback3[Derive Subject from PatientID]
    subject_fallback3 --> session_fallback4[Derive Session from StudyDescription]
    session_fallback4 --> result_invalid[Default Group, Project + Derived Subject, Session]

    result_complete --> next[Proceed to Upload Decision]
    result_partial_subject --> next
    result_partial_project --> next
    result_group_only --> next
    result_invalid --> next

    style start fill:#e8f5e9
    style parse fill:#fff9c4
    style complete fill:#fff
    style partial_subject fill:#fff
    style partial_project fill:#fff
    style group_only fill:#fff
    style invalid fill:#fff
    style result_complete fill:#e3f2fd
    style result_partial_subject fill:#e3f2fd
    style result_partial_project fill:#e3f2fd
    style result_group_only fill:#e3f2fd
    style result_invalid fill:#e3f2fd
    style next fill:#e8f5e9

Upload Decision Logic:

After resolving container labels, the Connector determines whether to update existing containers or create new ones:

flowchart TD
    start([Upload Ready]) --> session_check{Session UID exists in Flywheel?}

    session_check -->|Yes| acq_check{Acquisition UID exists in session?}
    session_check -->|No| group_check{Group ID exists? - Fuzzy Match}

    acq_check -->|Yes| uid_placement[UID Placement: Update existing acquisition]
    acq_check -->|No| uid_placement_new[UID Placement - New Acq: Create acquisition in existing session]

    group_check -->|Yes| project_check{Project Label exists in group?}
    group_check -->|No| unknown_placement[Unknown Placement: Create in Unknown Group, Unsorted Project]

    project_check -->|Yes| new_session[New Placement - Session: Create new session in existing project]
    project_check -->|No| unsorted_placement[Unsorted Placement: Create in existing group, Unsorted Project]

    uid_placement --> complete([Upload Complete])
    uid_placement_new --> complete
    new_session --> complete
    unsorted_placement --> complete
    unknown_placement --> complete

    style start fill:#e8f5e9
    style session_check fill:#fff9c4
    style acq_check fill:#fff9c4
    style group_check fill:#fff9c4
    style project_check fill:#fff9c4
    style uid_placement fill:#e1f5fe
    style uid_placement_new fill:#fff9c4
    style new_session fill:#c8e6c9
    style unsorted_placement fill:#ffe0b2
    style unknown_placement fill:#ffccbc
    style complete fill:#e8f5e9

Flywheel Container Hierarchy

The DICOM Connector places data in the Flywheel hierarchy:

1
2
3
4
5
6
Group (Institution/Department)
└── Project (Study/Research Initiative)
    └── Subject (Participant/Patient)
        └── Session (Scan Visit/Date)
            └── Acquisition (Scan Series)
                └── Files (Image Files)

Complete Mapping Example

DICOM Field DICOM Value Flywheel Field Flywheel Value
PatientComments fw://neurology/parkinsons/sub-001 group.id neurology
PatientComments fw://neurology/parkinsons/sub-001 project.label parkinsons
PatientComments fw://neurology/parkinsons/sub-001 subject.label sub-001
PatientComments fw://neurology/parkinsons/sub-001 session.label ses-baseline
PatientName doe^john subject.firstname John
PatientName doe^john subject.lastname Doe
StudyInstanceUID 1.2.3.4.5 session.uid 1.2.3.4.5
StudyDescription Baseline Assessment session.label Baseline Assessment
OperatorsName tech^smith session.operator tech^smith
StudyDate 20241201 session.timestamp 2024-12-01T14:30:00+00:00
StudyTime 143000
SeriesInstanceUID 1.2.3.4.5.6 acquisition.uid 1.2.3.4.5.6
SeriesDescription T1w MPRAGE acquisition.label T1w MPRAGE
AcquisitionDate 20241201 acquisition.timestamp 2024-12-01T14:35:00+00:00
AcquisitionTime 143500

When Custom Configuration Is Needed

The default mappings work for many scenarios, but custom configuration may be needed when:

  • Series Descriptions Are Not Unique: Multiple unrelated series share the same description
  • Series Grouping Is Incorrect: Related series should be grouped but have different descriptions, or vice versa
  • Labels Are Not Meaningful: Default DICOM fields do not provide useful labels for your workflow
  • Routing Information Is Missing: Standard DICOM fields do not contain group/project information

Custom configuration options are documented in the Advanced Configuration Guide.