changeset 963:81134ea872ff

retrieve values of modules
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 26 Jun 2014 16:42:05 +0200
parents b39c4837966e
children cc7a4ae474c1
files NEWS OrthancServer/OrthancRestApi/OrthancRestResources.cpp UnitTestsSources/DicomMap.cpp
diffstat 3 files changed, 123 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Thu Jun 26 16:01:57 2014 +0200
+++ b/NEWS	Thu Jun 26 16:42:05 2014 +0200
@@ -2,6 +2,7 @@
 ===============================
 
 * Official support of OS X (Darwin)
+* Extraction of patient/study/series/instance DICOM modules
 * Extraction of the tags shared by all the instances of a patient/study/series
 * Options to limit the number of results for an incoming C-FIND query
 * Support of kFreeBSD
--- a/OrthancServer/OrthancRestApi/OrthancRestResources.cpp	Thu Jun 26 16:01:57 2014 +0200
+++ b/OrthancServer/OrthancRestApi/OrthancRestResources.cpp	Thu Jun 26 16:42:05 2014 +0200
@@ -691,6 +691,60 @@
   }
 
 
+  template <enum ResourceType resourceType, bool simplify>
+  static void GetModule(RestApi::GetCall& call)
+  {
+    ServerContext& context = OrthancRestApi::GetContext(call);
+    std::string publicId = call.GetUriComponent("id", "");
+
+    typedef std::set<DicomTag> Module;
+    Module module;
+    DicomTag::GetTagsForModule(module, resourceType);
+
+    Json::Value tags;
+
+    if (resourceType != ResourceType_Instance)
+    {
+      // Retrieve all the instances of this patient/study/series
+      typedef std::list<std::string> Instances;
+      Instances instances;
+      context.GetIndex().GetChildInstances(instances, publicId);
+
+      if (instances.empty())
+      {
+        return;   // Error: No instance (should never happen)
+      }
+
+      // Select one child instance
+      publicId = instances.front();
+    }
+
+    context.ReadJson(tags, publicId);
+    
+    // Filter the tags of the instance according to the module
+    Json::Value result = Json::objectValue;
+    for (Module::const_iterator it = module.begin(); it != module.end(); it++)
+    {
+      std::string s = it->Format();
+      if (tags.isMember(s))
+      {
+        result[s] = tags[s];
+      }      
+    }
+
+    if (simplify)
+    {
+      Json::Value simplified;
+      SimplifyTags(simplified, result);
+      call.GetOutput().AnswerJson(simplified);
+    }
+    else
+    {
+      call.GetOutput().AnswerJson(result);
+    }
+  }
+
+
   void OrthancRestApi::RegisterResources()
   {
     Register("/instances", ListResources<ResourceType_Instance>);
@@ -719,6 +773,15 @@
     Register("/studies/{id}/shared-tags", GetSharedTags<false>);
     Register("/studies/{id}/simplified-shared-tags", GetSharedTags<true>);
 
+    Register("/instances/{id}/module", GetModule<ResourceType_Instance, false>);
+    Register("/patients/{id}/module", GetModule<ResourceType_Patient, false>);
+    Register("/series/{id}/module", GetModule<ResourceType_Series, false>);
+    Register("/studies/{id}/module", GetModule<ResourceType_Study, false>);
+    Register("/instances/{id}/simplified-module", GetModule<ResourceType_Instance, true>);
+    Register("/patients/{id}/simplified-module", GetModule<ResourceType_Patient, true>);
+    Register("/series/{id}/simplified-module", GetModule<ResourceType_Series, true>);
+    Register("/studies/{id}/simplified-module", GetModule<ResourceType_Study, true>);
+
     Register("/instances/{id}/file", GetInstanceFile);
     Register("/instances/{id}/export", ExportInstanceFile);
     Register("/instances/{id}/tags", GetInstanceTags<false>);
--- a/UnitTestsSources/DicomMap.cpp	Thu Jun 26 16:01:57 2014 +0200
+++ b/UnitTestsSources/DicomMap.cpp	Thu Jun 26 16:42:05 2014 +0200
@@ -37,6 +37,7 @@
 #include "../Core/OrthancException.h"
 #include "../Core/DicomFormat/DicomMap.h"
 #include "../Core/DicomFormat/DicomNullValue.h"
+#include "../OrthancServer/FromDcmtkBridge.h"
 
 #include <memory>
 
@@ -128,3 +129,61 @@
   DicomMap::SetupFindInstanceTemplate(m);
   ASSERT_TRUE(m.HasTag(DICOM_TAG_SOP_INSTANCE_UID));
 }
+
+
+
+
+static void TestModule(ResourceType level)
+{
+  std::set<DicomTag> module, main;
+  DicomTag::GetTagsForModule(module, level);
+  DicomMap::GetMainDicomTags(main, level);
+  
+  // The main dicom tags are a subset of the module
+  for (std::set<DicomTag>::const_iterator it = main.begin(); it != main.end(); it++)
+  {
+    bool ok = module.find(*it) != module.end();
+
+    // Exceptions for the Series level
+    /*if ((//
+          *it == DicomTag(0x, 0x) && 
+          level == ResourceType_Series))
+    {
+      ok = true;
+      }*/
+
+    // Exceptions for the Instance level
+    if ((/* Accession number, from Image module */
+          *it == DicomTag(0x0020, 0x0012) && 
+          level == ResourceType_Instance) ||
+        (/* Image Index, from PET Image module */
+          *it == DicomTag(0x0054, 0x1330) && 
+          level == ResourceType_Instance) ||
+        (/* Temporal Position Identifier, from MR Image module */
+          *it == DicomTag(0x0020, 0x0100) && 
+          level == ResourceType_Instance) ||
+        (/* Number of Frames, from Multi-frame module attributes, related to Image IOD */
+          *it == DicomTag(0x0028, 0x0008) && 
+          level == ResourceType_Instance ))
+    {
+      ok = true;
+    }
+
+    if (!ok)
+    {
+      std::cout << it->Format() << ": " << FromDcmtkBridge::GetName(*it)
+                << " not expected at level " << EnumerationToString(level) << std::endl;
+    }
+
+    EXPECT_TRUE(ok);
+  }
+}
+
+
+TEST(DicomMap, Modules)
+{
+  TestModule(ResourceType_Patient);
+  TestModule(ResourceType_Study);
+  //TestModule(ResourceType_Series);   // TODO
+  TestModule(ResourceType_Instance);
+}