changeset 1353:d7da97e21161

ResourceFinder
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 12 May 2015 18:27:14 +0200
parents 382439943749
children 3dd494f201a1
files OrthancServer/ResourceFinder.cpp OrthancServer/ResourceFinder.h
diffstat 2 files changed, 128 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancServer/ResourceFinder.cpp	Mon May 11 17:25:53 2015 +0200
+++ b/OrthancServer/ResourceFinder.cpp	Tue May 12 18:27:14 2015 +0200
@@ -60,6 +60,8 @@
     class CandidateResources
     {
     private:
+      typedef std::map<DicomTag, std::string>  Query;
+
       ServerIndex&  index_;
       ResourceType  level_;
       bool  isFilterApplied_;
@@ -77,6 +79,58 @@
       }
 
 
+      void RestrictIdentifier(const DicomTag& tag, 
+                              const std::string& value)
+      {
+        assert((level_ == ResourceType_Patient && tag == DICOM_TAG_PATIENT_ID) ||
+               (level_ == ResourceType_Study && tag == DICOM_TAG_STUDY_INSTANCE_UID) ||
+               (level_ == ResourceType_Study && tag == DICOM_TAG_ACCESSION_NUMBER) ||
+               (level_ == ResourceType_Series && tag == DICOM_TAG_SERIES_INSTANCE_UID) ||
+               (level_ == ResourceType_Instance && tag == DICOM_TAG_SOP_INSTANCE_UID));
+
+        LOG(INFO) << "Lookup for identifier tag "
+                  << FromDcmtkBridge::GetName(tag) << " (value: " << value << ")";
+
+        std::list<std::string> resources;
+        index_.LookupIdentifier(resources, tag, value, level_);
+
+        if (isFilterApplied_)
+        {
+          std::set<std::string>  s;
+          ListToSet(s, resources);
+
+          std::set<std::string> tmp = filtered_;
+          filtered_.clear();
+
+          for (std::set<std::string>::const_iterator 
+                 it = tmp.begin(); it != tmp.end(); ++it)
+          {
+            if (s.find(*it) != s.end())
+            {
+              filtered_.insert(*it);
+            }
+          }
+        }
+        else
+        {
+          assert(filtered_.empty());
+          isFilterApplied_ = true;
+          ListToSet(filtered_, resources);
+        }
+      }
+
+
+      void RestrictIdentifier(const Query& query,
+                              const DicomTag& tag)
+      {
+        Query::const_iterator it = query.find(tag);
+        if (it != query.end())
+        {
+          RestrictIdentifier(it->first, it->second);
+        }
+      }
+
+
     public:
       CandidateResources(ServerIndex& index) : 
         index_(index), 
@@ -153,50 +207,49 @@
       }
 
 
-      void RestrictIdentifier(const DicomTag& tag, 
-                              const std::string& value)
+      void RestrictIdentifier(const Query& query)
       {
-        assert((level_ == ResourceType_Patient && tag == DICOM_TAG_PATIENT_ID) ||
-               (level_ == ResourceType_Study && tag == DICOM_TAG_STUDY_INSTANCE_UID) ||
-               (level_ == ResourceType_Study && tag == DICOM_TAG_ACCESSION_NUMBER) ||
-               (level_ == ResourceType_Series && tag == DICOM_TAG_SERIES_INSTANCE_UID) ||
-               (level_ == ResourceType_Instance && tag == DICOM_TAG_SOP_INSTANCE_UID));
-
-        LOG(INFO) << "Lookup for identifier tag "
-                  << FromDcmtkBridge::GetName(tag) << " (value: " << value << ")";
-
-        std::list<std::string> resources;
-        index_.LookupIdentifier(resources, tag, value, level_);
-
-        if (isFilterApplied_)
+        switch (level_)
         {
-          std::set<std::string>  s;
-          ListToSet(s, resources);
+          case ResourceType_Patient:
+          {
+            RestrictIdentifier(query, DICOM_TAG_PATIENT_ID);
+            break;
+          }
 
-          std::set<std::string> tmp = filtered_;
-          filtered_.clear();
-
-          for (std::set<std::string>::const_iterator 
-                 it = tmp.begin(); it != tmp.end(); ++it)
+          case ResourceType_Study:
           {
-            if (s.find(*it) != s.end())
-            {
-              filtered_.insert(*it);
-            }
+            RestrictIdentifier(query, DICOM_TAG_STUDY_INSTANCE_UID);
+            RestrictIdentifier(query, DICOM_TAG_ACCESSION_NUMBER);
+            break;
+          }
+
+          case ResourceType_Series:
+          {
+            RestrictIdentifier(query, DICOM_TAG_SERIES_INSTANCE_UID);
+            break;
           }
-        }
-        else
-        {
-          assert(filtered_.empty());
-          isFilterApplied_ = true;
-          ListToSet(filtered_, resources);
+
+          case ResourceType_Instance:
+          {
+            RestrictIdentifier(query, DICOM_TAG_SOP_INSTANCE_UID);
+            break;
+          }
+
+          default:
+            throw OrthancException(ErrorCode_InternalError);
         }
       }
 
 
