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];