changeset 1429:7366a0bdda6a

attempt of fix for Syngo.Via
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 29 Jun 2015 14:43:08 +0200
parents 0a355eeeb351
children ad94a3583b07
files Core/DicomFormat/DicomTag.h OrthancServer/DicomProtocol/DicomUserConnection.cpp OrthancServer/FromDcmtkBridge.cpp OrthancServer/OrthancFindRequestHandler.cpp OrthancServer/OrthancInitialization.cpp OrthancServer/ServerEnumerations.cpp OrthancServer/ServerEnumerations.h Resources/Configuration.json UnitTestsSources/UnitTestsMain.cpp
diffstat 9 files changed, 82 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/Core/DicomFormat/DicomTag.h	Mon Jun 29 13:26:34 2015 +0200
+++ b/Core/DicomFormat/DicomTag.h	Mon Jun 29 14:43:08 2015 +0200
@@ -108,6 +108,9 @@
   static const DicomTag DICOM_TAG_IMAGES_IN_ACQUISITION(0x0020, 0x1002);
 
   static const DicomTag DICOM_TAG_PATIENT_NAME(0x0010, 0x0010);
+  static const DicomTag DICOM_TAG_STUDY_DATE(0x0008, 0x0020);
+  static const DicomTag DICOM_TAG_SERIES_DATE(0x0008, 0x0021);
+  static const DicomTag DICOM_TAG_PATIENT_BIRTH_DATE(0x0010, 0x0030);
 
   // The following is used for "modify/anonymize" operations
   static const DicomTag DICOM_TAG_SOP_CLASS_UID(0x0008, 0x0016);
--- a/OrthancServer/DicomProtocol/DicomUserConnection.cpp	Mon Jun 29 13:26:34 2015 +0200
+++ b/OrthancServer/DicomProtocol/DicomUserConnection.cpp	Mon Jun 29 14:43:08 2015 +0200
@@ -419,6 +419,46 @@
   }
 
 
+  static DcmDataset* ConvertQueryFields(const DicomMap& fields,
+                                        ModalityManufacturer manufacturer)
+  {
+    switch (manufacturer)
+    {
+      case ModalityManufacturer_SyngoVia:
+      {
+        std::auto_ptr<DicomMap> fix(fields.Clone());
+
+        // This issue for Syngo.Via and its solution was reported by
+        // Emsy Chan by private mail on June 17th, 2015.
+        std::set<DicomTag> tags;
+        fix->GetTags(tags);
+
+        for (std::set<DicomTag>::const_iterator it = tags.begin(); it != tags.end(); ++it)
+        {
+          if (FromDcmtkBridge::GetValueRepresentation(*it) == ValueRepresentation_Date)
+          {
+            // Replace a "*" query by an empty query ("") for "date"
+            // value representations. Necessary to search over dates
+            // in Syngo.Via.
+            const DicomValue* value = fix->TestAndGetValue(*it);
+
+            if (value != NULL && 
+                value->AsString() == "*")
+            {
+              fix->SetValue(*it, "");
+            }
+          }
+        }
+
+        return ToDcmtkBridge::Convert(*fix);
+      }
+
+      default:
+        return ToDcmtkBridge::Convert(fields);
+    }
+  }
+
+
   void DicomUserConnection::Find(DicomFindAnswers& result,
                                  ResourceType level,
                                  const DicomMap& fields)
@@ -430,8 +470,9 @@
     FindPayload payload;
     payload.answers = &result;
 
+    std::auto_ptr<DcmDataset> dataset(ConvertQueryFields(fields, manufacturer_));
+
     const char* sopClass;
