# HG changeset patch # User Sebastien Jodogne # Date 1544701030 -3600 # Node ID 0e1755e5efd04c6d098cb788bd8086f6cda4e702 # Parent 8265a6b5610027a4fbbdd5f3f9d07a2f8b00e5f2 DicomMap::ExtractMainDicomTags() diff -r 8265a6b56100 -r 0e1755e5efd0 Core/DicomFormat/DicomMap.cpp --- a/Core/DicomFormat/DicomMap.cpp Wed Dec 12 15:42:33 2018 +0100 +++ b/Core/DicomFormat/DicomMap.cpp Thu Dec 13 12:37:10 2018 +0100 @@ -1021,6 +1021,54 @@ } + void DicomMap::Merge(const DicomMap& other) + { + for (Map::const_iterator it = other.map_.begin(); + it != other.map_.end(); ++it) + { + assert(it->second != NULL); + + if (map_.find(it->first) == map_.end()) + { + map_[it->first] = it->second->Clone(); + } + } + } + + + void DicomMap::ExtractMainDicomTagsInternal(const DicomMap& other, + ResourceType level) + { + const DicomTag* tags = NULL; + size_t size = 0; + + LoadMainDicomTags(tags, size, level); + assert(tags != NULL && size > 0); + + for (size_t i = 0; i < size; i++) + { + Map::const_iterator found = other.map_.find(tags[i]); + + if (found != other.map_.end() && + map_.find(tags[i]) == map_.end()) + { + assert(found->second != NULL); + map_[tags[i]] = found->second->Clone(); + } + } + } + + + void DicomMap::ExtractMainDicomTags(const DicomMap& other) + { + Clear(); + ExtractMainDicomTagsInternal(other, ResourceType_Patient); + ExtractMainDicomTagsInternal(other, ResourceType_Study); + ExtractMainDicomTagsInternal(other, ResourceType_Series); + ExtractMainDicomTagsInternal(other, ResourceType_Instance); + } + + void DicomMap::Serialize(Json::Value& target) const { target = Json::objectValue; diff -r 8265a6b56100 -r 0e1755e5efd0 Core/DicomFormat/DicomMap.h --- a/Core/DicomFormat/DicomMap.h Wed Dec 12 15:42:33 2018 +0100 +++ b/Core/DicomFormat/DicomMap.h Thu Dec 13 12:37:10 2018 +0100 @@ -59,7 +59,7 @@ uint16_t element, DicomValue* value); - void SetValue(DicomTag tag, + void SetValue(DicomTag tag, DicomValue* value); void ExtractTags(DicomMap& source, @@ -68,6 +68,9 @@ static void GetMainDicomTagsInternal(std::set& result, ResourceType level); + void ExtractMainDicomTagsInternal(const DicomMap& other, + ResourceType level); + public: DicomMap() { @@ -218,6 +221,10 @@ const DicomTag& tag) const; void FromDicomAsJson(const Json::Value& dicomAsJson); + + void Merge(const DicomMap& other); + + void ExtractMainDicomTags(const DicomMap& other); void Serialize(Json::Value& target) const; diff -r 8265a6b56100 -r 0e1755e5efd0 LinuxCompilation.txt --- a/LinuxCompilation.txt Wed Dec 12 15:42:33 2018 +0100 +++ b/LinuxCompilation.txt Thu Dec 13 12:37:10 2018 +0100 @@ -115,8 +115,8 @@ -SUPPORTED - Ubuntu 14.04 LTS ----------------------------- +SUPPORTED - Ubuntu 14.04 LTS and 16.04 LTS +------------------------------------------ # sudo apt-get install build-essential unzip cmake mercurial \ uuid-dev libcurl4-openssl-dev liblua5.1-0-dev \ diff -r 8265a6b56100 -r 0e1755e5efd0 OrthancServer/ServerIndex.cpp --- a/OrthancServer/ServerIndex.cpp Wed Dec 12 15:42:33 2018 +0100 +++ b/OrthancServer/ServerIndex.cpp Thu Dec 13 12:37:10 2018 +0100 @@ -2248,6 +2248,78 @@ } + bool ServerIndex::GetAllMainDicomTags(DicomMap& result, + const std::string& instancePublicId) + { + result.Clear(); + + boost::mutex::scoped_lock lock(mutex_); + + // Lookup for the requested resource + int64_t instance; + ResourceType type; + if (!db_.LookupResource(instance, type, instancePublicId) || + type != ResourceType_Instance) + { + return false; + } + else + { + DicomMap tmp; + + db_.GetMainDicomTags(tmp, instance); + result.Merge(tmp); + + int64_t series; + if (!db_.LookupParent(series, instance)) + { + throw OrthancException(ErrorCode_InternalError); + } + + tmp.Clear(); + db_.GetMainDicomTags(tmp, series); + result.Merge(tmp); + + int64_t study; + if (!db_.LookupParent(study, series)) + { + throw OrthancException(ErrorCode_InternalError); + } + + tmp.Clear(); + db_.GetMainDicomTags(tmp, study); + result.Merge(tmp); + +#ifndef NDEBUG + { + // Sanity test to check that all the main DICOM tags from the + // patient level are copied at the study level + + int64_t patient; + if (!db_.LookupParent(patient, study)) + { + throw OrthancException(ErrorCode_InternalError); + } + + tmp.Clear(); + db_.GetMainDicomTags(tmp, study); + + std::set patientTags; + tmp.GetTags(patientTags); + + for (std::set::const_iterator + it = patientTags.begin(); it != patientTags.end(); ++it) + { + assert(result.HasTag(*it)); + } + } +#endif + + return true; + } + } + + bool ServerIndex::LookupResourceType(ResourceType& type, const std::string& publicId) { diff -r 8265a6b56100 -r 0e1755e5efd0 OrthancServer/ServerIndex.h --- a/OrthancServer/ServerIndex.h Wed Dec 12 15:42:33 2018 +0100 +++ b/OrthancServer/ServerIndex.h Thu Dec 13 12:37:10 2018 +0100 @@ -275,6 +275,10 @@ ResourceType expectedType, ResourceType levelOfInterest); + // Only applicable at the instance level + bool GetAllMainDicomTags(DicomMap& result, + const std::string& instancePublicId); + bool LookupResourceType(ResourceType& type, const std::string& publicId); diff -r 8265a6b56100 -r 0e1755e5efd0 UnitTestsSources/DicomMapTests.cpp --- a/UnitTestsSources/DicomMapTests.cpp Wed Dec 12 15:42:33 2018 +0100 +++ b/UnitTestsSources/DicomMapTests.cpp Thu Dec 13 12:37:10 2018 +0100 @@ -504,3 +504,44 @@ //std::cout << toStore.GetJson() << std::endl; //a.Print(stdout); } + + + +TEST(DicomMap, ExtractMainDicomTags) +{ + DicomMap b; + b.SetValue(DICOM_TAG_PATIENT_NAME, "E", false); + + { + DicomMap a; + a.SetValue(DICOM_TAG_PATIENT_NAME, "A", false); + a.SetValue(DICOM_TAG_STUDY_DESCRIPTION, "B", false); + a.SetValue(DICOM_TAG_SERIES_DESCRIPTION, "C", false); + a.SetValue(DICOM_TAG_NUMBER_OF_FRAMES, "D", false); + a.SetValue(DICOM_TAG_SLICE_THICKNESS, "F", false); + b.ExtractMainDicomTags(a); + } + + ASSERT_EQ(4u, b.GetSize()); + ASSERT_EQ("A", b.GetValue(DICOM_TAG_PATIENT_NAME).GetContent()); + ASSERT_EQ("B", b.GetValue(DICOM_TAG_STUDY_DESCRIPTION).GetContent()); + ASSERT_EQ("C", b.GetValue(DICOM_TAG_SERIES_DESCRIPTION).GetContent()); + ASSERT_EQ("D", b.GetValue(DICOM_TAG_NUMBER_OF_FRAMES).GetContent()); + ASSERT_FALSE(b.HasTag(DICOM_TAG_SLICE_THICKNESS)); + + b.SetValue(DICOM_TAG_PATIENT_NAME, "G", false); + + { + DicomMap a; + a.SetValue(DICOM_TAG_PATIENT_NAME, "A", false); + a.SetValue(DICOM_TAG_SLICE_THICKNESS, "F", false); + b.Merge(a); + } + + ASSERT_EQ(5u, b.GetSize()); + ASSERT_EQ("G", b.GetValue(DICOM_TAG_PATIENT_NAME).GetContent()); + ASSERT_EQ("B", b.GetValue(DICOM_TAG_STUDY_DESCRIPTION).GetContent()); + ASSERT_EQ("C", b.GetValue(DICOM_TAG_SERIES_DESCRIPTION).GetContent()); + ASSERT_EQ("D", b.GetValue(DICOM_TAG_NUMBER_OF_FRAMES).GetContent()); + ASSERT_EQ("F", b.GetValue(DICOM_TAG_SLICE_THICKNESS).GetContent()); +}