changeset 611:9924aec1d694 find-move-scp

filtering on modalities
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 18 Oct 2013 13:12:18 +0200
parents 5ba825b87b21
children fdd5f7f9c4d7
files Core/DicomFormat/DicomTag.h OrthancServer/OrthancFindRequestHandler.cpp
diffstat 2 files changed, 67 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/Core/DicomFormat/DicomTag.h	Fri Oct 18 10:32:12 2013 +0200
+++ b/Core/DicomFormat/DicomTag.h	Fri Oct 18 13:12:18 2013 +0200
@@ -114,4 +114,5 @@
   // Tags for C-FIND and C-MOVE
   static const DicomTag DICOM_TAG_SPECIFIC_CHARACTER_SET(0x0008, 0x0005);
   static const DicomTag DICOM_TAG_QUERY_RETRIEVE_LEVEL(0x0008, 0x0052);
+  static const DicomTag DICOM_TAG_MODALITIES_IN_STUDY(0x0008, 0x0061);
 }
--- a/OrthancServer/OrthancFindRequestHandler.cpp	Fri Oct 18 10:32:12 2013 +0200
+++ b/OrthancServer/OrthancFindRequestHandler.cpp	Fri Oct 18 13:12:18 2013 +0200
@@ -76,8 +76,6 @@
   static bool ApplyListConstraint(const std::string& value,
                                   const std::string& constraint)
   {
-    std::cout << value << std::endl;
-
     std::string v1 = ToLowerCase(value);
 
     std::vector<std::string> items;
@@ -163,7 +161,8 @@
     {
       if (query.GetElement(i).GetValue().IsNull() ||
           query.GetElement(i).GetTag() == DICOM_TAG_QUERY_RETRIEVE_LEVEL ||
-          query.GetElement(i).GetTag() == DICOM_TAG_SPECIFIC_CHARACTER_SET)
+          query.GetElement(i).GetTag() == DICOM_TAG_SPECIFIC_CHARACTER_SET ||
+          query.GetElement(i).GetTag() == DICOM_TAG_MODALITIES_IN_STUDY)
       {
         continue;
       }
@@ -175,8 +174,6 @@
         value = resource.get(tag, Json::arrayValue).get("Value", "").asString();
       }
 
-      std::cout << tag << " " << value << std::endl;
-
       if (!Matches(value, query.GetElement(i).GetValue().AsString()))
       {
         return false;
@@ -245,11 +242,73 @@
     context_.GetIndex().GetAllUuids(resources, level);
     assert(resources.type() == Json::arrayValue);
 
-
     // TODO : Speed up using MainDicomTags (to avoid looping over ALL
     // the resources and reading the JSON file for each of them)
 
 
+
+    /**
+     * Apply filtering on modalities for studies, if asked (this is an
+     * extension to standard DICOM)
+     * http://www.medicalconnections.co.uk/kb/Filtering_on_and_Retrieving_the_Modality_in_a_C_FIND
+     **/
+
+    if (level == ResourceType_Study &&
+        input.HasTag(DICOM_TAG_MODALITIES_IN_STUDY))
+    {
+      const DicomValue& v = input.GetValue(DICOM_TAG_MODALITIES_IN_STUDY);
+      if (!v.IsNull())
+      {
+        // Move the allowed modalities into a "std::set"
+        std::vector<std::string>  tmp;
+        Toolbox::TokenizeString(tmp, v.AsString(), '\\'); 
+
+        std::set<std::string> modalities;
+        for (size_t i = 0; i < tmp.size(); i++)
+        {
+          modalities.insert(tmp[i]);
+        }
+
+        // Loop over the studies
+        Json::Value studies = resources;
+        resources = Json::arrayValue;
+
+        for (Json::Value::ArrayIndex i = 0; i < studies.size(); i++)
+        {
+          // We are considering a single study. Check whether one of
+          // its child series matches one of the modalities.
+          Json::Value study;
+          if (context_.GetIndex().LookupResource(study, studies[i].asString(), ResourceType_Study))
+          {
+            // Loop over the series of the considered study.
+            for (Json::Value::ArrayIndex j = 0; j < study["Series"].size(); j++)   // (*)
+            {
+              Json::Value series;
+              if (context_.GetIndex().LookupResource(series, study["Series"][j].asString(), ResourceType_Series))
+              {
+                // Get the modality of this series
+                if (series["MainDicomTags"].isMember("Modality"))
+                {
+                  std::string modality = series["MainDicomTags"]["Modality"].asString();
+                  if (modalities.find(modality) != modalities.end())
+                  {
+                    // This series of the considered study matches one
+                    // of the required modalities. Take the study into
+                    // consideration for future filtering.
+                    resources.append(studies[i]);
+
+                    // We have finished considering this study. Break the study loop at (*).
+                    break;
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+
+
     /**
      * Loop over all the resources for this query level.
      **/
@@ -273,7 +332,7 @@
       }
       catch (OrthancException&)
       {
-        // This resource has been deleted during the find request
+        // This resource has probably been deleted during the find request
       }
     }
   }