How the DICOM Connector Uploads an Image
Introduction
The Flywheel DICOM Connector (formerly known as the reaper) uploads images from a PACS or scanner to Flywheel via HTTPS.
This article explains in detail how the DICOM connector extracts metadata from a DICOM image and uploads it to Flywheel. To learn how to set up a scanning console to upload data, see this guide.
Instruction Steps
Types of Connectors
PULL and PUSH
There are two methods for data to get from the connector to Flywheel:
- PULL: The Connector pulls images directly from a scanner.
- PUSH: The scanner sends images to a Flywheel receiver. From the receiver, the Connector collects the images and sends them to your Flywheel instance.
Opt-in and Opt-Out
There are two options to determine when data is uploaded to Flywheel:
- Opt-out: The Connector uploads all data to Flywheel by default. An opt-out string is entered at the scanner's console if the user does not want to upload data.
- Opt-in: The Connector uploads data only when the opt-in string is entered by a user at the scanner's console.
Uploading Data
The Flywheel Connector uploads images by querying a PACS or scanner at regular intervals for new data items. Next, the Connector examines the available items to determine if they are ready to be entered into the Flywheel database.
For example, when using MR scanners, Flywheel watches the Series (typically defined by SeriesInstanceUID
) and the number of images in that series (NumberOfSeriesRelatedInstances
) to see if there is an increase in that number.
In general, the Connector uses the following logic to determine if it can start uploading scans to Flywheel:
- Has the number of images in the series changed since the last time it checked?
- If yes, the Connector assumes the scan is still in progress and waits.
- If the item has not changed since the last time it checked, has it already been uploaded?
- If yes, the Connector waits.
- If the item hasn't changed and hasn't already been uploaded, the Connector uploads it. Files continue to be monitored.
- An automatic re-upload is triggered if there is a change of state of monitored and previously uploaded items.
The definition for "item", "state", and "change" varies for different data types or modalities.
Extracting Metadata
As the connector uploads data, it also parses metadata to make sure it stays current with the scans and to determine how to organize the data once it is in Flywheel.
Below is the default method for mapping DICOM tags to Flywheel fields.
These are default mappings. Your site may use different DICOM tags for these Flywheel fields. See your institution's Flywheel Site Admin for your specific mappings.
DICOM tag | Flywheel field |
---|---|
PatientID This is based on using the PatientID field for the routing string. Learn more about the routing string. | group._id |
PatientID | project.label |
PatientID | subject.label |
PatientName | |
Learn more about how PatientName is parsed | subject.firstname |
PatientName Learn more about how PatientName is parsed | subject.lastname |
StudyInstanceUID | session.uid |
StudyDescription (--session-label-key ) (4) | session.label |
OperatorsName | session.operator |
StudyDate/StudyTime Learn more about how StudyDate is parsed | session.timestamp |
StudyTime Learn more about how StudyTime is parsed | session.timestamp |
SeriesInstanceUID Learn more about how SeriesInstanceUID is parsed | acquisition.uid |
SeriesDescription | acquisition.label |
AcquisitionDate Learn more about how AcquisitionDate is parsed | acquisition.timestamp |
AcquisitionTime Learn more about how AcquisitionTime is parsed | acquisition.timestamp |
PatientName to subject.firstname and subject.lastname
The name is split as {lastname}^{firstname}
if the caret (^) character is found, otherwise on a space character as {firstname} {lastname}
. If neither a caret nor a space delimiter is present, the whole PatientName
will go to subject.lastname
and subject.firstname
will be empty. Both fields are capitalized.
For example:
PatientName | subject.firstname in Flywheel | subject.lastname in Flywheel |
---|---|---|
Doe^John | John | Doe |
Doe^John^Mid | John^Mid | Doe |
John Doe | John | Doe |
John Mid Doe | John Mid | Doe |
john doe | John | Doe |
JohnDoe | JohnDoe |
SeriesInstanceUID to Acquisition.uid
DICOMs that have an ImageType
tag with value DERIVED\SECONDARY\SCREEN SAVE
or DERIVED\SECONDARY\VXTL STATE
will be assigned a "decremented" UID. For example SeriesInstanceUID=4.5.6
would translate to acquisition.uid=4.5.5
. If the Manufacturer
is not Siemens
and AcquisitionNumber
is set and greater than 1, then acquisition.uid
is suffixed with _{AcquisitionNumber}
.
For example:
SeriesInstanceUID | ImageType | Manufacturer | AcquisitionNumber | acquisition.uid in Flywheel |
---|---|---|---|---|
1.2.3.4 | ORIGINAL\... | 1.2.3.4 | ||
1.2.3.4 | DERIVED\... | 1.2.3.3 | ||
1.2.3.4 | SIEMENS | 2 | 1.2.3.4 | |
1.2.3.4 | GE | 2 | 1.2.3.4_2 | |
1.2.3.4 | GE | 1 | 1.2.3.4 |
SeriesDate, SeriesTime, AcquisitionDate, and AcquisitionTime to session.timestamp and acquisition.timestamp
Timestamp fields in Flywheel are parsed from a pair of date and time fields like StudyDate and StudyTime. Similar pairs exist with prefixes Acquisition* and Series*. The timezone is configured via the --timezone
option which defaults to UTC
.
Siemens scanners
If the Manufacturer
is Siemens
, then acquisition.timestamp
is parsed from SeriesDate
and SeriesTime
instead of AcquisitionDate
and AcquisitionTime
. If these tags are not parsable, the value defaults to session.timestamp
.
Example DICOM Metadata Mapping
DICOM tags | Flywheel metadata |
---|---|
patientID : fw://g/p/s | group.id : g project.label : psubject.label : s |
PatientName : doe^john | subject.firstname : John subject.lastname : Doe |
StudyInstanceUID : 1.2.3 | session.uid : 1.2.3 |
StudyDescription : My Study | session.label : My Study |
OperatorsName : OP^Mike | session.operator : OP^Mike |
StudyDate : 20201023 StudyTime : 105624 | session.timestamp : 2020-10-23T10:56:24+00:00 |
SeriesInstanceUID : 4.5.6 | acquisition.uid : 4.5.6 |
series.description : Series 002 | acquisition.label : Series 002 |
AcquisitionDate : 20201023AcquisitionTimestamp : 105649 | acquisition.timestamp : 2020-10-23T10:56:49+00:00 |
Determining Where to Place Data in Flywheel
Once the metadata is extracted from the images, the Connector uses that information, along with the routing string, to place the data within Group, Project, Subject, Session, and Acquisition containers. The diagram below shows where the data from the Connector is placed.
The Routing String
The routing string tells the Connector where to place data on your Flywheel site. In a predetermined field on the scanner console, the user enters the following:
fw://group/project/subject/session
with the appropriate labels for group, project, subject, and session.
Common fields for the routing string include PatientID
and Additional Info
. These fields are configurable per site, so you should check with your institution's Site Admin to verify which field you should use.
Learn more about how to enter the routing string in the scanner console.
The Connector still uploads sessions that have missing, incomplete, or incorrect routing strings.
These sessions are uploaded to the Unknown Group or Unsorted Project (depending on how much information was given at the scanner).
Sessions in the Unknown Group require a Site Admin to move them into the correct Group and Project. Sessions in a Group, but not sorted into a Project must also be manually moved from the Unsorted Project to the correct Project.
Here's an example of how the Connector would parse an incomplete routing string:
Routing string entered | group.id | project.label | session.label | Notes |
---|---|---|---|---|
fw://psych/study01/ses01 | psych | study01 | ses01 | |
fw://psych/study01 | psych | study01 | Flywheel will attempt to use studyDescription for the session label | |
fw://psych | This will go into the Unsorted project within the psych group | |||
psych/study01 | This will go into Unknown Group since it does not include fw:// |
How does Flywheel determine where to place data?
Below is a diagram of how the DICOM Connector determines where to upload a session and if it should create new containers or use existing containers: