Mercurial > hg > orthanc
comparison OrthancFramework/Sources/DicomFormat/DicomMap.cpp @ 5040:1c08cd68250a
removed the 'name' of MainDicomTags to simplify code -> DicomMap::ParseMainDicomTags has been deprecated and one should use DicomMap::FromDicomAsJson on 'full' formatted tags
author | Alain Mazy <am@osimis.io> |
---|---|
date | Mon, 27 Jun 2022 12:39:51 +0200 |
parents | f8bea9c1c0fc |
children | 6fed78e13233 |
comparison
equal
deleted
inserted
replaced
5039:28db9663fc2d | 5040:1c08cd68250a |
---|---|
39 #include "../DicomParsing/FromDcmtkBridge.h" | 39 #include "../DicomParsing/FromDcmtkBridge.h" |
40 #endif | 40 #endif |
41 | 41 |
42 namespace Orthanc | 42 namespace Orthanc |
43 { | 43 { |
44 namespace | |
45 { | |
46 struct MainDicomTag | |
47 { | |
48 const DicomTag tag_; | |
49 const char* name_; | |
50 }; | |
51 typedef std::vector<MainDicomTag> MainDicomTags; | |
52 | |
53 } | |
54 | |
55 | |
56 // WARNING: the DEFAULT list of main dicom tags below are the list as they | 44 // WARNING: the DEFAULT list of main dicom tags below are the list as they |
57 // were in Orthanc 1.10 before we introduced the dynamic main dicom tags. | 45 // were in Orthanc 1.10 before we introduced the dynamic main dicom tags. |
58 // This list has not changed since Orthanc 1.4.2 and had a single change since | 46 // This list has not changed since Orthanc 1.4.2 and had a single change since |
59 // Orthanc 0.9.5. | 47 // Orthanc 0.9.5. |
60 // These lists have a specific signature. When a resource does not have | 48 // These lists have a specific signature. When a resource does not have |
61 // the metadata "MainDicomTagsSignature", we'll assume that they were stored | 49 // the metadata "MainDicomTagsSignature", we'll assume that they were stored |
62 // with an Orthanc prior to 1.11. It is therefore very important that you never | 50 // with an Orthanc prior to 1.11. It is therefore very important that you never |
63 // change these lists ! | 51 // change these lists ! |
64 | 52 |
65 static const MainDicomTag DEFAULT_PATIENT_MAIN_DICOM_TAGS[] = | 53 static const DicomTag DEFAULT_PATIENT_MAIN_DICOM_TAGS[] = |
66 { | 54 { |
67 // { DicomTag(0x0010, 0x1010), "PatientAge" }, | 55 // { DicomTag(0x0010, 0x1010), "PatientAge" }, |
68 // { DicomTag(0x0010, 0x1040), "PatientAddress" }, | 56 // { DicomTag(0x0010, 0x1040), "PatientAddress" }, |
69 { DICOM_TAG_PATIENT_NAME, "PatientName" }, | 57 DICOM_TAG_PATIENT_NAME, |
70 { DICOM_TAG_PATIENT_BIRTH_DATE, "PatientBirthDate" }, | 58 DICOM_TAG_PATIENT_BIRTH_DATE, |
71 { DICOM_TAG_PATIENT_SEX, "PatientSex" }, | 59 DICOM_TAG_PATIENT_SEX, |
72 { DICOM_TAG_OTHER_PATIENT_IDS, "OtherPatientIDs" }, | 60 DICOM_TAG_OTHER_PATIENT_IDS, |
73 { DICOM_TAG_PATIENT_ID, "PatientID" } | 61 DICOM_TAG_PATIENT_ID, |
62 | |
74 }; | 63 }; |
75 | 64 |
76 static const MainDicomTag DEFAULT_STUDY_MAIN_DICOM_TAGS[] = | 65 static const DicomTag DEFAULT_STUDY_MAIN_DICOM_TAGS[] = |
77 { | 66 { |
78 // { DicomTag(0x0010, 0x1020), "PatientSize" }, | 67 // { DicomTag(0x0010, 0x1020), "PatientSize" }, |
79 // { DicomTag(0x0010, 0x1030), "PatientWeight" }, | 68 // { DicomTag(0x0010, 0x1030), "PatientWeight" }, |
80 { DICOM_TAG_STUDY_DATE, "StudyDate" }, | 69 DICOM_TAG_STUDY_DATE, |
81 { DICOM_TAG_STUDY_TIME, "StudyTime" }, | 70 DICOM_TAG_STUDY_TIME, |
82 { DICOM_TAG_STUDY_ID, "StudyID" }, | 71 DICOM_TAG_STUDY_ID, |
83 { DICOM_TAG_STUDY_DESCRIPTION, "StudyDescription" }, | 72 DICOM_TAG_STUDY_DESCRIPTION, |
84 { DICOM_TAG_ACCESSION_NUMBER, "AccessionNumber" }, | 73 DICOM_TAG_ACCESSION_NUMBER, |
85 { DICOM_TAG_STUDY_INSTANCE_UID, "StudyInstanceUID" }, | 74 DICOM_TAG_STUDY_INSTANCE_UID, |
86 | |
87 // New in db v6 | 75 // New in db v6 |
88 { DICOM_TAG_REQUESTED_PROCEDURE_DESCRIPTION, "RequestedProcedureDescription" }, | 76 DICOM_TAG_REQUESTED_PROCEDURE_DESCRIPTION, |
89 { DICOM_TAG_INSTITUTION_NAME, "InstitutionName" }, | 77 DICOM_TAG_INSTITUTION_NAME, |
90 { DICOM_TAG_REQUESTING_PHYSICIAN, "RequestingPhysician" }, | 78 DICOM_TAG_REQUESTING_PHYSICIAN, |
91 { DICOM_TAG_REFERRING_PHYSICIAN_NAME, "ReferringPhysicianName" } | 79 DICOM_TAG_REFERRING_PHYSICIAN_NAME |
92 }; | 80 }; |
93 | 81 |
94 static const MainDicomTag DEFAULT_SERIES_MAIN_DICOM_TAGS[] = | 82 static const DicomTag DEFAULT_SERIES_MAIN_DICOM_TAGS[] = |
95 { | 83 { |
96 // { DicomTag(0x0010, 0x1080), "MilitaryRank" }, | 84 // { DicomTag(0x0010, 0x1080), "MilitaryRank" }, |
97 { DICOM_TAG_SERIES_DATE, "SeriesDate" }, | 85 DICOM_TAG_SERIES_DATE, |
98 { DICOM_TAG_SERIES_TIME, "SeriesTime" }, | 86 DICOM_TAG_SERIES_TIME, |
99 { DICOM_TAG_MODALITY, "Modality" }, | 87 DICOM_TAG_MODALITY, |
100 { DICOM_TAG_MANUFACTURER, "Manufacturer" }, | 88 DICOM_TAG_MANUFACTURER, |
101 { DICOM_TAG_STATION_NAME, "StationName" }, | 89 DICOM_TAG_STATION_NAME, |
102 { DICOM_TAG_SERIES_DESCRIPTION, "SeriesDescription" }, | 90 DICOM_TAG_SERIES_DESCRIPTION, |
103 { DICOM_TAG_BODY_PART_EXAMINED, "BodyPartExamined" }, | 91 DICOM_TAG_BODY_PART_EXAMINED, |
104 { DICOM_TAG_SEQUENCE_NAME, "SequenceName" }, | 92 DICOM_TAG_SEQUENCE_NAME, |
105 { DICOM_TAG_PROTOCOL_NAME, "ProtocolName" }, | 93 DICOM_TAG_PROTOCOL_NAME, |
106 { DICOM_TAG_SERIES_NUMBER, "SeriesNumber" }, | 94 DICOM_TAG_SERIES_NUMBER, |
107 { DICOM_TAG_CARDIAC_NUMBER_OF_IMAGES, "CardiacNumberOfImages" }, | 95 DICOM_TAG_CARDIAC_NUMBER_OF_IMAGES, |
108 { DICOM_TAG_IMAGES_IN_ACQUISITION, "ImagesInAcquisition" }, | 96 DICOM_TAG_IMAGES_IN_ACQUISITION, |
109 { DICOM_TAG_NUMBER_OF_TEMPORAL_POSITIONS, "NumberOfTemporalPositions" }, | 97 DICOM_TAG_NUMBER_OF_TEMPORAL_POSITIONS, |
110 { DICOM_TAG_NUMBER_OF_SLICES, "NumberOfSlices" }, | 98 DICOM_TAG_NUMBER_OF_SLICES, |
111 { DICOM_TAG_NUMBER_OF_TIME_SLICES, "NumberOfTimeSlices" }, | 99 DICOM_TAG_NUMBER_OF_TIME_SLICES, |
112 { DICOM_TAG_SERIES_INSTANCE_UID, "SeriesInstanceUID" }, | 100 DICOM_TAG_SERIES_INSTANCE_UID, |
101 | |
102 // New in db v6 | |
103 DICOM_TAG_IMAGE_ORIENTATION_PATIENT, | |
104 DICOM_TAG_SERIES_TYPE, | |
105 DICOM_TAG_OPERATOR_NAME, | |
106 DICOM_TAG_PERFORMED_PROCEDURE_STEP_DESCRIPTION, | |
107 DICOM_TAG_ACQUISITION_DEVICE_PROCESSING_DESCRIPTION, | |
108 DICOM_TAG_CONTRAST_BOLUS_AGENT | |
109 }; | |
110 | |
111 static const DicomTag DEFAULT_INSTANCE_MAIN_DICOM_TAGS[] = | |
112 { | |
113 DICOM_TAG_INSTANCE_CREATION_DATE, | |
114 DICOM_TAG_INSTANCE_CREATION_TIME, | |
115 DICOM_TAG_ACQUISITION_NUMBER, | |
116 DICOM_TAG_IMAGE_INDEX, | |
117 DICOM_TAG_INSTANCE_NUMBER, | |
118 DICOM_TAG_NUMBER_OF_FRAMES, | |
119 DICOM_TAG_TEMPORAL_POSITION_IDENTIFIER, | |
120 DICOM_TAG_SOP_INSTANCE_UID, | |
113 | 121 |
114 // New in db v6 | 122 // New in db v6 |
115 { DICOM_TAG_IMAGE_ORIENTATION_PATIENT, "ImageOrientationPatient" }, | 123 DICOM_TAG_IMAGE_POSITION_PATIENT, |
116 { DICOM_TAG_SERIES_TYPE, "SeriesType" }, | 124 DICOM_TAG_IMAGE_COMMENTS, |
117 { DICOM_TAG_OPERATOR_NAME, "OperatorsName" }, | |
118 { DICOM_TAG_PERFORMED_PROCEDURE_STEP_DESCRIPTION, "PerformedProcedureStepDescription" }, | |
119 { DICOM_TAG_ACQUISITION_DEVICE_PROCESSING_DESCRIPTION, "AcquisitionDeviceProcessingDescription" }, | |
120 { DICOM_TAG_CONTRAST_BOLUS_AGENT, "ContrastBolusAgent" } | |
121 }; | |
122 | |
123 static const MainDicomTag DEFAULT_INSTANCE_MAIN_DICOM_TAGS[] = | |
124 { | |
125 { DICOM_TAG_INSTANCE_CREATION_DATE, "InstanceCreationDate" }, | |
126 { DICOM_TAG_INSTANCE_CREATION_TIME, "InstanceCreationTime" }, | |
127 { DICOM_TAG_ACQUISITION_NUMBER, "AcquisitionNumber" }, | |
128 { DICOM_TAG_IMAGE_INDEX, "ImageIndex" }, | |
129 { DICOM_TAG_INSTANCE_NUMBER, "InstanceNumber" }, | |
130 { DICOM_TAG_NUMBER_OF_FRAMES, "NumberOfFrames" }, | |
131 { DICOM_TAG_TEMPORAL_POSITION_IDENTIFIER, "TemporalPositionIdentifier" }, | |
132 { DICOM_TAG_SOP_INSTANCE_UID, "SOPInstanceUID" }, | |
133 | |
134 // New in db v6 | |
135 { DICOM_TAG_IMAGE_POSITION_PATIENT, "ImagePositionPatient" }, | |
136 { DICOM_TAG_IMAGE_COMMENTS, "ImageComments" }, | |
137 | 125 |
138 /** | 126 /** |
139 * Main DICOM tags that are not part of any release of the | 127 * Main DICOM tags that are not part of any release of the |
140 * database schema yet, and that will be part of future db v7. In | 128 * database schema yet, and that will be part of future db v7. In |
141 * the meantime, the user must call "/tools/reconstruct" once to | 129 * the meantime, the user must call "/tools/reconstruct" once to |
142 * access these tags if the corresponding DICOM files where | 130 * access these tags if the corresponding DICOM files where |
143 * indexed in the database by an older version of Orthanc. | 131 * indexed in the database by an older version of Orthanc. |
144 **/ | 132 **/ |
145 { DICOM_TAG_IMAGE_ORIENTATION_PATIENT, "ImageOrientationPatient" } // New in Orthanc 1.4.2 | 133 DICOM_TAG_IMAGE_ORIENTATION_PATIENT // New in Orthanc 1.4.2 |
146 }; | 134 }; |
147 | 135 |
148 | 136 |
149 namespace | |
150 { | |
151 class DicomTag2 : public DicomTag | |
152 { | |
153 public: | |
154 DicomTag2() : | |
155 DicomTag(0, 0) // To make std::map<> happy | |
156 { | |
157 } | |
158 | |
159 explicit DicomTag2(const DicomTag& tag) : | |
160 DicomTag(tag) | |
161 { | |
162 } | |
163 }; | |
164 } | |
165 | 137 |
166 | 138 |
167 class DicomMap::MainDicomTagsConfiguration | 139 class DicomMap::MainDicomTagsConfiguration |
168 { | 140 { |
169 private: | 141 private: |
170 friend DicomMap; | 142 friend DicomMap; |
171 | 143 |
172 // we keep many "copies" of the same data to guarantee quick access to organized data | |
173 // and avoid rebuilding it all the time. | |
174 std::map<DicomTag, std::string> patientsMainDicomTagsByTag_; | |
175 std::map<std::string, DicomTag2> patientsMainDicomTagsByName_; | |
176 std::set<DicomTag> patientsMainDicomTagsByLevel_; | 144 std::set<DicomTag> patientsMainDicomTagsByLevel_; |
177 | |
178 std::map<DicomTag, std::string> studiesMainDicomTagsByTag_; | |
179 std::map<std::string, DicomTag2> studiesMainDicomTagsByName_; | |
180 std::set<DicomTag> studiesMainDicomTagsByLevel_; | 145 std::set<DicomTag> studiesMainDicomTagsByLevel_; |
181 | |
182 std::map<DicomTag, std::string> seriesMainDicomTagsByTag_; | |
183 std::map<std::string, DicomTag2> seriesMainDicomTagsByName_; | |
184 std::set<DicomTag> seriesMainDicomTagsByLevel_; | 146 std::set<DicomTag> seriesMainDicomTagsByLevel_; |
185 | |
186 std::map<DicomTag, std::string> instancesMainDicomTagsByTag_; | |
187 std::map<std::string, DicomTag2> instancesMainDicomTagsByName_; | |
188 std::set<DicomTag> instancesMainDicomTagsByLevel_; | 147 std::set<DicomTag> instancesMainDicomTagsByLevel_; |
189 | 148 |
190 std::set<DicomTag> allMainDicomTags_; | 149 std::set<DicomTag> allMainDicomTags_; |
191 | 150 |
192 std::map<ResourceType, std::string> signatures_; | 151 std::map<ResourceType, std::string> signatures_; |
197 ResetDefaultMainDicomTags(); | 156 ResetDefaultMainDicomTags(); |
198 } | 157 } |
199 | 158 |
200 void ResetDefaultMainDicomTags() | 159 void ResetDefaultMainDicomTags() |
201 { | 160 { |
202 patientsMainDicomTagsByTag_.clear(); | |
203 patientsMainDicomTagsByName_.clear(); | |
204 patientsMainDicomTagsByLevel_.clear(); | 161 patientsMainDicomTagsByLevel_.clear(); |
205 | |
206 studiesMainDicomTagsByTag_.clear(); | |
207 studiesMainDicomTagsByName_.clear(); | |
208 studiesMainDicomTagsByLevel_.clear(); | 162 studiesMainDicomTagsByLevel_.clear(); |
209 | |
210 seriesMainDicomTagsByTag_.clear(); | |
211 seriesMainDicomTagsByName_.clear(); | |
212 seriesMainDicomTagsByLevel_.clear(); | 163 seriesMainDicomTagsByLevel_.clear(); |
213 | |
214 instancesMainDicomTagsByTag_.clear(); | |
215 instancesMainDicomTagsByName_.clear(); | |
216 instancesMainDicomTagsByLevel_.clear(); | 164 instancesMainDicomTagsByLevel_.clear(); |
217 | 165 |
218 allMainDicomTags_.clear(); | 166 allMainDicomTags_.clear(); |
219 | 167 |
220 // by default, initialize with the previous static list (up to 1.10.0) | 168 // by default, initialize with the previous static list (up to 1.10.0) |
243 return signatureText; | 191 return signatureText; |
244 } | 192 } |
245 | 193 |
246 void LoadDefaultMainDicomTags(ResourceType level) | 194 void LoadDefaultMainDicomTags(ResourceType level) |
247 { | 195 { |
248 const MainDicomTag* tags = NULL; | 196 const DicomTag* tags = NULL; |
249 size_t size; | 197 size_t size; |
250 | 198 |
251 switch (level) | 199 switch (level) |
252 { | 200 { |
253 case ResourceType_Patient: | 201 case ResourceType_Patient: |
254 tags = DEFAULT_PATIENT_MAIN_DICOM_TAGS; | 202 tags = DEFAULT_PATIENT_MAIN_DICOM_TAGS; |
255 size = sizeof(DEFAULT_PATIENT_MAIN_DICOM_TAGS) / sizeof(MainDicomTag); | 203 size = sizeof(DEFAULT_PATIENT_MAIN_DICOM_TAGS) / sizeof(DicomTag); |
256 break; | 204 break; |
257 | 205 |
258 case ResourceType_Study: | 206 case ResourceType_Study: |
259 tags = DEFAULT_STUDY_MAIN_DICOM_TAGS; | 207 tags = DEFAULT_STUDY_MAIN_DICOM_TAGS; |
260 size = sizeof(DEFAULT_STUDY_MAIN_DICOM_TAGS) / sizeof(MainDicomTag); | 208 size = sizeof(DEFAULT_STUDY_MAIN_DICOM_TAGS) / sizeof(DicomTag); |
261 break; | 209 break; |
262 | 210 |
263 case ResourceType_Series: | 211 case ResourceType_Series: |
264 tags = DEFAULT_SERIES_MAIN_DICOM_TAGS; | 212 tags = DEFAULT_SERIES_MAIN_DICOM_TAGS; |
265 size = sizeof(DEFAULT_SERIES_MAIN_DICOM_TAGS) / sizeof(MainDicomTag); | 213 size = sizeof(DEFAULT_SERIES_MAIN_DICOM_TAGS) / sizeof(DicomTag); |
266 break; | 214 break; |
267 | 215 |
268 case ResourceType_Instance: | 216 case ResourceType_Instance: |
269 tags = DEFAULT_INSTANCE_MAIN_DICOM_TAGS; | 217 tags = DEFAULT_INSTANCE_MAIN_DICOM_TAGS; |
270 size = sizeof(DEFAULT_INSTANCE_MAIN_DICOM_TAGS) / sizeof(MainDicomTag); | 218 size = sizeof(DEFAULT_INSTANCE_MAIN_DICOM_TAGS) / sizeof(DicomTag); |
271 break; | 219 break; |
272 | 220 |
273 default: | 221 default: |
274 throw OrthancException(ErrorCode_ParameterOutOfRange); | 222 throw OrthancException(ErrorCode_ParameterOutOfRange); |
275 } | 223 } |
277 assert(tags != NULL && | 225 assert(tags != NULL && |
278 size != 0); | 226 size != 0); |
279 | 227 |
280 for (size_t i = 0; i < size; i++) | 228 for (size_t i = 0; i < size; i++) |
281 { | 229 { |
282 AddMainDicomTag(tags[i].tag_, tags[i].name_, level); | 230 AddMainDicomTag(tags[i], level); |
283 } | 231 } |
284 | 232 |
285 } | 233 } |
286 | 234 |
287 std::map<DicomTag, std::string>& GetMainDicomTags(ResourceType level) | |
288 { | |
289 switch (level) | |
290 { | |
291 case ResourceType_Patient: | |
292 return patientsMainDicomTagsByTag_; | |
293 | |
294 case ResourceType_Study: | |
295 return studiesMainDicomTagsByTag_; | |
296 | |
297 case ResourceType_Series: | |
298 return seriesMainDicomTagsByTag_; | |
299 | |
300 case ResourceType_Instance: | |
301 return instancesMainDicomTagsByTag_; | |
302 | |
303 default: | |
304 throw OrthancException(ErrorCode_InternalError); | |
305 } | |
306 } | |
307 | |
308 std::map<std::string, DicomTag2>& GetMainDicomTagsByName(ResourceType level) | |
309 { | |
310 switch (level) | |
311 { | |
312 case ResourceType_Patient: | |
313 return patientsMainDicomTagsByName_; | |
314 | |
315 case ResourceType_Study: | |
316 return studiesMainDicomTagsByName_; | |
317 | |
318 case ResourceType_Series: | |
319 return seriesMainDicomTagsByName_; | |
320 | |
321 case ResourceType_Instance: | |
322 return instancesMainDicomTagsByName_; | |
323 | |
324 default: | |
325 throw OrthancException(ErrorCode_InternalError); | |
326 } | |
327 } | |
328 | 235 |
329 std::set<DicomTag>& GetMainDicomTagsByLevel(ResourceType level) | 236 std::set<DicomTag>& GetMainDicomTagsByLevel(ResourceType level) |
330 { | 237 { |
331 switch (level) | 238 switch (level) |
332 { | 239 { |
353 { | 260 { |
354 static MainDicomTagsConfiguration parameters; | 261 static MainDicomTagsConfiguration parameters; |
355 return parameters; | 262 return parameters; |
356 } | 263 } |
357 | 264 |
358 void AddMainDicomTag(const DicomTag& tag, const std::string& name, ResourceType level) | 265 void AddMainDicomTag(const DicomTag& tag, ResourceType level) |
359 { | 266 { |
360 std::map<DicomTag, std::string>& byTag = GetMainDicomTags(level); | 267 const std::set<DicomTag>& existingLevelTags = GetMainDicomTagsByLevel(level); |
361 std::map<std::string, DicomTag2>& byName = GetMainDicomTagsByName(level); | |
362 | 268 |
363 if (byTag.find(tag) != byTag.end()) | 269 if (existingLevelTags.find(tag) != existingLevelTags.end()) |
364 { | 270 { |
365 throw OrthancException(ErrorCode_MainDicomTagsMultiplyDefined, tag.Format() + " is already defined"); | 271 throw OrthancException(ErrorCode_MainDicomTagsMultiplyDefined, tag.Format() + " is already defined"); |
366 } | 272 } |
367 | 273 |
368 if (byName.find(name) != byName.end()) | 274 |
369 { | |
370 throw OrthancException(ErrorCode_MainDicomTagsMultiplyDefined, name + " is already defined"); | |
371 } | |
372 | |
373 byTag[tag] = name; | |
374 byName[name] = DicomTag2(tag); | |
375 GetMainDicomTagsByLevel(level).insert(tag); | 275 GetMainDicomTagsByLevel(level).insert(tag); |
376 allMainDicomTags_.insert(tag); | 276 allMainDicomTags_.insert(tag); |
377 signatures_[level] = ComputeSignature(GetMainDicomTagsByLevel(level)); | 277 signatures_[level] = ComputeSignature(GetMainDicomTagsByLevel(level)); |
378 } | 278 } |
379 | 279 |
473 { | 373 { |
474 return GetValue(DicomTag(group, element)); | 374 return GetValue(DicomTag(group, element)); |
475 } | 375 } |
476 | 376 |
477 | 377 |
478 // MORE_TAGS: TODO: we can probably remove the std::string from MainDicomTags (not used here !!!) | |
479 static void ExtractTagsInternal(DicomMap& result, | 378 static void ExtractTagsInternal(DicomMap& result, |
480 const DicomMap::Content& source, | 379 const DicomMap::Content& source, |
481 const std::map<DicomTag, std::string>& mainDicomTags) | 380 const std::set<DicomTag>& mainDicomTags) |
482 { | 381 { |
483 result.Clear(); | 382 result.Clear(); |
484 | 383 |
485 for (std::map<DicomTag, std::string>::const_iterator itmt = mainDicomTags.begin(); | 384 for (std::set<DicomTag>::const_iterator itmt = mainDicomTags.begin(); |
486 itmt != mainDicomTags.end(); ++itmt) | 385 itmt != mainDicomTags.end(); ++itmt) |
487 { | 386 { |
488 DicomMap::Content::const_iterator it = source.find(itmt->first); | 387 DicomMap::Content::const_iterator it = source.find(*itmt); |
489 if (it != source.end()) | 388 if (it != source.end()) |
490 { | 389 { |
491 result.SetValue(it->first, *it->second /* value will be cloned */); | 390 result.SetValue(it->first, *it->second /* value will be cloned */); |
492 } | 391 } |
493 } | 392 } |
508 } | 407 } |
509 } | 408 } |
510 | 409 |
511 void DicomMap::ExtractResourceInformation(DicomMap& result, ResourceType level) const | 410 void DicomMap::ExtractResourceInformation(DicomMap& result, ResourceType level) const |
512 { | 411 { |
513 const std::map<DicomTag, std::string>& mainDicomTags = DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTags(level); | 412 const std::set<DicomTag>& mainDicomTags = DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTagsByLevel(level); |
514 ExtractTagsInternal(result, content_, mainDicomTags); | 413 ExtractTagsInternal(result, content_, mainDicomTags); |
515 } | 414 } |
516 | 415 |
517 void DicomMap::ExtractPatientInformation(DicomMap& result) const | 416 void DicomMap::ExtractPatientInformation(DicomMap& result) const |
518 { | 417 { |
622 Remove(*it); | 521 Remove(*it); |
623 } | 522 } |
624 } | 523 } |
625 | 524 |
626 static void SetupFindTemplate(DicomMap& result, | 525 static void SetupFindTemplate(DicomMap& result, |
627 const std::map<DicomTag, std::string>& mainDicomTags) | 526 const std::set<DicomTag>& mainDicomTags) |
628 { | 527 { |
629 result.Clear(); | 528 result.Clear(); |
630 | 529 |
631 for (std::map<DicomTag, std::string>::const_iterator itmt = mainDicomTags.begin(); | 530 for (std::set<DicomTag>::const_iterator itmt = mainDicomTags.begin(); |
632 itmt != mainDicomTags.end(); ++itmt) | 531 itmt != mainDicomTags.end(); ++itmt) |
633 { | 532 { |
634 result.SetValue(itmt->first, "", false); | 533 result.SetValue(*itmt, "", false); |
635 } | 534 } |
636 } | 535 } |
637 | 536 |
638 void DicomMap::SetupFindPatientTemplate(DicomMap& result) | 537 void DicomMap::SetupFindPatientTemplate(DicomMap& result) |
639 { | 538 { |
640 const std::map<DicomTag, std::string>& mainDicomTags = DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTags(ResourceType_Patient); | 539 const std::set<DicomTag>& mainDicomTags = DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTagsByLevel(ResourceType_Patient); |
641 SetupFindTemplate(result, mainDicomTags); | 540 SetupFindTemplate(result, mainDicomTags); |
642 } | 541 } |
643 | 542 |
644 void DicomMap::SetupFindStudyTemplate(DicomMap& result) | 543 void DicomMap::SetupFindStudyTemplate(DicomMap& result) |
645 { | 544 { |
646 const std::map<DicomTag, std::string>& mainDicomTags = DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTags(ResourceType_Study); | 545 const std::set<DicomTag>& mainDicomTags = DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTagsByLevel(ResourceType_Study); |
647 SetupFindTemplate(result, mainDicomTags); | 546 SetupFindTemplate(result, mainDicomTags); |
648 result.SetValue(DICOM_TAG_ACCESSION_NUMBER, "", false); | 547 result.SetValue(DICOM_TAG_ACCESSION_NUMBER, "", false); |
649 result.SetValue(DICOM_TAG_PATIENT_ID, "", false); | 548 result.SetValue(DICOM_TAG_PATIENT_ID, "", false); |
650 | 549 |
651 // These main DICOM tags are only indirectly related to the | 550 // These main DICOM tags are only indirectly related to the |
655 result.Remove(DICOM_TAG_REQUESTED_PROCEDURE_DESCRIPTION); | 554 result.Remove(DICOM_TAG_REQUESTED_PROCEDURE_DESCRIPTION); |
656 } | 555 } |
657 | 556 |
658 void DicomMap::SetupFindSeriesTemplate(DicomMap& result) | 557 void DicomMap::SetupFindSeriesTemplate(DicomMap& result) |
659 { | 558 { |
660 const std::map<DicomTag, std::string>& mainDicomTags = DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTags(ResourceType_Series); | 559 const std::set<DicomTag>& mainDicomTags = DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTagsByLevel(ResourceType_Series); |
661 SetupFindTemplate(result, mainDicomTags); | 560 SetupFindTemplate(result, mainDicomTags); |
662 result.SetValue(DICOM_TAG_ACCESSION_NUMBER, "", false); | 561 result.SetValue(DICOM_TAG_ACCESSION_NUMBER, "", false); |
663 result.SetValue(DICOM_TAG_PATIENT_ID, "", false); | 562 result.SetValue(DICOM_TAG_PATIENT_ID, "", false); |
664 result.SetValue(DICOM_TAG_STUDY_INSTANCE_UID, "", false); | 563 result.SetValue(DICOM_TAG_STUDY_INSTANCE_UID, "", false); |
665 | 564 |
678 result.Remove(DICOM_TAG_CONTRAST_BOLUS_AGENT); | 577 result.Remove(DICOM_TAG_CONTRAST_BOLUS_AGENT); |
679 } | 578 } |
680 | 579 |
681 void DicomMap::SetupFindInstanceTemplate(DicomMap& result) | 580 void DicomMap::SetupFindInstanceTemplate(DicomMap& result) |
682 { | 581 { |
683 const std::map<DicomTag, std::string>& mainDicomTags = DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTags(ResourceType_Instance); | 582 const std::set<DicomTag>& mainDicomTags = DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTagsByLevel(ResourceType_Instance); |
684 SetupFindTemplate(result, mainDicomTags); | 583 SetupFindTemplate(result, mainDicomTags); |
685 result.SetValue(DICOM_TAG_ACCESSION_NUMBER, "", false); | 584 result.SetValue(DICOM_TAG_ACCESSION_NUMBER, "", false); |
686 result.SetValue(DICOM_TAG_PATIENT_ID, "", false); | 585 result.SetValue(DICOM_TAG_PATIENT_ID, "", false); |
687 result.SetValue(DICOM_TAG_STUDY_INSTANCE_UID, "", false); | 586 result.SetValue(DICOM_TAG_STUDY_INSTANCE_UID, "", false); |
688 result.SetValue(DICOM_TAG_SERIES_INSTANCE_UID, "", false); | 587 result.SetValue(DICOM_TAG_SERIES_INSTANCE_UID, "", false); |
699 } | 598 } |
700 | 599 |
701 | 600 |
702 bool DicomMap::IsMainDicomTag(const DicomTag& tag, ResourceType level) | 601 bool DicomMap::IsMainDicomTag(const DicomTag& tag, ResourceType level) |
703 { | 602 { |
704 const std::map<DicomTag, std::string>& mainDicomTags = DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTags(level); | 603 const std::set<DicomTag>& mainDicomTags = DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTagsByLevel(level); |
705 return mainDicomTags.find(tag) != mainDicomTags.end(); | 604 return mainDicomTags.find(tag) != mainDicomTags.end(); |
706 } | 605 } |
707 | 606 |
708 bool DicomMap::IsMainDicomTag(const DicomTag& tag) | 607 bool DicomMap::IsMainDicomTag(const DicomTag& tag) |
709 { | 608 { |
810 const std::set<DicomTag>& DicomMap::GetAllMainDicomTags() | 709 const std::set<DicomTag>& DicomMap::GetAllMainDicomTags() |
811 { | 710 { |
812 return DicomMap::MainDicomTagsConfiguration::GetInstance().GetAllMainDicomTags(); | 711 return DicomMap::MainDicomTagsConfiguration::GetInstance().GetAllMainDicomTags(); |
813 } | 712 } |
814 | 713 |
815 void DicomMap::AddMainDicomTag(const DicomTag& tag, const std::string& name, ResourceType level) | 714 void DicomMap::AddMainDicomTag(const DicomTag& tag, ResourceType level) |
816 { | 715 { |
817 DicomMap::MainDicomTagsConfiguration::GetInstance().AddMainDicomTag(tag, name, level); | 716 DicomMap::MainDicomTagsConfiguration::GetInstance().AddMainDicomTag(tag, level); |
818 } | 717 } |
819 | 718 |
820 void DicomMap::ResetDefaultMainDicomTags() | 719 void DicomMap::ResetDefaultMainDicomTags() |
821 { | 720 { |
822 DicomMap::MainDicomTagsConfiguration::GetInstance().ResetDefaultMainDicomTags(); | 721 DicomMap::MainDicomTagsConfiguration::GetInstance().ResetDefaultMainDicomTags(); |
1427 return value->ParseDouble(result); | 1326 return value->ParseDouble(result); |
1428 } | 1327 } |
1429 } | 1328 } |
1430 | 1329 |
1431 | 1330 |
1432 void DicomMap::FromDicomAsJson(const Json::Value& dicomAsJson) | 1331 void DicomMap::FromDicomAsJson(const Json::Value& dicomAsJson, bool append) |
1433 { | 1332 { |
1434 if (dicomAsJson.type() != Json::objectValue) | 1333 if (dicomAsJson.type() != Json::objectValue) |
1435 { | 1334 { |
1436 throw OrthancException(ErrorCode_BadFileFormat); | 1335 throw OrthancException(ErrorCode_BadFileFormat); |
1437 } | 1336 } |
1438 | 1337 |
1439 Clear(); | 1338 if (!append) |
1339 { | |
1340 Clear(); | |
1341 } | |
1440 | 1342 |
1441 Json::Value::Members tags = dicomAsJson.getMemberNames(); | 1343 Json::Value::Members tags = dicomAsJson.getMemberNames(); |
1442 for (Json::Value::Members::const_iterator | 1344 for (Json::Value::Members::const_iterator |
1443 it = tags.begin(); it != tags.end(); ++it) | 1345 it = tags.begin(); it != tags.end(); ++it) |
1444 { | 1346 { |
1489 | 1391 |
1490 | 1392 |
1491 void DicomMap::MergeMainDicomTags(const DicomMap& other, | 1393 void DicomMap::MergeMainDicomTags(const DicomMap& other, |
1492 ResourceType level) | 1394 ResourceType level) |
1493 { | 1395 { |
1494 const std::map<DicomTag, std::string>& mainDicomTags = DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTags(level); | 1396 const std::set<DicomTag>& mainDicomTags = DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTagsByLevel(level); |
1495 | 1397 |
1496 for (std::map<DicomTag, std::string>::const_iterator itmt = mainDicomTags.begin(); | 1398 for (std::set<DicomTag>::const_iterator itmt = mainDicomTags.begin(); |
1497 itmt != mainDicomTags.end(); ++itmt) | 1399 itmt != mainDicomTags.end(); ++itmt) |
1498 { | 1400 { |
1499 Content::const_iterator found = other.content_.find(itmt->first); | 1401 Content::const_iterator found = other.content_.find(*itmt); |
1500 | 1402 |
1501 if (found != other.content_.end() && | 1403 if (found != other.content_.end() && |
1502 content_.find(itmt->first) == content_.end()) | 1404 content_.find(*itmt) == content_.end()) |
1503 { | 1405 { |
1504 assert(found->second != NULL); | 1406 assert(found->second != NULL); |
1505 content_[itmt->first] = found->second->Clone(); | 1407 content_[*itmt] = found->second->Clone(); |
1506 } | 1408 } |
1507 } | 1409 } |
1508 } | 1410 } |
1509 | 1411 |
1510 | 1412 |
1772 | 1674 |
1773 | 1675 |
1774 void DicomMap::DumpMainDicomTags(Json::Value& target, | 1676 void DicomMap::DumpMainDicomTags(Json::Value& target, |
1775 ResourceType level) const | 1677 ResourceType level) const |
1776 { | 1678 { |
1777 const std::map<DicomTag, std::string>& mainDicomTags = DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTags(level); | 1679 const std::set<DicomTag>& mainDicomTags = DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTagsByLevel(level); |
1778 | 1680 |
1779 target = Json::objectValue; | 1681 target = Json::objectValue; |
1780 | 1682 |
1781 for (Content::const_iterator it = content_.begin(); it != content_.end(); ++it) | 1683 for (Content::const_iterator it = content_.begin(); it != content_.end(); ++it) |
1782 { | 1684 { |
1783 assert(it->second != NULL); | 1685 assert(it->second != NULL); |
1784 | 1686 |
1785 if (!it->second->IsBinary() && | 1687 if (!it->second->IsBinary() && |
1786 !it->second->IsNull()) | 1688 !it->second->IsNull()) |
1787 { | 1689 { |
1788 std::map<DicomTag, std::string>::const_iterator found = mainDicomTags.find(it->first); | 1690 std::set<DicomTag>::const_iterator found = mainDicomTags.find(it->first); |
1789 | 1691 |
1790 if (found != mainDicomTags.end()) | 1692 if (found != mainDicomTags.end()) |
1791 { | 1693 { |
1792 target[found->second] = it->second->GetContent(); | 1694 #if ORTHANC_ENABLE_DCMTK == 1 |
1695 target[FromDcmtkBridge::GetTagName(*found, "")] = it->second->GetContent(); | |
1696 #else | |
1697 target[found->Format()] = it->second->GetContent(); | |
1698 #endif | |
1793 } | 1699 } |
1794 } | 1700 } |
1795 } | 1701 } |
1796 } | 1702 } |
1797 | 1703 |
1798 | 1704 |
1799 void DicomMap::ParseMainDicomTags(const Json::Value& source, | 1705 |
1800 ResourceType level) | |
1801 { | |
1802 if (source.type() != Json::objectValue) | |
1803 { | |
1804 throw OrthancException(ErrorCode_BadFileFormat); | |
1805 } | |
1806 | |
1807 const std::map<std::string, DicomTag2>& mainTags = DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTagsByName(level); | |
1808 | |
1809 Json::Value::Members members = source.getMemberNames(); | |
1810 for (size_t i = 0; i < members.size(); i++) | |
1811 { | |
1812 std::map<std::string, DicomTag2>::const_iterator found = mainTags.find(members[i]); | |
1813 | |
1814 if (found != mainTags.end()) | |
1815 { | |
1816 const Json::Value& value = source[members[i]]; | |
1817 if (value.type() != Json::stringValue) | |
1818 { | |
1819 throw OrthancException(ErrorCode_BadFileFormat); | |
1820 } | |
1821 else | |
1822 { | |
1823 SetValue(found->second, value.asString(), false); | |
1824 } | |
1825 } | |
1826 } | |
1827 } | |
1828 | |
1829 | 1706 |
1830 void DicomMap::Print(FILE* fp) const | 1707 void DicomMap::Print(FILE* fp) const |
1831 { | 1708 { |
1832 DicomArray a(*this); | 1709 DicomArray a(*this); |
1833 a.Print(fp); | 1710 a.Print(fp); |