changeset 796:e7b1ca0f1e04

creation of dicom files
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 06 May 2014 12:09:11 +0200
parents d466b3606aca
children 37adac56017a
files NEWS OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp OrthancServer/OrthancRestApi/OrthancRestApi.cpp OrthancServer/OrthancRestApi/OrthancRestApi.h
diffstat 4 files changed, 86 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Tue May 06 11:01:30 2014 +0200
+++ b/NEWS	Tue May 06 12:09:11 2014 +0200
@@ -2,8 +2,9 @@
 ===============================
 
 * Dynamic negotiation of SOP classes for C-Store SCU
+* Creation of DICOM instances using the REST API
 * Reuse of the previous SCU connection to avoid unecessary handshakes
-* Fix missing licensing terms about reuse of some DCMTK code
+* Fix missing licensing terms about reuse of some code from DCMTK
 * Various code refactorings
 
 
--- a/OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp	Tue May 06 11:01:30 2014 +0200
+++ b/OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp	Tue May 06 12:09:11 2014 +0200
@@ -95,8 +95,11 @@
       const std::string& name = members[i];
       std::string value = replacements[name].asString();
 
-      DicomTag tag = FromDcmtkBridge::ParseTag(name);      
-      target.Replace(tag, value);
+      DicomTag tag = FromDcmtkBridge::ParseTag(name);
+      if (tag != DICOM_TAG_PIXEL_DATA)
+      {
+        target.Replace(tag, value);
+      }
 
       VLOG(1) << "Replace: " << name << " " << tag << " == " << value << std::endl;
     }
@@ -336,10 +339,25 @@
   {
     DicomModification modification;
 
-    // TODO : modification.SetLevel(ResourceType_Series); ?????
-
     if (ParseModifyRequest(modification, call))
     {
+      if (modification.IsReplaced(DICOM_TAG_PATIENT_ID))
+      {
+        modification.SetLevel(ResourceType_Patient);
+      }
+      else if (modification.IsReplaced(DICOM_TAG_STUDY_INSTANCE_UID))
+      {
+        modification.SetLevel(ResourceType_Study);
+      }
+      else if (modification.IsReplaced(DICOM_TAG_SERIES_INSTANCE_UID))
+      {
+        modification.SetLevel(ResourceType_Series);
+      }
+      else
+      {
+        modification.SetLevel(ResourceType_Instance);
+      }
+
       AnonymizeOrModifyInstance(modification, call);
     }
   }
@@ -362,26 +380,9 @@
   {
     DicomModification modification;
 
-    switch (resourceType)
-    {
-      case ResourceType_Series:
-        modification.SetLevel(ResourceType_Series);
-        break;
-
-      case ResourceType_Study:
-        modification.SetLevel(ResourceType_Study);
-        break;
-
-      case ResourceType_Patient:
-        modification.SetLevel(ResourceType_Patient);
-        break;
-
-      default:
-        throw OrthancException(ErrorCode_InternalError);
-    }
-
     if (ParseModifyRequest(modification, call))
     {
+      modification.SetLevel(resourceType);
       AnonymizeOrModifyResource(modification, MetadataType_ModifiedFrom, 
                                 changeType, resourceType, call);
     }
@@ -402,16 +403,45 @@
   }
 
 
