comparison OrthancServer/OrthancRestApi.cpp @ 344:cd6749e53a03

anonymization from orthanc explorer
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 21 Jan 2013 13:23:26 +0100
parents a58a8be26aff
children 1082e8121d10
comparison
equal deleted inserted replaced
343:b1edbd636cb8 344:cd6749e53a03
1164 bool removePrivateTags, 1164 bool removePrivateTags,
1165 MetadataType metadataType, 1165 MetadataType metadataType,
1166 ChangeType changeType, 1166 ChangeType changeType,
1167 RestApi::PostCall& call) 1167 RestApi::PostCall& call)
1168 { 1168 {
1169 RETRIEVE_CONTEXT(call); 1169 Json::Value result = Json::objectValue;
1170 1170
1171 boost::mutex::scoped_lock lock(cacheMutex_); 1171 {
1172 1172 boost::mutex::scoped_lock lock(cacheMutex_);
1173 typedef std::list<std::string> Instances; 1173 RETRIEVE_CONTEXT(call);
1174 Instances instances; 1174
1175 std::string id = call.GetUriComponent("id", ""); 1175 typedef std::list<std::string> Instances;
1176 context.GetIndex().GetChildInstances(instances, id); 1176 Instances instances;
1177 1177 std::string id = call.GetUriComponent("id", "");
1178 if (instances.size() == 0) 1178 context.GetIndex().GetChildInstances(instances, id);
1179 { 1179
1180 return; 1180 if (instances.size() == 0)
1181 } 1181 {
1182
1183 replacements[DICOM_TAG_SERIES_INSTANCE_UID] = FromDcmtkBridge::GenerateUniqueIdentifier(DicomRootLevel_Series);
1184
1185 std::string newSeriesId;
1186 for (Instances::const_iterator it = instances.begin();
1187 it != instances.end(); it++)
1188 {
1189 LOG(INFO) << "Modifying instance " << *it;
1190 ParsedDicomFile& original = context.GetDicomFile(*it);
1191 std::auto_ptr<ParsedDicomFile> modified(original.Clone());
1192 ReplaceInstanceInternal(*modified, removals, replacements, DicomReplaceMode_InsertIfAbsent, removePrivateTags);
1193
1194 std::string modifiedInstance;
1195 if (context.Store(modifiedInstance, modified->GetDicom()) != StoreStatus_Success)
1196 {
1197 LOG(ERROR) << "Error while storing a modified instance " << *it;
1198 return; 1182 return;
1199 } 1183 }
1200 1184
1201 DicomInstanceHasher modifiedHasher = modified->GetHasher(); 1185 replacements[DICOM_TAG_SERIES_INSTANCE_UID] = FromDcmtkBridge::GenerateUniqueIdentifier(DicomRootLevel_Series);
1202 DicomInstanceHasher originalHasher = original.GetHasher(); 1186
1203 1187 std::string newSeriesId, newPatientId;
1204 if (newSeriesId.size() == 0) 1188 for (Instances::const_iterator it = instances.begin();
1205 { 1189 it != instances.end(); it++)
1206 assert(id == originalHasher.HashSeries()); 1190 {
1207 newSeriesId = modifiedHasher.HashSeries(); 1191 LOG(INFO) << "Modifying instance " << *it;
1208 context.GetIndex().SetMetadata(newSeriesId, metadataType, id); 1192 ParsedDicomFile& original = context.GetDicomFile(*it);
1209 } 1193 std::auto_ptr<ParsedDicomFile> modified(original.Clone());
1210 1194 ReplaceInstanceInternal(*modified, removals, replacements, DicomReplaceMode_InsertIfAbsent, removePrivateTags);
1211 assert(*it == originalHasher.HashInstance()); 1195
1212 assert(modifiedInstance == modifiedHasher.HashInstance()); 1196 std::string modifiedInstance;
1213 context.GetIndex().SetMetadata(modifiedInstance, metadataType, *it); 1197 if (context.Store(modifiedInstance, modified->GetDicom()) != StoreStatus_Success)
1214 } 1198 {
1215 1199 LOG(ERROR) << "Error while storing a modified instance " << *it;
1216 context.GetIndex().LogChange(changeType, newSeriesId); 1200 return;
1217 1201 }
1218 assert(newSeriesId.size() != 0); 1202
1219 Json::Value result = Json::objectValue; 1203 DicomInstanceHasher modifiedHasher = modified->GetHasher();
1220 result["ID"] = newSeriesId; 1204 DicomInstanceHasher originalHasher = original.GetHasher();
1221 result["Path"] = GetBasePath(ResourceType_Series, newSeriesId); 1205
1206 if (newSeriesId.size() == 0)
1207 {
1208 assert(id == originalHasher.HashSeries());
1209 newSeriesId = modifiedHasher.HashSeries();
1210 context.GetIndex().SetMetadata(newSeriesId, metadataType, id);
1211 }
1212
1213 if (newPatientId.size() == 0)
1214 {
1215 newPatientId = modifiedHasher.HashPatient();
1216 }
1217
1218 assert(*it == originalHasher.HashInstance());
1219 assert(modifiedInstance == modifiedHasher.HashInstance());
1220 context.GetIndex().SetMetadata(modifiedInstance, metadataType, *it);
1221 }
1222
1223 context.GetIndex().LogChange(changeType, newSeriesId);
1224
1225 assert(newSeriesId.size() != 0);
1226 result["Type"] = ToString(ResourceType_Series);
1227 result["ID"] = newSeriesId;
1228 result["Path"] = GetBasePath(ResourceType_Series, newSeriesId);
1229 result["PatientID"] = newPatientId;
1230 }
1231
1232 // Do not answer before the lock has been released
1222 call.GetOutput().AnswerJson(result); 1233 call.GetOutput().AnswerJson(result);
1223 } 1234 }
1224 1235
1225 1236
1226 static void AnonymizeOrModifyStudy(Removals removals, 1237 static void AnonymizeOrModifyStudy(Removals removals,
1228 bool removePrivateTags, 1239 bool removePrivateTags,
1229 MetadataType metadataType, 1240 MetadataType metadataType,
1230 ChangeType changeType, 1241 ChangeType changeType,
1231 RestApi::PostCall& call) 1242 RestApi::PostCall& call)
1232 { 1243 {
1233 RETRIEVE_CONTEXT(call); 1244 Json::Value result = Json::objectValue;
1234 boost::mutex::scoped_lock lock(cacheMutex_); 1245
1235 1246 {
1236 typedef std::list<std::string> Instances; 1247 boost::mutex::scoped_lock lock(cacheMutex_);
1237 typedef std::map<std::string, std::string> SeriesUidMap; 1248 RETRIEVE_CONTEXT(call);
1238 1249
1239 Instances instances; 1250 typedef std::list<std::string> Instances;
1240 std::string id = call.GetUriComponent("id", ""); 1251 typedef std::map<std::string, std::string> SeriesUidMap;
1241 context.GetIndex().GetChildInstances(instances, id); 1252
1242 1253 Instances instances;
1243 if (instances.size() == 0) 1254 std::string id = call.GetUriComponent("id", "");
1244 { 1255 context.GetIndex().GetChildInstances(instances, id);
1245 return; 1256
1246 } 1257 if (instances.size() == 0)
1247 1258 {
1248 std::string newStudyId;
1249 replacements[DICOM_TAG_STUDY_INSTANCE_UID] = FromDcmtkBridge::GenerateUniqueIdentifier(DicomRootLevel_Study);
1250
1251 SeriesUidMap seriesUidMap;
1252 for (Instances::const_iterator it = instances.begin();
1253 it != instances.end(); it++)
1254 {
1255 LOG(INFO) << "Modifying instance " << *it;
1256 ParsedDicomFile& original = context.GetDicomFile(*it);
1257
1258 std::string seriesUid;
1259 if (!original.GetTagValue(seriesUid, DICOM_TAG_SERIES_INSTANCE_UID))
1260 {
1261 throw OrthancException(ErrorCode_InternalError);
1262 }
1263
1264 bool isNewSeries;
1265 SeriesUidMap::const_iterator it2 = seriesUidMap.find(seriesUid);
1266 if (it2 == seriesUidMap.end())
1267 {
1268 std::string newSeriesUid = FromDcmtkBridge::GenerateUniqueIdentifier(DicomRootLevel_Series);
1269 seriesUidMap[seriesUid] = newSeriesUid;
1270 replacements[DICOM_TAG_SERIES_INSTANCE_UID] = newSeriesUid;
1271 isNewSeries = true;
1272 }
1273 else
1274 {
1275 replacements[DICOM_TAG_SERIES_INSTANCE_UID] = it2->second;
1276 isNewSeries = false;
1277 }
1278
1279 std::auto_ptr<ParsedDicomFile> modified(original.Clone());
1280 ReplaceInstanceInternal(*modified, removals, replacements, DicomReplaceMode_InsertIfAbsent, removePrivateTags);
1281
1282 std::string modifiedInstance;
1283 if (context.Store(modifiedInstance, modified->GetDicom()) != StoreStatus_Success)
1284 {
1285 LOG(ERROR) << "Error while storing a modified instance " << *it;
1286 return; 1259 return;
1287 } 1260 }
1288 1261
1289 DicomInstanceHasher modifiedHasher = modified->GetHasher(); 1262 std::string newPatientId;
1290 DicomInstanceHasher originalHasher = original.GetHasher(); 1263 std::string newStudyId;
1291 1264 replacements[DICOM_TAG_STUDY_INSTANCE_UID] = FromDcmtkBridge::GenerateUniqueIdentifier(DicomRootLevel_Study);
1292 if (isNewSeries) 1265
1293 { 1266 SeriesUidMap seriesUidMap;
1294 context.GetIndex().SetMetadata 1267 for (Instances::const_iterator it = instances.begin();
1295 (modifiedHasher.HashSeries(), metadataType, originalHasher.HashSeries()); 1268 it != instances.end(); it++)
1296 } 1269 {
1297 1270 LOG(INFO) << "Modifying instance " << *it;
1298 if (newStudyId.size() == 0) 1271 ParsedDicomFile& original = context.GetDicomFile(*it);
1299 { 1272
1300 newStudyId = modifiedHasher.HashStudy(); 1273 std::string seriesUid;
1301 context.GetIndex().SetMetadata(newStudyId, metadataType, originalHasher.HashStudy()); 1274 if (!original.GetTagValue(seriesUid, DICOM_TAG_SERIES_INSTANCE_UID))
1302 } 1275 {
1303 1276 throw OrthancException(ErrorCode_InternalError);
1304 assert(*it == originalHasher.HashInstance()); 1277 }
1305 assert(modifiedInstance == modifiedHasher.HashInstance()); 1278
1306 context.GetIndex().SetMetadata(modifiedInstance, metadataType, *it); 1279 bool isNewSeries;
1307 } 1280 SeriesUidMap::const_iterator it2 = seriesUidMap.find(seriesUid);
1308 1281 if (it2 == seriesUidMap.end())
1309 context.GetIndex().LogChange(changeType, newStudyId); 1282 {
1310 1283 std::string newSeriesUid = FromDcmtkBridge::GenerateUniqueIdentifier(DicomRootLevel_Series);
1311 assert(newStudyId.size() != 0); 1284 seriesUidMap[seriesUid] = newSeriesUid;
1312 Json::Value result = Json::objectValue; 1285 replacements[DICOM_TAG_SERIES_INSTANCE_UID] = newSeriesUid;
1313 result["ID"] = newStudyId; 1286 isNewSeries = true;
1314 result["Path"] = GetBasePath(ResourceType_Study, newStudyId); 1287 }
1288 else
1289 {
1290 replacements[DICOM_TAG_SERIES_INSTANCE_UID] = it2->second;
1291 isNewSeries = false;
1292 }
1293
1294 std::auto_ptr<ParsedDicomFile> modified(original.Clone());
1295 ReplaceInstanceInternal(*modified, removals, replacements, DicomReplaceMode_InsertIfAbsent, removePrivateTags);
1296
1297 std::string modifiedInstance;
1298 if (context.Store(modifiedInstance, modified->GetDicom()) != StoreStatus_Success)
1299 {
1300 LOG(ERROR) << "Error while storing a modified instance " << *it;
1301 return;
1302 }
1303
1304 DicomInstanceHasher modifiedHasher = modified->GetHasher();
1305 DicomInstanceHasher originalHasher = original.GetHasher();
1306
1307 if (isNewSeries)
1308 {
1309 context.GetIndex().SetMetadata
1310 (modifiedHasher.HashSeries(), metadataType, originalHasher.HashSeries());
1311 }
1312
1313 if (newStudyId.size() == 0)
1314 {
1315 newStudyId = modifiedHasher.HashStudy();
1316 context.GetIndex().SetMetadata(newStudyId, metadataType, originalHasher.HashStudy());
1317 }
1318
1319 if (newPatientId.size() == 0)
1320 {
1321 newPatientId = modifiedHasher.HashPatient();
1322 }
1323
1324 assert(*it == originalHasher.HashInstance());
1325 assert(modifiedInstance == modifiedHasher.HashInstance());
1326 context.GetIndex().SetMetadata(modifiedInstance, metadataType, *it);
1327 }
1328
1329 context.GetIndex().LogChange(changeType, newStudyId);
1330
1331 assert(newStudyId.size() != 0);
1332 result["Type"] = ToString(ResourceType_Study);
1333 result["ID"] = newStudyId;
1334 result["Path"] = GetBasePath(ResourceType_Study, newStudyId);
1335 result["PatientID"] = newPatientId;
1336 }
1337
1338 // Do not answer before the lock has been released
1315 call.GetOutput().AnswerJson(result); 1339 call.GetOutput().AnswerJson(result);
1316 } 1340 }
1317 1341
1318 1342
1319 1343