dcm4chee: Updating sps order status of an MWL item via HL7 and better HL7 compliance

Suppose you wish to update the sps status of an mwl item in dcm4chee, preferably in an HL7 compliant way.

(Creating mwl items from scratch in dcm4chee via HL7 messages is easy and is discussed separately here.)

The obvious guess from reading the HL7 standard on this matter would be to send an ORM message with an ORC segment like so:

ORC|SC|1|||SCHEDULED||1^0^60^20161012040000

if you are updating the status of an existing MWL item (indicated by setting ORC-1 to SC, which according to HL7 2.5 signifies “Status Changed”), or perhaps:

ORC|XO|1|||SCHEDULED||1^0^60^20161012040000

if you are simultaneously creating and setting the status of an MWL item.

(The full set of ORC-1 values are defined in Ch. 4 of the HL7 2.5 standard under “HL7 Table 0119 – Order Control Codes.” How to download and navigate the specs of the standard is touched upon here.)

However, in dcm4chee’s default config, neither one of these will actually work as intended.

Even though we are specifying the status in the ORC-5 field (which according to HL7 v2.5 corresponds to an optional “OrderStatus” field), you will find that this field is completely ignored by dcm4chee’s parser running the default config. Even worse, messages with ORC-1 set to SC are completely ignored.

This is because dcm4chee by default handles SPS updates in its own particular (and not exactly HL7 compliant) way, and this is to some degree specified in the configuration of the OrderControlOPerationMap field in its HL7Server,type=ORM bean (configurable via the jmx-console).

HL7Service,type=ORM bean.

HL7Service, type=ORM bean.

Opening up the jmx console for this bean, you will find that the default OrderControlOperationMap field value is:

NW:NW
XO:XO
XO(SC):XO(SCHEDULED)
XO(CM):XO(COMPLETED)
CA:CA
OC:CA
DC:SC(DISCONTINUED)
OD:SC(DISCONTINUED)
SC(IP):SC(STARTED)
SC(AR):SC(ARRIVED)
SC(CM):SC(COMPLETED)
SC(DC):SC(DISCONTINUED)
SC(CA):CA
SC:NOOP

which tells dcm4chee which internal prebuilt function to use to parse an incoming ORM message based on the value of it’s ORC-1 field (ie: the second to last line of the above config means that if the ORC-1 field is “SC(CA)” that dcm4chee will execute an internal function called “CA” – without any arguments).

So if you are just interested in knowing how to update the SPS status of an MWL item the dcm4chee way, the help docs of the OrderControlOperationMap field will tell you that to update the status to SCHEDULED, the ORC-1 field must be set to XO(SC):

ORC|XO(SC)|1|||||1^0^60^20161012040000

and to update the status to STARTED, ORC-1 must be SC(IP):

ORC|SC(IP)|1|||||1^0^60^20161012040000

and so on. The ORC-5 field which would normally correspond to OrderStatus, is irrelevant in the default config.

Configuring dcm4chee for HL7 compliant order status updates

Although dcm4chee’s default solution gets the job done, suppose you want something that is more strictly HL7 compliant.

For example, looking at the HL7 v2.5 standard, Chapter 4 (which covers ORM messages and in particular the ORC segment), there is no mention of the ORC-1 codes XO(SC), XO(CM), SC(IP), SC(AR), and so on, which are used to set the mwl status in dcm4chee. Instead the standard tells us to set ORC-1 to SC when updating the status, with the status value itself specified in ORC-5. And as we have seen above, in its default config, dcm4chee (v2.18.x) simply ignores the ORC-5 sps status field, setting it does nothing.

We can remedy this situation and make the install HL7 compliant with respect to order status updates by modify the config file orm2dcm.xml. This is the config file in charge of telling dcm4chee how to parse an HL7 message and convert it into DICOM data (which dcm4chee understands better, and enters directly into its columns in its db model when appropriate, being its ‘native’ data format, if you will).

