changeset 3370:872bd3b6ec72

"/modalities/{id}/query": New argument "Normalize"
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 14 May 2019 10:30:43 +0200
parents 20b38a533254
children fe73717105b6
files Core/DicomNetworking/DicomUserConnection.cpp Core/DicomNetworking/DicomUserConnection.h NEWS OrthancServer/OrthancRestApi/OrthancRestModalities.cpp OrthancServer/QueryRetrieveHandler.cpp OrthancServer/QueryRetrieveHandler.h
diffstat 6 files changed, 56 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/Core/DicomNetworking/DicomUserConnection.cpp	Tue May 14 10:03:11 2019 +0200
+++ b/Core/DicomNetworking/DicomUserConnection.cpp	Tue May 14 10:30:43 2019 +0200
@@ -482,9 +482,9 @@
   }
 
 
-  static void FixFindQuery(DicomMap& fixedQuery,
-                           ResourceType level,
-                           const DicomMap& fields)
+  static void NormalizeFindQuery(DicomMap& fixedQuery,
+                                 ResourceType level,
+                                 const DicomMap& fields)
   {
     std::set<DicomTag> allowedTags;
 
@@ -657,24 +657,25 @@
 
   void DicomUserConnection::Find(DicomFindAnswers& result,
                                  ResourceType level,
-                                 const DicomMap& originalFields)
+                                 const DicomMap& originalFields,
+                                 bool normalize)
   {
     CheckIsOpen();
 
     std::auto_ptr<ParsedDicomFile> query;
 
-    if (0)
+    if (normalize)
+    {
+      DicomMap fields;
+      NormalizeFindQuery(fields, level, originalFields);
+      query.reset(ConvertQueryFields(fields, manufacturer_));
+    }
+    else
     {
       query.reset(new ParsedDicomFile(originalFields,
                                       GetDefaultDicomEncoding(),
                                       false /* be strict */));
     }
-    else
-    {
-      DicomMap fields;
-      FixFindQuery(fields, level, originalFields);
-      query.reset(ConvertQueryFields(fields, manufacturer_));
-    }
     
     DcmDataset* dataset = query->GetDcmtkObject().getDataset();
 
--- a/Core/DicomNetworking/DicomUserConnection.h	Tue May 14 10:03:11 2019 +0200
+++ b/Core/DicomNetworking/DicomUserConnection.h	Tue May 14 10:30:43 2019 +0200
@@ -176,7 +176,8 @@
 
     void Find(DicomFindAnswers& result,
               ResourceType level,
-              const DicomMap& fields);
+              const DicomMap& fields,
+              bool normalize);  // Whether to normalize the DICOM query
 
     void Move(const std::string& targetAet,
               ResourceType level,
--- a/NEWS	Tue May 14 10:03:11 2019 +0200
+++ b/NEWS	Tue May 14 10:30:43 2019 +0200
@@ -2,6 +2,12 @@
 ===============================
 
 
+REST API
+--------
+
+* "/modalities/{id}/query": New argument "Normalize" can be set to "false"
+  to bypass the automated correction of outgoing C-FIND queries
+
 Maintenance
 -----------
 
--- a/OrthancServer/OrthancRestApi/OrthancRestModalities.cpp	Tue May 14 10:03:11 2019 +0200
+++ b/OrthancServer/OrthancRestApi/OrthancRestModalities.cpp	Tue May 14 10:30:43 2019 +0200
@@ -52,6 +52,7 @@
 {
   static const char* const KEY_LEVEL = "Level";
   static const char* const KEY_QUERY = "Query";
+  static const char* const KEY_NORMALIZE = "Normalize";
   static const char* const KEY_RESOURCES = "Resources";
 
   
@@ -131,7 +132,7 @@
     // Only keep the filters from "fields" that are related to the patient
     DicomMap s;
     fields.ExtractPatientInformation(s);
-    connection.Find(result, ResourceType_Patient, s);
+    connection.Find(result, ResourceType_Patient, s, true /* normalize */);
   }
 
 
@@ -147,7 +148,7 @@
     s.CopyTagIfExists(fields, DICOM_TAG_ACCESSION_NUMBER);
     s.CopyTagIfExists(fields, DICOM_TAG_MODALITIES_IN_STUDY);
 
-    connection.Find(result, ResourceType_Study, s);
+    connection.Find(result, ResourceType_Study, s, true /* normalize */);
   }
 
   static void FindSeries(DicomFindAnswers& result,
@@ -162,7 +163,7 @@
     s.CopyTagIfExists(fields, DICOM_TAG_ACCESSION_NUMBER);
     s.CopyTagIfExists(fields, DICOM_TAG_STUDY_INSTANCE_UID);
 
-    connection.Find(result, ResourceType_Series, s);
+    connection.Find(result, ResourceType_Series, s, true /* normalize */);
   }
 
   static void FindInstance(DicomFindAnswers& result,
@@ -178,7 +179,7 @@
     s.CopyTagIfExists(fields, DICOM_TAG_STUDY_INSTANCE_UID);
     s.CopyTagIfExists(fields, DICOM_TAG_SERIES_INSTANCE_UID);
 
-    connection.Find(result, ResourceType_Instance, s);
+    connection.Find(result, ResourceType_Instance, s, true /* normalize */);
   }
 
 
