changeset 2216:9a8fab016145

sample worklist plugin fine-tuning the C-Find query
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 12 Dec 2016 11:01:09 +0100
parents 028214a95194
children 4f39ab2cb453
files OrthancServer/FromDcmtkBridge.cpp Plugins/Include/orthanc/OrthancCPlugin.h Plugins/Samples/ModalityWorklists/Plugin.cpp
diffstat 3 files changed, 75 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancServer/FromDcmtkBridge.cpp	Sat Dec 10 11:41:17 2016 +0100
+++ b/OrthancServer/FromDcmtkBridge.cpp	Mon Dec 12 11:01:09 2016 +0100
@@ -1646,7 +1646,9 @@
 
     if (!ok)
     {
-      throw OrthancException(ErrorCode_InternalError);
+      LOG(ERROR) << "While creating a DICOM instance, tag (" << tag.Format()
+                 << ") has out-of-range value: \"" << *decoded << "\"";
+      throw OrthancException(ErrorCode_BadFileFormat);
     }
   }
 
@@ -1665,6 +1667,11 @@
         FillElementWithString(*element, tag, value.asString(), decodeDataUriScheme, dicomEncoding);
         break;
 
+      case Json::nullValue:
+        element.reset(CreateElementForTag(tag));
+        FillElementWithString(*element, tag, "", decodeDataUriScheme, dicomEncoding);
+        break;
+
       case Json::arrayValue:
       {
         DcmTag key(tag.GetGroup(), tag.GetElement());
@@ -1742,11 +1749,17 @@
       {
         const Json::Value& value = json[tags[i]];
         if (value.type() != Json::stringValue ||
-            !GetDicomEncoding(encoding, value.asCString()))
+            (value.asString().length() != 0 &&
+             !GetDicomEncoding(encoding, value.asCString())))
         {
           LOG(ERROR) << "Unknown encoding while creating DICOM from JSON: " << value;
           throw OrthancException(ErrorCode_BadRequest);
         }
+
+        if (value.asString().length() == 0)
+        {
+          return defaultEncoding;
+        }
       }
     }
 
--- a/Plugins/Include/orthanc/OrthancCPlugin.h	Sat Dec 10 11:41:17 2016 +0100
+++ b/Plugins/Include/orthanc/OrthancCPlugin.h	Mon Dec 12 11:01:09 2016 +0100
@@ -717,6 +717,7 @@
    **/
   typedef enum
   {
+    OrthancPluginDicomToJsonFlags_None                  = 0,
     OrthancPluginDicomToJsonFlags_IncludeBinary         = (1 << 0),  /*!< Include the binary tags */
     OrthancPluginDicomToJsonFlags_IncludePrivateTags    = (1 << 1),  /*!< Include the private tags */
     OrthancPluginDicomToJsonFlags_IncludeUnknownTags    = (1 << 2),  /*!< Include the tags unknown by the dictionary */
@@ -735,6 +736,7 @@
    **/
   typedef enum
   {
+    OrthancPluginCreateDicomFlags_None                  = 0,
     OrthancPluginCreateDicomFlags_DecodeDataUriScheme   = (1 << 0),  /*!< Decode fields encoded using data URI scheme */
     OrthancPluginCreateDicomFlags_GenerateIdentifiers   = (1 << 1),  /*!< Automatically generate DICOM identifiers */
 
--- a/Plugins/Samples/ModalityWorklists/Plugin.cpp	Sat Dec 10 11:41:17 2016 +0100
+++ b/Plugins/Samples/ModalityWorklists/Plugin.cpp	Mon Dec 12 11:01:09 2016 +0100
@@ -57,23 +57,71 @@
 }
 
 
-OrthancPlugins::FindMatcher* CreateMatcher(const OrthancPluginWorklistQuery* query,
-                                           const char*                       remoteAet)
+static OrthancPlugins::FindMatcher* CreateMatcher(const OrthancPluginWorklistQuery* query,
+                                                  const char*                       remoteAet)
 {
+  // Extract the DICOM instance underlying the C-Find query
   OrthancPlugins::MemoryBuffer dicom(context_);
   dicom.GetDicomQuery(query);
 
+  // Convert the DICOM as JSON, and dump it to the user in "--verbose" mode
+  Json::Value json;
+  dicom.DicomToJson(json, OrthancPluginDicomToJsonFormat_Short, 
+                    static_cast<OrthancPluginDicomToJsonFlags>(0), 0);
+  
+  OrthancPlugins::LogInfo(context_, "Received worklist query from remote modality " + 
+                          std::string(remoteAet) + ":\n" + json.toStyledString());
+
+#if 1
+  return new OrthancPlugins::FindMatcher(context_, query);
+
+#else
+  // Alternative sample showing how to fine-tune an incoming C-Find
+  // request, before matching it against the worklist database. The
+  // code below will restrict the original DICOM request by requesting
+  // the ScheduledStationAETitle to correspond to the AET of the
+  // issuer. This code will make the integration test "test_other_aet"
+  // succeed (cf. the orthanc-tests repository).
+
+  static const char* SCHEDULED_PROCEDURE_STEP_SEQUENCE = "0040,0100";
+  static const char* SCHEDULED_STATION_AETITLE = "0040,0001";
+
+  if (!json.isMember(SCHEDULED_PROCEDURE_STEP_SEQUENCE))
   {
-    Json::Value json;
-    dicom.DicomToJson(json, OrthancPluginDicomToJsonFormat_Short, 
-                      static_cast<OrthancPluginDicomToJsonFlags>(0), 0);
-
-    OrthancPlugins::LogInfo(context_, "Received worklist query from remote modality " + 
-                            std::string(remoteAet) + ":\n" + json.toStyledString());
+    // Create a ScheduledProcedureStepSequence sequence, with one empty element
+    json[SCHEDULED_PROCEDURE_STEP_SEQUENCE] = Json::arrayValue;
+    json[SCHEDULED_PROCEDURE_STEP_SEQUENCE].append(Json::objectValue);
   }
 
-  return new OrthancPlugins::FindMatcher(context_, query);
-  //return new OrthancPlugins::FindMatcher(context_, dicom);
+  Json::Value& v = json[SCHEDULED_PROCEDURE_STEP_SEQUENCE];
+
+  if (v.type() != Json::arrayValue ||
+      v.size() != 1 ||
+      v[0].type() != Json::objectValue)
+  {
+    ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);
+  }
+
+  // Set the ScheduledStationAETitle if none was provided
+  if (!v[0].isMember(SCHEDULED_STATION_AETITLE) ||
+      v[0].type() != Json::stringValue ||
+      v[0][SCHEDULED_STATION_AETITLE].asString().size() == 0 ||
+      v[0][SCHEDULED_STATION_AETITLE].asString() == "*")
+  {
+    v[0][SCHEDULED_STATION_AETITLE] = remoteAet;
+  }
+
+  if (json.isMember("0010,21c0") &&
+      json["0010,21c0"].asString().size() == 0)
+  {
+    json.removeMember("0010,21c0");
+  }
+
+  // Encode the modified JSON as a DICOM instance, then convert it to a C-Find matcher
+  OrthancPlugins::MemoryBuffer modified(context_);
+  modified.CreateDicom(json, OrthancPluginCreateDicomFlags_None);
+  return new OrthancPlugins::FindMatcher(context_, modified);
+#endif
 }