Mercurial > hg > orthanc
comparison OrthancServer/Search/DatabaseLookup.cpp @ 3025:039a9d262d64 db-changes
preparing to speed up find in databases
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 17 Dec 2018 17:05:28 +0100 |
parents | 1723cbba55c7 |
children | fd587cf51a89 |
comparison
equal
deleted
inserted
replaced
3024:ef17a587e10d | 3025:039a9d262d64 |
---|---|
37 #include "../ServerToolbox.h" | 37 #include "../ServerToolbox.h" |
38 #include "../../Core/DicomParsing/FromDcmtkBridge.h" | 38 #include "../../Core/DicomParsing/FromDcmtkBridge.h" |
39 | 39 |
40 namespace Orthanc | 40 namespace Orthanc |
41 { | 41 { |
42 void DatabaseLookup::LoadTags(ResourceType level) | |
43 { | |
44 const DicomTag* tags = NULL; | |
45 size_t size; | |
46 | |
47 ServerToolbox::LoadIdentifiers(tags, size, level); | |
48 | |
49 for (size_t i = 0; i < size; i++) | |
50 { | |
51 if (tags_.find(tags[i]) == tags_.end()) | |
52 { | |
53 tags_[tags[i]] = TagInfo(DicomTagType_Identifier, level); | |
54 } | |
55 else | |
56 { | |
57 // These patient-level tags are copied in the study level | |
58 assert(level == ResourceType_Study && | |
59 (tags[i] == DICOM_TAG_PATIENT_ID || | |
60 tags[i] == DICOM_TAG_PATIENT_NAME || | |
61 tags[i] == DICOM_TAG_PATIENT_BIRTH_DATE)); | |
62 } | |
63 } | |
64 | |
65 DicomMap::LoadMainDicomTags(tags, size, level); | |
66 | |
67 for (size_t i = 0; i < size; i++) | |
68 { | |
69 if (tags_.find(tags[i]) == tags_.end()) | |
70 { | |
71 tags_[tags[i]] = TagInfo(DicomTagType_Main, level); | |
72 } | |
73 } | |
74 } | |
75 | |
76 | |
77 DatabaseLookup::DatabaseLookup() | |
78 { | |
79 LoadTags(ResourceType_Patient); | |
80 LoadTags(ResourceType_Study); | |
81 LoadTags(ResourceType_Series); | |
82 LoadTags(ResourceType_Instance); | |
83 } | |
84 | |
85 | |
86 DatabaseLookup::~DatabaseLookup() | 42 DatabaseLookup::~DatabaseLookup() |
87 { | 43 { |
88 for (size_t i = 0; i < constraints_.size(); i++) | 44 for (size_t i = 0; i < constraints_.size(); i++) |
89 { | 45 { |
90 assert(constraints_[i] != NULL); | 46 assert(constraints_[i] != NULL); |
114 throw OrthancException(ErrorCode_NullPointer); | 70 throw OrthancException(ErrorCode_NullPointer); |
115 } | 71 } |
116 else | 72 else |
117 { | 73 { |
118 constraints_.push_back(constraint); | 74 constraints_.push_back(constraint); |
119 | |
120 std::map<DicomTag, TagInfo>::const_iterator tag = tags_.find(constraint->GetTag()); | |
121 | |
122 if (tag == tags_.end()) | |
123 { | |
124 constraint->SetTagInfo(DicomTagType_Generic, ResourceType_Instance); | |
125 } | |
126 else | |
127 { | |
128 constraint->SetTagInfo(tag->second.GetType(), tag->second.GetLevel()); | |
129 } | |
130 } | 75 } |
131 } | 76 } |
132 | 77 |
133 | 78 |
134 bool DatabaseLookup::IsMatch(const DicomMap& value) | 79 bool DatabaseLookup::IsMatch(const DicomMap& value) |
146 } | 91 } |
147 | 92 |
148 | 93 |
149 void DatabaseLookup::AddDicomConstraint(const DicomTag& tag, | 94 void DatabaseLookup::AddDicomConstraint(const DicomTag& tag, |
150 const std::string& dicomQuery, | 95 const std::string& dicomQuery, |
151 bool caseSensitivePN) | 96 bool caseSensitivePN, |
97 bool mandatoryTag) | |
152 { | 98 { |
153 ValueRepresentation vr = FromDcmtkBridge::LookupValueRepresentation(tag); | 99 ValueRepresentation vr = FromDcmtkBridge::LookupValueRepresentation(tag); |
154 | 100 |
155 if (vr == ValueRepresentation_Sequence) | 101 if (vr == ValueRepresentation_Sequence) |
156 { | 102 { |
212 std::string upper = dicomQuery.substr(separator + 1); | 158 std::string upper = dicomQuery.substr(separator + 1); |
213 | 159 |
214 if (!lower.empty()) | 160 if (!lower.empty()) |
215 { | 161 { |
216 AddConstraint(new DicomTagConstraint | 162 AddConstraint(new DicomTagConstraint |
217 (tag, ConstraintType_GreaterOrEqual, lower, caseSensitive)); | 163 (tag, ConstraintType_GreaterOrEqual, lower, caseSensitive, mandatoryTag)); |
218 } | 164 } |
219 | 165 |
220 if (!upper.empty()) | 166 if (!upper.empty()) |
221 { | 167 { |
222 AddConstraint(new DicomTagConstraint | 168 AddConstraint(new DicomTagConstraint |
223 (tag, ConstraintType_SmallerOrEqual, upper, caseSensitive)); | 169 (tag, ConstraintType_SmallerOrEqual, upper, caseSensitive, mandatoryTag)); |
224 } | 170 } |
225 } | 171 } |
226 else if (dicomQuery.find('\\') != std::string::npos) | 172 else if (dicomQuery.find('\\') != std::string::npos) |
227 { | 173 { |
228 DicomTag fixedTag(tag); | 174 DicomTag fixedTag(tag); |
233 // http://dicomiseasy.blogspot.be/2012/01/dicom-queryretrieve-part-i.html | 179 // http://dicomiseasy.blogspot.be/2012/01/dicom-queryretrieve-part-i.html |
234 fixedTag = DICOM_TAG_MODALITY; | 180 fixedTag = DICOM_TAG_MODALITY; |
235 } | 181 } |
236 | 182 |
237 std::auto_ptr<DicomTagConstraint> constraint | 183 std::auto_ptr<DicomTagConstraint> constraint |
238 (new DicomTagConstraint(fixedTag, ConstraintType_List, caseSensitive)); | 184 (new DicomTagConstraint(fixedTag, ConstraintType_List, caseSensitive, mandatoryTag)); |
239 | 185 |
240 std::vector<std::string> items; | 186 std::vector<std::string> items; |
241 Toolbox::TokenizeString(items, dicomQuery, '\\'); | 187 Toolbox::TokenizeString(items, dicomQuery, '\\'); |
242 | 188 |
243 for (size_t i = 0; i < items.size(); i++) | 189 for (size_t i = 0; i < items.size(); i++) |
249 } | 195 } |
250 else if (dicomQuery.find('*') != std::string::npos || | 196 else if (dicomQuery.find('*') != std::string::npos || |
251 dicomQuery.find('?') != std::string::npos) | 197 dicomQuery.find('?') != std::string::npos) |
252 { | 198 { |
253 AddConstraint(new DicomTagConstraint | 199 AddConstraint(new DicomTagConstraint |
254 (tag, ConstraintType_Wildcard, dicomQuery, caseSensitive)); | 200 (tag, ConstraintType_Wildcard, dicomQuery, caseSensitive, mandatoryTag)); |
255 } | 201 } |
256 else | 202 else |
257 { | 203 { |
258 AddConstraint(new DicomTagConstraint | 204 AddConstraint(new DicomTagConstraint |
259 (tag, ConstraintType_Equal, dicomQuery, caseSensitive)); | 205 (tag, ConstraintType_Equal, dicomQuery, caseSensitive, mandatoryTag)); |
260 } | 206 } |
261 } | 207 } |
262 } | 208 } |