Sample Modality Worklists plugin¶
Contents
This page describes the official sample plugin turning Orthanc into a server of DICOM worklists. General information about how Orthanc supports DICOM worklists through plugins is explained in the FAQ.
The sample plugin will serve the worklists stored in some folder on
the filesystem. This mimics the behavior of the wlmscpfs
command-line tool from the DCMTK software.
The worklists to be served must be put inside the folder of interest
by an external application or script (note: files must have a .wl
extension). dump2dcm
might be a very
useful companion tool to generate such
worklist files. Whenever a C-Find SCP request is issued to Orthanc,
the plugin will read the content of the folder of interest to locate
the worklists that match the request. As a consequence, the external
application can dynamically modify the content of this folder while
Orthanc is running to add/remove worklists.
The source code of this sample plugin is available in the source distribution of Orthanc (GPLv3+ license).
Note that it is possible to reproduce the features of this sample using Python plugins.
Basic configuration¶
First, generate the default configuration of Orthanc.
Then, modify the
Plugins
option to point to the folder containing the shared library of the plugin.Finally, create a section “ModalityWorklists” in the configuration file to configure the worklist server.
A basic configuration would read as follows:
{
[...]
"Plugins" : [
"."
],
"Worklists" : {
"Enable": true,
"Database": "./WorklistsDatabase",
"FilterIssuerAet": false, // Some modalities do not specify 'ScheduledStationAETitle (0040,0001)'
// in the C-Find and may receive worklists not related to them. This option
// adds an extra filtering based on the AET of the modality issuing the C-Find.
"LimitAnswers": 0 // Maximum number of answers to be returned (new in release 1.7.3)
}
}
The folder WorklistsDatabase
of the source distribution of
Orthanc
contains a database of sample worklists, that comes from the DCMTK
source distribution, as described in the FAQ entry #37 of the DCMTK
project.
Tutorial¶
Download DCMTK utilities.
Download sample worklist files from the Orthanc source code and copy them in a dedicated folder.
Generate the default configuration of Orthanc.
Enable the ModalityWorklist plugin in your configuration file by adding this section:
"Worklists" : { "Enable": true, "Database": "WorklistsDatabase" // Path to the folder with the worklist files },
Add the plugin to the list of plugins to load (this is an example for Microsoft Windows):
"Plugins" : [ "StoneWebViewer.dll", "ModalityWorklists.dll" // On GNU/Linux, use libModalityWorklists.so ],
The tests below will be done using the
findscu
command-line tool from the DCMTK utilities. Assumingfindscu
and Orthanc runs on the same computer (i.e. on the127.0.0.1
localhost), declare theFINDSCU
AET to the list of know modalities:"DicomModalities" : { "horos" : [ "HOROS", "192.168.0.8", 11112 ], "findscu" : [ "FINDSCU", "127.0.0.1", 1234 ] },
Launch Orthanc as usual, making sure to give the proper configuration file (e.g. for Microsoft Windows):
Orthanc.exe config.json
In another command-line prompt, launch a
findscu
request to ask Orthanc to return all worklists forCT
modalities:findscu -W -k "ScheduledProcedureStepSequence[0].Modality=CT" 127.0.0.1 4242
The
-W
option makesfindscu
issue a DICOM worklist query, the-k
option specifies the query of interest,127.0.0.1
corresponds to the localhost, and4242
corresponds to the default DICOM TCP port of Orthanc.findscu
will display the matching worklists.
How to create a worklist file¶
Start with an existing worklist file, some samples of which can be found in the Orthanc source distribution (with
.wl
file extensions).The worklist file is a DICOM file. Dump its content as a text file using
dcmdump
:dcmdump.exe wklist1.wl > sampleWorklist.txt
The content of the just-generated
sampleWorklist.txt
file should look similar to this text file:# Dicom-File-Format # Dicom-Meta-Information-Header # Used TransferSyntax: Little Endian Explicit (0002,0000) UL 202 # 4, 1 FileMetaInformationGroupLength (0002,0001) OB 00\01 # 2, 1 FileMetaInformationVersion (0002,0002) UI [1.2.276.0.7230010.3.1.0.1] # 26, 1 MediaStorageSOPClassUID (0002,0003) UI [1.2.276.0.7230010.3.1.4.2831176407.11154.1448031138.805061] # 58, 1 MediaStorageSOPInstanceUID (0002,0010) UI =LittleEndianExplicit # 20, 1 TransferSyntaxUID (0002,0012) UI [1.2.276.0.7230010.3.0.3.6.0] # 28, 1 ImplementationClassUID (0002,0013) SH [OFFIS_DCMTK_360] # 16, 1 ImplementationVersionName # Dicom-Data-Set # Used TransferSyntax: Little Endian Explicit (0008,0005) CS [ISO_IR 100] # 10, 1 SpecificCharacterSet (0008,0050) SH [00000] # 6, 1 AccessionNumber (0010,0010) PN [VIVALDI^ANTONIO] # 16, 1 PatientName (0010,0020) LO [AV35674] # 8, 1 PatientID (0010,0030) DA [16780304] # 8, 1 PatientBirthDate (0010,0040) CS [M] # 2, 1 PatientSex (0010,2000) LO [METASTASIS] # 10, 1 MedicalAlerts (0010,2110) LO [TANTAL] # 6, 1 Allergies (0020,000d) UI [1.2.276.0.7230010.3.2.101] # 26, 1 StudyInstanceUID (0032,1032) PN [SMITH] # 6, 1 RequestingPhysician (0032,1060) LO [EXAM6] # 6, 1 RequestedProcedureDescription (0040,0100) SQ (Sequence with explicit length #=1) # 176, 1 ScheduledProcedureStepSequence (fffe,e000) na (Item with explicit length #=19) # 168, 1 Item (0008,0060) CS [US] # 2, 1 Modality (0040,0001) AE [AS_AET] # 5, 2 ScheduledStationAETitle (0040,0002) DA [19951015] # 8, 1 ScheduledProcedureStepStartDate (0040,0003) TM [085607] # 6, 1 ScheduledProcedureStepStartTime (0040,0006) PN [JOHNSON] # 8, 1 ScheduledPerformingPhysicianName (0040,0007) LO [EXAM74] # 6, 1 ScheduledProcedureStepDescription (0040,0009) SH [SPD3445] # 8, 1 ScheduledProcedureStepID (0040,0010) SH [STN456] # 6, 1 ScheduledStationName (0040,0011) SH [B34F56] # 6, 1 ScheduledProcedureStepLocation (0040,0012) LO (no value available) # 0, 0 PreMedication (0040,0400) LT (no value available) # 0, 0 CommentsOnTheScheduledProcedureStep (fffe,e00d) na (ItemDelimitationItem for re-encoding) # 0, 0 ItemDelimitationItem (fffe,e0dd) na (SequenceDelimitationItem for re-encod.) # 0, 0 SequenceDelimitationItem (0040,1001) SH [RP454G234] # 10, 1 RequestedProcedureID (0040,1003) SH [LOW] # 4, 1 RequestedProcedurePriority
Open
sampleWorklist.txt
file in a standard text editor so as to modify, add or remove some DICOM tags depending on your needs.Generate a new DICOM worklist file from your modified file using
dump2dcm
:dump2dcm.exe sampleWorklist.txt newWorklist.wl
As a last step, copy that file in the folder where Orthanc searches for its worklist files. Of course, this worklist generation workflow can be automated using any scripting language.
Troubleshooting C-Find queries¶
When trying to retrieve worklists from a modality, one usually don’t get debugging capabilities from the modality itself.
Therefore, it is usually convenient to mimic the modality with findscu
(provided by DCMTK software).
First, you should make sure that you have configured the Worklist plugin correctly and that you have pushed at least a
.wl
file in the worklist database. For this, you should issue this kind of command:findscu -W 127.0.0.1 4242 -k 0008,0050="*"
This is the most generic C-Find request and should return all AccessionNumber of all the worklists in your database.
Note: you should make sure you have added a
findscu
DICOM modality in your configuration file.findscu
should output something like this:W: --------------------------- W: Find Response: 1 (Pending) W: W: # Dicom-Data-Set W: # Used TransferSyntax: Little Endian Explicit W: (0008,0005) CS [ISO_IR 100] # 10, 1 SpecificCharacterSet W: (0008,0050) SH [**********] # 10, 1 AccessionNumber W:
If you don’t get any output, you may add
-v -d
options to thefindscu
command line to get additional details.Everytime it receives a C-Find request, Orthanc displays the query parameters in its logs. With the previous C-Find command, you should expect this kind of output:
I0422 17:16:03.512449 CommandDispatcher.cpp:490] Association Received from AET FINDSCU on IP 127.0.0.1 I0422 17:16:03.514433 CommandDispatcher.cpp:688] Association Acknowledged (Max Send PDV: 16372) I0422 17:16:03.532062 main.cpp:118] No limit on the number of C-FIND results at the Patient, Study and Series levels I0422 17:16:03.535986 main.cpp:128] No limit on the number of C-FIND results at the Instance level I0422 17:16:03.536968 PluginsManager.cpp:171] Received worklist query from remote modality FINDSCU: { "0008,0050" : "*" } I0422 17:16:03.559539 CommandDispatcher.cpp:891] DUL Peer Requested Release I0422 17:16:03.560520 CommandDispatcher.cpp:898] Association Release
Now you may try to issue a C-Find request from your modality and check Orthanc logs. You should then have a better understanding of the query content and eventually understand why it does not match your worklists. You should also be able re-issue
findscu
requests with additional arguments to mimic the requests issued by your modality.
Common problems¶
C-FIND requests can be modified by implementing the
IncomingWorklistRequestFilter
Lua callback since Orthanc 1.4.2. This can be useful to fix/sanitize worklist queries.According to the specification, modalities should not include their AET name in
ScheduledStationAETitle
on user initiated queries. Therefore, they do receive worklists that do not concern them. This may be handled by theFilterIssuerAet
configuration option. Note that the default behavior might in some cases be intended.Orthanc <= 1.4.1 might behave unexpectedly in the presence of
Generic group length (0x????, 0x0000)
tags. Please upgrade.