# HG changeset patch # User Alain Mazy # Date 1646824605 -3600 # Node ID 312c6f4da88844cc2dd29557b96b607772469802 # Parent b7ce2bb6b881bad8ec8cc870b907010af2daa8e2 adding MainDicomTags signatures diff -r b7ce2bb6b881 -r 312c6f4da888 OrthancFramework/Sources/DicomFormat/DicomMap.cpp --- a/OrthancFramework/Sources/DicomFormat/DicomMap.cpp Wed Mar 09 11:17:08 2022 +0100 +++ b/OrthancFramework/Sources/DicomFormat/DicomMap.cpp Wed Mar 09 12:16:45 2022 +0100 @@ -26,6 +26,7 @@ #include #include +#include #include "../Compatibility.h" #include "../Endianness.h" @@ -49,6 +50,15 @@ } + // WARNING: the DEFAULT list of main dicom tags below are the list as they + // were in Orthanc 1.10 before we introduced the dynamic main dicom tags. + // This list has not changed since Orthanc 1.4.2 and had a single change since + // Orthanc 0.9.5. + // These lists have a specific signature. When a resource does not have + // the metadata "MainDicomTagsSignature", we'll assume that they were stored + // with an Orthanc prior to 1.11. It is therefore very important that you never + // change these lists ! + static const MainDicomTag DEFAULT_PATIENT_MAIN_DICOM_TAGS[] = { // { DicomTag(0x0010, 0x1010), "PatientAge" }, @@ -163,6 +173,9 @@ std::map > mainDicomTagsByLevel_; std::set allMainDicomTags_; + std::map signatures_; + std::map defaultSignatures_; + MainDicomTagsConfiguration() { ResetDefaultMainDicomTags(); @@ -180,6 +193,27 @@ LoadDefaultMainDicomTags(ResourceType_Study); LoadDefaultMainDicomTags(ResourceType_Series); LoadDefaultMainDicomTags(ResourceType_Instance); + + defaultSignatures_[ResourceType_Patient] = signatures_[ResourceType_Patient]; + defaultSignatures_[ResourceType_Study] = signatures_[ResourceType_Study]; + defaultSignatures_[ResourceType_Series] = signatures_[ResourceType_Series]; + defaultSignatures_[ResourceType_Instance] = signatures_[ResourceType_Instance]; + } + + std::string ComputeSignature(const std::set& tags) + { + // std::set are sorted by default (which is important for us !) + std::set tagsIds; + for (std::set::const_iterator it = tags.begin(); it != tags.end(); it++) + { + tagsIds.insert(it->Format()); + } + + std::string signatureText = boost::algorithm::join(tagsIds, "|"); + std::string signatureMD5; + Toolbox::ComputeMD5(signatureMD5, signatureText); + + return signatureMD5; } void LoadDefaultMainDicomTags(ResourceType level) @@ -249,6 +283,7 @@ mainDicomTagsByName_[level][name] = DicomTag2(tag); mainDicomTagsByLevel_[level].insert(tag); allMainDicomTags_.insert(tag); + signatures_[level] = ComputeSignature(GetMainDicomTagsByLevel(level)); } const std::map& GetMainDicomTags(ResourceType level) const @@ -276,6 +311,21 @@ { return allMainDicomTags_; } + + const std::string& GetMainDicomTagsSignature(ResourceType level) + { + assert(signatures_.find(level) != signatures_.end()); + + return signatures_[level]; + } + + const std::string& GetDefaultMainDicomTagsSignature(ResourceType level) + { + assert(defaultSignatures_.find(level) != defaultSignatures_.end()); + + return defaultSignatures_[level]; + } + }; @@ -589,6 +639,16 @@ DicomMap::MainDicomTagsConfiguration::GetInstance().ResetDefaultMainDicomTags(); } + const std::string& DicomMap::GetMainDicomTagsSignature(ResourceType level) + { + return DicomMap::MainDicomTagsConfiguration::GetInstance().GetMainDicomTagsSignature(level); + } + + const std::string& DicomMap::GetDefaultMainDicomTagsSignature(ResourceType level) + { + return DicomMap::MainDicomTagsConfiguration::GetInstance().GetDefaultMainDicomTagsSignature(level); + } + void DicomMap::GetTags(std::set& tags) const { tags.clear(); diff -r b7ce2bb6b881 -r 312c6f4da888 OrthancFramework/Sources/DicomFormat/DicomMap.h --- a/OrthancFramework/Sources/DicomFormat/DicomMap.h Wed Mar 09 11:17:08 2022 +0100 +++ b/OrthancFramework/Sources/DicomFormat/DicomMap.h Wed Mar 09 12:16:45 2022 +0100 @@ -135,6 +135,11 @@ static const std::set& GetMainDicomTags(ResourceType level); + // returns a string uniquely identifying the list of main dicom tags for a level + static const std::string& GetMainDicomTagsSignature(ResourceType level); + + static const std::string& GetDefaultMainDicomTagsSignature(ResourceType level); + static const std::set& GetAllMainDicomTags(); // adds a main dicom tag to the definition of main dicom tags for each level. diff -r b7ce2bb6b881 -r 312c6f4da888 OrthancFramework/UnitTestsSources/DicomMapTests.cpp --- a/OrthancFramework/UnitTestsSources/DicomMapTests.cpp Wed Mar 09 11:17:08 2022 +0100 +++ b/OrthancFramework/UnitTestsSources/DicomMapTests.cpp Wed Mar 09 12:16:45 2022 +0100 @@ -138,6 +138,35 @@ // adding another tag with same name should throw ASSERT_THROW(DicomMap::AddMainDicomTag(DICOM_TAG_BITS_STORED, "BitsAllocated", ResourceType_Instance), OrthancException); } + + TEST_F(DicomMapMainTagsTests, Signatures) + { + std::string defaultPatientSignature = DicomMap::GetDefaultMainDicomTagsSignature(ResourceType_Patient); + std::string defaultStudySignature = DicomMap::GetDefaultMainDicomTagsSignature(ResourceType_Study); + std::string defaultSeriesSignature = DicomMap::GetDefaultMainDicomTagsSignature(ResourceType_Series); + std::string defaultInstanceSignature = DicomMap::GetDefaultMainDicomTagsSignature(ResourceType_Instance); + + ASSERT_NE(defaultInstanceSignature, defaultPatientSignature); + ASSERT_NE(defaultSeriesSignature, defaultStudySignature); + ASSERT_NE(defaultSeriesSignature, defaultPatientSignature); + + std::string patientSignature = DicomMap::GetMainDicomTagsSignature(ResourceType_Patient); + std::string studySignature = DicomMap::GetMainDicomTagsSignature(ResourceType_Study); + std::string seriesSignature = DicomMap::GetMainDicomTagsSignature(ResourceType_Series); + std::string instanceSignature = DicomMap::GetMainDicomTagsSignature(ResourceType_Instance); + + // at start, default and current signature should be equal + ASSERT_EQ(defaultPatientSignature, patientSignature); + ASSERT_EQ(defaultStudySignature, studySignature); + ASSERT_EQ(defaultSeriesSignature, seriesSignature); + ASSERT_EQ(defaultInstanceSignature, instanceSignature); + + DicomMap::AddMainDicomTag(DICOM_TAG_BITS_ALLOCATED, "BitsAllocated", ResourceType_Instance); + instanceSignature = DicomMap::GetMainDicomTagsSignature(ResourceType_Instance); + + ASSERT_NE(defaultInstanceSignature, instanceSignature); + } + } TEST(DicomMap, Tags)