Mercurial > hg > orthanc
annotate OrthancServer/OrthancFindRequestHandler.cpp @ 1348:cff17da28916
ArchiveStudiesInTimeRange.py sample
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 22 Apr 2015 15:12:04 +0200 |
parents | 911a1ad5ebe8 |
children | 3dd494f201a1 |
rev | line source |
---|---|
565
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
1 /** |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
2 * Orthanc - A Lightweight, RESTful DICOM Store |
1288
6e7e5ed91c2d
upgrade to year 2015
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1162
diff
changeset
|
3 * Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics |
6e7e5ed91c2d
upgrade to year 2015
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1162
diff
changeset
|
4 * Department, University Hospital of Liege, Belgium |
565
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
5 * |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
6 * This program is free software: you can redistribute it and/or |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
7 * modify it under the terms of the GNU General Public License as |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
8 * published by the Free Software Foundation, either version 3 of the |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
9 * License, or (at your option) any later version. |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
10 * |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
11 * In addition, as a special exception, the copyright holders of this |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
12 * program give permission to link the code of its release with the |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
13 * OpenSSL project's "OpenSSL" library (or with modified versions of it |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
14 * that use the same license as the "OpenSSL" library), and distribute |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
15 * the linked executables. You must obey the GNU General Public License |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
16 * in all respects for all of the code used other than "OpenSSL". If you |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
17 * modify file(s) with this exception, you may extend this exception to |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
18 * your version of the file(s), but you are not obligated to do so. If |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
19 * you do not wish to do so, delete this exception statement from your |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
20 * version. If you delete this exception statement from all source files |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
21 * in the program, then also delete it here. |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
22 * |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
23 * This program is distributed in the hope that it will be useful, but |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
24 * WITHOUT ANY WARRANTY; without even the implied warranty of |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
26 * General Public License for more details. |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
27 * |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
28 * You should have received a copy of the GNU General Public License |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
29 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
30 **/ |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
31 |
824
a811bdf8b8eb
precompiled headers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
810
diff
changeset
|
32 |
831
84513f2ee1f3
pch for unit tests and server
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
824
diff
changeset
|
33 #include "PrecompiledHeadersServer.h" |
565
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
34 #include "OrthancFindRequestHandler.h" |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
35 |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
36 #include <glog/logging.h> |
608 | 37 #include <boost/regex.hpp> |
565
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
38 |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
39 #include "../Core/DicomFormat/DicomArray.h" |
608 | 40 #include "ServerToolbox.h" |
618 | 41 #include "OrthancInitialization.h" |
795 | 42 #include "FromDcmtkBridge.h" |
565
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
43 |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
44 namespace Orthanc |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
45 { |
615 | 46 static bool IsWildcard(const std::string& constraint) |
47 { | |
48 return (constraint.find('-') != std::string::npos || | |
49 constraint.find('*') != std::string::npos || | |
50 constraint.find('\\') != std::string::npos || | |
51 constraint.find('?') != std::string::npos); | |
52 } | |
53 | |
608 | 54 static bool ApplyRangeConstraint(const std::string& value, |
55 const std::string& constraint) | |
56 { | |
610 | 57 size_t separator = constraint.find('-'); |
690
2e67366aab83
case-insensitive matching of Application Entity Titles
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
689
diff
changeset
|
58 std::string lower, upper, v; |
2e67366aab83
case-insensitive matching of Application Entity Titles
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
689
diff
changeset
|
59 Toolbox::ToLowerCase(lower, constraint.substr(0, separator)); |
2e67366aab83
case-insensitive matching of Application Entity Titles
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
689
diff
changeset
|
60 Toolbox::ToLowerCase(upper, constraint.substr(separator + 1)); |
2e67366aab83
case-insensitive matching of Application Entity Titles
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
689
diff
changeset
|
61 Toolbox::ToLowerCase(v, value); |
610 | 62 |
63 if (lower.size() == 0 && upper.size() == 0) | |
64 { | |
65 return false; | |
66 } | |
67 | |
68 if (lower.size() == 0) | |
69 { | |
70 return v <= upper; | |
71 } | |
72 | |
73 if (upper.size() == 0) | |
74 { | |
75 return v >= lower; | |
76 } | |
77 | |
78 return (v >= lower && v <= upper); | |
608 | 79 } |
80 | |
81 | |
82 static bool ApplyListConstraint(const std::string& value, | |
83 const std::string& constraint) | |
84 { | |
690
2e67366aab83
case-insensitive matching of Application Entity Titles
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
689
diff
changeset
|
85 std::string v1; |
2e67366aab83
case-insensitive matching of Application Entity Titles
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
689
diff
changeset
|
86 Toolbox::ToLowerCase(v1, value); |
608 | 87 |
88 std::vector<std::string> items; | |
89 Toolbox::TokenizeString(items, constraint, '\\'); | |
90 | |
91 for (size_t i = 0; i < items.size(); i++) | |
92 { | |
690
2e67366aab83
case-insensitive matching of Application Entity Titles
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
689
diff
changeset
|
93 std::string lower; |
2e67366aab83
case-insensitive matching of Application Entity Titles
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
689
diff
changeset
|
94 Toolbox::ToLowerCase(lower, items[i]); |
2e67366aab83
case-insensitive matching of Application Entity Titles
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
689
diff
changeset
|
95 if (lower == v1) |
608 | 96 { |
97 return true; | |
98 } | |
99 } | |
100 | |
101 return false; | |
102 } | |
103 | |
104 | |
105 static bool Matches(const std::string& value, | |
106 const std::string& constraint) | |
107 { | |
108 // http://www.itk.org/Wiki/DICOM_QueryRetrieve_Explained | |
109 // http://dicomiseasy.blogspot.be/2012/01/dicom-queryretrieve-part-i.html | |
110 | |
111 if (constraint.find('-') != std::string::npos) | |
112 { | |
113 return ApplyRangeConstraint(value, constraint); | |
114 } | |
115 | |
116 if (constraint.find('\\') != std::string::npos) | |
117 { | |
118 return ApplyListConstraint(value, constraint); | |
119 } | |
120 | |
121 if (constraint.find('*') != std::string::npos || | |
122 constraint.find('?') != std::string::npos) | |
123 { | |
124 // TODO - Cache the constructed regular expression | |
125 boost::regex pattern(Toolbox::WildcardToRegularExpression(constraint), | |
126 boost::regex::icase /* case insensitive search */); | |
127 return boost::regex_match(value, pattern); | |
128 } | |
129 else | |
130 { | |
690
2e67366aab83
case-insensitive matching of Application Entity Titles
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
689
diff
changeset
|
131 std::string v, c; |
2e67366aab83
case-insensitive matching of Application Entity Titles
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
689
diff
changeset
|
132 Toolbox::ToLowerCase(v, value); |
2e67366aab83
case-insensitive matching of Application Entity Titles
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
689
diff
changeset
|
133 Toolbox::ToLowerCase(c, constraint); |
2e67366aab83
case-insensitive matching of Application Entity Titles
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
689
diff
changeset
|
134 return v == c; |
608 | 135 } |
136 } | |
137 | |
138 | |
139 static bool LookupOneInstance(std::string& result, | |
140 ServerIndex& index, | |
141 const std::string& id, | |
142 ResourceType type) | |
143 { | |
144 if (type == ResourceType_Instance) | |
145 { | |
146 result = id; | |
147 return true; | |
148 } | |
149 | |
150 std::string childId; | |
151 | |
152 { | |
153 std::list<std::string> children; | |
154 index.GetChildInstances(children, id); | |
155 | |
656 | 156 if (children.empty()) |
608 | 157 { |
158 return false; | |
159 } | |
160 | |
161 childId = children.front(); | |
162 } | |
163 | |
164 return LookupOneInstance(result, index, childId, GetChildResourceType(type)); | |
165 } | |
166 | |
167 | |
168 static bool Matches(const Json::Value& resource, | |
169 const DicomArray& query) | |
170 { | |
171 for (size_t i = 0; i < query.GetSize(); i++) | |
172 { | |
173 if (query.GetElement(i).GetValue().IsNull() || | |
174 query.GetElement(i).GetTag() == DICOM_TAG_QUERY_RETRIEVE_LEVEL || | |
611
9924aec1d694
filtering on modalities
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
610
diff
changeset
|
175 query.GetElement(i).GetTag() == DICOM_TAG_SPECIFIC_CHARACTER_SET || |
9924aec1d694
filtering on modalities
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
610
diff
changeset
|
176 query.GetElement(i).GetTag() == DICOM_TAG_MODALITIES_IN_STUDY) |
608 | 177 { |
178 continue; | |
179 } | |
180 | |
181 std::string tag = query.GetElement(i).GetTag().Format(); | |
182 std::string value; | |
183 if (resource.isMember(tag)) | |
184 { | |
185 value = resource.get(tag, Json::arrayValue).get("Value", "").asString(); | |
186 } | |
187 | |
188 if (!Matches(value, query.GetElement(i).GetValue().AsString())) | |
189 { | |
190 return false; | |
191 } | |
192 } | |
193 | |
194 return true; | |
195 } | |
196 | |
197 | |
198 static void AddAnswer(DicomFindAnswers& answers, | |
199 const Json::Value& resource, | |
1331
77e129ba64e4
Prevent freeze on C-FIND if no DICOM tag is to be returned
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
200 const DicomArray& query, |
77e129ba64e4
Prevent freeze on C-FIND if no DICOM tag is to be returned
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
201 bool isFirst) |
608 | 202 { |
203 DicomMap result; | |
204 | |
205 for (size_t i = 0; i < query.GetSize(); i++) | |
206 { | |
1332 | 207 // Fix issue 30 (QR response missing "Query/Retrieve Level" (008,0052)) |
1346 | 208 if (query.GetElement(i).GetTag() == DICOM_TAG_QUERY_RETRIEVE_LEVEL) |
209 { | |
210 result.SetValue(query.GetElement(i).GetTag(), query.GetElement(i).GetValue()); | |
211 } | |
212 else if (query.GetElement(i).GetTag() == DICOM_TAG_SPECIFIC_CHARACTER_SET) | |
213 { | |
214 } | |
215 else | |
608 | 216 { |
217 std::string tag = query.GetElement(i).GetTag().Format(); | |
218 std::string value; | |
219 if (resource.isMember(tag)) | |
220 { | |
221 value = resource.get(tag, Json::arrayValue).get("Value", "").asString(); | |
222 result.SetValue(query.GetElement(i).GetTag(), value); | |
223 } | |
722 | 224 else |
225 { | |
226 result.SetValue(query.GetElement(i).GetTag(), ""); | |
227 } | |
608 | 228 } |
229 } | |
230 | |
1331
77e129ba64e4
Prevent freeze on C-FIND if no DICOM tag is to be returned
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
231 if (result.GetSize() == 0) |
77e129ba64e4
Prevent freeze on C-FIND if no DICOM tag is to be returned
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
232 { |
77e129ba64e4
Prevent freeze on C-FIND if no DICOM tag is to be returned
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
233 if (isFirst) |
77e129ba64e4
Prevent freeze on C-FIND if no DICOM tag is to be returned
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
234 { |
77e129ba64e4
Prevent freeze on C-FIND if no DICOM tag is to be returned
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
235 LOG(WARNING) << "The C-FIND request does not return any DICOM tag"; |
77e129ba64e4
Prevent freeze on C-FIND if no DICOM tag is to be returned
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
236 } |
77e129ba64e4
Prevent freeze on C-FIND if no DICOM tag is to be returned
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
237 } |
77e129ba64e4
Prevent freeze on C-FIND if no DICOM tag is to be returned
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
238 else |
77e129ba64e4
Prevent freeze on C-FIND if no DICOM tag is to be returned
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
239 { |
77e129ba64e4
Prevent freeze on C-FIND if no DICOM tag is to be returned
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
240 answers.Add(result); |
77e129ba64e4
Prevent freeze on C-FIND if no DICOM tag is to be returned
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
241 } |
608 | 242 } |
243 | |
244 | |
615 | 245 static bool ApplyModalitiesInStudyFilter(std::list<std::string>& filteredStudies, |
246 const std::list<std::string>& studies, | |
612 | 247 const DicomMap& input, |
248 ServerIndex& index) | |
249 { | |
615 | 250 filteredStudies.clear(); |
612 | 251 |
252 const DicomValue& v = input.GetValue(DICOM_TAG_MODALITIES_IN_STUDY); | |
253 if (v.IsNull()) | |
254 { | |
255 return false; | |
256 } | |
257 | |
258 // Move the allowed modalities into a "std::set" | |
259 std::vector<std::string> tmp; | |
260 Toolbox::TokenizeString(tmp, v.AsString(), '\\'); | |
261 | |
262 std::set<std::string> modalities; | |
263 for (size_t i = 0; i < tmp.size(); i++) | |
264 { | |
265 modalities.insert(tmp[i]); | |
266 } | |
267 | |
268 // Loop over the studies | |
615 | 269 for (std::list<std::string>::const_iterator |
656 | 270 it = studies.begin(); it != studies.end(); ++it) |
612 | 271 { |
272 try | |
273 { | |
274 // We are considering a single study. Check whether one of | |
275 // its child series matches one of the modalities. | |
276 Json::Value study; | |
615 | 277 if (index.LookupResource(study, *it, ResourceType_Study)) |
612 | 278 { |
279 // Loop over the series of the considered study. | |
280 for (Json::Value::ArrayIndex j = 0; j < study["Series"].size(); j++) // (*) | |
281 { | |
282 Json::Value series; | |
283 if (index.LookupResource(series, study["Series"][j].asString(), ResourceType_Series)) | |
284 { | |
285 // Get the modality of this series | |
286 if (series["MainDicomTags"].isMember("Modality")) | |
287 { | |
288 std::string modality = series["MainDicomTags"]["Modality"].asString(); | |
289 if (modalities.find(modality) != modalities.end()) | |
290 { | |
291 // This series of the considered study matches one | |
292 // of the required modalities. Take the study into | |
293 // consideration for future filtering. | |
615 | 294 filteredStudies.push_back(*it); |
612 | 295 |
296 // We have finished considering this study. Break the study loop at (*). | |
297 break; | |
298 } | |
299 } | |
300 } | |
301 } | |
302 } | |
303 } | |
304 catch (OrthancException&) | |
305 { | |
306 // This resource has probably been deleted during the find request | |
307 } | |
308 } | |
309 | |
310 return true; | |
311 } | |
312 | |
313 | |
714
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
314 namespace |
615 | 315 { |
714
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
316 class CandidateResources |
615 | 317 { |
714
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
318 private: |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
319 ServerIndex& index_; |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
320 ModalityManufacturer manufacturer_; |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
321 ResourceType level_; |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
322 bool isFilterApplied_; |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
323 std::set<std::string> filtered_; |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
324 |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
325 static void ListToSet(std::set<std::string>& target, |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
326 const std::list<std::string>& source) |
615 | 327 { |
714
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
328 for (std::list<std::string>::const_iterator |
716 | 329 it = source.begin(); it != source.end(); ++it) |
615 | 330 { |
714
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
331 target.insert(*it); |
615 | 332 } |
333 } | |
334 | |
714
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
335 void ApplyExactFilter(const DicomTag& tag, const std::string& value) |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
336 { |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
337 LOG(INFO) << "Applying exact filter on tag " |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
338 << FromDcmtkBridge::GetName(tag) << " (value: " << value << ")"; |
615 | 339 |
714
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
340 std::list<std::string> resources; |
1162 | 341 index_.LookupIdentifier(resources, tag, value, level_); |
615 | 342 |
714
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
343 if (isFilterApplied_) |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
344 { |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
345 std::set<std::string> s; |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
346 ListToSet(s, resources); |
615 | 347 |
714
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
348 std::set<std::string> tmp = filtered_; |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
349 filtered_.clear(); |
615 | 350 |
714
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
351 for (std::set<std::string>::const_iterator |
716 | 352 it = tmp.begin(); it != tmp.end(); ++it) |
665 | 353 { |
714
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
354 if (s.find(*it) != s.end()) |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
355 { |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
356 filtered_.insert(*it); |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
357 } |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
358 } |
665 | 359 } |
360 else | |
361 { | |
714
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
362 assert(filtered_.empty()); |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
363 isFilterApplied_ = true; |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
364 ListToSet(filtered_, resources); |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
365 } |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
366 } |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
367 |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
368 public: |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
369 CandidateResources(ServerIndex& index, |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
370 ModalityManufacturer manufacturer) : |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
371 index_(index), |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
372 manufacturer_(manufacturer), |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
373 level_(ResourceType_Patient), |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
374 isFilterApplied_(false) |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
375 { |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
376 } |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
377 |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
378 ResourceType GetLevel() const |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
379 { |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
380 return level_; |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
381 } |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
382 |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
383 void GoDown() |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
384 { |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
385 assert(level_ != ResourceType_Instance); |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
386 |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
387 if (isFilterApplied_) |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
388 { |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
389 std::set<std::string> tmp = filtered_; |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
390 |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
391 filtered_.clear(); |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
392 |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
393 for (std::set<std::string>::const_iterator |
716 | 394 it = tmp.begin(); it != tmp.end(); ++it) |
714
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
395 { |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
396 std::list<std::string> children; |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
397 index_.GetChildren(children, *it); |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
398 ListToSet(filtered_, children); |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
399 } |
665 | 400 } |
401 | |
714
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
402 switch (level_) |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
403 { |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
404 case ResourceType_Patient: |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
405 level_ = ResourceType_Study; |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
406 break; |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
407 |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
408 case ResourceType_Study: |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
409 level_ = ResourceType_Series; |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
410 break; |
615 | 411 |
714
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
412 case ResourceType_Series: |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
413 level_ = ResourceType_Instance; |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
414 break; |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
415 |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
416 default: |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
417 throw OrthancException(ErrorCode_InternalError); |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
418 } |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
419 } |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
420 |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
421 void Flatten(std::list<std::string>& resources) const |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
422 { |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
423 resources.clear(); |
615 | 424 |
714
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
425 if (isFilterApplied_) |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
426 { |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
427 for (std::set<std::string>::const_iterator |
716 | 428 it = filtered_.begin(); it != filtered_.end(); ++it) |
714
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
429 { |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
430 resources.push_back(*it); |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
431 } |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
432 } |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
433 else |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
434 { |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
435 Json::Value tmp; |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
436 index_.GetAllUuids(tmp, level_); |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
437 for (Json::Value::ArrayIndex i = 0; i < tmp.size(); i++) |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
438 { |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
439 resources.push_back(tmp[i].asString()); |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
440 } |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
441 } |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
442 } |
615 | 443 |
714
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
444 void ApplyFilter(const DicomTag& tag, const DicomMap& query) |
615 | 445 { |
714
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
446 if (query.HasTag(tag)) |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
447 { |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
448 const DicomValue& value = query.GetValue(tag); |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
449 if (!value.IsNull()) |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
450 { |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
451 std::string value = query.GetValue(tag).AsString(); |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
452 if (!IsWildcard(value)) |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
453 { |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
454 ApplyExactFilter(tag, value); |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
455 } |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
456 } |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
457 } |
615 | 458 } |
714
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
459 }; |
615 | 460 } |
461 | |
462 | |
941
83489fddd8c5
Options to limit the number of results for an incoming C-FIND query
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
463 bool OrthancFindRequestHandler::HasReachedLimit(const DicomFindAnswers& answers, |
83489fddd8c5
Options to limit the number of results for an incoming C-FIND query
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
464 ResourceType level) const |
83489fddd8c5
Options to limit the number of results for an incoming C-FIND query
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
465 { |
83489fddd8c5
Options to limit the number of results for an incoming C-FIND query
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
466 switch (level) |
83489fddd8c5
Options to limit the number of results for an incoming C-FIND query
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
467 { |
83489fddd8c5
Options to limit the number of results for an incoming C-FIND query
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
468 case ResourceType_Patient: |
83489fddd8c5
Options to limit the number of results for an incoming C-FIND query
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
469 case ResourceType_Study: |
83489fddd8c5
Options to limit the number of results for an incoming C-FIND query
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
470 case ResourceType_Series: |
83489fddd8c5
Options to limit the number of results for an incoming C-FIND query
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
471 return (maxResults_ != 0 && answers.GetSize() >= maxResults_); |
83489fddd8c5
Options to limit the number of results for an incoming C-FIND query
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
472 |
83489fddd8c5
Options to limit the number of results for an incoming C-FIND query
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
473 case ResourceType_Instance: |
83489fddd8c5
Options to limit the number of results for an incoming C-FIND query
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
474 return (maxInstances_ != 0 && answers.GetSize() >= maxInstances_); |
83489fddd8c5
Options to limit the number of results for an incoming C-FIND query
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
475 |
83489fddd8c5
Options to limit the number of results for an incoming C-FIND query
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
476 default: |
83489fddd8c5
Options to limit the number of results for an incoming C-FIND query
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
477 throw OrthancException(ErrorCode_InternalError); |
83489fddd8c5
Options to limit the number of results for an incoming C-FIND query
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
478 } |
83489fddd8c5
Options to limit the number of results for an incoming C-FIND query
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
479 } |
83489fddd8c5
Options to limit the number of results for an incoming C-FIND query
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
480 |
83489fddd8c5
Options to limit the number of results for an incoming C-FIND query
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
481 |
83489fddd8c5
Options to limit the number of results for an incoming C-FIND query
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
482 bool OrthancFindRequestHandler::Handle(DicomFindAnswers& answers, |
665 | 483 const DicomMap& input, |
484 const std::string& callingAETitle) | |
565
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
485 { |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
486 /** |
665 | 487 * Retrieve the manufacturer of this modality. |
488 **/ | |
489 | |
490 ModalityManufacturer manufacturer; | |
491 | |
492 { | |
806 | 493 RemoteModalityParameters modality; |
665 | 494 |
810
401a9633e492
configuration into a namespace
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
806
diff
changeset
|
495 if (!Configuration::LookupDicomModalityUsingAETitle(modality, callingAETitle)) |
665 | 496 { |
497 throw OrthancException("Unknown modality"); | |
498 } | |
806 | 499 |
500 manufacturer = modality.GetManufacturer(); | |
665 | 501 } |
502 | |
503 | |
504 /** | |
565
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
505 * Retrieve the query level. |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
506 **/ |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
507 |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
508 const DicomValue* levelTmp = input.TestAndGetValue(DICOM_TAG_QUERY_RETRIEVE_LEVEL); |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
509 if (levelTmp == NULL) |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
510 { |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
511 throw OrthancException(ErrorCode_BadRequest); |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
512 } |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
513 |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
514 ResourceType level = StringToResourceType(levelTmp->AsString().c_str()); |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
515 |
714
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
516 if (level != ResourceType_Patient && |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
517 level != ResourceType_Study && |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
518 level != ResourceType_Series && |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
519 level != ResourceType_Instance) |
565
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
520 { |
714
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
521 throw OrthancException(ErrorCode_NotImplemented); |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
522 } |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
523 |
665 | 524 |
714
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
525 DicomArray query(input); |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
526 LOG(INFO) << "DICOM C-Find request at level: " << EnumerationToString(level); |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
527 |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
528 for (size_t i = 0; i < query.GetSize(); i++) |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
529 { |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
530 if (!query.GetElement(i).GetValue().IsNull()) |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
531 { |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
532 LOG(INFO) << " " << query.GetElement(i).GetTag() |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
533 << " " << FromDcmtkBridge::GetName(query.GetElement(i).GetTag()) |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
534 << " = " << query.GetElement(i).GetValue().AsString(); |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
535 } |
565
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
536 } |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
537 |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
538 |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
539 /** |
615 | 540 * Retrieve the candidate resources for this query level. Whenever |
541 * possible, we avoid returning ALL the resources for this query | |
542 * level, as it would imply reading the JSON file on the harddisk | |
543 * for each of them. | |
608 | 544 **/ |
545 | |
714
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
546 CandidateResources candidates(context_.GetIndex(), manufacturer); |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
547 |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
548 for (;;) |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
549 { |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
550 switch (candidates.GetLevel()) |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
551 { |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
552 case ResourceType_Patient: |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
553 candidates.ApplyFilter(DICOM_TAG_PATIENT_ID, input); |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
554 break; |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
555 |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
556 case ResourceType_Study: |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
557 candidates.ApplyFilter(DICOM_TAG_STUDY_INSTANCE_UID, input); |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
558 candidates.ApplyFilter(DICOM_TAG_ACCESSION_NUMBER, input); |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
559 break; |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
560 |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
561 case ResourceType_Series: |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
562 candidates.ApplyFilter(DICOM_TAG_SERIES_INSTANCE_UID, input); |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
563 break; |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
564 |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
565 case ResourceType_Instance: |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
566 candidates.ApplyFilter(DICOM_TAG_SOP_INSTANCE_UID, input); |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
567 break; |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
568 |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
569 default: |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
570 throw OrthancException(ErrorCode_InternalError); |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
571 } |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
572 |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
573 if (candidates.GetLevel() == level) |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
574 { |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
575 break; |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
576 } |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
577 |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
578 candidates.GoDown(); |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
579 } |
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
580 |
615 | 581 std::list<std::string> resources; |
714
6a1dbba0cca7
new implementation of C-Find handler
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
690
diff
changeset
|
582 candidates.Flatten(resources); |
608 | 583 |
611
9924aec1d694
filtering on modalities
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
610
diff
changeset
|
584 |
9924aec1d694
filtering on modalities
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
610
diff
changeset
|
585 /** |
9924aec1d694
filtering on modalities
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
610
diff
changeset
|
586 * Apply filtering on modalities for studies, if asked (this is an |
9924aec1d694
filtering on modalities
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
610
diff
changeset
|
587 * extension to standard DICOM) |
9924aec1d694
filtering on modalities
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
610
diff
changeset
|
588 * http://www.medicalconnections.co.uk/kb/Filtering_on_and_Retrieving_the_Modality_in_a_C_FIND |
9924aec1d694
filtering on modalities
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
610
diff
changeset
|
589 **/ |
9924aec1d694
filtering on modalities
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
610
diff
changeset
|
590 |
9924aec1d694
filtering on modalities
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
610
diff
changeset
|
591 if (level == ResourceType_Study && |
9924aec1d694
filtering on modalities
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
610
diff
changeset
|
592 input.HasTag(DICOM_TAG_MODALITIES_IN_STUDY)) |
9924aec1d694
filtering on modalities
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
610
diff
changeset
|
593 { |
615 | 594 std::list<std::string> filtered; |
612 | 595 if (ApplyModalitiesInStudyFilter(filtered, resources, input, context_.GetIndex())) |
611
9924aec1d694
filtering on modalities
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
610
diff
changeset
|
596 { |
612 | 597 resources = filtered; |
611
9924aec1d694
filtering on modalities
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
610
diff
changeset
|
598 } |
9924aec1d694
filtering on modalities
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
610
diff
changeset
|
599 } |
9924aec1d694
filtering on modalities
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
610
diff
changeset
|
600 |
608 | 601 /** |
602 * Loop over all the resources for this query level. | |
565
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
603 **/ |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
604 |
1331
77e129ba64e4
Prevent freeze on C-FIND if no DICOM tag is to be returned
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
605 LOG(INFO) << "Number of candidate resources after exact filtering on the identifiers only: " << resources.size(); |
77e129ba64e4
Prevent freeze on C-FIND if no DICOM tag is to be returned
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
606 |
77e129ba64e4
Prevent freeze on C-FIND if no DICOM tag is to be returned
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
607 bool isFirst = true; |
77e129ba64e4
Prevent freeze on C-FIND if no DICOM tag is to be returned
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
608 |
615 | 609 for (std::list<std::string>::const_iterator |
656 | 610 resource = resources.begin(); resource != resources.end(); ++resource) |
565
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
611 { |
608 | 612 try |
565
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
613 { |
608 | 614 std::string instance; |
615 | 615 if (LookupOneInstance(instance, context_.GetIndex(), *resource, level)) |
565
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
616 { |
615 | 617 Json::Value info; |
618 context_.ReadJson(info, instance); | |
1331
77e129ba64e4
Prevent freeze on C-FIND if no DICOM tag is to be returned
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
619 |
615 | 620 if (Matches(info, query)) |
608 | 621 { |
941
83489fddd8c5
Options to limit the number of results for an incoming C-FIND query
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
622 if (HasReachedLimit(answers, level)) |
83489fddd8c5
Options to limit the number of results for an incoming C-FIND query
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
623 { |
83489fddd8c5
Options to limit the number of results for an incoming C-FIND query
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
624 // Too many results, stop before recording this new match |
83489fddd8c5
Options to limit the number of results for an incoming C-FIND query
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
625 return false; |
83489fddd8c5
Options to limit the number of results for an incoming C-FIND query
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
626 } |
83489fddd8c5
Options to limit the number of results for an incoming C-FIND query
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
627 |
1331
77e129ba64e4
Prevent freeze on C-FIND if no DICOM tag is to be returned
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
628 AddAnswer(answers, info, query, isFirst); |
77e129ba64e4
Prevent freeze on C-FIND if no DICOM tag is to be returned
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
629 isFirst = false; |
608 | 630 } |
565
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
631 } |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
632 } |
608 | 633 catch (OrthancException&) |
634 { | |
611
9924aec1d694
filtering on modalities
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
610
diff
changeset
|
635 // This resource has probably been deleted during the find request |
608 | 636 } |
565
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
637 } |
941
83489fddd8c5
Options to limit the number of results for an incoming C-FIND query
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
638 |
1331
77e129ba64e4
Prevent freeze on C-FIND if no DICOM tag is to be returned
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
639 LOG(INFO) << "Number of candidate resources after filtering on all tags: " << answers.GetSize(); |
77e129ba64e4
Prevent freeze on C-FIND if no DICOM tag is to be returned
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
1288
diff
changeset
|
640 |
941
83489fddd8c5
Options to limit the number of results for an incoming C-FIND query
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
831
diff
changeset
|
641 return true; // All the matching resources have been returned |
565
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
642 } |
c931ac02db82
refactoring of find class
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
643 } |
682
efc4928be6fb
Recover pixel data for more transfer syntaxes (notably JPEG)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
665
diff
changeset
|
644 |
efc4928be6fb
Recover pixel data for more transfer syntaxes (notably JPEG)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
665
diff
changeset
|
645 |
efc4928be6fb
Recover pixel data for more transfer syntaxes (notably JPEG)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
665
diff
changeset
|
646 |
efc4928be6fb
Recover pixel data for more transfer syntaxes (notably JPEG)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
665
diff
changeset
|
647 /** |
efc4928be6fb
Recover pixel data for more transfer syntaxes (notably JPEG)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
665
diff
changeset
|
648 * TODO : Case-insensitive match for PN value representation (Patient |
efc4928be6fb
Recover pixel data for more transfer syntaxes (notably JPEG)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
665
diff
changeset
|
649 * Name). Case-senstive match for all the other value representations. |
efc4928be6fb
Recover pixel data for more transfer syntaxes (notably JPEG)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
665
diff
changeset
|
650 * |
efc4928be6fb
Recover pixel data for more transfer syntaxes (notably JPEG)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
665
diff
changeset
|
651 * Reference: DICOM PS 3.4 |
efc4928be6fb
Recover pixel data for more transfer syntaxes (notably JPEG)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
665
diff
changeset
|
652 * - C.2.2.2.1 ("Single Value Matching") |
efc4928be6fb
Recover pixel data for more transfer syntaxes (notably JPEG)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
665
diff
changeset
|
653 * - C.2.2.2.4 ("Wild Card Matching") |
1070 | 654 * http://medical.nema.org/Dicom/2011/11_04pu.pdf |
655 * | |
656 * "Except for Attributes with a PN Value Representation, only | |
657 * entities with values which match exactly the value specified in the | |
658 * request shall match. This matching is case-sensitive, i.e., | |
659 * sensitive to the exact encoding of the key attribute value in | |
660 * character sets where a letter may have multiple encodings (e.g., | |
661 * based on its case, its position in a word, or whether it is | |
662 * accented) | |
663 * | |
664 * For Attributes with a PN Value Representation (e.g., Patient Name | |
665 * (0010,0010)), an application may perform literal matching that is | |
666 * either case-sensitive, or that is insensitive to some or all | |
667 * aspects of case, position, accent, or other character encoding | |
668 * variants." | |
669 * | |
670 * (0008,0018) UI SOPInstanceUID => Case-sensitive | |
671 * (0008,0050) SH AccessionNumber => Case-sensitive | |
672 * (0010,0020) LO PatientID => Case-sensitive | |
673 * (0020,000D) UI StudyInstanceUID => Case-sensitive | |
674 * (0020,000E) UI SeriesInstanceUID => Case-sensitive | |
682
efc4928be6fb
Recover pixel data for more transfer syntaxes (notably JPEG)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
665
diff
changeset
|
675 **/ |