comparison OrthancFramework/Sources/DicomFormat/DicomMap.cpp @ 5177:6807a2b012a0

cont
author Sebastien Jodogne <s.jodogne@gmail.com>
date Sat, 25 Mar 2023 10:37:56 +0100
parents 6d8647122ef3
children 02c7e4aa7946
comparison
equal deleted inserted replaced
5176:6d8647122ef3 5177:6807a2b012a0
56 // { DicomTag(0x0010, 0x1040), "PatientAddress" }, 56 // { DicomTag(0x0010, 0x1040), "PatientAddress" },
57 DICOM_TAG_PATIENT_NAME, 57 DICOM_TAG_PATIENT_NAME,
58 DICOM_TAG_PATIENT_BIRTH_DATE, 58 DICOM_TAG_PATIENT_BIRTH_DATE,
59 DICOM_TAG_PATIENT_SEX, 59 DICOM_TAG_PATIENT_SEX,
60 DICOM_TAG_OTHER_PATIENT_IDS, 60 DICOM_TAG_OTHER_PATIENT_IDS,
61 DICOM_TAG_PATIENT_ID, 61 DICOM_TAG_PATIENT_ID
62
63 }; 62 };
64 63
65 static const DicomTag DEFAULT_STUDY_MAIN_DICOM_TAGS[] = 64 static const DicomTag DEFAULT_STUDY_MAIN_DICOM_TAGS[] =
66 { 65 {
67 // { DicomTag(0x0010, 0x1020), "PatientSize" }, 66 // { DicomTag(0x0010, 0x1020), "PatientSize" },
97 DICOM_TAG_NUMBER_OF_TEMPORAL_POSITIONS, 96 DICOM_TAG_NUMBER_OF_TEMPORAL_POSITIONS,
98 DICOM_TAG_NUMBER_OF_SLICES, 97 DICOM_TAG_NUMBER_OF_SLICES,
99 DICOM_TAG_NUMBER_OF_TIME_SLICES, 98 DICOM_TAG_NUMBER_OF_TIME_SLICES,
100 DICOM_TAG_SERIES_INSTANCE_UID, 99 DICOM_TAG_SERIES_INSTANCE_UID,
101 100
102 // New in db v6 101 // New in db v6
103 DICOM_TAG_IMAGE_ORIENTATION_PATIENT, 102 DICOM_TAG_IMAGE_ORIENTATION_PATIENT,
104 DICOM_TAG_SERIES_TYPE, 103 DICOM_TAG_SERIES_TYPE,
105 DICOM_TAG_OPERATOR_NAME, 104 DICOM_TAG_OPERATOR_NAME,
106 DICOM_TAG_PERFORMED_PROCEDURE_STEP_DESCRIPTION, 105 DICOM_TAG_PERFORMED_PROCEDURE_STEP_DESCRIPTION,
107 DICOM_TAG_ACQUISITION_DEVICE_PROCESSING_DESCRIPTION, 106 DICOM_TAG_ACQUISITION_DEVICE_PROCESSING_DESCRIPTION,
131 * indexed in the database by an older version of Orthanc. 130 * indexed in the database by an older version of Orthanc.
132 **/ 131 **/
133 DICOM_TAG_IMAGE_ORIENTATION_PATIENT // New in Orthanc 1.4.2 132 DICOM_TAG_IMAGE_ORIENTATION_PATIENT // New in Orthanc 1.4.2
134 }; 133 };
135 134
136
137
138
139 class DicomMap::MainDicomTagsConfiguration 135 class DicomMap::MainDicomTagsConfiguration
140 { 136 {
141 private: 137 private:
142 std::set<DicomTag> patientsMainDicomTagsByLevel_; 138 std::set<DicomTag> patientsMainDicomTagsByLevel_;
143 std::set<DicomTag> studiesMainDicomTagsByLevel_; 139 std::set<DicomTag> studiesMainDicomTagsByLevel_;
144 std::set<DicomTag> seriesMainDicomTagsByLevel_; 140 std::set<DicomTag> seriesMainDicomTagsByLevel_;
145 std::set<DicomTag> instancesMainDicomTagsByLevel_; 141 std::set<DicomTag> instancesMainDicomTagsByLevel_;
146 142
147 std::set<DicomTag> allMainDicomTags_; 143 std::set<DicomTag> allMainDicomTags_;
148 144
149 std::map<ResourceType, std::string> signatures_; 145 std::map<ResourceType, std::string> signatures_;
150 std::map<ResourceType, std::string> defaultSignatures_; 146 std::map<ResourceType, std::string> defaultSignatures_;
203 size != 0); 199 size != 0);
204 200
205 for (size_t i = 0; i < size; i++) 201 for (size_t i = 0; i < size; i++)
206 { 202 {
207 AddMainDicomTag(tags[i], level); 203 AddMainDicomTag(tags[i], level);
204 }
205 }
206
207 std::set<DicomTag>& GetMainDicomTagsByLevelInternal(ResourceType level)
208 {
209 switch (level)
210 {
211 case ResourceType_Patient:
212 return patientsMainDicomTagsByLevel_;
213
214 case ResourceType_Study:
215 return studiesMainDicomTagsByLevel_;
216
217 case ResourceType_Series:
218 return seriesMainDicomTagsByLevel_;
219
220 case ResourceType_Instance:
221 return instancesMainDicomTagsByLevel_;
222
223 default:
224 throw OrthancException(ErrorCode_InternalError);
208 } 225 }
209 } 226 }
210 227
211 public: 228 public:
212 // Singleton pattern 229 // Singleton pattern
235 defaultSignatures_[ResourceType_Study] = signatures_[ResourceType_Study]; 252 defaultSignatures_[ResourceType_Study] = signatures_[ResourceType_Study];
236 defaultSignatures_[ResourceType_Series] = signatures_[ResourceType_Series]; 253 defaultSignatures_[ResourceType_Series] = signatures_[ResourceType_Series];
237 defaultSignatures_[ResourceType_Instance] = signatures_[ResourceType_Instance]; 254 defaultSignatures_[ResourceType_Instance] = signatures_[ResourceType_Instance];
238 } 255 }
239 256
240 void AddMainDicomTag(const DicomTag& tag, ResourceType level) 257 void AddMainDicomTag(const DicomTag& tag,
241 { 258 ResourceType level)
242 const std::set<DicomTag>& existingLevelTags = GetMainDicomTagsByLevel(level); 259 {
260 std::set<DicomTag>& existingLevelTags = GetMainDicomTagsByLevelInternal(level);
243 261
244 if (existingLevelTags.find(tag) != existingLevelTags.end()) 262 if (existingLevelTags.find(tag) != existingLevelTags.end())
245 { 263 {
246 throw OrthancException(ErrorCode_MainDicomTagsMultiplyDefined, tag.Format() + " is already defined"); 264 throw OrthancException(ErrorCode_MainDicomTagsMultiplyDefined, tag.Format() + " is already defined");
247 } 265 }
248 266
249 267 existingLevelTags.insert(tag);
250 GetMainDicomTagsByLevel(level).insert(tag);
251 allMainDicomTags_.insert(tag); 268 allMainDicomTags_.insert(tag);
252 signatures_[level] = ComputeSignature(GetMainDicomTagsByLevel(level)); 269
253 } 270 std::set<DicomTag> mainDicomTags;
254 271 GetMainDicomTagsByLevel(mainDicomTags, level);
255 const std::set<DicomTag>& GetAllMainDicomTags() const 272 signatures_[level] = ComputeSignature(mainDicomTags);
256 { 273 }
257 return allMainDicomTags_; 274
275 void GetAllMainDicomTags(std::set<DicomTag>& target) const
276 {
277 target = allMainDicomTags_;
278 }
279
280 void GetMainDicomTagsByLevel(std::set<DicomTag>& target,
281 ResourceType level)
282 {
283 target = GetMainDicomTagsByLevelInternal(level);
258 } 284 }
259 285
260 std::string GetMainDicomTagsSignature(ResourceType level) 286 std::string GetMainDicomTagsSignature(ResourceType level)
261 { 287 {
262 assert(signatures_.find(level) != signatures_.end()); 288 assert(signatures_.find(level) != signatures_.end());
269 assert(defaultSignatures_.find(level) != defaultSignatures_.end()); 295 assert(defaultSignatures_.find(level) != defaultSignatures_.end());
270 296
271 return defaultSignatures_[level]; 297 return defaultSignatures_[level];
272 } 298 }
273 299
274 std::set<DicomTag>& GetMainDicomTagsByLevel(ResourceType level) 300 bool IsMainDicomTag(const DicomTag& tag)
275 { 301 {
276 switch (level) 302 return allMainDicomTags_.find(tag) != allMainDicomTags_.end();
277 { 303 }
278 case ResourceType_Patient: 304
279 return patientsMainDicomTagsByLevel_; 305 bool IsMainDicomTag(const DicomTag& tag,
280 306 ResourceType level)
281 case ResourceType_Study: 307 {
282 return studiesMainDicomTagsByLevel_; 308 const std::set<DicomTag>& mainDicomTags = GetMainDicomTagsByLevelInternal(level);
283 309 return mainDicomTags.find(tag) != mainDicomTags.end();
284 case ResourceType_Series:
285 return seriesMainDicomTagsByLevel_;
286
287 case ResourceType_Instance:
288 return instancesMainDicomTagsByLevel_;
289
290 default:
291 throw OrthancException(ErrorCode_InternalError);
292 }
293 } 310 }
294 }; 311 };
295 312
296 313
297 void DicomMap::SetValueInternal(uint16_t group, 314 void DicomMap::SetValueInternal(uint16_t group,
407 } 424 }
408 } 425 }
409 426
410 void DicomMap::ExtractResourceInformation(DicomMap& result, ResourceType level) const 427 void DicomMap::ExtractResourceInformation(DicomMap& result, ResourceType level) const
411 { 428 {
412 const std::set<DicomTag>& mainDicomTags = DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTagsByLevel(level); 429 std::set<DicomTag> mainDicomTags;
430 DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTagsByLevel(mainDicomTags, level);
413 ExtractTagsInternal(result, content_, mainDicomTags); 431 ExtractTagsInternal(result, content_, mainDicomTags);
414 } 432 }
415 433
416 void DicomMap::ExtractPatientInformation(DicomMap& result) const 434 void DicomMap::ExtractPatientInformation(DicomMap& result) const
417 { 435 {
534 } 552 }
535 } 553 }
536 554
537 void DicomMap::SetupFindPatientTemplate(DicomMap& result) 555 void DicomMap::SetupFindPatientTemplate(DicomMap& result)
538 { 556 {
539 const std::set<DicomTag>& mainDicomTags = DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTagsByLevel(ResourceType_Patient); 557 std::set<DicomTag> mainDicomTags;
558 DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTagsByLevel(mainDicomTags, ResourceType_Patient);
540 SetupFindTemplate(result, mainDicomTags); 559 SetupFindTemplate(result, mainDicomTags);
541 } 560 }
542 561
543 void DicomMap::SetupFindStudyTemplate(DicomMap& result) 562 void DicomMap::SetupFindStudyTemplate(DicomMap& result)
544 { 563 {
545 const std::set<DicomTag>& mainDicomTags = DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTagsByLevel(ResourceType_Study); 564 std::set<DicomTag> mainDicomTags;
565 DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTagsByLevel(mainDicomTags, ResourceType_Study);
546 SetupFindTemplate(result, mainDicomTags); 566 SetupFindTemplate(result, mainDicomTags);
547 result.SetValue(DICOM_TAG_ACCESSION_NUMBER, "", false); 567 result.SetValue(DICOM_TAG_ACCESSION_NUMBER, "", false);
548 result.SetValue(DICOM_TAG_PATIENT_ID, "", false); 568 result.SetValue(DICOM_TAG_PATIENT_ID, "", false);
549 569
550 // These main DICOM tags are only indirectly related to the 570 // These main DICOM tags are only indirectly related to the
554 result.Remove(DICOM_TAG_REQUESTED_PROCEDURE_DESCRIPTION); 574 result.Remove(DICOM_TAG_REQUESTED_PROCEDURE_DESCRIPTION);
555 } 575 }
556 576
557 void DicomMap::SetupFindSeriesTemplate(DicomMap& result) 577 void DicomMap::SetupFindSeriesTemplate(DicomMap& result)
558 { 578 {
559 const std::set<DicomTag>& mainDicomTags = DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTagsByLevel(ResourceType_Series); 579 std::set<DicomTag> mainDicomTags;
580 DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTagsByLevel(mainDicomTags, ResourceType_Series);
560 SetupFindTemplate(result, mainDicomTags); 581 SetupFindTemplate(result, mainDicomTags);
561 result.SetValue(DICOM_TAG_ACCESSION_NUMBER, "", false); 582 result.SetValue(DICOM_TAG_ACCESSION_NUMBER, "", false);
562 result.SetValue(DICOM_TAG_PATIENT_ID, "", false); 583 result.SetValue(DICOM_TAG_PATIENT_ID, "", false);
563 result.SetValue(DICOM_TAG_STUDY_INSTANCE_UID, "", false); 584 result.SetValue(DICOM_TAG_STUDY_INSTANCE_UID, "", false);
564 585
577 result.Remove(DICOM_TAG_CONTRAST_BOLUS_AGENT); 598 result.Remove(DICOM_TAG_CONTRAST_BOLUS_AGENT);
578 } 599 }
579 600
580 void DicomMap::SetupFindInstanceTemplate(DicomMap& result) 601 void DicomMap::SetupFindInstanceTemplate(DicomMap& result)
581 { 602 {
582 const std::set<DicomTag>& mainDicomTags = DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTagsByLevel(ResourceType_Instance); 603 std::set<DicomTag> mainDicomTags;
604 DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTagsByLevel(mainDicomTags, ResourceType_Instance);
583 SetupFindTemplate(result, mainDicomTags); 605 SetupFindTemplate(result, mainDicomTags);
584 result.SetValue(DICOM_TAG_ACCESSION_NUMBER, "", false); 606 result.SetValue(DICOM_TAG_ACCESSION_NUMBER, "", false);
585 result.SetValue(DICOM_TAG_PATIENT_ID, "", false); 607 result.SetValue(DICOM_TAG_PATIENT_ID, "", false);
586 result.SetValue(DICOM_TAG_STUDY_INSTANCE_UID, "", false); 608 result.SetValue(DICOM_TAG_STUDY_INSTANCE_UID, "", false);
587 result.SetValue(DICOM_TAG_SERIES_INSTANCE_UID, "", false); 609 result.SetValue(DICOM_TAG_SERIES_INSTANCE_UID, "", false);
598 } 620 }
599 621
600 622
601 bool DicomMap::IsMainDicomTag(const DicomTag& tag, ResourceType level) 623 bool DicomMap::IsMainDicomTag(const DicomTag& tag, ResourceType level)
602 { 624 {
603 const std::set<DicomTag>& mainDicomTags = DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTagsByLevel(level); 625 return DicomMap::MainDicomTagsConfiguration::GetInstance().IsMainDicomTag(tag, level);
604 return mainDicomTags.find(tag) != mainDicomTags.end();
605 } 626 }
606 627
607 bool DicomMap::IsMainDicomTag(const DicomTag& tag) 628 bool DicomMap::IsMainDicomTag(const DicomTag& tag)
608 { 629 {
609 return (IsMainDicomTag(tag, ResourceType_Patient) || 630 return (IsMainDicomTag(tag, ResourceType_Patient) ||
702 723
703 724
704 void DicomMap::GetMainDicomTags(std::set<DicomTag>& target, 725 void DicomMap::GetMainDicomTags(std::set<DicomTag>& target,
705 ResourceType level) 726 ResourceType level)
706 { 727 {
707 target = DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTagsByLevel(level); 728 DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTagsByLevel(target, level);
708 } 729 }
709 730
710 void DicomMap::GetAllMainDicomTags(std::set<DicomTag>& target) 731 void DicomMap::GetAllMainDicomTags(std::set<DicomTag>& target)
711 { 732 {
712 target = DicomMap::MainDicomTagsConfiguration::GetInstance().GetAllMainDicomTags(); 733 DicomMap::MainDicomTagsConfiguration::GetInstance().GetAllMainDicomTags(target);
713 } 734 }
714 735
715 void DicomMap::AddMainDicomTag(const DicomTag& tag, ResourceType level) 736 void DicomMap::AddMainDicomTag(const DicomTag& tag, ResourceType level)
716 { 737 {
717 DicomMap::MainDicomTagsConfiguration::GetInstance().AddMainDicomTag(tag, level); 738 DicomMap::MainDicomTagsConfiguration::GetInstance().AddMainDicomTag(tag, level);
1403 1424
1404 1425
1405 void DicomMap::MergeMainDicomTags(const DicomMap& other, 1426 void DicomMap::MergeMainDicomTags(const DicomMap& other,
1406 ResourceType level) 1427 ResourceType level)
1407 { 1428 {
1408 const std::set<DicomTag>& mainDicomTags = DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTagsByLevel(level); 1429 std::set<DicomTag> mainDicomTags;
1430 DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTagsByLevel(mainDicomTags, level);
1409 1431
1410 for (std::set<DicomTag>::const_iterator itmt = mainDicomTags.begin(); 1432 for (std::set<DicomTag>::const_iterator itmt = mainDicomTags.begin();
1411 itmt != mainDicomTags.end(); ++itmt) 1433 itmt != mainDicomTags.end(); ++itmt)
1412 { 1434 {
1413 Content::const_iterator found = other.content_.find(*itmt); 1435 Content::const_iterator found = other.content_.find(*itmt);
1432 } 1454 }
1433 1455
1434 1456
1435 bool DicomMap::HasOnlyMainDicomTags() const 1457 bool DicomMap::HasOnlyMainDicomTags() const
1436 { 1458 {
1437 const std::set<DicomTag>& allMainDicomTags = DicomMap::MainDicomTagsConfiguration::GetInstance().GetAllMainDicomTags();
1438
1439 for (Content::const_iterator it = content_.begin(); it != content_.end(); ++it) 1459 for (Content::const_iterator it = content_.begin(); it != content_.end(); ++it)
1440 { 1460 {
1441 if (allMainDicomTags.find(it->first) == allMainDicomTags.end()) 1461 if (!DicomMap::MainDicomTagsConfiguration::GetInstance().IsMainDicomTag(it->first))
1442 { 1462 {
1443 return false; 1463 return false;
1444 } 1464 }
1445 } 1465 }
1446 1466
1704 } 1724 }
1705 1725
1706 void DicomMap::DumpMainDicomTags(Json::Value& target, 1726 void DicomMap::DumpMainDicomTags(Json::Value& target,
1707 ResourceType level) const 1727 ResourceType level) const
1708 { 1728 {
1709 const std::set<DicomTag>& mainDicomTags = DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTagsByLevel(level); 1729 std::set<DicomTag> mainDicomTags;
1730 DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTagsByLevel(mainDicomTags, level);
1710 1731
1711 target = Json::objectValue; 1732 target = Json::objectValue;
1712 1733
1713 for (Content::const_iterator it = content_.begin(); it != content_.end(); ++it) 1734 for (Content::const_iterator it = content_.begin(); it != content_.end(); ++it)
1714 { 1735 {