+  static void Create(RestApi::PostCall& call)
+  {
+    // curl http://localhost:8042/tools/create-dicom -X POST -d '{"PatientName":"Hello^World"}'
+
+    Json::Value request;
+    if (call.ParseJsonRequest(request) && request.isObject())
+    {
+      DicomModification modification;
+      ParseReplacements(modification, request);
+
+      ParsedDicomFile dicom;
+      modification.Apply(dicom);
+
+      std::string id;
+      StoreStatus status = OrthancRestApi::GetContext(call).Store(id, dicom);
+
+      if (status == StoreStatus_Failure)
+      {
+        LOG(ERROR) << "Error while storing a manually-created instance";
+        return;
+      }
+
+      OrthancRestApi::GetApi(call).AnswerStoredInstance(call, id, status);
+    }
+  }
+
+
   void OrthancRestApi::RegisterAnonymizeModify()
   {
     Register("/instances/{id}/modify", ModifyInstance);
     Register("/series/{id}/modify", ModifyResource<ChangeType_ModifiedSeries, ResourceType_Series>);
     Register("/studies/{id}/modify", ModifyResource<ChangeType_ModifiedStudy, ResourceType_Study>);
-    //Register("/patients/{id}/modify", ModifyResource<ChangeType_ModifiedPatient, ResourceType_Patient>);
+    Register("/patients/{id}/modify", ModifyResource<ChangeType_ModifiedPatient, ResourceType_Patient>);
 
     Register("/instances/{id}/anonymize", AnonymizeInstance);
     Register("/series/{id}/anonymize", AnonymizeResource<ChangeType_ModifiedSeries, ResourceType_Series>);
     Register("/studies/{id}/anonymize", AnonymizeResource<ChangeType_ModifiedStudy, ResourceType_Study>);
     Register("/patients/{id}/anonymize", AnonymizeResource<ChangeType_ModifiedPatient, ResourceType_Patient>);
+
+    Register("/tools/create-dicom", Create);
   }
 }
--- a/OrthancServer/OrthancRestApi/OrthancRestApi.cpp	Tue May 06 11:01:30 2014 +0200
+++ b/OrthancServer/OrthancRestApi/OrthancRestApi.cpp	Tue May 06 12:09:11 2014 +0200
@@ -32,10 +32,30 @@
 
 #include "OrthancRestApi.h"
 
+#include "../DicomModification.h"
+
 #include <glog/logging.h>
 
 namespace Orthanc
 {
+  void OrthancRestApi::AnswerStoredInstance(RestApi::PostCall& call,
+                                            const std::string& publicId,
+                                            StoreStatus status)
+  {
+    Json::Value result = Json::objectValue;
+
+    if (status != StoreStatus_Failure)
+    {
+      result["ID"] = publicId;
+      result["Path"] = GetBasePath(ResourceType_Instance, publicId);
+    }
+
+    result["Status"] = EnumerationToString(status);
+    call.GetOutput().AnswerJson(result);
+  }
+
+
+
   // Upload of DICOM files through HTTP ---------------------------------------
 
   static void UploadDicomFile(RestApi::PostCall& call)
@@ -52,16 +72,8 @@
 
     std::string publicId;
     StoreStatus status = context.Store(publicId, postData);
-    Json::Value result = Json::objectValue;
 
-    if (status != StoreStatus_Failure)
-    {
-      result["ID"] = publicId;
-      result["Path"] = GetBasePath(ResourceType_Instance, publicId);
-    }
-
-    result["Status"] = EnumerationToString(status);
-    call.GetOutput().AnswerJson(result);
+    OrthancRestApi::GetApi(call).AnswerStoredInstance(call, publicId, status);
   }
 
 
--- a/OrthancServer/OrthancRestApi/OrthancRestApi.h	Tue May 06 11:01:30 2014 +0200
+++ b/OrthancServer/OrthancRestApi/OrthancRestApi.h	Tue May 06 12:09:11 2014 +0200
@@ -62,15 +62,23 @@
   public:
     OrthancRestApi(ServerContext& context);
 
+    static OrthancRestApi& GetApi(RestApi::Call& call)
+    {
+      return dynamic_cast<OrthancRestApi&>(call.GetContext());
+    }
+
     static ServerContext& GetContext(RestApi::Call& call)
     {
-      OrthancRestApi& that = dynamic_cast<OrthancRestApi&>(call.GetContext());
-      return that.context_;
+      return GetApi(call).context_;
     }
 
     static ServerIndex& GetIndex(RestApi::Call& call)
     {
       return GetContext(call).GetIndex();
     }
+
+    void AnswerStoredInstance(RestApi::PostCall& call,
+                              const std::string& publicId,
+                              StoreStatus status);
   };
 }