# HG changeset patch # User Alain Mazy # Date 1726644892 -7200 # Node ID a3d283f61304df8dd53481c50155181deb2d9c17 # Parent 40ad08b75d84f811a04cd50ef7612f3522c31cac improved handling of DicomSequences in parent diff -r 40ad08b75d84 -r a3d283f61304 OrthancFramework/Sources/DicomFormat/DicomMap.cpp --- a/OrthancFramework/Sources/DicomFormat/DicomMap.cpp Tue Sep 17 17:16:42 2024 +0200 +++ b/OrthancFramework/Sources/DicomFormat/DicomMap.cpp Wed Sep 18 09:34:52 2024 +0200 @@ -739,21 +739,6 @@ } } - void DicomMap::RemoveComputedTags(std::set& tags) - { - std::set tagsToRemove; - - for (std::set::const_iterator it = tags.begin(); it != tags.end(); ++it) - { - if (IsComputedTag(*it)) - { - tagsToRemove.insert(*it); - } - } - - Toolbox::RemoveSets(tags, tagsToRemove); - } - bool DicomMap::HasOnlyComputedTags(const std::set& tags) { if (tags.size() == 0) diff -r 40ad08b75d84 -r a3d283f61304 OrthancFramework/Sources/DicomFormat/DicomMap.h --- a/OrthancFramework/Sources/DicomFormat/DicomMap.h Tue Sep 17 17:16:42 2024 +0200 +++ b/OrthancFramework/Sources/DicomFormat/DicomMap.h Wed Sep 18 09:34:52 2024 +0200 @@ -142,8 +142,6 @@ static bool HasOnlyComputedTags(const std::set& tags); - static void RemoveComputedTags(std::set& tags); - static bool HasComputedTags(const std::set& tags, ResourceType level); static bool HasComputedTags(const std::set& tags); diff -r 40ad08b75d84 -r a3d283f61304 OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp --- a/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp Tue Sep 17 17:16:42 2024 +0200 +++ b/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp Wed Sep 18 09:34:52 2024 +0200 @@ -469,42 +469,86 @@ } } - // need MainDicomTags from parent ? - if (requestLevel > ResourceType_Patient && request.GetParentSpecification(static_cast(requestLevel - 1)).IsRetrieveMainDicomTags()) + + if (requestLevel > ResourceType_Patient) { - sql = "SELECT currentLevel.internalId, tagGroup, tagElement, value " - "FROM MainDicomTags " - "INNER JOIN Resources currentLevel ON Lookup.internalId = currentLevel.internalId " - "INNER JOIN Lookup ON MainDicomTags.id = currentLevel.parentId"; + // need MainDicomTags from parent ? + if (request.GetParentSpecification(static_cast(requestLevel - 1)).IsRetrieveMainDicomTags()) + { + sql = "SELECT currentLevel.internalId, tagGroup, tagElement, value " + "FROM MainDicomTags " + "INNER JOIN Resources currentLevel ON Lookup.internalId = currentLevel.internalId " + "INNER JOIN Lookup ON MainDicomTags.id = currentLevel.parentId"; - SQLite::Statement s(db_, SQLITE_FROM_HERE, sql); - while (s.Step()) + SQLite::Statement s(db_, SQLITE_FROM_HERE, sql); + while (s.Step()) + { + FindResponse::Resource& res = response.GetResourceByInternalId(s.ColumnInt64(0)); + res.AddStringDicomTag(static_cast(requestLevel - 1), + static_cast(s.ColumnInt(1)), + static_cast(s.ColumnInt(2)), + s.ColumnString(3)); + } + } + + // need metadata from parent ? + if (request.GetParentSpecification(static_cast(requestLevel - 1)).IsRetrieveMetadata()) { - FindResponse::Resource& res = response.GetResourceByInternalId(s.ColumnInt64(0)); - res.AddStringDicomTag(static_cast(requestLevel - 1), - static_cast(s.ColumnInt(1)), - static_cast(s.ColumnInt(2)), - s.ColumnString(3)); + sql = "SELECT currentLevel.internalId, type, value " + "FROM Metadata " + "INNER JOIN Resources currentLevel ON Lookup.internalId = currentLevel.internalId " + "INNER JOIN Lookup ON Metadata.id = currentLevel.parentId"; + + SQLite::Statement s(db_, SQLITE_FROM_HERE, sql); + while (s.Step()) + { + FindResponse::Resource& res = response.GetResourceByInternalId(s.ColumnInt64(0)); + res.AddMetadata(static_cast(requestLevel - 1), + static_cast(s.ColumnInt(1)), + s.ColumnString(2)); + } } } - // need MainDicomTags from grandparent ? - if (requestLevel > ResourceType_Study && request.GetParentSpecification(static_cast(requestLevel - 2)).IsRetrieveMainDicomTags()) + if (requestLevel > ResourceType_Study) { - sql = "SELECT currentLevel.internalId, tagGroup, tagElement, value " - "FROM MainDicomTags " - "INNER JOIN Resources currentLevel ON Lookup.internalId = currentLevel.internalId " - "INNER JOIN Resources parentLevel ON currentLevel.parentId = parentLevel.internalId " - "INNER JOIN Lookup ON MainDicomTags.id = parentLevel.parentId"; + // need MainDicomTags from grandparent ? + if (request.GetParentSpecification(static_cast(requestLevel - 2)).IsRetrieveMainDicomTags()) + { + sql = "SELECT currentLevel.internalId, tagGroup, tagElement, value " + "FROM MainDicomTags " + "INNER JOIN Resources currentLevel ON Lookup.internalId = currentLevel.internalId " + "INNER JOIN Resources parentLevel ON currentLevel.parentId = parentLevel.internalId " + "INNER JOIN Lookup ON MainDicomTags.id = parentLevel.parentId"; - SQLite::Statement s(db_, SQLITE_FROM_HERE, sql); - while (s.Step()) + SQLite::Statement s(db_, SQLITE_FROM_HERE, sql); + while (s.Step()) + { + FindResponse::Resource& res = response.GetResourceByInternalId(s.ColumnInt64(0)); + res.AddStringDicomTag(static_cast(requestLevel - 2), + static_cast(s.ColumnInt(1)), + static_cast(s.ColumnInt(2)), + s.ColumnString(3)); + } + } + + // need metadata from grandparent ? + if (request.GetParentSpecification(static_cast(requestLevel - 2)).IsRetrieveMetadata()) { - FindResponse::Resource& res = response.GetResourceByInternalId(s.ColumnInt64(0)); - res.AddStringDicomTag(static_cast(requestLevel - 2), - static_cast(s.ColumnInt(1)), - static_cast(s.ColumnInt(2)), - s.ColumnString(3)); + sql = "SELECT currentLevel.internalId, type, value " + "FROM Metadata " + "INNER JOIN Resources currentLevel ON Lookup.internalId = currentLevel.internalId " + "INNER JOIN Resources parentLevel ON currentLevel.parentId = parentLevel.internalId " + "INNER JOIN Lookup ON Metadata.id = parentLevel.parentId"; + + SQLite::Statement s(db_, SQLITE_FROM_HERE, sql); + while (s.Step()) + { + FindResponse::Resource& res = response.GetResourceByInternalId(s.ColumnInt64(0)); + res.AddMetadata(static_cast(requestLevel - 2), + static_cast(s.ColumnInt(1)), + s.ColumnString(2)); + } } } diff -r 40ad08b75d84 -r a3d283f61304 OrthancServer/Sources/ResourceFinder.cpp --- a/OrthancServer/Sources/ResourceFinder.cpp Tue Sep 17 17:16:42 2024 +0200 +++ b/OrthancServer/Sources/ResourceFinder.cpp Wed Sep 18 09:34:52 2024 +0200 @@ -190,7 +190,7 @@ { // read all main sequences from DB std::string serializedSequences; - if (resource.LookupMetadata(serializedSequences, resource.GetLevel(), MetadataType_MainDicomSequences)) + if (resource.LookupMetadata(serializedSequences, level, MetadataType_MainDicomSequences)) { Json::Value jsonMetadata; Toolbox::ReadJson(jsonMetadata, serializedSequences); @@ -651,6 +651,7 @@ else { request_.GetParentSpecification(ResourceType_Study).SetRetrieveMainDicomTags(true); + request_.GetParentSpecification(ResourceType_Study).SetRetrieveMetadata(true); // to get the MainDicomSequences } } } @@ -674,6 +675,7 @@ else { request_.GetParentSpecification(ResourceType_Study).SetRetrieveMainDicomTags(true); + request_.GetParentSpecification(ResourceType_Study).SetRetrieveMetadata(true); // to get the MainDicomSequences } } } @@ -698,6 +700,7 @@ else { request_.GetParentSpecification(ResourceType_Series).SetRetrieveMainDicomTags(true); + request_.GetParentSpecification(ResourceType_Series).SetRetrieveMetadata(true); // to get the MainDicomSequences } } } @@ -794,23 +797,29 @@ ResourceType level/*, const std::set& tags*/) { - if (!remainingRequestedTags.empty()) + if (!remainingRequestedTags.empty() && level <= resource.GetLevel()) { - DicomMap m; - resource.GetAllMainDicomTags(m); // DicomTags from DB - GetMainDicomSequencesFromMetadata(m, resource, resource.GetLevel()); // DicomSequences from metadata - - // check which tags have been saved in DB; that's the way to know if they are missing because they were not saved or because they have no value std::set savedMainDicomTags; - std::string signature = DicomMap::GetDefaultMainDicomTagsSignature(ResourceType_Study); // default signature in case it's not in the metadata (= the signature for 1.11.0) - if (resource.LookupMetadata(signature, resource.GetLevel(), MetadataType_MainDicomTagsSignature)) + + DicomMap m; + resource.GetMainDicomTags(m, level); // read DicomTags from DB + + if (resource.GetMetadata(level).size() > 0) { - if (level == ResourceType_Study) // when we retrieve the study tags, we actually also get the patient tags that are also saved at study level but not included in the signature + GetMainDicomSequencesFromMetadata(m, resource, level); // read DicomSequences from metadata + + // check which tags have been saved in DB; that's the way to know if they are missing because they were not saved or because they have no value + + std::string signature = DicomMap::GetDefaultMainDicomTagsSignature(ResourceType_Study); // default signature in case it's not in the metadata (= the signature for 1.11.0) + if (resource.LookupMetadata(signature, level, MetadataType_MainDicomTagsSignature)) { - signature += ";" + DicomMap::GetDefaultMainDicomTagsSignature(ResourceType_Patient); // append the default signature (from before 1.11.0) + if (level == ResourceType_Study) // when we retrieve the study tags, we actually also get the patient tags that are also saved at study level but not included in the signature + { + signature += ";" + DicomMap::GetDefaultMainDicomTagsSignature(ResourceType_Patient); // append the default signature (from before 1.11.0) + } + + FromDcmtkBridge::ParseListOfTags(savedMainDicomTags, signature); } - - FromDcmtkBridge::ParseListOfTags(savedMainDicomTags, signature); } std::set copiedTags;