Sunday, July 8, 2012

DICOM Modality Worklist Server

The DICOM Server, DSRSVC, is in use for many years in my custom software projects. It's a windows based service that is easily installed and configured. I've been using it since 2008 for various purposes and it is now a very stable and reliable software.
In this post I'm going to present its use as a Modality Worklist Server (or in short MWL SCP), explain how to install the software and how to configure the database to match your needs. Then, on the next post, I'm going to combine it together with processing HL7 order message to schedule a new work item. This will close the gap between HL7 and DICOM and we'll have most of the parts of IHE's radiology schedule workflow (SWF) integration profile.


What's the difference between a DICOM Server and a PACS?

Throughout the years, as PACS evolved, there were many debates about what is the feature set that makes a PACS? Does it have to have a Viewer? Does it have to provide all DICOM services? Should it have HL7? Many questions and even more answers. Calling it a DICOM Server is a laundry cleaning bypass of all that. It's a DICOM Server meaning it serves requests for DICOM Clients. What services does it provide? DSRSVC is a Storage SCP by default and you can add more services to it as you like using a plugin API. In the download page you'll find two plugins. The INI file plugin provides configuration for the storage service. The MS SQL Server DICOM Database Plugin adds:
  • Query/Retrieve SCP, 
  • Storage Commitment SCP and 
  • Modality Worklist SCP
Throughout the years it was used in all kind of applications, as an inbox for web viewer, as a CAD engine, as a departmental archive, as a proxy, as a bridge, and many more.

If you're looking to speed up development and use an off-the-shelf software product that you can easily extend, customize and integrate with your system, read on.


Installing the basic Server

You can use the DICOM server without any configuration just to store incoming DICOM files on port 104.
  1. Download the DICOM Server from (updated version, thanks Igor) here (win32 version) or from here (x64 version).
  2. Extract the content of the Zip file,
  3. CD to DSRSVC\DistWin32 and Copy DicomServer.EXE to your desired folder. Make sure not to copy DicomServer.INI because it is part of the DB plugin.
  4. From command line run DicomServer.EXE -i
    This will install it as a service. You can also run it from command line with DicomServer.EXE -r
    To uninstall, first stop it and than run DicomServer.EXE -u
After doing that you should see a new service installed in you services control panel (Start services.msc) called "Storage DICOM Service"
The DICOM Storage Service in the services control panel
By default it will start and stop with your system, listen on port 104 and save new DICOM files into \DSRSVC i.e. if your system is on C:\ then it will be in C:\DSRSVC

Adding Q/R SCP and MWL SCP

To add Modality Worklist, Storage Commitment and Query/Retrieve we'll need a database to record the images, key attributes and worklist records. The DicomDBPlugin.DLL adds this functionality.
As a start you'll need a MS SQL Server. An express version will do.
Database Creation Scripts

Follow these steps:
  1. Run DicomDB_CREATE_SCRIPT.sql to create the RZ_DICOM schema,
  2. Run DicomDB_INSERT_STATIC_DATA_SCRIPT.sql,
  3. Copy DicomDBPlugin.DLL to the folder where the DicomServer.EXE is and rename it to DSRSVCP.DLL
  4. Copy DicomServer.INI to the same folder and change the connection string to match your database server and credentials.
  5. Restart the service or install it and start it if you didn't already do so.
Now you have the same service but every file is processed and recorded in the database and you have Q/R SCP for that and you can configure it as you like in the configuration table.

The Plugin Model

DSRSVC has a plugin API model. The behavior of the service is fully controlled and configurable using the plugin DLL DSRSVCP.DLL. When you license the software, you can get the API header files and source files for the two plugins in the package. In the coming posts, I'll release the full source code of the INI file plugin project that can be used as an example.

How to configure the Q/R SCP and MWL SCP of the Database Plugin

The supported tags for Q/R and MWL are all dynamic and controlled using the column names of the database views.
Database Views to control Q/R and MWL
Each of these views has column names identical to DICOM attribute names. The C-FIND and C-MOVE views has also Q/R level in their name so a patient level query will be made from the CFIND_PATIENT_VIEW. There's no distinction between the query models and all are mapped to the same views. To add a supported column, all you need to do is to add the appropriate column name to the view that is mapped to the query and that's it. Oh, and you need to get the data for it. If you implement the plugin API that's easy.

