Mercurial > hg > orthanc
comparison OrthancServer/Search/HierarchicalMatcher.cpp @ 3071:2df061cf2fec db-changes
getting rid of IFindConstraint hierarchy
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 02 Jan 2019 11:26:27 +0100 |
parents | 4e43e67f8ecf |
children | 1b05fd072c57 |
comparison
equal
deleted
inserted
replaced
3070:1bc4a1bb66e9 | 3071:2df061cf2fec |
---|---|
57 } | 57 } |
58 | 58 |
59 | 59 |
60 HierarchicalMatcher::~HierarchicalMatcher() | 60 HierarchicalMatcher::~HierarchicalMatcher() |
61 { | 61 { |
62 for (Constraints::iterator it = constraints_.begin(); | |
63 it != constraints_.end(); ++it) | |
64 { | |
65 if (it->second != NULL) | |
66 { | |
67 delete it->second; | |
68 } | |
69 } | |
70 | |
71 for (Sequences::iterator it = sequences_.begin(); | 62 for (Sequences::iterator it = sequences_.begin(); |
72 it != sequences_.end(); ++it) | 63 it != sequences_.end(); ++it) |
73 { | 64 { |
74 if (it->second != NULL) | 65 if (it->second != NULL) |
75 { | 66 { |
96 tag.GetElement() == 0x0000) // Ignore all "Group Length" tags | 87 tag.GetElement() == 0x0000) // Ignore all "Group Length" tags |
97 { | 88 { |
98 continue; | 89 continue; |
99 } | 90 } |
100 | 91 |
101 ValueRepresentation vr = FromDcmtkBridge::LookupValueRepresentation(tag); | 92 if (flatTags_.find(tag) != flatTags_.end() || |
102 | |
103 if (constraints_.find(tag) != constraints_.end() || | |
104 sequences_.find(tag) != sequences_.end()) | 93 sequences_.find(tag) != sequences_.end()) |
105 { | 94 { |
95 // A constraint already exists on this tag | |
106 throw OrthancException(ErrorCode_BadRequest); | 96 throw OrthancException(ErrorCode_BadRequest); |
107 } | 97 } |
108 | 98 |
109 if (vr == ValueRepresentation_Sequence) | 99 if (FromDcmtkBridge::LookupValueRepresentation(tag) == ValueRepresentation_Sequence) |
110 { | 100 { |
111 DcmSequenceOfItems& sequence = dynamic_cast<DcmSequenceOfItems&>(*element); | 101 DcmSequenceOfItems& sequence = dynamic_cast<DcmSequenceOfItems&>(*element); |
112 | 102 |
113 if (sequence.card() == 0 || | 103 if (sequence.card() == 0 || |
114 (sequence.card() == 1 && sequence.getItem(0)->card() == 0)) | 104 (sequence.card() == 1 && sequence.getItem(0)->card() == 0)) |
130 std::set<DicomTag> ignoreTagLength; | 120 std::set<DicomTag> ignoreTagLength; |
131 std::auto_ptr<DicomValue> value(FromDcmtkBridge::ConvertLeafElement | 121 std::auto_ptr<DicomValue> value(FromDcmtkBridge::ConvertLeafElement |
132 (*element, DicomToJsonFlags_None, | 122 (*element, DicomToJsonFlags_None, |
133 ORTHANC_MAXIMUM_TAG_LENGTH, encoding, ignoreTagLength)); | 123 ORTHANC_MAXIMUM_TAG_LENGTH, encoding, ignoreTagLength)); |
134 | 124 |
125 flatTags_.insert(tag); | |
126 | |
135 if (value->IsBinary()) | 127 if (value->IsBinary()) |
136 { | 128 { |
137 if (!value->GetContent().empty()) | 129 if (!value->GetContent().empty()) |
138 { | 130 { |
139 LOG(WARNING) << "This C-Find modality worklist query contains a non-empty tag (" | 131 LOG(WARNING) << "This C-Find modality worklist query contains a non-empty tag (" |
140 << tag.Format() << ") with UN (unknown) value representation. " | 132 << tag.Format() << ") with UN (unknown) value representation. " |
141 << "It will be ignored."; | 133 << "It will be ignored."; |
142 } | 134 } |
143 | |
144 constraints_[tag] = NULL; | |
145 } | 135 } |
146 else if (value->IsNull() || | 136 else if (value->IsNull() || |
147 value->GetContent().empty()) | 137 value->GetContent().empty()) |
148 { | 138 { |
149 // This is an universal matcher | 139 // This is an universal matcher |
150 constraints_[tag] = NULL; | |
151 } | 140 } |
152 else | 141 else |
153 { | 142 { |
154 // DICOM specifies that searches must be case sensitive, except | 143 flatConstraints_.AddDicomConstraint |
155 // for tags with a PN value representation | 144 (tag, value->GetContent(), caseSensitivePN, true /* mandatory */); |
156 bool sensitive = true; | |
157 if (vr == ValueRepresentation_PersonName) | |
158 { | |
159 sensitive = caseSensitivePN; | |
160 } | |
161 | |
162 constraints_[tag] = IFindConstraint::ParseDicomConstraint(tag, value->GetContent(), sensitive); | |
163 } | 145 } |
164 } | 146 } |
165 } | 147 } |
166 } | 148 } |
167 | 149 |
168 | 150 |
169 std::string HierarchicalMatcher::Format(const std::string& prefix) const | 151 std::string HierarchicalMatcher::Format(const std::string& prefix) const |
170 { | 152 { |
171 std::string s; | 153 std::string s; |
154 | |
155 std::set<DicomTag> tags; | |
156 for (size_t i = 0; i < flatConstraints_.GetConstraintsCount(); i++) | |
157 { | |
158 const DicomTagConstraint& c = flatConstraints_.GetConstraint(i); | |
159 | |
160 s += c.Format() + "\n"; | |
161 tags.insert(c.GetTag()); | |
162 } | |
172 | 163 |
173 for (Constraints::const_iterator it = constraints_.begin(); | 164 // Loop over the universal constraints |
174 it != constraints_.end(); ++it) | 165 for (std::set<DicomTag>::const_iterator it = flatTags_.begin(); |
175 { | 166 it != flatTags_.end(); ++it) |
176 s += prefix + it->first.Format() + " "; | 167 { |
177 | 168 if (tags.find(*it) == tags.end()) |
178 if (it->second == NULL) | 169 { |
179 { | 170 s += prefix + it->Format() + " == *\n"; |
180 s += "*\n"; | |
181 } | |
182 else | |
183 { | |
184 s += it->second->Format() + "\n"; | |
185 } | 171 } |
186 } | 172 } |
187 | 173 |
188 for (Sequences::const_iterator it = sequences_.begin(); | 174 for (Sequences::const_iterator it = sequences_.begin(); |
189 it != sequences_.end(); ++it) | 175 it != sequences_.end(); ++it) |
212 | 198 |
213 | 199 |
214 bool HierarchicalMatcher::MatchInternal(DcmItem& item, | 200 bool HierarchicalMatcher::MatchInternal(DcmItem& item, |
215 Encoding encoding) const | 201 Encoding encoding) const |
216 { | 202 { |
217 for (Constraints::const_iterator it = constraints_.begin(); | 203 if (!flatConstraints_.IsMatch(item, encoding)) |
218 it != constraints_.end(); ++it) | 204 { |
219 { | 205 return false; |
220 if (it->second != NULL) | 206 } |
221 { | 207 |
222 DcmTagKey tag = ToDcmtkBridge::Convert(it->first); | |
223 | |
224 DcmElement* element = NULL; | |
225 if (!item.findAndGetElement(tag, element).good() || | |
226 element == NULL) | |
227 { | |
228 return false; | |
229 } | |
230 | |
231 std::set<DicomTag> ignoreTagLength; | |
232 std::auto_ptr<DicomValue> value(FromDcmtkBridge::ConvertLeafElement | |
233 (*element, DicomToJsonFlags_None, | |
234 ORTHANC_MAXIMUM_TAG_LENGTH, encoding, ignoreTagLength)); | |
235 | |
236 if (value->IsNull() || | |
237 value->IsBinary() || | |
238 !it->second->Match(value->GetContent())) | |
239 { | |
240 return false; | |
241 } | |
242 } | |
243 } | |
244 | |
245 for (Sequences::const_iterator it = sequences_.begin(); | 208 for (Sequences::const_iterator it = sequences_.begin(); |
246 it != sequences_.end(); ++it) | 209 it != sequences_.end(); ++it) |
247 { | 210 { |
248 if (it->second != NULL) | 211 if (it->second != NULL) |
249 { | 212 { |
281 DcmDataset* HierarchicalMatcher::ExtractInternal(DcmItem& source, | 244 DcmDataset* HierarchicalMatcher::ExtractInternal(DcmItem& source, |
282 Encoding encoding) const | 245 Encoding encoding) const |
283 { | 246 { |
284 std::auto_ptr<DcmDataset> target(new DcmDataset); | 247 std::auto_ptr<DcmDataset> target(new DcmDataset); |
285 | 248 |
286 for (Constraints::const_iterator it = constraints_.begin(); | 249 for (std::set<DicomTag>::const_iterator it = flatTags_.begin(); |
287 it != constraints_.end(); ++it) | 250 it != flatTags_.end(); ++it) |
288 { | 251 { |
289 DcmTagKey tag = ToDcmtkBridge::Convert(it->first); | 252 DcmTagKey tag = ToDcmtkBridge::Convert(*it); |
290 | 253 |
291 DcmElement* element = NULL; | 254 DcmElement* element = NULL; |
292 if (source.findAndGetElement(tag, element).good() && | 255 if (source.findAndGetElement(tag, element).good() && |
293 element != NULL) | 256 element != NULL) |
294 { | 257 { |
295 std::auto_ptr<DcmElement> cloned(FromDcmtkBridge::CreateElementForTag(it->first)); | 258 std::auto_ptr<DcmElement> cloned(FromDcmtkBridge::CreateElementForTag(*it)); |
296 cloned->copyFrom(*element); | 259 cloned->copyFrom(*element); |
297 target->insert(cloned.release()); | 260 target->insert(cloned.release()); |
298 } | 261 } |
299 } | 262 } |
300 | 263 |