# HG changeset patch # User Sebastien Jodogne # Date 1359382697 -3600 # Node ID 1082e8121d10a51a667d47b1e981c6dae9214220 # Parent a9752f88400c2f008c830dffc062405c8c656a4b refactoring anonymization/modification diff -r a9752f88400c -r 1082e8121d10 OrthancServer/OrthancRestApi.cpp --- 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, std::string> UidMap; + } + + static void RetrieveMappedUid(ParsedDicomFile& dicom, + DicomRootLevel level, + Replacements& replacements, + UidMap& uidMap) + { + std::auto_ptr 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 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 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; diff -r a9752f88400c -r 1082e8121d10 OrthancServer/ServerEnumerations.cpp --- 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); } diff -r a9752f88400c -r 1082e8121d10 OrthancServer/ServerEnumerations.h --- 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,