@@ -453,6 +454,12 @@
       throw OrthancException(ErrorCode_BadFileFormat,
                              "The JSON body must contain field " + std::string(KEY_LEVEL));
     }
+    else if (request.isMember(KEY_NORMALIZE) &&
+             request[KEY_NORMALIZE].type() != Json::booleanValue)
+    {
+      throw OrthancException(ErrorCode_BadFileFormat,
+                             "The field " + std::string(KEY_NORMALIZE) + " must contain a Boolean");
+    }
     else if (request.isMember(KEY_QUERY) &&
              request[KEY_QUERY].type() != Json::objectValue)
     {
@@ -462,7 +469,7 @@
     else
     {
       std::auto_ptr<QueryRetrieveHandler>  handler(new QueryRetrieveHandler(context));
-
+      
       handler->SetModality(call.GetUriComponent("id", ""));
       handler->SetLevel(StringToResourceType(request[KEY_LEVEL].asCString()));
 
@@ -478,6 +485,11 @@
         }
       }
 
+      if (request.isMember(KEY_NORMALIZE))
+      {
+        handler->SetFindNormalized(request[KEY_NORMALIZE].asBool());
+      }
+
       AnswerQueryHandler(call, handler);
     }
   }
@@ -772,6 +784,7 @@
       }
       else
       {
+        handler->SetFindNormalized(parent.GetHandler().IsFindNormalized());
         handler->SetModality(parent.GetHandler().GetModalitySymbolicName());
         handler->SetLevel(CHILDREN_LEVEL);
 
--- a/OrthancServer/QueryRetrieveHandler.cpp	Tue May 14 10:03:11 2019 +0200
+++ b/OrthancServer/QueryRetrieveHandler.cpp	Tue May 14 10:30:43 2019 +0200
@@ -62,21 +62,6 @@
   }
 
 
-  static void FixQueryBuiltin(DicomMap& query,
-                              ModalityManufacturer manufacturer)
-  {
-    /**
-     * Introduce patches for specific manufacturers below.
-     **/
-
-    switch (manufacturer)
-    {
-      default:
-        break;
-    }
-  }
-
-
   void QueryRetrieveHandler::Invalidate()
   {
     done_ = false;
@@ -91,7 +76,6 @@
       // Firstly, fix the content of the query for specific manufacturers
       DicomMap fixed;
       fixed.Assign(query_);
-      FixQueryBuiltin(fixed, modality_.GetManufacturer());
 
       // Secondly, possibly fix the query with the user-provider Lua callback
       FixQueryLua(fixed, context_, modality_.GetApplicationEntityTitle()); 
@@ -99,7 +83,7 @@
       {
         DicomUserConnection connection(localAet_, modality_);
         connection.Open();
-        connection.Find(answers_, level_, fixed);
+        connection.Find(answers_, level_, fixed, findNormalized_);
       }
 
       done_ = true;
@@ -112,7 +96,8 @@
     localAet_(context.GetDefaultLocalApplicationEntityTitle()),
     done_(false),
     level_(ResourceType_Study),
-    answers_(false)
+    answers_(false),
+    findNormalized_(true)
   {
   }
 
@@ -175,4 +160,11 @@
     Run();
     answers_.GetAnswer(i).ExtractDicomSummary(target);
   }
+
+  
+  void QueryRetrieveHandler::SetFindNormalized(bool normalized)
+  {
+    Invalidate();
+    findNormalized_ = normalized;
+  }
 }
--- a/OrthancServer/QueryRetrieveHandler.h	Tue May 14 10:03:11 2019 +0200
+++ b/OrthancServer/QueryRetrieveHandler.h	Tue May 14 10:30:43 2019 +0200
@@ -51,6 +51,7 @@
     DicomMap                   query_;
     DicomFindAnswers           answers_;
     std::string                modalityName_;
+    bool                       findNormalized_;
 
     void Invalidate();
 
@@ -98,5 +99,12 @@
 
     void GetAnswer(DicomMap& target,
                    size_t i);
+
+    bool IsFindNormalized() const
+    {
+      return findNormalized_;
+    }
+
+    void SetFindNormalized(bool normalized);
   };
 }