comparison OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp @ 5044:6fed78e13233

Refactored DicomMap to handle sequences when needed
author Alain Mazy <am@osimis.io>
date Tue, 28 Jun 2022 17:45:09 +0200
parents ec5c203a97ea
children e95fadefeb72
comparison
equal deleted inserted replaced
5043:ec5c203a97ea 5044:6fed78e13233
879 { 879 {
880 Json::Value jsonMetadata; 880 Json::Value jsonMetadata;
881 Toolbox::ReadJson(jsonMetadata, serializedSequences); 881 Toolbox::ReadJson(jsonMetadata, serializedSequences);
882 882
883 assert(jsonMetadata["Version"].asInt() == 1); 883 assert(jsonMetadata["Version"].asInt() == 1);
884 target.sequences_.Deserialize(jsonMetadata["Sequences"]); 884 target.tags_.FromDicomAsJson(jsonMetadata["Sequences"], true /* append */, true /* parseSequences */);
885 } 885 }
886 886
887 // check if we have access to all requestedTags or if we must get tags from parents 887 // check if we have access to all requestedTags or if we must get tags from parents
888 const std::set<DicomTag>& requestedTags = tuple.get<4>(); 888 const std::set<DicomTag>& requestedTags = tuple.get<4>();
889 889
2627 Operations operations(internalId, changeType, publicId, level); 2627 Operations operations(internalId, changeType, publicId, level);
2628 Apply(operations); 2628 Apply(operations);
2629 } 2629 }
2630 2630
2631 2631
2632 static void GetMainDicomSequenceMetadataContent(std::string& result,
2633 const DicomMap& dicomSummary,
2634 ResourceType level)
2635 {
2636 DicomMap levelSummary;
2637 DicomMap levelSequences;
2638
2639 dicomSummary.ExtractResourceInformation(levelSummary, level);
2640 levelSummary.ExtractSequences(levelSequences);
2641
2642 if (levelSequences.GetSize() > 0)
2643 {
2644 Json::Value jsonMetadata;
2645 jsonMetadata["Version"] = 1;
2646 jsonMetadata["Sequences"] = Json::objectValue;
2647 FromDcmtkBridge::ToJson(jsonMetadata["Sequences"], levelSequences, DicomToJsonFormat_Full);
2648
2649 Toolbox::WriteFastJson(result, jsonMetadata);
2650 }
2651 }
2652
2653
2632 void StatelessDatabaseOperations::ReconstructInstance(const ParsedDicomFile& dicom) 2654 void StatelessDatabaseOperations::ReconstructInstance(const ParsedDicomFile& dicom)
2633 { 2655 {
2634 class Operations : public IReadWriteOperations 2656 class Operations : public IReadWriteOperations
2635 { 2657 {
2636 private: 2658 private:
2655 { 2677 {
2656 transaction.SetMetadata(instance, metadata, value, 0); 2678 transaction.SetMetadata(instance, metadata, value, 0);
2657 } 2679 }
2658 } 2680 }
2659 2681
2682 static void SetMainDicomSequenceMetadata(ReadWriteTransaction& transaction,
2683 int64_t instance,
2684 const DicomMap& dicomSummary,
2685 ResourceType level)
2686 {
2687 std::string serialized;
2688 GetMainDicomSequenceMetadataContent(serialized, dicomSummary, level);
2689
2690 if (!serialized.empty())
2691 {
2692 ReplaceMetadata(transaction, instance, MetadataType_MainDicomSequences, serialized);
2693 }
2694 else
2695 {
2696 transaction.DeleteMetadata(instance, MetadataType_MainDicomSequences);
2697 }
2698
2699 }
2700
2660 public: 2701 public:
2661 explicit Operations(const ParsedDicomFile& dicom) 2702 explicit Operations(const ParsedDicomFile& dicom)
2662 { 2703 {
2663 OrthancConfiguration::DefaultExtractDicomSummary(summary_, dicom); 2704 OrthancConfiguration::DefaultExtractDicomSummary(summary_, dicom);
2664 hasher_.reset(new DicomInstanceHasher(summary_)); 2705 hasher_.reset(new DicomInstanceHasher(summary_));
2702 2743
2703 ReplaceMetadata(transaction, patient, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Patient)); // New in Orthanc 1.11.0 2744 ReplaceMetadata(transaction, patient, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Patient)); // New in Orthanc 1.11.0
2704 ReplaceMetadata(transaction, study, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Study)); // New in Orthanc 1.11.0 2745 ReplaceMetadata(transaction, study, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Study)); // New in Orthanc 1.11.0
2705 ReplaceMetadata(transaction, series, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Series)); // New in Orthanc 1.11.0 2746 ReplaceMetadata(transaction, series, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Series)); // New in Orthanc 1.11.0
2706 ReplaceMetadata(transaction, instance, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Instance)); // New in Orthanc 1.11.0 2747 ReplaceMetadata(transaction, instance, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Instance)); // New in Orthanc 1.11.0
2748
2749 SetMainDicomSequenceMetadata(transaction, patient, summary_, ResourceType_Patient);
2750 SetMainDicomSequenceMetadata(transaction, study, summary_, ResourceType_Study);
2751 SetMainDicomSequenceMetadata(transaction, series, summary_, ResourceType_Series);
2752 SetMainDicomSequenceMetadata(transaction, instance, summary_, ResourceType_Instance);
2707 } 2753 }
2708 2754
2709 if (hasTransferSyntax_) 2755 if (hasTransferSyntax_)
2710 { 2756 {
2711 ReplaceMetadata(transaction, instance, MetadataType_Instance_TransferSyntax, GetTransferSyntaxUid(transferSyntax_)); 2757 ReplaceMetadata(transaction, instance, MetadataType_Instance_TransferSyntax, GetTransferSyntaxUid(transferSyntax_));
2850 } 2896 }
2851 2897
2852 2898
2853 StoreStatus StatelessDatabaseOperations::Store(std::map<MetadataType, std::string>& instanceMetadata, 2899 StoreStatus StatelessDatabaseOperations::Store(std::map<MetadataType, std::string>& instanceMetadata,
2854 const DicomMap& dicomSummary, 2900 const DicomMap& dicomSummary,
2855 const DicomSequencesMap& sequencesToStore,
2856 const Attachments& attachments, 2901 const Attachments& attachments,
2857 const MetadataMap& metadata, 2902 const MetadataMap& metadata,
2858 const DicomInstanceOrigin& origin, 2903 const DicomInstanceOrigin& origin,
2859 bool overwrite, 2904 bool overwrite,
2860 bool hasTransferSyntax, 2905 bool hasTransferSyntax,
2869 { 2914 {
2870 private: 2915 private:
2871 StoreStatus storeStatus_; 2916 StoreStatus storeStatus_;
2872 std::map<MetadataType, std::string>& instanceMetadata_; 2917 std::map<MetadataType, std::string>& instanceMetadata_;
2873 const DicomMap& dicomSummary_; 2918 const DicomMap& dicomSummary_;
2874 const DicomSequencesMap& sequencesToStore_;
2875 const Attachments& attachments_; 2919 const Attachments& attachments_;
2876 const MetadataMap& metadata_; 2920 const MetadataMap& metadata_;
2877 const DicomInstanceOrigin& origin_; 2921 const DicomInstanceOrigin& origin_;
2878 bool overwrite_; 2922 bool overwrite_;
2879 bool hasTransferSyntax_; 2923 bool hasTransferSyntax_;
2902 content.AddMetadata(instance, metadata, value); 2946 content.AddMetadata(instance, metadata, value);
2903 instanceMetadata[metadata] = value; 2947 instanceMetadata[metadata] = value;
2904 } 2948 }
2905 2949
2906 static void SetMainDicomSequenceMetadata(ResourcesContent& content, 2950 static void SetMainDicomSequenceMetadata(ResourcesContent& content,
2907 int64_t resource, 2951 int64_t resource,
2908 const DicomSequencesMap& sequencesToStore, // all sequences for all levels ! 2952 const DicomMap& dicomSummary,
2909 ResourceType level) 2953 ResourceType level)
2910 { 2954 {
2911 if (sequencesToStore.GetSize() > 0) 2955 std::string serialized;
2912 { 2956 GetMainDicomSequenceMetadataContent(serialized, dicomSummary, level);
2913 const std::set<DicomTag>& levelTags = DicomMap::GetMainDicomTags(level); 2957
2914 std::set<DicomTag> levelSequences; 2958 if (!serialized.empty())
2915 DicomMap::ExtractSequences(levelSequences, levelTags); 2959 {
2916
2917 if (levelSequences.size() == 0)
2918 {
2919 return;
2920 }
2921
2922 Json::Value jsonMetadata;
2923 jsonMetadata["Version"] = 1;
2924 jsonMetadata["Sequences"] = Json::objectValue;
2925 sequencesToStore.Serialize(jsonMetadata["Sequences"], levelSequences);
2926
2927 std::string serialized;
2928 Toolbox::WriteFastJson(serialized, jsonMetadata);
2929
2930 content.AddMetadata(resource, MetadataType_MainDicomSequences, serialized); 2960 content.AddMetadata(resource, MetadataType_MainDicomSequences, serialized);
2931 } 2961 }
2932
2933 } 2962 }
2934 2963
2935 static bool ComputeExpectedNumberOfInstances(int64_t& target, 2964 static bool ComputeExpectedNumberOfInstances(int64_t& target,
2936 const DicomMap& dicomSummary) 2965 const DicomMap& dicomSummary)
2937 { 2966 {
2987 } 3016 }
2988 3017
2989 public: 3018 public:
2990 Operations(std::map<MetadataType, std::string>& instanceMetadata, 3019 Operations(std::map<MetadataType, std::string>& instanceMetadata,
2991 const DicomMap& dicomSummary, 3020 const DicomMap& dicomSummary,
2992 const DicomSequencesMap& sequencesToStore,
2993 const Attachments& attachments, 3021 const Attachments& attachments,
2994 const MetadataMap& metadata, 3022 const MetadataMap& metadata,
2995 const DicomInstanceOrigin& origin, 3023 const DicomInstanceOrigin& origin,
2996 bool overwrite, 3024 bool overwrite,
2997 bool hasTransferSyntax, 3025 bool hasTransferSyntax,
3002 unsigned int maximumPatientCount, 3030 unsigned int maximumPatientCount,
3003 bool isReconstruct) : 3031 bool isReconstruct) :
3004 storeStatus_(StoreStatus_Failure), 3032 storeStatus_(StoreStatus_Failure),
3005 instanceMetadata_(instanceMetadata), 3033 instanceMetadata_(instanceMetadata),
3006 dicomSummary_(dicomSummary), 3034 dicomSummary_(dicomSummary),
3007 sequencesToStore_(sequencesToStore),
3008 attachments_(attachments), 3035 attachments_(attachments),
3009 metadata_(metadata), 3036 metadata_(metadata),
3010 origin_(origin), 3037 origin_(origin),
3011 overwrite_(overwrite), 3038 overwrite_(overwrite),
3012 hasTransferSyntax_(hasTransferSyntax), 3039 hasTransferSyntax_(hasTransferSyntax),
3153 3180
3154 // Populate the tags of the newly-created resources 3181 // Populate the tags of the newly-created resources
3155 3182
3156 content.AddResource(instanceId, ResourceType_Instance, dicomSummary_); 3183 content.AddResource(instanceId, ResourceType_Instance, dicomSummary_);
3157 SetInstanceMetadata(content, instanceMetadata_, instanceId, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Instance)); // New in Orthanc 1.11.0 3184 SetInstanceMetadata(content, instanceMetadata_, instanceId, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Instance)); // New in Orthanc 1.11.0
3158 SetMainDicomSequenceMetadata(content, instanceId, sequencesToStore_, ResourceType_Instance); // new in Orthanc 1.11.1 3185 SetMainDicomSequenceMetadata(content, instanceId, dicomSummary_, ResourceType_Instance); // new in Orthanc 1.11.1
3159 3186
3160 if (status.isNewSeries_) 3187 if (status.isNewSeries_)
3161 { 3188 {
3162 content.AddResource(status.seriesId_, ResourceType_Series, dicomSummary_); 3189 content.AddResource(status.seriesId_, ResourceType_Series, dicomSummary_);
3163 content.AddMetadata(status.seriesId_, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Series)); // New in Orthanc 1.11.0 3190 content.AddMetadata(status.seriesId_, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Series)); // New in Orthanc 1.11.0
3164 SetMainDicomSequenceMetadata(content, status.seriesId_, sequencesToStore_, ResourceType_Series); // new in Orthanc 1.11.1 3191 SetMainDicomSequenceMetadata(content, status.seriesId_, dicomSummary_, ResourceType_Series); // new in Orthanc 1.11.1
3165 } 3192 }
3166 3193
3167 if (status.isNewStudy_) 3194 if (status.isNewStudy_)
3168 { 3195 {
3169 content.AddResource(status.studyId_, ResourceType_Study, dicomSummary_); 3196 content.AddResource(status.studyId_, ResourceType_Study, dicomSummary_);
3170 content.AddMetadata(status.studyId_, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Study)); // New in Orthanc 1.11.0 3197 content.AddMetadata(status.studyId_, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Study)); // New in Orthanc 1.11.0
3171 SetMainDicomSequenceMetadata(content, status.studyId_, sequencesToStore_, ResourceType_Study); // new in Orthanc 1.11.1 3198 SetMainDicomSequenceMetadata(content, status.studyId_, dicomSummary_, ResourceType_Study); // new in Orthanc 1.11.1
3172 } 3199 }
3173 3200
3174 if (status.isNewPatient_) 3201 if (status.isNewPatient_)
3175 { 3202 {
3176 content.AddResource(status.patientId_, ResourceType_Patient, dicomSummary_); 3203 content.AddResource(status.patientId_, ResourceType_Patient, dicomSummary_);
3177 content.AddMetadata(status.patientId_, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Patient)); // New in Orthanc 1.11.0 3204 content.AddMetadata(status.patientId_, MetadataType_MainDicomTagsSignature, DicomMap::GetMainDicomTagsSignature(ResourceType_Patient)); // New in Orthanc 1.11.0
3178 SetMainDicomSequenceMetadata(content, status.patientId_, sequencesToStore_, ResourceType_Patient); // new in Orthanc 1.11.1 3205 SetMainDicomSequenceMetadata(content, status.patientId_, dicomSummary_, ResourceType_Patient); // new in Orthanc 1.11.1
3179 } 3206 }
3180 3207
3181 // Attach the auto-computed metadata for the patient/study/series levels 3208 // Attach the auto-computed metadata for the patient/study/series levels
3182 std::string now = SystemToolbox::GetNowIsoString(true /* use UTC time (not local time) */); 3209 std::string now = SystemToolbox::GetNowIsoString(true /* use UTC time (not local time) */);
3183 content.AddMetadata(status.seriesId_, MetadataType_LastUpdate, now); 3210 content.AddMetadata(status.seriesId_, MetadataType_LastUpdate, now);
3318 } 3345 }
3319 } 3346 }
3320 }; 3347 };
3321 3348
3322 3349
3323 Operations operations(instanceMetadata, dicomSummary, sequencesToStore, attachments, metadata, origin, 3350 Operations operations(instanceMetadata, dicomSummary, attachments, metadata, origin,
3324 overwrite, hasTransferSyntax, transferSyntax, hasPixelDataOffset, 3351 overwrite, hasTransferSyntax, transferSyntax, hasPixelDataOffset,
3325 pixelDataOffset, maximumStorageSize, maximumPatients, isReconstruct); 3352 pixelDataOffset, maximumStorageSize, maximumPatients, isReconstruct);
3326 Apply(operations); 3353 Apply(operations);
3327 return operations.GetStoreStatus(); 3354 return operations.GetStoreStatus();
3328 } 3355 }