Mercurial > hg > orthanc
comparison OrthancFramework/Sources/DicomParsing/DicomModification.cpp @ 4687:fcd2dc7c8f31
"Replace", "Keep" and "Remove" in "/modify" and "/anonymize" accept paths to subsequences
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 09 Jun 2021 17:24:44 +0200 |
parents | 693f049729ba |
children | 177ad026d219 |
comparison
equal
deleted
inserted
replaced
4685:693f049729ba | 4687:fcd2dc7c8f31 |
---|---|
1074 throw OrthancException(ErrorCode_BadRequest); | 1074 throw OrthancException(ErrorCode_BadRequest); |
1075 } | 1075 } |
1076 | 1076 |
1077 std::string name = query[i].asString(); | 1077 std::string name = query[i].asString(); |
1078 | 1078 |
1079 DicomTag tag = FromDcmtkBridge::ParseTag(name); | 1079 const DicomPath path(DicomPath::Parse(name)); |
1080 | 1080 |
1081 if (!force && IsDatabaseKey(tag)) | 1081 if (path.GetPrefixLength() == 0 && |
1082 !force && | |
1083 IsDatabaseKey(path.GetFinalTag())) | |
1082 { | 1084 { |
1083 throw OrthancException(ErrorCode_BadRequest, | 1085 throw OrthancException(ErrorCode_BadRequest, |
1084 "Marking tag \"" + name + "\" as to be " + | 1086 "Marking tag \"" + name + "\" as to be " + |
1085 (operation == DicomModification::TagOperation_Keep ? "kept" : "removed") + | 1087 (operation == DicomModification::TagOperation_Keep ? "kept" : "removed") + |
1086 " requires the \"Force\" option to be set to true"); | 1088 " requires the \"Force\" option to be set to true"); |
1087 } | 1089 } |
1088 | 1090 |
1089 switch (operation) | 1091 switch (operation) |
1090 { | 1092 { |
1091 case DicomModification::TagOperation_Keep: | 1093 case DicomModification::TagOperation_Keep: |
1092 target.Keep(tag); | 1094 target.Keep(path); |
1093 LOG(TRACE) << "Keep: " << name << " (" << tag.Format() << ")"; | 1095 LOG(TRACE) << "Keep: " << name << " = " << path.Format(); |
1094 break; | 1096 break; |
1095 | 1097 |
1096 case DicomModification::TagOperation_Remove: | 1098 case DicomModification::TagOperation_Remove: |
1097 target.Remove(tag); | 1099 target.Remove(path); |
1098 LOG(TRACE) << "Remove: " << name << " (" << tag.Format() << ")"; | 1100 LOG(TRACE) << "Remove: " << name << " = " << path.Format(); |
1099 break; | 1101 break; |
1100 | 1102 |
1101 default: | 1103 default: |
1102 throw OrthancException(ErrorCode_InternalError); | 1104 throw OrthancException(ErrorCode_InternalError); |
1103 } | 1105 } |
1118 for (size_t i = 0; i < members.size(); i++) | 1120 for (size_t i = 0; i < members.size(); i++) |
1119 { | 1121 { |
1120 const std::string& name = members[i]; | 1122 const std::string& name = members[i]; |
1121 const Json::Value& value = replacements[name]; | 1123 const Json::Value& value = replacements[name]; |
1122 | 1124 |
1123 DicomTag tag = FromDcmtkBridge::ParseTag(name); | 1125 const DicomPath path(DicomPath::Parse(name)); |
1124 | 1126 |
1125 if (!force && IsDatabaseKey(tag)) | 1127 if (path.GetPrefixLength() == 0 && |
1128 !force && | |
1129 IsDatabaseKey(path.GetFinalTag())) | |
1126 { | 1130 { |
1127 throw OrthancException(ErrorCode_BadRequest, | 1131 throw OrthancException(ErrorCode_BadRequest, |
1128 "Marking tag \"" + name + "\" as to be replaced " + | 1132 "Marking tag \"" + name + "\" as to be replaced " + |
1129 "requires the \"Force\" option to be set to true"); | 1133 "requires the \"Force\" option to be set to true"); |
1130 } | 1134 } |
1131 | 1135 |
1132 target.Replace(tag, value, false /* not safe for anonymization */); | 1136 target.Replace(path, value, false /* not safe for anonymization */); |
1133 | 1137 |
1134 LOG(TRACE) << "Replace: " << name << " (" << tag.Format() | 1138 LOG(TRACE) << "Replace: " << name << " = " << path.Format() |
1135 << ") == " << value.toStyledString(); | 1139 << " by: " << value.toStyledString(); |
1136 } | 1140 } |
1137 } | 1141 } |
1138 | 1142 |
1139 | 1143 |
1140 static bool GetBooleanValue(const std::string& member, | 1144 static bool GetBooleanValue(const std::string& member, |
1280 static const char* REPLACEMENTS = "Replacements"; | 1284 static const char* REPLACEMENTS = "Replacements"; |
1281 static const char* MAP_PATIENTS = "MapPatients"; | 1285 static const char* MAP_PATIENTS = "MapPatients"; |
1282 static const char* MAP_STUDIES = "MapStudies"; | 1286 static const char* MAP_STUDIES = "MapStudies"; |
1283 static const char* MAP_SERIES = "MapSeries"; | 1287 static const char* MAP_SERIES = "MapSeries"; |
1284 static const char* MAP_INSTANCES = "MapInstances"; | 1288 static const char* MAP_INSTANCES = "MapInstances"; |
1285 static const char* PRIVATE_CREATOR = "PrivateCreator"; // New in Orthanc 1.6.0 | 1289 static const char* PRIVATE_CREATOR = "PrivateCreator"; // New in Orthanc 1.6.0 |
1286 static const char* UIDS = "Uids"; // New in Orthanc 1.9.4 | 1290 static const char* UIDS = "Uids"; // New in Orthanc 1.9.4 |
1287 static const char* REMOVED_RANGES = "RemovedRanges"; // New in Orthanc 1.9.4 | 1291 static const char* REMOVED_RANGES = "RemovedRanges"; // New in Orthanc 1.9.4 |
1292 static const char* KEEP_SEQUENCES = "KeepSequences"; // New in Orthanc 1.9.4 | |
1293 static const char* REMOVE_SEQUENCES = "RemoveSequences"; // New in Orthanc 1.9.4 | |
1294 static const char* SEQUENCE_REPLACEMENTS = "SequenceReplacements"; // New in Orthanc 1.9.4 | |
1288 | 1295 |
1289 void DicomModification::Serialize(Json::Value& value) const | 1296 void DicomModification::Serialize(Json::Value& value) const |
1290 { | 1297 { |
1291 if (identifierGenerator_ != NULL) | 1298 if (identifierGenerator_ != NULL) |
1292 { | 1299 { |
1375 item.append(it->GetElementTo()); | 1382 item.append(it->GetElementTo()); |
1376 ranges.append(item); | 1383 ranges.append(item); |
1377 } | 1384 } |
1378 | 1385 |
1379 value[REMOVED_RANGES] = ranges; | 1386 value[REMOVED_RANGES] = ranges; |
1387 | |
1388 // New in Orthanc 1.9.4 | |
1389 Json::Value lst = Json::arrayValue; | |
1390 for (ListOfPaths::const_iterator it = keepSequences_.begin(); it != keepSequences_.end(); ++it) | |
1391 { | |
1392 assert(it->GetPrefixLength() > 0); | |
1393 lst.append(it->Format()); | |
1394 } | |
1395 | |
1396 value[KEEP_SEQUENCES] = lst; | |
1397 | |
1398 // New in Orthanc 1.9.4 | |
1399 lst = Json::arrayValue; | |
1400 for (ListOfPaths::const_iterator it = removeSequences_.begin(); it != removeSequences_.end(); ++it) | |
1401 { | |
1402 assert(it->GetPrefixLength() > 0); | |
1403 lst.append(it->Format()); | |
1404 } | |
1405 | |
1406 value[REMOVE_SEQUENCES] = lst; | |
1407 | |
1408 // New in Orthanc 1.9.4 | |
1409 lst = Json::objectValue; | |
1410 for (SequenceReplacements::const_iterator it = sequenceReplacements_.begin(); it != sequenceReplacements_.end(); ++it) | |
1411 { | |
1412 assert(*it != NULL); | |
1413 assert((*it)->GetPath().GetPrefixLength() > 0); | |
1414 lst[(*it)->GetPath().Format()] = (*it)->GetValue(); | |
1415 } | |
1416 | |
1417 value[SEQUENCE_REPLACEMENTS] = lst; | |
1380 } | 1418 } |
1381 | 1419 |
1382 void DicomModification::UnserializeUidMap(ResourceType level, | 1420 void DicomModification::UnserializeUidMap(ResourceType level, |
1383 const Json::Value& serialized, | 1421 const Json::Value& serialized, |
1384 const char* field) | 1422 const char* field) |
1509 } | 1547 } |
1510 } | 1548 } |
1511 } | 1549 } |
1512 } | 1550 } |
1513 } | 1551 } |
1552 | |
1553 // New in Orthanc 1.9.4 | |
1554 if (serialized.isMember(KEEP_SEQUENCES)) | |
1555 { | |
1556 const Json::Value& keep = serialized[KEEP_SEQUENCES]; | |
1557 | |
1558 if (keep.type() != Json::arrayValue) | |
1559 { | |
1560 throw OrthancException(ErrorCode_BadFileFormat); | |
1561 } | |
1562 else | |
1563 { | |
1564 for (Json::Value::ArrayIndex i = 0; i < keep.size(); i++) | |
1565 { | |
1566 if (keep[i].type() != Json::stringValue) | |
1567 { | |
1568 throw OrthancException(ErrorCode_BadFileFormat); | |
1569 } | |
1570 else | |
1571 { | |
1572 keepSequences_.push_back(DicomPath::Parse(keep[i].asString())); | |
1573 } | |
1574 } | |
1575 } | |
1576 } | |
1577 | |
1578 // New in Orthanc 1.9.4 | |
1579 if (serialized.isMember(REMOVE_SEQUENCES)) | |
1580 { | |
1581 const Json::Value& remove = serialized[REMOVE_SEQUENCES]; | |
1582 | |
1583 if (remove.type() != Json::arrayValue) | |
1584 { | |
1585 throw OrthancException(ErrorCode_BadFileFormat); | |
1586 } | |
1587 else | |
1588 { | |
1589 for (Json::Value::ArrayIndex i = 0; i < remove.size(); i++) | |
1590 { | |
1591 if (remove[i].type() != Json::stringValue) | |
1592 { | |
1593 throw OrthancException(ErrorCode_BadFileFormat); | |
1594 } | |
1595 else | |
1596 { | |
1597 removeSequences_.push_back(DicomPath::Parse(remove[i].asString())); | |
1598 } | |
1599 } | |
1600 } | |
1601 } | |
1602 | |
1603 // New in Orthanc 1.9.4 | |
1604 if (serialized.isMember(SEQUENCE_REPLACEMENTS)) | |
1605 { | |
1606 const Json::Value& replace = serialized[SEQUENCE_REPLACEMENTS]; | |
1607 | |
1608 if (replace.type() != Json::objectValue) | |
1609 { | |
1610 throw OrthancException(ErrorCode_BadFileFormat); | |
1611 } | |
1612 else | |
1613 { | |
1614 Json::Value::Members members = replace.getMemberNames(); | |
1615 for (size_t i = 0; i < members.size(); i++) | |
1616 { | |
1617 sequenceReplacements_.push_back( | |
1618 new SequenceReplacement(DicomPath::Parse(members[i]), replace[members[i]])); | |
1619 } | |
1620 } | |
1621 } | |
1514 } | 1622 } |
1515 | 1623 |
1516 | 1624 |
1517 void DicomModification::SetPrivateCreator(const std::string &privateCreator) | 1625 void DicomModification::SetPrivateCreator(const std::string &privateCreator) |
1518 { | 1626 { |