comparison OrthancServer/Internals/FindScp.cpp @ 2204:0158f2de8cad

Fix handling of worklist SCP with ReferencedStudySequence and ReferencedPatientSequence
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 08 Dec 2016 14:46:13 +0100
parents bb199bccdc45
children a3a65de1840f
comparison
equal deleted inserted replaced
2203:7d5320c59a05 2204:0158f2de8cad
87 #include "../../Core/Logging.h" 87 #include "../../Core/Logging.h"
88 #include "../../Core/OrthancException.h" 88 #include "../../Core/OrthancException.h"
89 #include "../OrthancInitialization.h" 89 #include "../OrthancInitialization.h"
90 90
91 #include <dcmtk/dcmdata/dcfilefo.h> 91 #include <dcmtk/dcmdata/dcfilefo.h>
92 #include <dcmtk/dcmdata/dcdeftag.h>
93
94
95
96 /**
97 * The function below is extracted from DCMTK 3.6.0, cf. file
98 * "dcmtk-3.6.0/dcmwlm/libsrc/wldsfs.cc".
99 **/
100
101 static void HandleExistentButEmptyReferencedStudyOrPatientSequenceAttributes(DcmDataset *dataset,
102 const DcmTagKey &sequenceTagKey)
103 // Date : May 3, 2005
104 // Author : Thomas Wilkens
105 // Task : This function performs a check on a sequence attribute in the given dataset. At two different places
106 // in the definition of the DICOM worklist management service, a sequence attribute with a return type
107 // of 2 is mentioned containing two 1C attributes in its item; the condition of the two 1C attributes
108 // specifies that in case a sequence item is present, then these two attributes must be existent and
109 // must contain a value. (I am talking about ReferencedStudySequence and ReferencedPatientSequence.)
110 // In cases where the sequence attribute contains exactly one item with an empty ReferencedSOPClass
111 // and an empty ReferencedSOPInstance, we want to remove the item from the sequence. This is what
112 // this function does.
113 // Parameters : dataset - [in] Dataset in which the consistency of the sequence attribute shall be checked.
114 // sequenceTagKey - [in] DcmTagKey of the sequence attribute which shall be checked.
115 // Return Value : none.
116 {
117 DcmElement *sequenceAttribute = NULL, *referencedSOPClassUIDAttribute = NULL, *referencedSOPInstanceUIDAttribute = NULL;
118
119 // in case the sequence attribute contains exactly one item with an empty
120 // ReferencedSOPClassUID and an empty ReferencedSOPInstanceUID, remove the item
121 if( dataset->findAndGetElement( sequenceTagKey, sequenceAttribute ).good() &&
122 ( (DcmSequenceOfItems*)sequenceAttribute )->card() == 1 &&
123 ( (DcmSequenceOfItems*)sequenceAttribute )->getItem(0)->findAndGetElement( DCM_ReferencedSOPClassUID, referencedSOPClassUIDAttribute ).good() &&
124 referencedSOPClassUIDAttribute->getLength() == 0 &&
125 ( (DcmSequenceOfItems*)sequenceAttribute )->getItem(0)->findAndGetElement( DCM_ReferencedSOPInstanceUID, referencedSOPInstanceUIDAttribute, OFFalse ).good() &&
126 referencedSOPInstanceUIDAttribute->getLength() == 0 )
127 {
128 DcmItem *item = ((DcmSequenceOfItems*)sequenceAttribute)->remove( ((DcmSequenceOfItems*)sequenceAttribute)->getItem(0) );
129 delete item;
130 }
131 }
132
133
92 134
93 namespace Orthanc 135 namespace Orthanc
94 { 136 {
95 namespace 137 namespace
96 { 138 {
106 148
107 FindScpData() : answers_(false) 149 FindScpData() : answers_(false)
108 { 150 {
109 } 151 }
110 }; 152 };
153
154
155
156 static void FixWorklistQuery(ParsedDicomFile& query)
157 {
158 // TODO: Check out
159 // WlmDataSourceFileSystem::HandleExistentButEmptyDescriptionAndCodeSequenceAttributes()"
160 // in DCMTK 3.6.0
161
162 DcmDataset* dataset = query.GetDcmtkObject().getDataset();
163 HandleExistentButEmptyReferencedStudyOrPatientSequenceAttributes(dataset, DCM_ReferencedStudySequence);
164 HandleExistentButEmptyReferencedStudyOrPatientSequenceAttributes(dataset, DCM_ReferencedPatientSequence);
165 }
166
111 167
112 168
113 void FindScpCallback( 169 void FindScpCallback(
114 /* in */ 170 /* in */
115 void *callbackData, 171 void *callbackData,
139 data.answers_.SetWorklist(true); 195 data.answers_.SetWorklist(true);
140 196
141 if (data.worklistHandler_ != NULL) 197 if (data.worklistHandler_ != NULL)
142 { 198 {
143 ParsedDicomFile query(*requestIdentifiers); 199 ParsedDicomFile query(*requestIdentifiers);
200 FixWorklistQuery(query);
201
144 data.worklistHandler_->Handle(data.answers_, query, 202 data.worklistHandler_->Handle(data.answers_, query,
145 *data.remoteIp_, *data.remoteAet_, 203 *data.remoteIp_, *data.remoteAet_,
146 *data.calledAet_); 204 *data.calledAet_);
147 ok = true; 205 ok = true;
148 } 206 }