Skip to content

Converting DICOM to HL7

This chapter walks step by step through reading values from an incoming DICOM message and writing them into an HL7 ORU^R01 result message. After completing the steps in this chapter you should have a channel that accepts a DICOM message on a listener port and delivers a corresponding HL7 result message to a downstream system.

Note

QIE does not provide a built-in DICOM-to-HL7 converter. The conversion is performed in a mapping script that you write, using the DICOM node-path syntax to read tag values and the HL7 message model to build the result message. This chapter shows you how.

Step 1: Create a new channel

Navigate to the Channels page and click New. Name the channel DICOM to HL7 and click OK.

Step 2: Configure the DICOM listener source

Select the source node and configure it as a DICOM Listener the same way you did in Creating Your First DICOM Channel. Choose a different port from the passthrough channel (for example, 11113) so the two channels do not conflict.

Save a sample DICOM message on the source node so you can use the Test Window and the Node Path Lookup dialog while writing the mapping script.

Step 3: Add a mapping node

Drag a Mapping node onto the channel between the source and destination, and connect them.

Click the mapping node to select it, then add a Custom Script mapping function and open the script editor.

Step 4: Change the output message format to HL7

QIE's mapping node lets you change the format of the output message independently of the input. Because the source message is DICOM and the output is HL7, the script needs to create a new HL7 message and write tag values into it.

In the script editor, start with:

// Create a new empty HL7 message that the script will populate.
message = qie.createHL7Message();

This replaces the current working message with an empty HL7 message that subsequent message.setNode(...) calls modify. The original incoming DICOM message remains available through the source object.

Step 5: Populate the MSH segment

message.setNode('MSH-3', 'QIE');
message.setNode('MSH-4', 'Imaging');
message.setNode('MSH-5', 'EHR');
message.setNode('MSH-6', 'Hospital');
message.setNode('MSH-7', qie.formatDate('yyyyMMddHHmmss'));
message.setNode('MSH-9', 'ORU^R01');
message.setNode('MSH-10', qie.getUUID(false));
message.setNode('MSH-11', 'P');
message.setNode('MSH-12', '2.5.1');

The values for sending application, receiving application, sending facility, and receiving facility should be set to the values appropriate for your environment.

Step 6: Populate the PID segment from DICOM tags

Use source.getNode(...) with the DICOM tag node paths to pull patient information from the source message:

message.setNode('PID-3',   source.getNode('0010,0020'));  // Patient ID
message.setNode('PID-5',   source.getNode('0010,0010'));  // Patient's Name
message.setNode('PID-7',   source.getNode('0010,0030'));  // Patient's Birth Date
message.setNode('PID-8',   source.getNode('0010,0040'));  // Patient's Sex

Note

If the patient name in the DICOM message uses the DICOM Last^First^Middle component separator, the value passes straight through to the HL7 PID-5 field which uses the same ^ separator. If the source format differs, parse and re-format the components before assignment.

Step 7: Populate the OBR segment from study tags

message.setNode('OBR-1',   '1');
message.setNode('OBR-2',   source.getNode('0008,0050'));  // Accession Number
message.setNode('OBR-4',   source.getNode('0008,1030'));  // Study Description
message.setNode('OBR-7',   source.getNode('0008,0020')
                         + source.getNode('0008,0030'));  // Observation Date/Time
message.setNode('OBR-16',  source.getNode('0008,0090'));  // Referring Physician's Name
message.setNode('OBR-25',  'F');                          // Result Status: Final

The 0008,0020 Study Date and 0008,0030 Study Time tags are concatenated to form a single HL7 timestamp.

Step 8: Add an OBX segment for the modality

message.setNode('OBX-1',   '1');
message.setNode('OBX-2',   'ST');
message.setNode('OBX-3',   'MODALITY');
message.setNode('OBX-5',   source.getNode('0008,0060'));  // Modality (e.g. CT, MR, XR)
message.setNode('OBX-11',  'F');

You can add additional OBX segments for any other tags you want to forward: image counts, series descriptions, body part examined, and so on. Reference DICOM - Node Path Syntax for the tag list, or use the DICOM Tag/UID Data Dictionary from the View menu of the script editor.

Step 9: Configure the HL7 destination

Select the destination node and configure it as the appropriate HL7 sender for your downstream system, typically HL7 MLLP for socket delivery to an EHR or File for file-based delivery.

If you use HL7 MLLP, point it at the receiving system's host and port and select an appropriate acknowledgement mode.

Step 10: Save the channel and test

Save the channel and start it.

Open the Test Window and click Test. Inspect each stage in the test output:

  • Source: the original DICOM message.
  • Mapping output: the HL7 ORU^R01 message your script built.
  • Destination output: the HL7 message as it is delivered.

Verify that the patient and study fields in the HL7 message contain the expected DICOM tag values.

If you also want to test from a real DICOM sender, point it at the listener port for this channel and trigger a send.

What You Should Have Now

  • A channel named DICOM to HL7 that accepts DICOM messages on a listener port.
  • A mapping node that reads DICOM tag values from source and writes them into a new HL7 ORU^R01 message.
  • An HL7 destination configured for your downstream system.
  • A working end-to-end DICOM-to-HL7 conversion.

You can extend the script to fan out to multiple destinations (for example, send the HL7 ORU to an EHR and also save the DICOM message to a file archive), to drive routing decisions with condition nodes, or to combine the conversion with the deidentification step from the previous chapter.