-      void RestrictMainDicomTags(const ResourceFinder::Query& query,
+      void RestrictMainDicomTags(const Query& query,
                                  bool caseSensitive)
       {
+        if (query.size() == 0)
+        {
+          return;
+        }
+
         std::list<std::string> resources;
         Flatten(resources);
 
@@ -209,18 +262,25 @@
           DicomMap mainTags;
           if (index_.GetMainDicomTags(mainTags, *it, level_))
           {
-            for (ResourceFinder::Query::const_iterator 
-                   tag = query.begin(); tag != query.end(); ++tag)
+            for (Query::const_iterator tag = query.begin(); 
+                 tag != query.end(); ++tag)
             {
               assert(DicomMap::IsMainDicomTag(tag->first, level_));
-              LOG(INFO) << "Lookup for main DICOM tag "
-                        << FromDcmtkBridge::GetName(tag->first) << " (value: " << tag->second << ")";
-
-              const DicomValue* value = mainTags.TestAndGetValue(tag->first);
-              if (value != NULL &&
-                  Compare(value->AsString(), tag->second, caseSensitive))
+              if (tag->first != DICOM_TAG_PATIENT_ID &&
+                  tag->first != DICOM_TAG_STUDY_INSTANCE_UID &&
+                  tag->first != DICOM_TAG_ACCESSION_NUMBER &&
+                  tag->first != DICOM_TAG_SERIES_INSTANCE_UID &&
+                  tag->first != DICOM_TAG_SOP_INSTANCE_UID)
               {
-                filtered_.insert(*it);
+                LOG(INFO) << "Lookup for main DICOM tag "
+                          << FromDcmtkBridge::GetName(tag->first) << " (value: " << tag->second << ")";
+                
+                const DicomValue* value = mainTags.TestAndGetValue(tag->first);
+                if (value != NULL &&
+                    Compare(value->AsString(), tag->second, caseSensitive))
+                {
+                  filtered_.insert(*it);
+                }
               }
             }            
           }
@@ -245,8 +305,29 @@
   }
 
 
+  void ResourceFinder::GetTagsForLevel(Query& result,
+                                       const Query& source,
+                                       ResourceType level)
+  {
+    typedef std::set<DicomTag>  Tags;
+
+    Tags  tags;
+    DicomMap::GetMainDicomTags(tags, level);
+
+    for (Tags::const_iterator tag = tags.begin(); tag != tags.end(); tag++)
+    {
+      Query::const_iterator value = source.find(*tag);
+      if (value != source.end())
+      {
+        result.insert(*value);
+      }
+    }
+  }
+
+
   void ResourceFinder::Apply(std::list<std::string>& result)
   {
     result.clear();
+
   }
 }
--- a/OrthancServer/ResourceFinder.h	Mon May 11 17:25:53 2015 +0200
+++ b/OrthancServer/ResourceFinder.h	Tue May 12 18:27:14 2015 +0200
@@ -40,15 +40,18 @@
 {
   class ResourceFinder : public boost::noncopyable
   {
-  public:
+  private:
     typedef std::map<DicomTag, std::string>  Query;
 
-  private:
     ServerContext&  context_;
     ResourceType    level_;
     bool            caseSensitive_;
     Query           query_;
 
+    static void GetTagsForLevel(Query& result,
+                                const Query& source,
+                                ResourceType level);
+
   public:
     ResourceFinder(ServerContext& context);