Monday, April 30, 2012

DICOM Modality Worklist

Modality worklist (MWL) is one of DICOM’s workflow services that really make a difference. It’s the difference between grocery store workflow with notes on little pieces of paper and a true modern accountable workflow.

Technically speaking, DICOM Modality Worklist is a task manager just like a piece of paper with short text and a check box or the tasks application on your iPhone (or Android). But for the imaging center or RAD department the advantages are enormous. The most obvious benefit is that there’s no need to reconcile all kind of misspelled names in the PACS because the patient name is no longer keyed in on the modality workstation but received electronically via the MWL query. The fact that the requested procedure is also received electronically reduces the chance for doing the wrong procedure to the wrong patient. Combined with Modality Performed Procedure step (MPPS), that allows the modality to report the task status, take ownership over the task and checkmark it as done when completed, the up side is obvious. No wonder then, that many HMO’s require Modality Worklist as a mandatory feature for every imaging device they purchase. 

The most basic abstraction of a task is a short description of what should be done and a checkbox. That’s all it takes. The MWL data model is a bit more complicated and has two levels.
The top, parent, level is called “Requested Procedure” (RP) and holds the information about the patient (name, id), the study (accession number, study instance UID) and the procedure. The procedure can be described as text using attribute (0032,1060) – “Requested Procedure Description” or in a more sophisticated manner using the (0032,1064) – “Requested Procedure Code Sequence” where static tables of codes and meanings can be used to configure and maintain procedures in the RIS or HIS.
The child level is called “Scheduled Procedure Step” (SPS) and holds attributes relevant to the modality and the actual procedure to be made. A single requested procedure may hold more than one SPS if the request is for a multi-modality study, for example a chest X-Ray and a CT or whatever combination, or if for example two protocols should be applied (e.g. Chest and Abdomen). As a modality, we will use the data in the RP to identify the patient and eliminate re-typing of the name and ID and the SPS to determine what exactly to do.

The DICOM images that the modality will create should use the attributes received from the MWL. When MWL is implemented, the Study Instance UID is generated in the RIS so if a multi-modality procedure is done, each modality will create a series and attach it to the Study by using the Study Instance UID received in the MWL query.
The Modality Worklist Server is responsible for managing the tasks. On one hand it provides means to schedule new tasks (e.g. via HL7 or using a web form) and on the other hand it provides means to get the list of scheduled tasks (via DICOM).
In this post, we’re going to write a simple MWL client using RZDCX DICOM Toolkit and discuss the details of the service and how the workflow is implemented. We’ll leave the MPPS for a future post.
Let’s start with a simplified overview of the workflow at the imaging center or the radiology department.
  1. An order is made for an imaging service, let’s say for example a chest X-Ray. The order can be made in various ways. For example it can arrive as a HL7 message from the HIS (Hospital Information System), or it can be that the patient walks in an the order is made at the reception desk. In either case, a new record is created in the worklist manager with the information for the service.
  2. The order is scheduled and assigned to the X-Ray machine or Room that will perform the exam. If there are many X-Ray machines, the order may be assigned to one of them. The assignment is made by setting the AE title on the order and setting a date. The exact way it is done, is very much the business of the worklist manager implementation. DICOM only defines the data model entities. The relevant entity for this is scheduled procedure step. It’s an abstraction of a task with description of what should be done, when it should be done and who should do it.
  3. When the X-Ray machine makes a modality worklist query, it gets the list of scheduled tasks and performs them.
Let’s have a look at a modality worklist client.

On the upper left of this single form application you see the DICOM network parameters that we’ve already seen on chapter 5 of the DICOM tutorial when talking about DICOM networking.
On the upper right side we have some filter attributes that we can use that make a lot of sense. We can filter by the AE title that the procedure was scheduled for, by the type of modality it was scheduled for and using the scheduled date. For demonstration purpose, the date matching attributes here are very detailed in order to show all possible date and time exact, open and closed range matching.
The Query button packs the filter into a DICOM object and then sends it to the MWL server using the Query method of the DCXREQ interface. The SOP class for Modality Worklist is “1.2.840.10008.”.
The construction of the query object is a bit tricky because we have to build the parent-child hierarchy. The mechanism of making queries for hierarchical objects is called sequence matching. The server (Q/R SCP) should search all the matching Requested Procedures that have at least one child Scheduled Procedure Step with attributes that matches the query. If it finds such, the complete RP with all its child nodes is sent as a result. The client (Query SCU) may set exactly one child node in the query.

The RP and SPS entities have many attributes but for this post what’s important is to understand that we, as a modality, are performing a schedule procedure step so we are looking for the child entity. The AE title, modality and scheduled date are all attributes of the schedule procedure step so in order to perform the matching, we create a filter for the scheduled procedure step and then put it into a requested procedure object as a sequence element and this is the query we send. Here’s the code:

