Mercurial > hg > orthanc-ohif
comparison Sources/Plugin.cpp @ 44:9afd691bfb74
added tags: RescaleIntercept, RescaleSlope, and NumberOfFrames
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 03 May 2024 13:02:51 +0200 |
parents | f3dc8ecf4349 |
children | 63a392fbf14e |
comparison
equal
deleted
inserted
replaced
43:f3dc8ecf4349 | 44:9afd691bfb74 |
---|---|
25 #include "../Resources/Orthanc/Plugins/OrthancPluginCppWrapper.h" | 25 #include "../Resources/Orthanc/Plugins/OrthancPluginCppWrapper.h" |
26 | 26 |
27 #include <Compression/GzipCompressor.h> | 27 #include <Compression/GzipCompressor.h> |
28 #include <DicomFormat/DicomInstanceHasher.h> | 28 #include <DicomFormat/DicomInstanceHasher.h> |
29 #include <DicomFormat/DicomMap.h> | 29 #include <DicomFormat/DicomMap.h> |
30 #include <Logging.h> | |
30 #include <MultiThreading/SharedMessageQueue.h> | 31 #include <MultiThreading/SharedMessageQueue.h> |
31 #include <SerializationToolbox.h> | 32 #include <SerializationToolbox.h> |
32 #include <SystemToolbox.h> | 33 #include <SystemToolbox.h> |
33 #include <Toolbox.h> | 34 #include <Toolbox.h> |
34 | 35 |
111 { | 112 { |
112 /** | 113 /** |
113 * Those are the tags that are found in the documentation of the | 114 * Those are the tags that are found in the documentation of the |
114 * "DICOM JSON" data source: | 115 * "DICOM JSON" data source: |
115 * https://docs.ohif.org/configuration/dataSources/dicom-json | 116 * https://docs.ohif.org/configuration/dataSources/dicom-json |
117 * | |
118 * Official list of tags: | |
119 * https://github.com/OHIF/Viewers/blob/master/platform/docs/docs/faq.md#what-are-the-list-of-required-metadata-for-the-ohif-viewer-to-work | |
120 * | |
121 * Official example: | |
122 * https://ohif-dicom-json-example.s3.amazonaws.com/LIDC-IDRI-0001.json | |
116 **/ | 123 **/ |
117 ohifStudyTags_[Orthanc::DICOM_TAG_STUDY_INSTANCE_UID] = TagInformation(DataType_String, "StudyInstanceUID"); | 124 ohifStudyTags_[Orthanc::DICOM_TAG_STUDY_INSTANCE_UID] = TagInformation(DataType_String, "StudyInstanceUID"); |
118 ohifStudyTags_[Orthanc::DICOM_TAG_STUDY_DATE] = TagInformation(DataType_String, "StudyDate"); | 125 ohifStudyTags_[Orthanc::DICOM_TAG_STUDY_DATE] = TagInformation(DataType_String, "StudyDate"); |
119 ohifStudyTags_[Orthanc::DICOM_TAG_STUDY_TIME] = TagInformation(DataType_String, "StudyTime"); | 126 ohifStudyTags_[Orthanc::DICOM_TAG_STUDY_TIME] = TagInformation(DataType_String, "StudyTime"); |
120 ohifStudyTags_[Orthanc::DICOM_TAG_STUDY_DESCRIPTION] = TagInformation(DataType_String, "StudyDescription"); | 127 ohifStudyTags_[Orthanc::DICOM_TAG_STUDY_DESCRIPTION] = TagInformation(DataType_String, "StudyDescription"); |
168 ohifInstanceTags_[Orthanc::DicomTag(0x0054, 0x1001)] = TagInformation(DataType_String, "Units"); | 175 ohifInstanceTags_[Orthanc::DicomTag(0x0054, 0x1001)] = TagInformation(DataType_String, "Units"); |
169 ohifInstanceTags_[Orthanc::DicomTag(0x0054, 0x1102)] = TagInformation(DataType_String, "DecayCorrection"); | 176 ohifInstanceTags_[Orthanc::DicomTag(0x0054, 0x1102)] = TagInformation(DataType_String, "DecayCorrection"); |
170 ohifInstanceTags_[Orthanc::DicomTag(0x0054, 0x1300)] = TagInformation(DataType_Float, "FrameReferenceTime"); | 177 ohifInstanceTags_[Orthanc::DicomTag(0x0054, 0x1300)] = TagInformation(DataType_Float, "FrameReferenceTime"); |
171 ohifInstanceTags_[RADIOPHARMACEUTICAL_INFORMATION_SEQUENCE] = TagInformation(DataType_None, "RadiopharmaceuticalInformationSequence"); | 178 ohifInstanceTags_[RADIOPHARMACEUTICAL_INFORMATION_SEQUENCE] = TagInformation(DataType_None, "RadiopharmaceuticalInformationSequence"); |
172 | 179 |
180 /** | |
181 * Added in version 1.3 | |
182 **/ | |
183 ohifInstanceTags_[Orthanc::DICOM_TAG_RESCALE_INTERCEPT] = TagInformation(DataType_Float, "RescaleIntercept"); | |
184 ohifInstanceTags_[Orthanc::DICOM_TAG_RESCALE_SLOPE] = TagInformation(DataType_Float, "RescaleSlope"); | |
185 ohifInstanceTags_[Orthanc::DICOM_TAG_NUMBER_OF_FRAMES] = TagInformation(DataType_Integer, "NumberOfFrames"); | |
186 | |
187 | |
173 // UNTESTED | 188 // UNTESTED |
174 ohifInstanceTags_[Orthanc::DicomTag(0x7053, 0x1000)] = TagInformation(DataType_Float, "70531000"); // Philips SUVScaleFactor | 189 ohifInstanceTags_[Orthanc::DicomTag(0x7053, 0x1000)] = TagInformation(DataType_Float, "70531000"); // Philips SUVScaleFactor |
175 ohifInstanceTags_[Orthanc::DicomTag(0x7053, 0x1009)] = TagInformation(DataType_Float, "70531009"); // Philips ActivityConcentrationScaleFactor | 190 ohifInstanceTags_[Orthanc::DicomTag(0x7053, 0x1009)] = TagInformation(DataType_Float, "70531009"); // Philips ActivityConcentrationScaleFactor |
176 ohifInstanceTags_[Orthanc::DicomTag(0x0009, 0x100d)] = TagInformation(DataType_String, "0009100d"); // GE PrivatePostInjectionDateTime | 191 ohifInstanceTags_[Orthanc::DicomTag(0x0009, 0x100d)] = TagInformation(DataType_String, "0009100d"); // GE PrivatePostInjectionDateTime |
177 | 192 |
308 target[name] = value; | 323 target[name] = value; |
309 return true; | 324 return true; |
310 | 325 |
311 case DataType_Integer: | 326 case DataType_Integer: |
312 { | 327 { |
313 int32_t v; | 328 std::vector<std::string> tokens; |
314 if (Orthanc::SerializationToolbox::ParseInteger32(v, value.asString())) | 329 Orthanc::Toolbox::TokenizeString(tokens, value.asString(), '\\'); |
315 { | 330 |
316 target[name] = v; | 331 if (!tokens.empty()) |
317 } | 332 { |
318 return true; | 333 int32_t v; |
334 if (Orthanc::SerializationToolbox::ParseInteger32(v, tokens[0])) | |
335 { | |
336 target[name] = v; | |
337 } | |
338 return true; | |
339 } | |
340 else | |
341 { | |
342 return false; | |
343 } | |
319 } | 344 } |
320 | 345 |
321 case DataType_Float: | 346 case DataType_Float: |
322 { | 347 { |
323 float v; | 348 std::vector<std::string> tokens; |
324 if (Orthanc::SerializationToolbox::ParseFloat(v, value.asString())) | 349 Orthanc::Toolbox::TokenizeString(tokens, value.asString(), '\\'); |
325 { | 350 |
326 target[name] = v; | 351 if (!tokens.empty()) |
327 } | 352 { |
328 return true; | 353 float v; |
354 if (Orthanc::SerializationToolbox::ParseFloat(v, tokens[0])) | |
355 { | |
356 target[name] = v; | |
357 } | |
358 return true; | |
359 } | |
360 else | |
361 { | |
362 return false; | |
363 } | |
329 } | 364 } |
330 | 365 |
331 case DataType_ListOfStrings: | 366 case DataType_ListOfStrings: |
332 { | 367 { |
333 std::vector<std::string> tokens; | 368 std::vector<std::string> tokens; |
455 | 490 |
456 | 491 |
457 static bool GetOhifInstance(Json::Value& target, | 492 static bool GetOhifInstance(Json::Value& target, |
458 const std::string& instanceId) | 493 const std::string& instanceId) |
459 { | 494 { |
495 #if 0 | |
496 // This disables all the caching (for debugging) | |
497 return EncodeOhifInstance(target, instanceId); | |
498 #else | |
460 const std::string uri = GetCacheUri(instanceId); | 499 const std::string uri = GetCacheUri(instanceId); |
461 | 500 |
462 std::string metadata; | 501 std::string metadata; |
463 | 502 |
464 if (OrthancPlugins::RestApiGetString(metadata, uri, false)) | 503 if (OrthancPlugins::RestApiGetString(metadata, uri, false)) |
496 } | 535 } |
497 else | 536 else |
498 { | 537 { |
499 return false; | 538 return false; |
500 } | 539 } |
540 #endif | |
501 } | 541 } |
502 | 542 |
503 | 543 |
504 static ResourcesCache cache_; | 544 static ResourcesCache cache_; |
505 static std::string userConfiguration_; | 545 static std::string userConfiguration_; |
658 } | 698 } |
659 } | 699 } |
660 | 700 |
661 study["series"] = Json::arrayValue; | 701 study["series"] = Json::arrayValue; |
662 | 702 |
703 std::set<std::string> modalities; | |
704 unsigned int countInstances = 0; | |
705 | |
663 for (MapOfResources::const_iterator it3 = seriesInStudy.begin(); it3 != seriesInStudy.end(); ++it3) | 706 for (MapOfResources::const_iterator it3 = seriesInStudy.begin(); it3 != seriesInStudy.end(); ++it3) |
664 { | 707 { |
665 if (!it3->second.empty()) | 708 if (!it3->second.empty()) |
666 { | 709 { |
667 assert(it3->second.front() != NULL); | 710 assert(it3->second.front() != NULL); |
668 const Json::Value& firstInstanceInSeries = *it3->second.front(); | 711 const Json::Value& firstInstanceInSeries = *it3->second.front(); |
669 | 712 |
713 if (firstInstanceInSeries.isMember(Orthanc::DICOM_TAG_MODALITY.Format())) | |
714 { | |
715 modalities.insert(firstInstanceInSeries[Orthanc::DICOM_TAG_MODALITY.Format()].asString()); | |
716 } | |
717 | |
670 Json::Value series = Json::objectValue; | 718 Json::Value series = Json::objectValue; |
671 for (TagsDictionary::const_iterator tag = ohifSeriesTags_.begin(); tag != ohifSeriesTags_.end(); ++tag) | 719 for (TagsDictionary::const_iterator tag = ohifSeriesTags_.begin(); tag != ohifSeriesTags_.end(); ++tag) |
672 { | 720 { |
673 if (firstInstanceInSeries.isMember(tag->first.Format())) | 721 if (firstInstanceInSeries.isMember(tag->first.Format())) |
674 { | 722 { |
700 Json::Value instance = Json::objectValue; | 748 Json::Value instance = Json::objectValue; |
701 instance["metadata"] = metadata; | 749 instance["metadata"] = metadata; |
702 instance["url"] = "dicomweb:../instances/" + hasher.HashInstance() + "/file"; | 750 instance["url"] = "dicomweb:../instances/" + hasher.HashInstance() + "/file"; |
703 | 751 |
704 series["instances"].append(instance); | 752 series["instances"].append(instance); |
753 countInstances++; | |
705 } | 754 } |
706 | 755 |
707 study["series"].append(series); | 756 study["series"].append(series); |
708 } | 757 } |
709 } | 758 } |
759 | |
760 std::string jsonModalities; | |
761 for (std::set<std::string>::const_iterator it = modalities.begin(); it != modalities.end(); ++it) | |
762 { | |
763 if (!jsonModalities.empty()) | |
764 { | |
765 jsonModalities += ","; | |
766 } | |
767 jsonModalities += *it; | |
768 } | |
769 | |
770 study["NumInstances"] = countInstances; | |
771 study["Modalities"] = jsonModalities; | |
710 | 772 |
711 target["studies"].append(study); | 773 target["studies"].append(study); |
712 } | 774 } |
713 } | 775 } |
714 } | 776 } |
853 extern "C" | 915 extern "C" |
854 { | 916 { |
855 ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* context) | 917 ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* context) |
856 { | 918 { |
857 OrthancPlugins::SetGlobalContext(context, ORTHANC_PLUGIN_NAME); | 919 OrthancPlugins::SetGlobalContext(context, ORTHANC_PLUGIN_NAME); |
920 | |
921 #if ORTHANC_FRAMEWORK_VERSION_IS_ABOVE(1, 12, 4) | |
922 Orthanc::Logging::InitializePluginContext(context, ORTHANC_PLUGIN_NAME); | |
923 #elif ORTHANC_FRAMEWORK_VERSION_IS_ABOVE(1, 7, 2) | |
924 Orthanc::Logging::InitializePluginContext(context); | |
925 #else | |
926 Orthanc::Logging::Initialize(context); | |
927 #endif | |
858 | 928 |
859 /* Check the version of the Orthanc core */ | 929 /* Check the version of the Orthanc core */ |
860 if (OrthancPluginCheckVersion(context) == 0) | 930 if (OrthancPluginCheckVersion(context) == 0) |
861 { | 931 { |
862 char info[1024]; | 932 char info[1024]; |