Mapping Sequence Matching to Database Views

The MWL C-FIND command makes extensive use of sequence matching. In sequence matching, a sequence element in the query is matched to database tables. The DB plugin does this mapping by using a column named as the sequence tag as the relationship key between the parent and child tables.
The root view is CFIND_MWL_VIEW that has a column names ScheduledProcedureStepSequence that is the name of the DICOM tag. The child view is CFIND_ScheduledProcedureStepSequence_VIEW that also has the same field name.
Adding more sequences for example for codes is done dynamically in the same way and no software change is required other than adding the views to the database.
To test the MWL SCP you can run the SQL script DicomDB_INSERT_MWL_TEST_DATA_SCRIPT.sql and run the modality worklist client for the Modality Worklist SCU post.

Promises

In the next post I'm going to show how to use HL7Kit Pro to receive a HL7 message with imaging service order and populate the database with the information from it to have a new Modality Worklist item and then use the Modality Worklist example to query the DICOM server and get this work entry.

40 comments:

  1. Hi, Roni. Thanks for your great articles.
    I tried using DSRSVC DICOM Server as described above.
    It works well with EchoSCUExample and StorageSCUExample.

    Then I tried ModalityWorklistSCU example, but service crashes on MWL Query with Peer aborted Association (or never connected) error in client log. Service also creates LicenseRequest.txt file.

    May be I did something wrong, please help to make it working?

    ReplyDelete
    Replies
    1. Hi Igor,
      Can you send me or post the MWL SCU log file?
      Add to form load:
      DCXAPP app = new DCXAPP();
      app.LogLevel = info (don't remember the enum)
      app.StartLogging("log.log");

      Delete
    2. Yes, that's MWL SCU log file:

      2012-07-1110:59:19.263000 7120 INFO Association Request Parameteres:
      Our Implementation Class UID: 2.16.124.113543.6021.1
      Our Implementation Version Name: RZDCX_2_0_2_2
      Their Implementation Class UID:
      Their Implementation Version Name:
      Application Context Name: 1.2.840.10008.3.1.1.1
      Calling Application Name: RZDCX
      Called Application Name: DSRSVC
      Responding Application Name: resp AP Title
      Our Max PDU Receive Size: 32768
      Their Max PDU Receive Size: 0
      Presentation Contexts:
      Context ID: 1 (Proposed)
      Abstract Syntax: =VerificationSOPClass
      Proposed SCP/SCU Role: Default
      Accepted SCP/SCU Role: Default
      Proposed Transfer Syntax(es):
      =LittleEndianExplicit
      =BigEndianExplicit
      =LittleEndianImplicit
      Context ID: 3 (Proposed)
      Abstract Syntax: =FINDModalityWorklistInformationModel
      Proposed SCP/SCU Role: Default
      Accepted SCP/SCU Role: Default
      Proposed Transfer Syntax(es):
      =LittleEndianExplicit
      =BigEndianExplicit
      =LittleEndianImplicit
      Requested Extended Negotiation: none
      Accepted Extended Negotiation: none

      2012-07-1110:59:19.513000 7120 INFO Association Request Result: Normal
      Association Response Parameteres:
      Our Implementation Class UID: 2.16.124.113543.6021.1
      Our Implementation Version Name: RZDCX_2_0_2_2
      Their Implementation Class UID: 2.16.124.113543.6021.1
      Their Implementation Version Name: RZDCX_2_0_2_2
      Application Context Name: 1.2.840.10008.3.1.1.1
      Calling Application Name: RZDCX
      Called Application Name: DSRSVC
      Responding Application Name: DSRSVC
      Our Max PDU Receive Size: 32768
      Their Max PDU Receive Size: 32768
      Presentation Contexts:
      Context ID: 1 (Accepted)
      Abstract Syntax: =VerificationSOPClass
      Proposed SCP/SCU Role: Default
      Accepted SCP/SCU Role: Default
      Accepted Transfer Syntax: =BigEndianExplicit
      Context ID: 3 (Accepted)
      Abstract Syntax: =FINDModalityWorklistInformationModel
      Proposed SCP/SCU Role: Default
      Accepted SCP/SCU Role: Default
      Accepted Transfer Syntax: =BigEndianExplicit
      Requested Extended Negotiation: none
      Accepted Extended Negotiation: none

      2012-07-1110:59:19.513000 7120 INFO
      C-FIND Identifier:
      # Dicom-Data-Set
      # Used TransferSyntax: UnknownTransferSyntax
      (0008,0050) SH (no value available) # 0, 0 AccessionNumber
      (0010,0010) PN (no value available) # 0, 0 PatientName
      (0010,0020) LO (no value available) # 0, 0 PatientID
      (0020,000d) UI (no value available) # 0, 0 StudyInstanceUID
      (0032,1060) LO (no value available) # 0, 0 RequestedProcedureDescription
      (0040,0100) SQ (Sequence with explicit length #=1) # 0, 1 ScheduledProcedureStepSequence
      (fffe,e000) na (Item with undefined length #=4) # u/l, 1 Item
      (0008,0060) CS [CR] # 2, 1 Modality
      (0040,0001) AE [TESTCR] # 6, 1 ScheduledStationAETitle
      (0040,0007) LO (no value available) # 0, 0 ScheduledProcedureStepDescription
      (0040,0009) SH (no value available) # 0, 0 ScheduledProcedureStepID
      (fffe,e00d) na (ItemDelimitationItem) # 0, 0 ItemDelimitationItem
      (fffe,e0dd) na (SequenceDelimitationItem for re-encod.) # 0, 0 SequenceDelimitationItem
      (0040,1001) SH (no value available) # 0, 0 RequestedProcedureID

      2012-07-1110:59:19.513000 7120 INFO DIMSE receiveCommand
      0006:0317 Peer aborted Association (or never connected)
      2012-07-1110:59:22.695000 7120 ERROR In DCXREQ, Code: 0, Text: Normal
      Stopped Logging.

      Delete
    3. Hi Igor,
      Let me check this.
      Thanks,
      Roni

      Delete
    4. yes, there's a problem. Thanks! Will post a fix soon

      Delete
    5. Hi roniza,

      Recently i tried to use the sample app you posted "ModalityWorklistSCU" against one of our test pacs and its errored out with the message
      "Peer aborted Association (or never connected)".

      please help us out on, why this happening and how to fix it mean while i am posting my log file also, it will be great if you help me on this.

      Delete
    6. The error in the log file
      =======================
      2015-07-0105:18:57.581000 3876 INFO DIMSE receiveCommand
      0006:0317 Peer aborted Association (or never connected)
      2015-07-0105:18:58.488000 3876 ERROR In DCXREQ, Code: 0, Text: Normal

      Delete
  2. Hi! I downloaded DSRSVC (latest version) and wanted to test it with a Modality Workstation I have on my computer. I followed the instructions up to how to configure MWL SCP plugin but when I try starting the service, it gives me an error that says this:

    Windows could not start the Storage DICOM Service service on Local Computer.

    Error 1067: The process terminated unexpectedly.


    Can you give me insight to what might be causing this? And if possible a detailed instruction on how solve it.

    ReplyDelete
    Replies
    1. Please try the latest build from tech zone.roniza.con/products/downloads
      There QA a mismatch between the db plugin platforms that was win32 in the x64 dist

      Delete
    2. It works now.. Thanks a lot!

      I have a couple of questions I'd like to ask just verify, if you don't mind.

      1. How do you input dicom info into the server? Is it by putting .dcm files into the rootfolder\DSRSVC directory and the service will automatically read these? if not, can you explain how?

      2. is the rootfolder\DSRSVC automatically generated by the service or do i have to create it? I put the DicomServer.EXE file in a folder named Dicom Server (C:\Dicom Server). Where should i find the DSRSVC Folder?

      Thanks a lot! I'm hoping for a reply soon.

      Delete
    3. Hi,
      The data is added as you send DICOM files to the server using C-STORE.
      To add MWL entries use the script. The hl7 order Example is not yet ready. You can add entries to the database with you software.
      As for the root folder, it is configurable from the configuration table root_folder entry. The default is \DSRSVC
      It should create automatically when you send new files.

      Delete
  3. Ah! Thanks so much for that. It made it clear for me now.

    One more thing since I think you're looking in your blogspot site, i'll ask already.

    Can you point me to a sample app you have that simulates the C-Store method. (sorry i'm really new to DICOM and i'm still crawling and finding my bearings in this field as of now). Or a tutorial about C-Store if any.

    Also, is it possible to, instead of using C-Store, insert the info into the database? Would that be retrieved by the MWL?

    ReplyDelete
  4. Hi! I'm trying to connect a Modality Worklist called XMaruViewer to DSRSVC and I get a Successful ECHO result but all of a sudden the DICOM Storage Service crashes and I would need to restart the service. After doing an echo again or try a retrieve, the service crashes again.

    So far, the changes I've done with the RZ_DICOM database is adding my Modality Worklist SCU configurations info to the DICOM_APPLICATIONS table. Nothing else.

    Do you know why this happens?

    Thanks

    ReplyDelete
    Replies
    1. Hi,
      What happens is probably that the evaluation limitation is triggered.
      Without a license the server stops (crashes, it actually writes the reason in the application event log) after 200 commands.
      This is the same as in the toolkit.
      Roni

      Delete
    2. Ahh.. That's unfortunate. Is it the same case for the features included in the RZDCX.dll library? Or can we use this as a reference with no limitations?

      Also, Do you have a licensed (full featured) version of the server that can is available?

      Thanks

      Delete
    3. Sure, you can purchase a license.
      Plese email info@roniza.com for pricing

      Delete
  5. Is there any way to set the server to write to a drive apart from C?

    ReplyDelete
    Replies
    1. Yes, in the IniFilePlugin, set STORAGE_ROOT in DicomServer.ini like this (you have it in the downloads)
      [DICOM_SERVER]
      AE_TITLE=DSRSVC
      PORT=104
      STORAGE_ROOT=F:\DSRSVC

      In the database plugin it's in the CONFIGURATION table root_dir row

      Delete
  6. I am trying to get the requesting and referring physician into the MWL SCU project but on both I receive N/A (on one the value is null and on the other one I get a tag not found exception.)

    The name are in the database (or view).
    I have used your testproject.

    Regards
    Jonathan

    ReplyDelete
    Replies
    1. Hi Jonathan,
      You are right. There a bug in the DICOM DB Plugin that I just found. It can't handle nvarchar(MAX) from some reason.
      Also the view field name is wrong.
      Please do the following:
      1) in SERVICE_REQUEST, change the type of Requesting and referring physicians from nvarchar(MAX) to nvarchar(400)
      2) in CFIND_MWL_VIEW change the alias to ReferringPhysicianName i.e. remove the s from Physicians.
      Then it will work.
      Thanks,
      Roni

      Delete
    2. The DB plugin can access tables with more then one blob data type.
      See: http://support.microsoft.com/kb/190904

      Delete
  7. ola tenho o servidor dicom estalado no windows server 2003 e o efilme no windows xp quando vou puxar uma imagem dicom da o seguinte erro
    THE DICOM SERVER PROCESS IS NOT RUNNING. SERVICE WILL NOW BE STARTED.

    ReplyDelete
    Replies
    1. Compruebe el número de puerto en el que escucha en eFilm y asegúrese de que no es 104. Si es así, cambie el número de puerto de eFilm o del servidor (ver tabla de configuración).
      Compruebe el registro de aplicación utilizando eventvwr

      Delete
  8. I try to install DicomServer 64bit on Windows7. I've copied file DicomServer.EXE to directory C:\DICOM and run at cmd prompt DicomServer.EXE -i. Then I got message "Storage DICOM Service failed to install. Error 5" . What I'm doing wrong ?

    ReplyDelete
    Replies
    1. You should run cmd as administrator. That's it.

      Delete
    2. Thanks, it's working

      Delete
  9. DicomServer exits with the message "Application aborted!" if I rename DicomDBPlugin.dll to DSRSVCP.DLL after following the steps to enable Modality Worklist plugin. It works ok if i dont rename dll file but does not reply to query. Any ideas?

    ReplyDelete
    Replies
    1. Ibrahim Bey Merhaba

      Bende de ayni hata var ama cozemedim bir turlu.Siz soruna cozum bulabildiniz mi acaba.

      Delete
    2. Merhaba Ibrahim Bey

      Bende ayni hata ile karsilastim.Siz bir cozum yolu bulabildiniz mi acaba.

      Delete
  10. hi, i'm new in this matter, DICOM, PACS, etc. Maybe it isn't the place for consulting, but i would like to know if i can connect a PACS server directly with a hospital information system (HIS) without a RIS application, for the implementation of a worklist manager. Thanks a lot.

    ReplyDelete
  11. HI i am new to this dicom thing.Can you please share the code in which the dicom object is passed in between the scu and scp services?so that i can extract the image data from dicom object and convert into jpeg or some other format.

    ReplyDelete
  12. Hi Roni,

    Based on the C-Find Request from the Worklist am sending back the C-Find response back to the ultra sound machine! But the machine always showing that the "No Details Found" whenever when ever I return the response back! below is the C-response which I generated!

    ******Response Generated*******
    (0008,0005) CS [ISO_IR 100] # 10, SpecificCharacterSet
    (0008,0050) SH (no value available) # 0, AccessionNumber
    (0008,0060) CS [US] # 4, Modality
    (0008,0090) PN (no value available) # 0, ReferringPhysicianName
    (0010,0010) PN [TEST^NAME] # 0, PatientName
    (0010,0020) LO [2647177] # 8, PatientID
    (0010,0021) LO (no value available) # 0, IssuerOfPatientID
    (0010,0030) DA (no value available) # 0, PatientBirthDate
    (0010,0040) CS [F] # 2, PatientSex
    (0010,1020) DS [170] # 4, PatientSize
    (0010,1030) DS [70] # 4, PatientWeight
    (0010,21d0) DA (no value available) # 0, LastMenstrualDate
    (0020,000d) UI (no value available) # 0, StudyInstanceUID
    (0032,1032) PN (no value available) # 0, RequestingPhysician
    (0032,1060) LO (no value available) # 0, RequestedProcedureDescription
    (0038,0010) LO (no value available) # 0, AdmissionID
    (0040,0001) AE [STORESCP] # 8, ScheduledStationAETitle
    (0040,0244) DA [20151027 - 20151027] # 20, PerformedProcedureStepStartDate
    (0040,0245) TM (no value available) # 0, PerformedProcedureStepStartTime
    (0040,1001) SH (no value available) # 0, RequestedProcedureID
    (0040,1002) LO (no value available) # 0, ReasonForTheRequestedProcedure

    Am I missing something here! I am really stuck!

    ReplyDelete
  13. Some devices will kit show results unless all tags they ask for are in the response and sometimes also if some tags don't have values. Take the request and add all the tags there by adding fixed values tags to the db views.

    ReplyDelete
  14. Happy New Everyone. So I am new to DICOM Servers, but I have a client that has a Phillips Echo Machine where they want to save the images onto a network share instead of a USB device or CD. Talking to the rep we just need the DICOM Server software so we can accept the images and place them on our network. The doctors will then run there DICOM Viewer to access these images and do whatever they do. Currently, they are writing everything to a CD then copying those contents to the network share so the doctors can read them from different locations across our VPN. Will this software allow me to do what I want and just save the images to the server directly?

    ReplyDelete
  15. Hi
    Well, yes. You can connect your Echo machine to a DICOM storage server (like ours) that will arrange the images nicely on a storage device. But you can easily take it one step further and make the doctors get these files using the same server (that by now we can call it a PACS), in a more convenient way then going through your file system, using a PACS workstation (like our DICOMIZER for example).
    Regards
    Roni

    ReplyDelete
  16. Hi.

    We need to replace our work List server.
    We want to allow our medical equipment can query the WL Server for available studies, to take patientid, patient name, AC Number, etc.
    The WL Server should see this request and query our RIS Database to see and send all these available studies to the medical equipment that made the request to the WL.

    I don't know what product I need to use.
    "DSRSVC ROBUST DICOM SERVER (PACS)" or "RZDCX FAST STRIKE DICOM TOOLKIT"
    I will not replace for now the Pacs Server.

    Regards
    Jhon

    ReplyDelete
    Replies
    1. DSRSVC with DB Plugin. Then use the insert entry script as basis for your application integration. You can install it easily by installing HL7Kit. This includes both DB and HL7 integration. Then you can process HL7 messages with Order (ORU^R01) directly to worklist entires. email info@roniza.com to get help if needed.

      Delete
  17. We are getting "0006:0317 & 0006:031c" Error ....

    Following is the log generate ....

    can you please help ?


    2016-03-0920:44:20.200000 8544 INFO Association Request Parameteres:
    Our Implementation Class UID: 2.16.124.113543.6021.1
    Our Implementation Version Name: RZDCX_2_0_3_2
    Their Implementation Class UID:
    Their Implementation Version Name:
    Application Context Name: 1.2.840.10008.3.1.1.1
    Calling Application Name: RZDCX
    Called Application Name: PACS
    Responding Application Name: resp AP Title
    Our Max PDU Receive Size: 32768
    Their Max PDU Receive Size: 0
    Presentation Contexts:
    Context ID: 1 (Proposed)
    Abstract Syntax: =VerificationSOPClass
    Proposed SCP/SCU Role: Default
    Accepted SCP/SCU Role: Default
    Proposed Transfer Syntax(es):
    =LittleEndianExplicit
    =BigEndianExplicit
    =LittleEndianImplicit
    Context ID: 3 (Proposed)
    Abstract Syntax: =FINDStudyRootQueryRetrieveInformationModel
    Proposed SCP/SCU Role: Default
    Accepted SCP/SCU Role: Default
    Proposed Transfer Syntax(es):
    =LittleEndianExplicit
    =BigEndianExplicit
    =LittleEndianImplicit
    Requested Extended Negotiation: none
    Accepted Extended Negotiation: none

    2016-03-0920:44:25.202000 8544 INFO Association Request Result: Failed to establish association
    0006:0317 Peer aborted Association (or never connected)
    0006:031c TCP Initialization Error: No error (Timeout)
    Association Response Parameteres:
    Our Implementation Class UID: 2.16.124.113543.6021.1
    Our Implementation Version Name: RZDCX_2_0_3_2
    Their Implementation Class UID:
    Their Implementation Version Name:
    Application Context Name: 1.2.840.10008.3.1.1.1
    Calling Application Name: RZDCX
    Called Application Name: PACS
    Responding Application Name: resp AP Title
    Our Max PDU Receive Size: 32768
    Their Max PDU Receive Size: 0
    Presentation Contexts:
    Context ID: 1 (Proposed)
    Abstract Syntax: =VerificationSOPClass
    Proposed SCP/SCU Role: Default
    Accepted SCP/SCU Role: Default
    Proposed Transfer Syntax(es):
    =LittleEndianExplicit
    =BigEndianExplicit
    =LittleEndianImplicit
    Context ID: 3 (Proposed)
    Abstract Syntax: =FINDStudyRootQueryRetrieveInformationModel
    Proposed SCP/SCU Role: Default
    Accepted SCP/SCU Role: Default
    Proposed Transfer Syntax(es):
    =LittleEndianExplicit
    =BigEndianExplicit
    =LittleEndianImplicit
    Requested Extended Negotiation: none
    Accepted Extended Negotiation: none

    2016-03-0920:44:25.202000 8544 ERROR In DCXREQ, Code: 795, Text: Failed to establish association
    0006:0317 Peer aborted Association (or never connected)
    0006:031c TCP Initialization Error: No error (Timeout)
    Stopped Logging.

    ReplyDelete
    Replies
    1. Nobody answers on the other side. Check IP address and port of the MWL SCP. Check firewalls. Verify you get C-ECHO

      Delete