322
|
1 .. _storage-commitment:
|
|
2
|
|
3 Storage commitment
|
|
4 ==================
|
|
5
|
|
6 .. contents::
|
|
7 :depth: 3
|
|
8
|
|
9
|
|
10 Introduction
|
|
11 ------------
|
|
12
|
|
13 Starting with **release 1.6.0**, Orthanc implements DICOM storage
|
323
|
14 commitment, both as SCP and as SCU (i.e. both as a server and as a
|
|
15 client).
|
322
|
16
|
|
17 Storage commitment is a feature of the DICOM standard by which an
|
|
18 imaging modality "A" asks a remote imaging modality "B", whether "B"
|
323
|
19 accepts responsibility for having stored a set of DICOM instances.
|
322
|
20
|
|
21 Typically, a storage commitment request is issued by "A" after "A" has
|
|
22 sent images to "B" using the :ref:`DICOM C-STORE command
|
|
23 <dicom-store>`. If "B" answers that all the images have been properly
|
|
24 received, the modality "A" has the guarantee that the C-STORE commands
|
323
|
25 ran fine, and thus "A" could decide to remove the images from its
|
|
26 local database. If "B" answers that there was an error, "A" could
|
|
27 decide to send the images again.
|
322
|
28
|
|
29 For more technical information, one may refer to the storage
|
|
30 commitment `Information Object Definition
|
|
31 <http://dicom.nema.org/medical/dicom/2019e/output/html/part03.html#sect_B.15>`__
|
|
32 and `Service Class
|
|
33 <http://dicom.nema.org/medical/dicom/2019e/output/html/part04.html#chapter_J>`__
|
|
34 in the DICOM standard. Orthanc follows the objective of the IHE
|
|
35 Technical Framework regarding the `Storage Commitment transaction
|
|
36 (RAD-10)
|
|
37 <https://www.ihe.net/uploadedFiles/Documents/Radiology/IHE_RAD_TF_Vol2.pdf#page=160>`__. Following
|
|
38 this IHE specification, Orthanc only implements the **Storage
|
|
39 Commitment Push Model SOP Class**, both as an SCU ("Evidence Creator")
|
|
40 and as an SCP ("Image Manager").
|
|
41
|
|
42 Orthanc makes the assumption that the storage commitment responses are
|
|
43 sent **asynchronously**, which corresponds to most implementations of
|
|
44 storage commitment.
|
|
45
|
|
46
|
|
47 .. _storage-commitment-scp:
|
|
48
|
|
49 Storage commitment SCP
|
|
50 ----------------------
|
|
51
|
|
52 Overview
|
|
53 ^^^^^^^^
|
|
54
|
|
55 Here is a diagram that outlines how storage commitment works in Orthanc:
|
|
56
|
|
57 .. image:: ../images/StorageCommitmentSCP.svg
|
|
58 :align: center
|
|
59 :width: 650px
|
|
60
|
|
61 | In this sequence, three DICOM associations are used: The first one
|
|
62 is the usual command to send the DICOM images from some SCU to the
|
|
63 Orthanc SCP (:ref:`C-STORE <dicom-store>`), the second association
|
|
64 is the one by which the SCU asks the Orthanc SCP to process a
|
|
65 storage commitment request (the SCU provides a list of DICOM
|
|
66 instances to be checked by specifying their SOP instance UID and
|
|
67 their SOP class UID), and the third one is the storage commitment
|
|
68 response coming from the Orthanc SCP. The response is sent
|
|
69 asynchronously from the Orthanc SCP to the SCU, once the storage
|
|
70 commitment request has been processed by Orthanc.
|
|
71
|
|
72 The list of the DICOM modalities from which Orthanc accepts incoming
|
|
73 storage commitment requests is specified in the :ref:`configuration
|
323
|
74 file of Orthanc <configuration>`, through the ``DicomModalities``
|
322
|
75 option. It is possible to disable storage commitment for selected
|
|
76 modalities by setting their dedicated Boolean permission flag
|
|
77 ``AllowStorageCommitment`` to ``false``.
|
|
78
|
323
|
79 As can be seen in the figure above, the storage commitment SCP of
|
|
80 Orthanc takes advantage of the :ref:`jobs engine <jobs>` that is
|
|
81 embedded within Orthanc. Whenever Orthanc receives a storage
|
|
82 commitment request, it internally creates a job with a dedicated type
|
|
83 (namely ``StorageCommitmentScp``). :ref:`This job can be controlled
|
322
|
84 <jobs-monitoring>` using the REST API of Orthanc, just like any other
|
|
85 job. As a consequence, an external software is able to monitor, cancel
|
|
86 or pause incoming storage commitment requests, by inspecting the list
|
|
87 of jobs whose type is ``StorageCommitmentScp``.
|
|
88
|
|
89
|
|
90 Sample usage
|
|
91 ^^^^^^^^^^^^
|
|
92
|
|
93 In this section, we show how to query the storage commitment SCP of
|
|
94 Orthanc from the command-line tool ``stgcmtscu``. This free and
|
323
|
95 open-source tool is part of the `dcm4che project
|
322
|
96 <https://www.dcm4che.org/>`__ and simulates a basic storage commitment
|
|
97 SCU.
|
|
98
|
|
99 .. highlight:: json
|
|
100
|
|
101 Firstly, we define one DICOM modality corresponding to ``stgcmtscu``
|
|
102 by creating the following :ref:`configuration file <configuration>`
|
|
103 for Orthanc::
|
|
104
|
|
105 {
|
|
106 "DicomPort" : 4242,
|
|
107 "DicomModalities" : {
|
|
108 "storage-commitment" : [ "STGCMTSCU", "127.0.0.1", 11114 ]
|
|
109 }
|
|
110 }
|
|
111
|
|
112
|
|
113 .. highlight:: text
|
|
114
|
|
115 Secondly, we start Orthanc using the just-created configuration file::
|
|
116
|
|
117 $ ./Orthanc --verbose storage-commitment.json
|
|
118
|
|
119 We'll be using some sample file ``/tmp/DummyCT.dcm``, whose DICOM tags
|
|
120 "SOP instance UID" and "SOP class UID" can be retrieved as follows::
|
|
121
|
|
122 $ dcm2xml /tmp/DummyCT.dcm | grep -E '"SOPInstanceUID"|"SOPClassUID"'
|
|
123 <element tag="0008,0016" vr="UI" vm="1" len="26" name="SOPClassUID">1.2.840.10008.5.1.4.1.1.4</element>
|
|
124 <element tag="0008,0018" vr="UI" vm="1" len="54" name="SOPInstanceUID">1.2.840.113619.2.176.2025.1499492.7040.1171286242.109</element>
|
|
125
|
|
126 Thirdly, we use ``stgcmtscu`` to get the status of one sample DICOM
|
|
127 file. Here is what can be read at the end of the logs of
|
|
128 ``stgcmtscu``::
|
|
129
|
|
130 $ /home/jodogne/Downloads/dcm4che-5.20.0/bin/stgcmtscu -b STGCMTSCU:11114 -c ORTHANC@localhost:4242 /tmp/DummyCT.dcm
|
|
131 [...]
|
|
132 18:14:22,949 DEBUG - STGCMTSCU<-ORTHANC(2) >> 1:N-EVENT-REPORT-RQ Dataset receiving...
|
|
133 18:14:22,949 DEBUG - Dataset:
|
|
134 (0008,1195) UI [2.25.250402771220435242864082979068071491247] TransactionUID
|
|
135 (0008,1198) SQ [1 Items] FailedSOPSequence
|
|
136 >Item #1
|
|
137 >(0008,1150) UI [1.2.840.10008.5.1.4.1.1.4] ReferencedSOPClassUID
|
|
138 >(0008,1155) UI [1.2.840.113619.2.176.2025.1499492.7040.1171286242.109] ReferencedSOPInstanceUID
|
|
139 >(0008,1197) US [274] FailureReason
|
|
140 (0008,1199) SQ [] ReferencedSOPSequence
|
|
141
|
|
142 As can be seen, the SOP class/instance UIDs of ``/tmp/DummyCT.dcm``
|
|
143 are reported by the Orthanc SCP in the ``FailedSOPSequence`` field,
|
|
144 which indicates the fact that Orthanc has not stored this instance
|
323
|
145 yet. The ``FailureReason`` 274 corresponds to `status 0x0112
|
|
146 <http://dicom.nema.org/medical/dicom/current/output/chtml/part03/sect_C.14.html#sect_C.14.1.1>`__,
|
|
147 namely *"No such object instance"*.
|
322
|
148
|
323
|
149 Fourthly, let's upload the sample file to Orthanc, then execute
|
|
150 ``stgcmtscu`` for a second time::
|
322
|
151
|
|
152 $ storescu localhost 4242 /tmp/DummyCT.dcm
|
|
153 $ /home/jodogne/Downloads/dcm4che-5.20.0/bin/stgcmtscu -b STGCMTSCU:11114 -c ORTHANC@localhost:4242 /tmp/DummyCT.dcm
|
|
154 [...]
|
|
155 18:19:48,090 DEBUG - STGCMTSCU<-ORTHANC(2) >> 1:N-EVENT-REPORT-RQ Dataset receiving...
|
|
156 18:19:48,090 DEBUG - Dataset:
|
|
157 (0008,1195) UI [2.25.141864351815234988385597655400095444069] TransactionUID
|
|
158 (0008,1199) SQ [1 Items] ReferencedSOPSequence
|
|
159 >Item #1
|
|
160 >(0008,1150) UI [1.2.840.10008.5.1.4.1.1.4] ReferencedSOPClassUID
|
|
161 >(0008,1155) UI [1.2.840.113619.2.176.2025.1499492.7040.1171286242.109] ReferencedSOPInstanceUID
|
|
162
|
|
163 The instance of interest is now reported in the
|
|
164 ``ReferencedSOPSequence`` tag, instead of ``FailedSOPSequence``. This
|
|
165 shows that Orthanc has properly received the sample instance.
|
|
166
|
|
167
|
|
168
|
|
169 Plugins
|
|
170 ^^^^^^^
|
|
171
|
|
172 The Orthanc core implements a basic storage commitment SCP. This basic
|
|
173 handler simply checks for the presence of the requested DICOM
|
|
174 instances in the Orthanc database, and makes sure that their SOP class
|
|
175 UIDs do match those provided by the remote storage commitment SCU.
|
|
176
|
|
177 For more advanced scenarios, it is possible to override this default
|
|
178 SCP to customize the way incoming storage commitment requests are
|
|
179 processed by Orthanc. This customization is done :ref:`by creating an
|
|
180 Orthanc plugin <creating-plugins>`.
|
|
181
|
|
182 The custom storage commitment SCP is installed in the Orthanc core by
|
|
183 using the ``OrthancPluginRegisterStorageCommitmentScpCallback()``
|
|
184 function of the `plugin SDK <http://sdk.orthanc-server.com/>`__.
|
|
185
|
|
186 Importantly, this primitive frees the plugin developer from manually
|
323
|
187 creating the Orthanc jobs. One job is transparently created by the
|
|
188 Orthanc core for each incoming storage commitment request, allowing
|
|
189 the plugin developer to focus only on the processing of the queried
|
|
190 instances.
|
322
|
191
|
|
192 Note that a `sample plugin
|
|
193 <https://bitbucket.org/sjodogne/orthanc/src/storage-commitment/Plugins/Samples/StorageCommitmentScp/>`__
|
|
194 is also available in the source distribution of Orthanc.
|
|
195
|
|
196
|
|
197
|
|
198 .. _storage-commitment-scu:
|
|
199
|
|
200 Storage commitment SCU
|
|
201 ----------------------
|
|
202
|
|
203 *Work in progress*
|
|
204
|
|
205 *Sample using dcmqrscp*
|