// Fill the query object
rp = new DCXOBJ();
sps = new DCXOBJ();
el = new DCXELM();

// Build the Scheduled procedure Step (SPS) item

// A lot of code to handle all the cases of date and time matching
// that eventually goes into the elements: ScheduledProcedureStepStartDate and ScheduledProcedureStepStartTime

/// This adds a filter for time

// Handle the modality Combo Box
if (comboBoxModality..SelectedItem.ToString() != "Any")
    el.Value = comboBoxModality.SelectedItem.ToString();

// Now we put it as an item to sequence
spsIt = new DCXOBJIterator();

// and add the sequence Scheduled Procedure Step Sequence to the requested procedure (parent) object
el.Value = spsIt;

/// Add the Requested Procedure attributes that we would like to get






// Create the requester object and connect it's callback to our method
req = new DCXREQClass();
req.OnQueryResponseRecieved += new IDCXREQEvents_OnQueryResponseRecievedEventHandler(OnQueryResponseRecievedAction);


// send the query command
it = req.Query(LocalAEEdit.Text,
               "1.2.840.10008."/// Modality Worklist SOP Class

At the bottom of the form we have a grid that will show the results.
We can handle the results either in the callback OnQueryResponseRecievedAction or iterate over the items in DCXREQ.Query return value. In this example we’ll do the later and unpack some of the attributes of the RP into a data grid. Here’s the code for it:

private void LoadResultsToGrid(DCXOBJIterator it)
    DCXOBJ currObj = null;

        DataTable dt = new DataTable();
        DataRow dr;

        dt.Columns.Add(new DataColumn("Patient Name", typeof(string)));
        dt.Columns.Add(new DataColumn("Accession Number", typeof(string)));
        dt.Columns.Add(new DataColumn("Requested Procedure ID", typeof(string)));
        dt.Columns.Add(new DataColumn("Requested Procedure Description", typeof(string)));
        // Iterate over the query results
        for (; !it.AtEnd(); it.Next())
            currObj = it.Get();
            dr = dt.NewRow();
            dr["Patient Name"] = TryGetString(currObj, DICOM_TAGS_ENUM.patientName);
            dr["Accession Number"] = TryGetString(currObj,DICOM_TAGS_ENUM.AccessionNumber);
            dr["Requested Procedure ID"] = TryGetString(currObj,DICOM_TAGS_ENUM.RequestedProcedureID);
            dr["Requested Procedure Description"] = TryGetString(currObj,DICOM_TAGS_ENUM.RequestedProcedureDescription);
        DataView dv = new DataView(dt);
        dgvQueryResults.DataSource = dv;


The full source code modality worklist SCU example can be downloaded from here. This example has a master-detail  data grid view that shows the SPS’s of the selected RP.

Don’t forget to download and register RZDCX (32 or 64 depending on your OS) before building the project.

As always, comments and questions are most welcome.


  1. Really helpful article.
    Looking ahead for MPPS deciphering...
    Thank you

  2. Thank you very much,
    All of these articles are very helpfull.

    I tried modality worklist,
    but got error like this
    'DUL Finite State Machine Error: No action defined, state 5 event 17'

    any idea?

    1. That's a protocol error.
      One of the sides, does not respond according to the expected.
      Can you add a log to the application and repeat the test.
      At the form load add this:

      app = new DCXAPP();

      Than run again and post here the log file.
      We'll analyze it online

    2. I solved it.
      The given port number was false.
      I changed it and it works :)

      Thanks a lot.

  3. This comment has been removed by the author.

  4. Hi! your contact page is broken :S,

    I thank your dicom posts, Im trying to create a SCP-MWL server, your appi is able to create it?


    1. Thanks no-body.
      I fixed it.
      Look at this post:
      about MWL SCP

  5. Hello.. i am using this client (DICOM Modality Worklist) but can't seem to make a connection to the server.. Maybe i just missed this info somewhere but what port number is this client listening to by default?

    1. Hi
      This DICOM Modality Worklist SCU (client) does not listen to any port.
      It initiates an association with the peer DICOM application that listen on a port on another computer.

  6. Hi from Mexico!

    I'm traing to run your aplication but I got this error:

    Query failed: DUL Association Rejected.

    Any idea ?

  7. Hi !

    I am a french student in computer science. In the context of my school, I've to code a Dicom software. I have decided to code a Worklist implementation but despite all my research some part of the Dicom standard escape me.
    I asked Roni (e-mail) about the "Admission ID", because I didn't know the meaning of this field. I share here his answer which can help everyone :

    "Admission id is an id that is created or assigned to the patient when admitted to the ward.
    For example when you visit a clinic, the secretary at the front desk opens a file for you and assigns an id to it.
    So this can be the admission id.
    It had no other logic attached to it in DICOM.
    In general you should look at the attribute type.
    There are types 1, 2, and 3.
    If it's not a 1, this means you can most probably live without it."

    I agree with that, but I have another question : how do you identify a patient ? With the Patient ID, the Accession Number or the Admission ID ? Do all the patients have an Admission id AND a Patient id ?

    Thank you so much again Roni for this first answer.

    1. Hi Laura,
      The identifier of the patient is Patient ID.
      Accession Number identifies the current page or incident or encounter of treatment in the patient record. It is related to study level.

    2. If you are not coming from a clinical background, all these different ID numbers can be confusing. I would look at the Admission ID as an account number. Upon admission, an account number is assigned that is used, among other things, to track all billing, procedures, etc. for that 'admission.' Next visit to doctor or hospital would/could generate another Admission (account) ID. Patient ID is unique to the PATIENT. Accession number is for the EXAM, for instance, a chest xray would have a unique accession number for that particular patient. If they had another chest xray later, it would get another unique accession number. The admission ID is for that particular visit or admission. Hopefully, this helps.

  8. SCU has fired a query on SCP.but the SCP returns "The response from SCP was not success" and the Error comment returns a "."(dot). what may the problem.
    [DicomQueryAPI::list] The response from SCP was not success .
    [DicomQueryAPI::list] Error Comment : .

    1. I this with out toolkit? If so, post the complete log please.

  9. Does the RZDCX toolkit is free?

  10. I am siva,

    I am not understanding RZDCX modalityworklistSCU,Query/RetriveSCU and mppsSCU code sample.who is the sender and listener and how to configure AET ,IPADDRESS AND PORT.I am strugling with send data to modality.Please give solution.advance thanks

  11. RZDCX code samples helping me,but i am not under standing flow between these exaples and modalites.Please help me.

  12. please help me,i am .net developer.i am facing problem with send patient data to modalities.i am using RZDCX examples.i am not understanding modalityworklistscu,query/retrivescu and mpps.please tell me who is listener and who is the client.please help me.

    1. Dear Suvarna
      All these examples are SCU or Client. I'm sorry that I can't answer you general call for help but if you have more specific questions please ask. I suggest that you read again the post and maybe try reading other resources that maybe more clear to you.

  13. please help me,i am .net developer,i am facing the problem for send patient data to modality.what is the use of modality worklist scu ,query/retrive scu and MPPS SCU.which is good example for send patient information to modality.please help me.advance thanks

  14. please help me,i am .net developer, i want modality worklist scp .net source code for send scheduled patient information to modality.advance thanks.

  15. In a worklist it is possible to have 2 different methods with the same number of access (same patient)?
    If the answer is Yes, can you give an example?
    Thank you

  16. In a worklist it is possible to have 2 different methods with the same number of access (same patient)?
    If the answer is Yes, can you give an example?
    Thank you

    1. Yes, in the response you can have two scheduled procedure steps for the same scheduled procedure. See the screenshot at the top of this post

    2. I'd seen the picture above, but you might attach a file example to better understand how it works.
      Thank you

  17. Thanks a lot for this excellent blog about DICOM an the great explanation of the backgrounds.
    I would have one question. What is the best case to handle a missing RP Description (0032,1060) in the MWL?

    Thanks a lot!
    Is it better not to process and attempt to fix the RIS config (that's how we handle) or can it be effectively worked around on the modality?

    1. Hi Tobias,
      Sorry for the late replay.
      According to the DICOM standard Requested Procedure Description or Requested Procedure Description should be provided by the SCP. IHE extend the requirement also to the SCU.
      How you handle missing attribute really depends on your workflow. I tend to take the more elaborative attitude but others may think differently.
      If you decide to reject MWL records due to missing attribute make sure to have a clear message to the user why you did this including the offending attribute name and tag.
      Consider displaying the record grayed out with the error information so it is displayed but can't be used.

  18. Thank your for this Toolkit, it really helping me.

    I m using the Toolkit to implement an application requesting the worklist from a Worklist Server using Delphi XE4.

    the server is running fine with MS SQL express. I can request the list and i m getting patient information quickly

    Things was going good until i face a problem converting this line to delphi when displaying SPS elements.

    DCXOBJIterator spsIt = currObj.getElementByTag((int) DICOM_TAGS_ENUM.ScheduledProcedureStepSequence).Value as DCXOBJIterator;

    The casting of the Value ( an OleVariant) to DCXOBJIterator failed and gives error during compilation.

    I tried many typacasting forma but there is no way to iterate over the SPS.

    Can u help please ?

    How to get the SPSs in DELPHI

    Thanks in advance

  19. Thanks a lot for the article.

    I was wondering if I can get number of images associated to a study from the modality worklist? The question is how the PACS would know if all the images for study/patient are received.


    1. Hi Arash,
      Great question! Because there's an answer ;) When the Modality sends MPPS COMPLETED it should include the list of SOP Instance UID's that were created during the procedure. This way the PACS knows exactly the content of the procedure.