Mercurial > hg > orthanc
changeset 2208:90ea60bee5ff
New metadata automatically computed at the instance level: "SopClassUid"
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 09 Dec 2016 14:48:31 +0100 |
parents | 6dc3bdb4088b |
children | e3fd5bc429a2 |
files | NEWS OrthancServer/OrthancFindRequestHandler.cpp OrthancServer/ServerEnumerations.cpp OrthancServer/ServerEnumerations.h OrthancServer/ServerIndex.cpp Resources/Configuration.json TODO UnitTestsSources/ServerIndexTests.cpp |
diffstat | 8 files changed, 59 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/NEWS Fri Dec 09 11:24:04 2016 +0100 +++ b/NEWS Fri Dec 09 14:48:31 2016 +0100 @@ -6,7 +6,7 @@ * Handling of private tags/creators in the "Dictionary" configuration option * New configuration options: "LoadPrivateDictionary", "DicomScuTimeout" and "DicomScpTimeout" -* New metadata automatically computed at the instance level: "TransferSyntax" +* New metadata automatically computed at the instance level: "TransferSyntax" and "SopClassUid" REST API --------
--- a/OrthancServer/OrthancFindRequestHandler.cpp Fri Dec 09 11:24:04 2016 +0100 +++ b/OrthancServer/OrthancFindRequestHandler.cpp Fri Dec 09 14:48:31 2016 +0100 @@ -107,10 +107,34 @@ } - static void ExtractTagFromInstances(std::set<std::string>& target, - ServerContext& context, - const DicomTag& tag, - const std::list<std::string>& instances) + static bool ExtractMetadata(std::set<std::string>& target, + ServerIndex& index, + MetadataType metadata, + const std::list<std::string>& resources) + { + for (std::list<std::string>::const_iterator + it = resources.begin(); it != resources.end(); ++it) + { + std::string value; + if (index.LookupMetadata(value, *it, metadata)) + { + target.insert(value); + } + else + { + // This metadata is unavailable for some resource, give up + return false; + } + } + + return true; + } + + + static void ExtractTagFromInstancesOnDisk(std::set<std::string>& target, + ServerContext& context, + const DicomTag& tag, + const std::list<std::string>& instances) { // WARNING: This function is slow, as it reads the JSON file // summarizing each instance of interest from the hard drive. @@ -226,10 +250,16 @@ if (query.HasTag(DICOM_TAG_SOP_CLASSES_IN_STUDY)) { - if (Configuration::GetGlobalBoolParameter("AllowFindSopClassesInStudy", false)) + std::set<std::string> values; + + if (ExtractMetadata(values, index, MetadataType_Instance_SopClassUid, instances)) { - std::set<std::string> values; - ExtractTagFromInstances(values, context, DICOM_TAG_SOP_CLASS_UID, instances); + // The metadata "SopClassUid" is available for each of these instances + StoreSetOfStrings(result, DICOM_TAG_SOP_CLASSES_IN_STUDY, values); + } + else if (Configuration::GetGlobalBoolParameter("AllowFindSopClassesInStudy", false)) + { + ExtractTagFromInstancesOnDisk(values, context, DICOM_TAG_SOP_CLASS_UID, instances); StoreSetOfStrings(result, DICOM_TAG_SOP_CLASSES_IN_STUDY, values); } else
--- a/OrthancServer/ServerEnumerations.cpp Fri Dec 09 11:24:04 2016 +0100 +++ b/OrthancServer/ServerEnumerations.cpp Fri Dec 09 14:48:31 2016 +0100 @@ -65,6 +65,7 @@ dictMetadataType_.Add(MetadataType_LastUpdate, "LastUpdate"); dictMetadataType_.Add(MetadataType_Instance_Origin, "Origin"); dictMetadataType_.Add(MetadataType_Instance_TransferSyntax, "TransferSyntax"); + dictMetadataType_.Add(MetadataType_Instance_SopClassUid, "SopClassUid"); dictContentType_.Add(FileContentType_Dicom, "dicom"); dictContentType_.Add(FileContentType_DicomAsJson, "dicom-as-json");
--- a/OrthancServer/ServerEnumerations.h Fri Dec 09 11:24:04 2016 +0100 +++ b/OrthancServer/ServerEnumerations.h Fri Dec 09 14:48:31 2016 +0100 @@ -159,6 +159,7 @@ MetadataType_LastUpdate = 7, MetadataType_Instance_Origin = 8, // New in Orthanc 0.9.5 MetadataType_Instance_TransferSyntax = 9, // New in Orthanc 1.2.0 + MetadataType_Instance_SopClassUid = 10, // New in Orthanc 1.2.0 // Make sure that the value "65535" can be stored into this enumeration MetadataType_StartUser = 1024,
--- a/OrthancServer/ServerIndex.cpp Fri Dec 09 11:24:04 2016 +0100 +++ b/OrthancServer/ServerIndex.cpp Fri Dec 09 14:48:31 2016 +0100 @@ -787,6 +787,13 @@ } const DicomValue* value; + if ((value = dicomSummary.TestAndGetValue(DICOM_TAG_SOP_CLASS_UID)) != NULL && + !value->IsNull() && + !value->IsBinary()) + { + SetInstanceMetadata(instanceMetadata, instance, MetadataType_Instance_SopClassUid, value->GetContent()); + } + if ((value = dicomSummary.TestAndGetValue(DICOM_TAG_INSTANCE_NUMBER)) != NULL || (value = dicomSummary.TestAndGetValue(DICOM_TAG_IMAGE_INDEX)) != NULL) {
--- a/Resources/Configuration.json Fri Dec 09 11:24:04 2016 +0100 +++ b/Resources/Configuration.json Fri Dec 09 14:48:31 2016 +0100 @@ -314,9 +314,12 @@ } **/ - // If set to "true", Orthanc will handle "SOP Classes in Study" - // (0008,0062) in C-FIND requests. This option is turned off by - // default, as it requires intensive accesses to the hard drive. + // If set to "true", Orthanc will still handle "SOP Classes in + // Study" (0008,0062) in C-FIND requests, even if the "SOP Class + // UID" metadata is not available in the database (which is the case + // if the DB was previously used by Orthanc <= 1.1.0). This option + // is turned off by default, as it requires intensive accesses to + // the hard drive. "AllowFindSopClassesInStudy" : false, // If set to "false", Orthanc will not load its default dictionary
--- a/TODO Fri Dec 09 11:24:04 2016 +0100 +++ b/TODO Fri Dec 09 14:48:31 2016 +0100 @@ -105,7 +105,7 @@ Orthanc Book ============ -* Document C-FIND filters +* Document Lua C-FIND filters (cf. "IncomingFindRequestFilter()") ================
--- a/UnitTestsSources/ServerIndexTests.cpp Fri Dec 09 11:24:04 2016 +0100 +++ b/UnitTestsSources/ServerIndexTests.cpp Fri Dec 09 14:48:31 2016 +0100 @@ -793,19 +793,23 @@ instance.SetValue(DICOM_TAG_STUDY_INSTANCE_UID, "study-" + id, false); instance.SetValue(DICOM_TAG_SERIES_INSTANCE_UID, "series-" + id, false); instance.SetValue(DICOM_TAG_SOP_INSTANCE_UID, "instance-" + id, false); + instance.SetValue(DICOM_TAG_SOP_CLASS_UID, "1.2.840.10008.5.1.4.1.1.1", false); // CR image std::map<MetadataType, std::string> instanceMetadata; DicomInstanceToStore toStore; toStore.SetSummary(instance); ASSERT_EQ(StoreStatus_Success, index.Store(instanceMetadata, toStore, attachments)); - ASSERT_EQ(4u, instanceMetadata.size()); + ASSERT_EQ(5u, instanceMetadata.size()); ASSERT_TRUE(instanceMetadata.find(MetadataType_Instance_RemoteAet) != instanceMetadata.end()); ASSERT_TRUE(instanceMetadata.find(MetadataType_Instance_ReceptionDate) != instanceMetadata.end()); ASSERT_TRUE(instanceMetadata.find(MetadataType_Instance_TransferSyntax) != instanceMetadata.end()); + ASSERT_TRUE(instanceMetadata.find(MetadataType_Instance_SopClassUid) != instanceMetadata.end()); // By default, an Explicit VR Little Endian is used by Orthanc ASSERT_EQ("1.2.840.10008.1.2.1", instanceMetadata[MetadataType_Instance_TransferSyntax]); + ASSERT_EQ("1.2.840.10008.5.1.4.1.1.1", instanceMetadata[MetadataType_Instance_SopClassUid]); + DicomInstanceHasher hasher(instance); ids.push_back(hasher.HashPatient()); ids.push_back(hasher.HashStudy());