changeset 348:1082e8121d10

refactoring anonymization/modification
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 28 Jan 2013 15:18:17 +0100
parents a9752f88400c
children c5edf0cc6e95
files OrthancServer/OrthancRestApi.cpp OrthancServer/ServerEnumerations.cpp OrthancServer/ServerEnumerations.h
diffstat 3 files changed, 144 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancServer/OrthancRestApi.cpp	Wed Jan 23 17:26:09 2013 +0100
+++ b/OrthancServer/OrthancRestApi.cpp	Mon Jan 28 15:18:17 2013 +0100
@@ -1141,8 +1141,8 @@
   }
 
 
-  static void AnonymizeOrModifyInstance(Removals removals,
-                                        Replacements replacements,
+  static void AnonymizeOrModifyInstance(Removals& removals,
+                                        Replacements& replacements,
                                         bool removePrivateTags,
                                         RestApi::PostCall& call)
   {
@@ -1159,8 +1159,8 @@
   }
 
 
-  static void AnonymizeOrModifySeries(Removals removals,
-                                      Replacements replacements,
+  static void AnonymizeOrModifySeries(Removals& removals,
+                                      Replacements& replacements,
                                       bool removePrivateTags,
                                       MetadataType metadataType,
                                       ChangeType changeType,
@@ -1234,8 +1234,8 @@
   }
 
 
-  static void AnonymizeOrModifyStudy(Removals removals,
-                                     Replacements replacements,
+  static void AnonymizeOrModifyStudy(Removals& removals,
+                                     Replacements& replacements,
                                      bool removePrivateTags,
                                      MetadataType metadataType,
                                      ChangeType changeType,
@@ -1341,6 +1341,135 @@
 
 
 
+  namespace
+  {
+    typedef std::map< std::pair<DicomRootLevel, std::string>, std::string>  UidMap;
+  }
+
+  static void RetrieveMappedUid(ParsedDicomFile& dicom,
+                                DicomRootLevel level,
+                                Replacements& replacements,
+                                UidMap& uidMap)
+  {
+    std::auto_ptr<DicomTag> tag;
+    if (level == DicomRootLevel_Series)
+    {
+      tag.reset(new DicomTag(DICOM_TAG_SERIES_INSTANCE_UID));
+    }
+    else
+    {
+      assert(level == DicomRootLevel_Study);
+      tag.reset(new DicomTag(DICOM_TAG_STUDY_INSTANCE_UID));
+    }
+
+    std::string original;
+    if (!dicom.GetTagValue(original, *tag))
+    {
+      throw OrthancException(ErrorCode_InternalError);
+    }
+
+    std::string mapped;
+
+    UidMap::const_iterator previous = uidMap.find(std::make_pair(level, original));
+    if (previous == uidMap.end())
+    {
+      mapped = FromDcmtkBridge::GenerateUniqueIdentifier(level);
+      uidMap.insert(std::make_pair(std::make_pair(level, original), mapped));
+    }
+    else
+    {
+      mapped = previous->second;
+    }    
+
+    replacements[*tag] = mapped;
+  }
+
+
+  static void AnonymizeOrModifyResource(Removals& removals,
+                                        Replacements& replacements,
+                                        bool removePrivateTags,
+                                        MetadataType metadataType,
+                                        ChangeType changeType,
+                                        ResourceType resourceType,
+                                        RestApi::PostCall& call)
+  {
+    typedef std::list<std::string> Instances;
+
+    bool isFirst = true;
+    Json::Value result(Json::objectValue);
+
+    boost::mutex::scoped_lock lock(cacheMutex_);
+    RETRIEVE_CONTEXT(call);
+
+    Instances instances;
+    std::string id = call.GetUriComponent("id", "");
+    context.GetIndex().GetChildInstances(instances, id);
+
+    if (instances.size() == 0)
+    {
+      return;
+    }
+
+    UidMap uidMap;
+    for (Instances::const_iterator it = instances.begin(); 
+         it != instances.end(); it++)
+    {
+      LOG(INFO) << "Modifying instance " << *it;
+      ParsedDicomFile& original = context.GetDicomFile(*it);
+
+      RetrieveMappedUid(original, DicomRootLevel_Series, replacements, uidMap);
+
+      if (resourceType == ResourceType_Study ||
+          resourceType == ResourceType_Patient)
+      {
+        RetrieveMappedUid(original, DicomRootLevel_Study, replacements, uidMap);
+      }
+
+      std::auto_ptr<ParsedDicomFile> modified(original.Clone());
+      ReplaceInstanceInternal(*modified, removals, replacements, DicomReplaceMode_InsertIfAbsent, removePrivateTags);
+
+      std::string modifiedInstance;
+      if (context.Store(modifiedInstance, modified->GetDicom()) != StoreStatus_Success)
+      {
+        LOG(ERROR) << "Error while storing a modified instance " << *it;
+        return;
+      }
+
+      if (isFirst)
+      {
+        DicomInstanceHasher modifiedHasher = modified->GetHasher();
+        std::string newId;
+
+        switch (resourceType)
+        {
+          case ResourceType_Series:
+            newId = modifiedHasher.HashSeries();
+            break;
+
+          case ResourceType_Study:
+            newId = modifiedHasher.HashStudy();
+            break;
+
+          case ResourceType_Patient:
+            newId = modifiedHasher.HashPatient();
+            break;
+
+          default:
+            throw OrthancException(ErrorCode_InternalError);
+        }
+
+        result["Type"] = ToString(resourceType);
+        result["Path"] = GetBasePath(resourceType, newId);
+        result["PatientID"] = modifiedHasher.HashPatient();
+        isFirst = false;
+      }
+    }
+
+    call.GetOutput().AnswerJson(result);
+  }
+
+
+
   static void ModifyInstance(RestApi::PostCall& call)
   {
     Removals removals;
--- a/OrthancServer/ServerEnumerations.cpp	Wed Jan 23 17:26:09 2013 +0100
+++ b/OrthancServer/ServerEnumerations.cpp	Mon Jan 28 15:18:17 2013 +0100
@@ -149,6 +149,12 @@
       case ChangeType_ModifiedSeries:
         return "ModifiedSeries";
 
+      case ChangeType_AnonymizedPatient:
+        return "AnonymizedPatient";
+
+      case ChangeType_ModifiedPatient:
+        return "ModifiedPatient";
+
       default:
         throw OrthancException(ErrorCode_ParameterOutOfRange);
     }
--- a/OrthancServer/ServerEnumerations.h	Wed Jan 23 17:26:09 2013 +0100
+++ b/OrthancServer/ServerEnumerations.h	Mon Jan 28 15:18:17 2013 +0100
@@ -92,7 +92,9 @@
     ChangeType_AnonymizedStudy = 6,
     ChangeType_AnonymizedSeries = 7,
     ChangeType_ModifiedStudy = 8,
-    ChangeType_ModifiedSeries = 9
+    ChangeType_ModifiedSeries = 9,
+    ChangeType_AnonymizedPatient = 10,
+    ChangeType_ModifiedPatient = 11
   };
 
   std::string GetBasePath(ResourceType type,