In particular we need to modify the part dictating the parsing of the ORC segment in mode=”sps”, so that it looks like so:

    <xsl:template match="ORC" mode="sps">
        <item>
            <!-- Scheduled Procedure Step Start Date/Time -->
            <xsl:call-template name="attrDATM">
                <xsl:with-param name="datag" select="'00400002'"/>
                <xsl:with-param name="tmtag" select="'00400003'"/>
                <xsl:with-param name="val" 
                    select="string(field[7]/component[3]/text())"/>
            </xsl:call-template>
            <!-- SPS Status -->
            <xsl:call-template name="attr">
                <xsl:with-param name="tag" select="'00400020'"/>
                <xsl:with-param name="vr" select="'UI'"/>
                <xsl:with-param name="val"
                    select="string(field[5]/text())"/>
            </xsl:call-template>
            <!-- End SPS Status -->
            <xsl:apply-templates
                select="following-sibling::OBR[1]" mode="sps"/>
        </item>
    </xsl:template>

(Where the section in between the comments “SPS Status” and “End SPS Status” is what we inserted.)

The inserted section tells dcm4chee to parse the 5th field of the ORC segment into the DICOM tag (0040,0020) which corresponds to “SPS Order Status”.

(If xsl files give you fear, uncertainty and dread (FUD), a few minutes reading up on XSLT will do you wonders. The basics of it are actually really simple.)

After the above config edit (no need to restart dcm4chee, yay), sending the following HL7 message now updates the mwl item to have sps_status=ARRIVED:

PID||1|9AG7989C16E9||BARRIO^EDGAR^^^^None
PV1||RAD|||||TEST.JaLo^Jaramillo^Lorenza
ORC|XO|||ARRIVED||1^0^60^20161012040000
OBR|1|1|2|CT^^^None|||||||||||||||2|JIXZFT||||CT||||||||||None
ZDS|1.2.826.0.1.3680043.9.6467.0.1476185012461.0^dorada.CT.1^CT.1

A more strictly HL7 compliant choice would be to use ORC-1=SC (which according to HL7 v2.5 is specifically reserved for order status updates) instead of “XO”. To get this working we need to update the line SC:NOOP in the ORM service bean OrderControlOperationMap field to be SC:XO instead of SC:NOOP, ie:

NW:NW
XO:XO
XO(SC):XO(SCHEDULED)
XO(CM):XO(COMPLETED)
CA:CA
OC:CA
DC:SC(DISCONTINUED)
OD:SC(DISCONTINUED)
SC(IP):SC(STARTED)
SC(AR):SC(ARRIVED)
SC(CM):SC(COMPLETED)
SC(DC):SC(DISCONTINUED)
SC(CA):CA
SC:XO

Why in that last line SC:XO and not SC:SC?

Well SC without arguments is not a defined function in dcm4chee, and mapping to NOOP will result in a no-operation, so the best we can do is set it to call the internal function “XO.” From the HL7 standard’s point of view this is immaterial, as it does not concern itself with the internal function names dcm4chee uses to execute operations, as long as the results of those operations are consistent with what was being asked / defined by the standard in response to the message sent.

With the above config change, the following ORM message updates the status of the MWL item to ARRIVED:

PID||1|9AG7989C16E9||BARRIO^EDGAR^^^^None
PV1||RAD|||||TEST.JaLo^Jaramillo^Lorenza
ORC|SC|||ARRIVED||1^0^60^20161012040000
OBR|1|1|2|CT^^^None|||||||||||||||2|JIXZFT||||CT||||||||||None
ZDS|1.2.826.0.1.3680043.9.6467.0.1476185012461.0^dorada.CT.1^CT.1

And that’s it!

Note: The above has been tested w/ dcm4chee v2.18.1.

Links

The dcm4chee default way is touched upon here as well:

https://groups.google.com/forum/#!topic/dcm4che/Yfkyp0S-Ns0


No fancy tricks or popups, simply an article like the above, which I write a few times a month - just for my subscribers.