# HG changeset patch # User Alain Mazy # Date 1726655449 -7200 # Node ID a8055aebc6cb68b481b2fa8d55e763293b5aae6e # Parent 89a13d8ec80b5ed1a67322543dfa58f0551c5d91 added standard MainDicomTags that are used in QIDO-RS diff -r 89a13d8ec80b -r a8055aebc6cb NEWS --- a/NEWS Wed Sep 18 10:38:42 2024 +0200 +++ b/NEWS Wed Sep 18 12:30:49 2024 +0200 @@ -60,6 +60,16 @@ - W003_DecoderFailure - W004_NoMainDicomTagsSignature - W005_RequestingTagFromLowerResourceLevel +* New default MainDicomTags are now stored in DB. Note that, in order to store these values + for resources that were ingested in Orthanc before this release, you would have to run + the Housekeeper plugin or call /reconstruct on every resources + - At Study Level: + - TimezoneOffsetFromUTC (used in QIDO-RS default queries) + - At Series Level: + - TimezoneOffsetFromUTC (used in QIDO-RS default queries) + - PerformedProcedureStepStartDate (used in QIDO-RS default queries) + - PerformedProcedureStepStartTime (used in QIDO-RS default queries) + - RequestAttributesSequence (used in QIDO-RS default queries) diff -r 89a13d8ec80b -r a8055aebc6cb OrthancFramework/Sources/DicomFormat/DicomMap.cpp --- a/OrthancFramework/Sources/DicomFormat/DicomMap.cpp Wed Sep 18 10:38:42 2024 +0200 +++ b/OrthancFramework/Sources/DicomFormat/DicomMap.cpp Wed Sep 18 12:30:49 2024 +0200 @@ -55,9 +55,9 @@ // 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 ! + // change these lists ! Update ResetDefaultMainDicomTags instead. - static const DicomTag DEFAULT_PATIENT_MAIN_DICOM_TAGS[] = + static const DicomTag DEFAULT_1_11_PATIENT_MAIN_DICOM_TAGS[] = { // { DicomTag(0x0010, 0x1010), "PatientAge" }, // { DicomTag(0x0010, 0x1040), "PatientAddress" }, @@ -66,9 +66,11 @@ DICOM_TAG_PATIENT_SEX, DICOM_TAG_OTHER_PATIENT_IDS, DICOM_TAG_PATIENT_ID + + // don't add tags here, check ResetDefaultMainDicomTags instead }; - static const DicomTag DEFAULT_STUDY_MAIN_DICOM_TAGS[] = + static const DicomTag DEFAULT_1_11_STUDY_MAIN_DICOM_TAGS[] = { // { DicomTag(0x0010, 0x1020), "PatientSize" }, // { DicomTag(0x0010, 0x1030), "PatientWeight" }, @@ -84,9 +86,11 @@ DICOM_TAG_INSTITUTION_NAME, DICOM_TAG_REQUESTING_PHYSICIAN, DICOM_TAG_REFERRING_PHYSICIAN_NAME + + // don't add tags here, check ResetDefaultMainDicomTags instead }; - static const DicomTag DEFAULT_SERIES_MAIN_DICOM_TAGS[] = + static const DicomTag DEFAULT_1_11_SERIES_MAIN_DICOM_TAGS[] = { // { DicomTag(0x0010, 0x1080), "MilitaryRank" }, DICOM_TAG_SERIES_DATE, @@ -113,9 +117,11 @@ DICOM_TAG_PERFORMED_PROCEDURE_STEP_DESCRIPTION, DICOM_TAG_ACQUISITION_DEVICE_PROCESSING_DESCRIPTION, DICOM_TAG_CONTRAST_BOLUS_AGENT + + // don't add tags here, check ResetDefaultMainDicomTags instead }; - static const DicomTag DEFAULT_INSTANCE_MAIN_DICOM_TAGS[] = + static const DicomTag DEFAULT_1_11_INSTANCE_MAIN_DICOM_TAGS[] = { DICOM_TAG_INSTANCE_CREATION_DATE, DICOM_TAG_INSTANCE_CREATION_TIME, @@ -138,6 +144,8 @@ * indexed in the database by an older version of Orthanc. **/ DICOM_TAG_IMAGE_ORIENTATION_PATIENT // New in Orthanc 1.4.2 + + // don't add tags here, check ResetDefaultMainDicomTags instead }; class DicomMap::MainDicomTagsConfiguration : public boost::noncopyable @@ -187,23 +195,23 @@ switch (level) { case ResourceType_Patient: - tags = DEFAULT_PATIENT_MAIN_DICOM_TAGS; - size = sizeof(DEFAULT_PATIENT_MAIN_DICOM_TAGS) / sizeof(DicomTag); + tags = DEFAULT_1_11_PATIENT_MAIN_DICOM_TAGS; + size = sizeof(DEFAULT_1_11_PATIENT_MAIN_DICOM_TAGS) / sizeof(DicomTag); break; case ResourceType_Study: - tags = DEFAULT_STUDY_MAIN_DICOM_TAGS; - size = sizeof(DEFAULT_STUDY_MAIN_DICOM_TAGS) / sizeof(DicomTag); + tags = DEFAULT_1_11_STUDY_MAIN_DICOM_TAGS; + size = sizeof(DEFAULT_1_11_STUDY_MAIN_DICOM_TAGS) / sizeof(DicomTag); break; case ResourceType_Series: - tags = DEFAULT_SERIES_MAIN_DICOM_TAGS; - size = sizeof(DEFAULT_SERIES_MAIN_DICOM_TAGS) / sizeof(DicomTag); + tags = DEFAULT_1_11_SERIES_MAIN_DICOM_TAGS; + size = sizeof(DEFAULT_1_11_SERIES_MAIN_DICOM_TAGS) / sizeof(DicomTag); break; case ResourceType_Instance: - tags = DEFAULT_INSTANCE_MAIN_DICOM_TAGS; - size = sizeof(DEFAULT_INSTANCE_MAIN_DICOM_TAGS) / sizeof(DicomTag); + tags = DEFAULT_1_11_INSTANCE_MAIN_DICOM_TAGS; + size = sizeof(DEFAULT_1_11_INSTANCE_MAIN_DICOM_TAGS) / sizeof(DicomTag); break; default: @@ -247,7 +255,7 @@ if (existingLevelTags.find(tag) != existingLevelTags.end()) { - throw OrthancException(ErrorCode_MainDicomTagsMultiplyDefined, tag.Format() + " is already defined"); + throw OrthancException(ErrorCode_MainDicomTagsMultiplyDefined, tag.Format() + " is already defined", false); } existingLevelTags.insert(tag); @@ -287,6 +295,17 @@ defaultSignatures_[ResourceType_Study] = signatures_[ResourceType_Study]; defaultSignatures_[ResourceType_Series] = signatures_[ResourceType_Series]; defaultSignatures_[ResourceType_Instance] = signatures_[ResourceType_Instance]; + + // only add new tags here ! + // introduced in v 1.12.5 + AddMainDicomTagInternal(DICOM_TAG_TIMEZONE_OFFSET_FROM_UTC, ResourceType_Study); // used in default QIDO-RS queries + + AddMainDicomTagInternal(DICOM_TAG_TIMEZONE_OFFSET_FROM_UTC, ResourceType_Series); // used in default QIDO-RS queries + AddMainDicomTagInternal(DICOM_TAG_PERFORMED_PROCEDURE_STEP_START_DATE, ResourceType_Series); // used in default QIDO-RS queries + AddMainDicomTagInternal(DICOM_TAG_PERFORMED_PROCEDURE_STEP_START_TIME, ResourceType_Series); // used in default QIDO-RS queries + AddMainDicomTagInternal(DICOM_TAG_REQUEST_ATTRIBUTES_SEQUENCE, ResourceType_Series); // used in default QIDO-RS queries + + // TODO-FIND: remove it from metadata when adding it ! AddMainDicomTagInternal(DICOM_TAG_SOP_CLASS_UID, ResourceType_Instance); // previously saved in a metadata; makes more sense to store it in a DICOM tag } void AddMainDicomTag(const DicomTag& tag, diff -r 89a13d8ec80b -r a8055aebc6cb OrthancFramework/Sources/DicomFormat/DicomTag.h --- a/OrthancFramework/Sources/DicomFormat/DicomTag.h Wed Sep 18 10:38:42 2024 +0200 +++ b/OrthancFramework/Sources/DicomFormat/DicomTag.h Wed Sep 18 12:30:49 2024 +0200 @@ -157,7 +157,10 @@ static const DicomTag DICOM_TAG_REQUESTING_PHYSICIAN(0x0032, 0x1032); static const DicomTag DICOM_TAG_REFERRING_PHYSICIAN_NAME(0x0008, 0x0090); static const DicomTag DICOM_TAG_OPERATOR_NAME(0x0008, 0x1070); + static const DicomTag DICOM_TAG_PERFORMED_PROCEDURE_STEP_START_DATE(0x0040, 0x0244); + static const DicomTag DICOM_TAG_PERFORMED_PROCEDURE_STEP_START_TIME(0x0040, 0x0245); static const DicomTag DICOM_TAG_PERFORMED_PROCEDURE_STEP_DESCRIPTION(0x0040, 0x0254); + static const DicomTag DICOM_TAG_REQUEST_ATTRIBUTES_SEQUENCE(0x0040, 0x0275); static const DicomTag DICOM_TAG_IMAGE_COMMENTS(0x0020, 0x4000); static const DicomTag DICOM_TAG_ACQUISITION_DEVICE_PROCESSING_DESCRIPTION(0x0018, 0x1400); static const DicomTag DICOM_TAG_ACQUISITION_DEVICE_PROCESSING_CODE(0x0018, 0x1401); diff -r 89a13d8ec80b -r a8055aebc6cb OrthancFramework/UnitTestsSources/DicomMapTests.cpp --- a/OrthancFramework/UnitTestsSources/DicomMapTests.cpp Wed Sep 18 10:38:42 2024 +0200 +++ b/OrthancFramework/UnitTestsSources/DicomMapTests.cpp Wed Sep 18 12:30:49 2024 +0200 @@ -1085,7 +1085,7 @@ std::set tags; m.GetTags(tags); - // This corresponds to the values of DEFAULT_PATIENT_MAIN_DICOM_TAGS + // This corresponds to the values of DEFAULT_1_11_PATIENT_MAIN_DICOM_TAGS ASSERT_EQ(5u, tags.size()); ASSERT_EQ("", m.GetStringValue(DICOM_TAG_PATIENT_ID, "nope", false)); diff -r 89a13d8ec80b -r a8055aebc6cb OrthancServer/Sources/OrthancInitialization.cpp --- a/OrthancServer/Sources/OrthancInitialization.cpp Wed Sep 18 10:38:42 2024 +0200 +++ b/OrthancServer/Sources/OrthancInitialization.cpp Wed Sep 18 12:30:49 2024 +0200 @@ -261,7 +261,17 @@ { LOG(INFO) << " - " << tagName; } - DicomMap::AddMainDicomTag(tag, level); + + try + { + DicomMap::AddMainDicomTag(tag, level); + } + catch(OrthancException& e) + { + LOG(WARNING) << " - !!! " << tagName << " is already defined as a standard MainDicomTags, it is useless to include it in the ExtraMainDicomTags"; + } + + } } } diff -r 89a13d8ec80b -r a8055aebc6cb OrthancServer/Sources/ResourceFinder.cpp --- a/OrthancServer/Sources/ResourceFinder.cpp Wed Sep 18 10:38:42 2024 +0200 +++ b/OrthancServer/Sources/ResourceFinder.cpp Wed Sep 18 12:30:49 2024 +0200 @@ -1008,7 +1008,8 @@ InjectRequestedTags(outRequestedTags, remainingRequestedTags, resource, ResourceType_Series); InjectRequestedTags(outRequestedTags, remainingRequestedTags, resource, ResourceType_Instance); - if (!remainingRequestedTags.empty()) + if (!remainingRequestedTags.empty() && + !DicomMap::HasOnlyComputedTags(remainingRequestedTags)) // if the only remaining tags are computed tags, it is worthless to read them from disk { if (!allowStorageAccess_) {