# HG changeset patch # User Sebastien Jodogne # Date 1714734171 -7200 # Node ID 9afd691bfb749d2a8b775803a1f2f483a54ce509 # Parent f3dc8ecf4349ce1826ae78be80bc61686e33abe9 added tags: RescaleIntercept, RescaleSlope, and NumberOfFrames diff -r f3dc8ecf4349 -r 9afd691bfb74 Resources/ClearMetadataCache.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/ClearMetadataCache.py Fri May 03 13:02:51 2024 +0200 @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 + +import argparse +import requests + +parser = argparse.ArgumentParser(description = 'Clear the cache of the OHIF plugin (for "dicom-json" data source).') +parser.add_argument('--url', + default = 'http://localhost:8042', + help = 'URL to the REST API of the Orthanc server') +parser.add_argument('--username', + default = 'orthanc', + help = 'Username to the REST API') +parser.add_argument('--password', + default = 'orthanc', + help = 'Password to the REST API') + +args = parser.parse_args() + +auth = requests.auth.HTTPBasicAuth(args.username, args.password) + +METADATA = '4202' + +for instance in requests.get('%s/instances' % args.url, auth=auth).json(): + if METADATA in requests.get('%s/instances/%s/metadata' % (args.url, instance), auth=auth).json(): + requests.delete('%s/instances/%s/metadata/%s' % (args.url, instance, METADATA), auth=auth) diff -r f3dc8ecf4349 -r 9afd691bfb74 Sources/Plugin.cpp --- a/Sources/Plugin.cpp Fri May 03 10:00:37 2024 +0200 +++ b/Sources/Plugin.cpp Fri May 03 13:02:51 2024 +0200 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -113,6 +114,12 @@ * Those are the tags that are found in the documentation of the * "DICOM JSON" data source: * https://docs.ohif.org/configuration/dataSources/dicom-json + * + * Official list of tags: + * 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 + * + * Official example: + * https://ohif-dicom-json-example.s3.amazonaws.com/LIDC-IDRI-0001.json **/ ohifStudyTags_[Orthanc::DICOM_TAG_STUDY_INSTANCE_UID] = TagInformation(DataType_String, "StudyInstanceUID"); ohifStudyTags_[Orthanc::DICOM_TAG_STUDY_DATE] = TagInformation(DataType_String, "StudyDate"); @@ -170,6 +177,14 @@ ohifInstanceTags_[Orthanc::DicomTag(0x0054, 0x1300)] = TagInformation(DataType_Float, "FrameReferenceTime"); ohifInstanceTags_[RADIOPHARMACEUTICAL_INFORMATION_SEQUENCE] = TagInformation(DataType_None, "RadiopharmaceuticalInformationSequence"); + /** + * Added in version 1.3 + **/ + ohifInstanceTags_[Orthanc::DICOM_TAG_RESCALE_INTERCEPT] = TagInformation(DataType_Float, "RescaleIntercept"); + ohifInstanceTags_[Orthanc::DICOM_TAG_RESCALE_SLOPE] = TagInformation(DataType_Float, "RescaleSlope"); + ohifInstanceTags_[Orthanc::DICOM_TAG_NUMBER_OF_FRAMES] = TagInformation(DataType_Integer, "NumberOfFrames"); + + // UNTESTED ohifInstanceTags_[Orthanc::DicomTag(0x7053, 0x1000)] = TagInformation(DataType_Float, "70531000"); // Philips SUVScaleFactor ohifInstanceTags_[Orthanc::DicomTag(0x7053, 0x1009)] = TagInformation(DataType_Float, "70531009"); // Philips ActivityConcentrationScaleFactor @@ -310,22 +325,42 @@ case DataType_Integer: { - int32_t v; - if (Orthanc::SerializationToolbox::ParseInteger32(v, value.asString())) + std::vector tokens; + Orthanc::Toolbox::TokenizeString(tokens, value.asString(), '\\'); + + if (!tokens.empty()) { - target[name] = v; + int32_t v; + if (Orthanc::SerializationToolbox::ParseInteger32(v, tokens[0])) + { + target[name] = v; + } + return true; } - return true; + else + { + return false; + } } case DataType_Float: { - float v; - if (Orthanc::SerializationToolbox::ParseFloat(v, value.asString())) + std::vector tokens; + Orthanc::Toolbox::TokenizeString(tokens, value.asString(), '\\'); + + if (!tokens.empty()) { - target[name] = v; + float v; + if (Orthanc::SerializationToolbox::ParseFloat(v, tokens[0])) + { + target[name] = v; + } + return true; } - return true; + else + { + return false; + } } case DataType_ListOfStrings: @@ -457,6 +492,10 @@ static bool GetOhifInstance(Json::Value& target, const std::string& instanceId) { +#if 0 + // This disables all the caching (for debugging) + return EncodeOhifInstance(target, instanceId); +#else const std::string uri = GetCacheUri(instanceId); std::string metadata; @@ -498,6 +537,7 @@ { return false; } +#endif } @@ -660,6 +700,9 @@ study["series"] = Json::arrayValue; + std::set modalities; + unsigned int countInstances = 0; + for (MapOfResources::const_iterator it3 = seriesInStudy.begin(); it3 != seriesInStudy.end(); ++it3) { if (!it3->second.empty()) @@ -667,6 +710,11 @@ assert(it3->second.front() != NULL); const Json::Value& firstInstanceInSeries = *it3->second.front(); + if (firstInstanceInSeries.isMember(Orthanc::DICOM_TAG_MODALITY.Format())) + { + modalities.insert(firstInstanceInSeries[Orthanc::DICOM_TAG_MODALITY.Format()].asString()); + } + Json::Value series = Json::objectValue; for (TagsDictionary::const_iterator tag = ohifSeriesTags_.begin(); tag != ohifSeriesTags_.end(); ++tag) { @@ -702,12 +750,26 @@ instance["url"] = "dicomweb:../instances/" + hasher.HashInstance() + "/file"; series["instances"].append(instance); + countInstances++; } study["series"].append(series); } } + std::string jsonModalities; + for (std::set::const_iterator it = modalities.begin(); it != modalities.end(); ++it) + { + if (!jsonModalities.empty()) + { + jsonModalities += ","; + } + jsonModalities += *it; + } + + study["NumInstances"] = countInstances; + study["Modalities"] = jsonModalities; + target["studies"].append(study); } } @@ -856,6 +918,14 @@ { OrthancPlugins::SetGlobalContext(context, ORTHANC_PLUGIN_NAME); +#if ORTHANC_FRAMEWORK_VERSION_IS_ABOVE(1, 12, 4) + Orthanc::Logging::InitializePluginContext(context, ORTHANC_PLUGIN_NAME); +#elif ORTHANC_FRAMEWORK_VERSION_IS_ABOVE(1, 7, 2) + Orthanc::Logging::InitializePluginContext(context); +#else + Orthanc::Logging::Initialize(context); +#endif + /* Check the version of the Orthanc core */ if (OrthancPluginCheckVersion(context) == 0) {