-    std::auto_ptr<DcmDataset> dataset(ToDcmtkBridge::Convert(fields));
     switch (level)
     {
       case ResourceType_Patient:
@@ -545,9 +586,9 @@
   {
     CheckIsOpen();
 
+    std::auto_ptr<DcmDataset> dataset(ConvertQueryFields(fields, manufacturer_));
+
     const char* sopClass = UID_MOVEStudyRootQueryRetrieveInformationModel;
-    std::auto_ptr<DcmDataset> dataset(ToDcmtkBridge::Convert(fields));
-
     switch (level)
     {
       case ResourceType_Patient:
--- a/OrthancServer/FromDcmtkBridge.cpp	Mon Jun 29 13:26:34 2015 +0200
+++ b/OrthancServer/FromDcmtkBridge.cpp	Mon Jun 29 14:43:08 2015 +0200
@@ -221,12 +221,18 @@
     if (element.isaString())
     {
       char *c;
-      if (element.getString(c).good() &&
-          c != NULL)
+      if (element.getString(c).good())
       {
-        std::string s(c);
-        std::string utf8 = Toolbox::ConvertToUtf8(s, encoding);
-        return new DicomString(utf8);
+        if (c == NULL)  // This case corresponds to the empty string
+        {
+          return new DicomString("");
+        }
+        else
+        {
+          std::string s(c);
+          std::string utf8 = Toolbox::ConvertToUtf8(s, encoding);
+          return new DicomString(utf8);
+        }
       }
       else
       {
--- a/OrthancServer/OrthancFindRequestHandler.cpp	Mon Jun 29 13:26:34 2015 +0200
+++ b/OrthancServer/OrthancFindRequestHandler.cpp	Mon Jun 29 14:43:08 2015 +0200
@@ -288,6 +288,11 @@
       }
 
       std::string value = query.GetElement(i).GetValue().AsString();
+      if (value.size() == 0)
+      {
+        // An empty string corresponds to a "*" wildcard constraint, so we ignore it
+        continue;
+      }
 
       if (tag == DICOM_TAG_MODALITIES_IN_STUDY)
       {
--- a/OrthancServer/OrthancInitialization.cpp	Mon Jun 29 13:26:34 2015 +0200
+++ b/OrthancServer/OrthancInitialization.cpp	Mon Jun 29 14:43:08 2015 +0200
@@ -375,7 +375,7 @@
     }
     catch (OrthancException& e)
     {
-      LOG(ERROR) << "Syntax error in the definition of modality \"" << name 
+      LOG(ERROR) << "Syntax error in the definition of DICOM modality \"" << name 
                  << "\". Please check your configuration file.";
       throw;
     }
--- a/OrthancServer/ServerEnumerations.cpp	Mon Jun 29 13:26:34 2015 +0200
+++ b/OrthancServer/ServerEnumerations.cpp	Mon Jun 29 14:43:08 2015 +0200
@@ -300,6 +300,9 @@
       case ModalityManufacturer_Dcm4Chee:
         return "Dcm4Chee";
       
+      case ModalityManufacturer_SyngoVia:
+        return "SyngoVia";
+      
       default:
         throw OrthancException(ErrorCode_ParameterOutOfRange);
     }
@@ -359,6 +362,10 @@
     {
       return ModalityManufacturer_Dcm4Chee;
     }
+    else if (manufacturer == "SyngoVia")
+    {
+      return ModalityManufacturer_SyngoVia;
+    }
     else
     {
       throw OrthancException(ErrorCode_ParameterOutOfRange);
--- a/OrthancServer/ServerEnumerations.h	Mon Jun 29 13:26:34 2015 +0200
+++ b/OrthancServer/ServerEnumerations.h	Mon Jun 29 14:43:08 2015 +0200
@@ -60,7 +60,8 @@
     ModalityManufacturer_StoreScp,
     ModalityManufacturer_ClearCanvas,
     ModalityManufacturer_MedInria,
-    ModalityManufacturer_Dcm4Chee
+    ModalityManufacturer_Dcm4Chee,
+    ModalityManufacturer_SyngoVia
   };
 
   enum DicomRequestType
--- a/Resources/Configuration.json	Mon Jun 29 13:26:34 2015 +0200
+++ b/Resources/Configuration.json	Mon Jun 29 14:43:08 2015 +0200
@@ -123,8 +123,8 @@
      * A fourth parameter is available to enable patches for a
      * specific PACS manufacturer. The allowed values are currently
      * "Generic" (default value), "StoreScp" (storescp tool from
-     * DCMTK), "ClearCanvas", "MedInria" and "Dcm4Chee". This
-     * parameter is case-sensitive.
+     * DCMTK), "ClearCanvas", "MedInria", "Dcm4Chee" and
+     * "SyngoVia". This parameter is case-sensitive.
      **/
     // "clearcanvas" : [ "CLEARCANVAS", "192.168.1.1", 104, "ClearCanvas" ]
   },
--- a/UnitTestsSources/UnitTestsMain.cpp	Mon Jun 29 13:26:34 2015 +0200
+++ b/UnitTestsSources/UnitTestsMain.cpp	Mon Jun 29 14:43:08 2015 +0200
@@ -612,6 +612,13 @@
   RegisterUserMetadata(2047, "Ceci est un test");
   ASSERT_EQ(2047, StringToMetadata("2047"));
   ASSERT_EQ(2047, StringToMetadata("Ceci est un test"));
+
+  ASSERT_STREQ("Generic", EnumerationToString(StringToModalityManufacturer("Generic")));
+  ASSERT_STREQ("StoreScp", EnumerationToString(StringToModalityManufacturer("StoreScp")));
+  ASSERT_STREQ("ClearCanvas", EnumerationToString(StringToModalityManufacturer("ClearCanvas")));
+  ASSERT_STREQ("MedInria", EnumerationToString(StringToModalityManufacturer("MedInria")));
+  ASSERT_STREQ("Dcm4Chee", EnumerationToString(StringToModalityManufacturer("Dcm4Chee")));
+  ASSERT_STREQ("SyngoVia", EnumerationToString(StringToModalityManufacturer("SyngoVia")));
 }