Mercurial > hg > orthanc
comparison OrthancServer/Search/HierarchicalMatcher.cpp @ 1796:5e08a5fe6b27 worklists
HierarchicalMatcher - extracting tags
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 19 Nov 2015 18:32:00 +0100 |
parents | af6840eb23ee |
children | 23722a191e4e |
comparison
equal
deleted
inserted
replaced
1795:af6840eb23ee | 1796:5e08a5fe6b27 |
---|---|
33 #include "../PrecompiledHeadersServer.h" | 33 #include "../PrecompiledHeadersServer.h" |
34 #include "HierarchicalMatcher.h" | 34 #include "HierarchicalMatcher.h" |
35 | 35 |
36 #include "../../Core/OrthancException.h" | 36 #include "../../Core/OrthancException.h" |
37 #include "../FromDcmtkBridge.h" | 37 #include "../FromDcmtkBridge.h" |
38 #include "../ToDcmtkBridge.h" | |
38 | 39 |
39 #include <dcmtk/dcmdata/dcfilefo.h> | 40 #include <dcmtk/dcmdata/dcfilefo.h> |
40 | 41 |
41 namespace Orthanc | 42 namespace Orthanc |
42 { | 43 { |
82 { | 83 { |
83 throw OrthancException(ErrorCode_InternalError); | 84 throw OrthancException(ErrorCode_InternalError); |
84 } | 85 } |
85 | 86 |
86 DicomTag tag(FromDcmtkBridge::Convert(element->getTag())); | 87 DicomTag tag(FromDcmtkBridge::Convert(element->getTag())); |
88 if (tag == DICOM_TAG_SPECIFIC_CHARACTER_SET) | |
89 { | |
90 // Ignore this specific tag | |
91 continue; | |
92 } | |
93 | |
87 ValueRepresentation vr = FromDcmtkBridge::GetValueRepresentation(tag); | 94 ValueRepresentation vr = FromDcmtkBridge::GetValueRepresentation(tag); |
88 | 95 |
89 if (constraints_.find(tag) != constraints_.end() || | 96 if (constraints_.find(tag) != constraints_.end() || |
90 sequences_.find(tag) != sequences_.end()) | 97 sequences_.find(tag) != sequences_.end()) |
91 { | 98 { |
177 } | 184 } |
178 } | 185 } |
179 | 186 |
180 return s; | 187 return s; |
181 } | 188 } |
189 | |
190 | |
191 bool HierarchicalMatcher::Match(ParsedDicomFile& dicom) const | |
192 { | |
193 return MatchInternal(*dicom.GetDcmtkObject().getDataset(), | |
194 dicom.GetEncoding()); | |
195 } | |
196 | |
197 | |
198 bool HierarchicalMatcher::MatchInternal(DcmItem& item, | |
199 Encoding encoding) const | |
200 { | |
201 for (Constraints::const_iterator it = constraints_.begin(); | |
202 it != constraints_.end(); ++it) | |
203 { | |
204 if (it->second != NULL) | |
205 { | |
206 DcmTagKey tag = ToDcmtkBridge::Convert(it->first); | |
207 | |
208 DcmElement* element = NULL; | |
209 if (!item.findAndGetElement(tag, element).good() || | |
210 element == NULL) | |
211 { | |
212 return false; | |
213 } | |
214 | |
215 std::auto_ptr<DicomValue> value(FromDcmtkBridge::ConvertLeafElement | |
216 (*element, DicomToJsonFlags_None, encoding)); | |
217 | |
218 if (value->IsNull() || | |
219 value->IsBinary() || | |
220 !it->second->Match(value->GetContent())) | |
221 { | |
222 return false; | |
223 } | |
224 } | |
225 } | |
226 | |
227 for (Sequences::const_iterator it = sequences_.begin(); | |
228 it != sequences_.end(); ++it) | |
229 { | |
230 if (it->second != NULL) | |
231 { | |
232 DcmTagKey tag = ToDcmtkBridge::Convert(it->first); | |
233 | |
234 DcmSequenceOfItems* sequence = NULL; | |
235 if (!item.findAndGetSequence(tag, sequence).good() || | |
236 sequence == NULL) | |
237 { | |
238 return false; | |
239 } | |
240 | |
241 bool match = false; | |
242 | |
243 for (unsigned long i = 0; i < sequence->card(); i++) | |
244 { | |
245 if (it->second->MatchInternal(*sequence->getItem(i), encoding)) | |
246 { | |
247 match = true; | |
248 break; | |
249 } | |
250 } | |
251 | |
252 if (!match) | |
253 { | |
254 return false; | |
255 } | |
256 } | |
257 } | |
258 | |
259 return true; | |
260 } | |
261 | |
262 | |
263 DcmDataset* HierarchicalMatcher::ExtractInternal(DcmItem& item, | |
264 Encoding encoding) const | |
265 { | |
266 std::auto_ptr<DcmDataset> dataset(new DcmDataset); | |
267 | |
268 for (Constraints::const_iterator it = constraints_.begin(); | |
269 it != constraints_.end(); ++it) | |
270 { | |
271 DcmTagKey tag = ToDcmtkBridge::Convert(it->first); | |
272 | |
273 DcmElement* element = NULL; | |
274 if (item.findAndGetElement(tag, element).good() && | |
275 element != NULL) | |
276 { | |
277 std::auto_ptr<DcmElement> cloned(FromDcmtkBridge::CreateElementForTag(it->first)); | |
278 cloned->copyFrom(*element); | |
279 dataset->insert(cloned.release()); | |
280 } | |
281 } | |
282 | |
283 for (Sequences::const_iterator it = sequences_.begin(); | |
284 it != sequences_.end(); ++it) | |
285 { | |
286 DcmTagKey tag = ToDcmtkBridge::Convert(it->first); | |
287 | |
288 DcmSequenceOfItems* sequence = NULL; | |
289 if (item.findAndGetSequence(tag, sequence).good() && | |
290 sequence != NULL) | |
291 { | |
292 std::auto_ptr<DcmSequenceOfItems> cloned(new DcmSequenceOfItems(tag)); | |
293 | |
294 for (unsigned long i = 0; i < sequence->card(); i++) | |
295 { | |
296 if (it->second == NULL) | |
297 { | |
298 cloned->append(new DcmItem(*sequence->getItem(i))); | |
299 } | |
300 else if (it->second->MatchInternal(*sequence->getItem(i), encoding)) | |
301 { | |
302 cloned->append(it->second->ExtractInternal(*sequence->getItem(i), encoding)); | |
303 } | |
304 } | |
305 | |
306 dataset->insert(cloned.release()); | |
307 } | |
308 } | |
309 | |
310 return dataset.release(); | |
311 } | |
312 | |
313 | |
314 ParsedDicomFile* HierarchicalMatcher::Extract(ParsedDicomFile& dicom) const | |
315 { | |
316 std::auto_ptr<DcmDataset> dataset(ExtractInternal(*dicom.GetDcmtkObject().getDataset(), | |
317 dicom.GetEncoding())); | |
318 | |
319 std::auto_ptr<ParsedDicomFile> result(new ParsedDicomFile(*dataset)); | |
320 result->SetEncoding(Encoding_Utf8); | |
321 | |
322 return result.release(); | |
323 } | |
182 } | 324 } |