Mercurial > hg > orthanc
diff 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 |
line wrap: on
line diff
--- a/OrthancServer/Search/HierarchicalMatcher.cpp Thu Nov 19 17:41:22 2015 +0100 +++ b/OrthancServer/Search/HierarchicalMatcher.cpp Thu Nov 19 18:32:00 2015 +0100 @@ -35,6 +35,7 @@ #include "../../Core/OrthancException.h" #include "../FromDcmtkBridge.h" +#include "../ToDcmtkBridge.h" #include <dcmtk/dcmdata/dcfilefo.h> @@ -84,6 +85,12 @@ } DicomTag tag(FromDcmtkBridge::Convert(element->getTag())); + if (tag == DICOM_TAG_SPECIFIC_CHARACTER_SET) + { + // Ignore this specific tag + continue; + } + ValueRepresentation vr = FromDcmtkBridge::GetValueRepresentation(tag); if (constraints_.find(tag) != constraints_.end() || @@ -179,4 +186,139 @@ return s; } + + + bool HierarchicalMatcher::Match(ParsedDicomFile& dicom) const + { + return MatchInternal(*dicom.GetDcmtkObject().getDataset(), + dicom.GetEncoding()); + } + + + bool HierarchicalMatcher::MatchInternal(DcmItem& item, + Encoding encoding) const + { + for (Constraints::const_iterator it = constraints_.begin(); + it != constraints_.end(); ++it) + { + if (it->second != NULL) + { + DcmTagKey tag = ToDcmtkBridge::Convert(it->first); + + DcmElement* element = NULL; + if (!item.findAndGetElement(tag, element).good() || + element == NULL) + { + return false; + } + + std::auto_ptr<DicomValue> value(FromDcmtkBridge::ConvertLeafElement + (*element, DicomToJsonFlags_None, encoding)); + + if (value->IsNull() || + value->IsBinary() || + !it->second->Match(value->GetContent())) + { + return false; + } + } + } + + for (Sequences::const_iterator it = sequences_.begin(); + it != sequences_.end(); ++it) + { + if (it->second != NULL) + { + DcmTagKey tag = ToDcmtkBridge::Convert(it->first); + + DcmSequenceOfItems* sequence = NULL; + if (!item.findAndGetSequence(tag, sequence).good() || + sequence == NULL) + { + return false; + } + + bool match = false; + + for (unsigned long i = 0; i < sequence->card(); i++) + { + if (it->second->MatchInternal(*sequence->getItem(i), encoding)) + { + match = true; + break; + } + } + + if (!match) + { + return false; + } + } + } + + return true; + } + + + DcmDataset* HierarchicalMatcher::ExtractInternal(DcmItem& item, + Encoding encoding) const + { + std::auto_ptr<DcmDataset> dataset(new DcmDataset); + + for (Constraints::const_iterator it = constraints_.begin(); + it != constraints_.end(); ++it) + { + DcmTagKey tag = ToDcmtkBridge::Convert(it->first); + + DcmElement* element = NULL; + if (item.findAndGetElement(tag, element).good() && + element != NULL) + { + std::auto_ptr<DcmElement> cloned(FromDcmtkBridge::CreateElementForTag(it->first)); + cloned->copyFrom(*element); + dataset->insert(cloned.release()); + } + } + + for (Sequences::const_iterator it = sequences_.begin(); + it != sequences_.end(); ++it) + { + DcmTagKey tag = ToDcmtkBridge::Convert(it->first); + + DcmSequenceOfItems* sequence = NULL; + if (item.findAndGetSequence(tag, sequence).good() && + sequence != NULL) + { + std::auto_ptr<DcmSequenceOfItems> cloned(new DcmSequenceOfItems(tag)); + + for (unsigned long i = 0; i < sequence->card(); i++) + { + if (it->second == NULL) + { + cloned->append(new DcmItem(*sequence->getItem(i))); + } + else if (it->second->MatchInternal(*sequence->getItem(i), encoding)) + { + cloned->append(it->second->ExtractInternal(*sequence->getItem(i), encoding)); + } + } + + dataset->insert(cloned.release()); + } + } + + return dataset.release(); + } + + + ParsedDicomFile* HierarchicalMatcher::Extract(ParsedDicomFile& dicom) const + { + std::auto_ptr<DcmDataset> dataset(ExtractInternal(*dicom.GetDcmtkObject().getDataset(), + dicom.GetEncoding())); + + std::auto_ptr<ParsedDicomFile> result(new ParsedDicomFile(*dataset)); + result->SetEncoding(Encoding_Utf8); + + return result.release(); + } }