comparison OrthancFramework/Sources/DicomParsing/DicomModification.cpp @ 5807:8279eaab0d1d attach-custom-data tip

merged default -> attach-custom-data
author Alain Mazy <am@orthanc.team>
date Tue, 24 Sep 2024 11:39:52 +0200
parents f7adfb22e20e
children
comparison
equal deleted inserted replaced
5085:79f98ee4f04b 5807:8279eaab0d1d
1 /** 1 /**
2 * Orthanc - A Lightweight, RESTful DICOM Store 2 * Orthanc - A Lightweight, RESTful DICOM Store
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics 3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium 4 * Department, University Hospital of Liege, Belgium
5 * Copyright (C) 2017-2022 Osimis S.A., Belgium 5 * Copyright (C) 2017-2023 Osimis S.A., Belgium
6 * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium 6 * Copyright (C) 2024-2024 Orthanc Team SRL, Belgium
7 * Copyright (C) 2021-2024 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
7 * 8 *
8 * This program is free software: you can redistribute it and/or 9 * This program is free software: you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License 10 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation, either version 3 of 11 * as published by the Free Software Foundation, either version 3 of
11 * the License, or (at your option) any later version. 12 * the License, or (at your option) any later version.
40 static const std::string ORTHANC_DEIDENTIFICATION_METHOD_2017c = 41 static const std::string ORTHANC_DEIDENTIFICATION_METHOD_2017c =
41 "Orthanc " ORTHANC_VERSION " - PS 3.15-2017c Table E.1-1 Basic Profile"; 42 "Orthanc " ORTHANC_VERSION " - PS 3.15-2017c Table E.1-1 Basic Profile";
42 43
43 static const std::string ORTHANC_DEIDENTIFICATION_METHOD_2021b = 44 static const std::string ORTHANC_DEIDENTIFICATION_METHOD_2021b =
44 "Orthanc " ORTHANC_VERSION " - PS 3.15-2021b Table E.1-1 Basic Profile"; 45 "Orthanc " ORTHANC_VERSION " - PS 3.15-2021b Table E.1-1 Basic Profile";
46
47 static const std::string ORTHANC_DEIDENTIFICATION_METHOD_2023b =
48 "Orthanc " ORTHANC_VERSION " - PS 3.15-2023b Table E.1-1 Basic Profile";
45 49
46 namespace Orthanc 50 namespace Orthanc
47 { 51 {
48 namespace 52 namespace
49 { 53 {
312 * In RT-STRUCT, this ReferencedSOPInstanceUID is actually 316 * In RT-STRUCT, this ReferencedSOPInstanceUID is actually
313 * referencing a StudyInstanceUID !! (observed in many 317 * referencing a StudyInstanceUID !! (observed in many
314 * data sets including: 318 * data sets including:
315 * https://wiki.cancerimagingarchive.net/display/Public/Lung+CT+Segmentation+Challenge+2017) 319 * https://wiki.cancerimagingarchive.net/display/Public/Lung+CT+Segmentation+Challenge+2017)
316 * Tested in "test_anonymize_relationships_5". Introduced 320 * Tested in "test_anonymize_relationships_5". Introduced
317 * in: https://hg.orthanc-server.com/orthanc/rev/3513 321 * in: https://orthanc.uclouvain.be/hg/orthanc/rev/3513
318 **/ 322 **/
319 newValue = that_.MapDicomIdentifier(value, ResourceType_Study); 323 newValue = that_.MapDicomIdentifier(value, ResourceType_Study);
320 } 324 }
321 else 325 else
322 { 326 {
425 { 429 {
426 assert(it->second != NULL); 430 assert(it->second != NULL);
427 431
428 if (it->second->asString() == ORTHANC_DEIDENTIFICATION_METHOD_2008 || 432 if (it->second->asString() == ORTHANC_DEIDENTIFICATION_METHOD_2008 ||
429 it->second->asString() == ORTHANC_DEIDENTIFICATION_METHOD_2017c || 433 it->second->asString() == ORTHANC_DEIDENTIFICATION_METHOD_2017c ||
430 it->second->asString() == ORTHANC_DEIDENTIFICATION_METHOD_2021b) 434 it->second->asString() == ORTHANC_DEIDENTIFICATION_METHOD_2021b ||
435 it->second->asString() == ORTHANC_DEIDENTIFICATION_METHOD_2023b)
431 { 436 {
432 delete it->second; 437 delete it->second;
433 replacements_.erase(it); 438 replacements_.erase(it);
434 } 439 }
435 } 440 }
519 } 524 }
520 525
521 526
522 DicomModification::DicomModification() : 527 DicomModification::DicomModification() :
523 removePrivateTags_(false), 528 removePrivateTags_(false),
529 keepLabels_(false),
524 level_(ResourceType_Instance), 530 level_(ResourceType_Instance),
525 allowManualIdentifiers_(true), 531 allowManualIdentifiers_(true),
526 keepStudyInstanceUid_(false), 532 keepStudyInstanceUid_(false),
527 keepSeriesInstanceUid_(false), 533 keepSeriesInstanceUid_(false),
528 keepSopInstanceUid_(false), 534 keepSopInstanceUid_(false),
538 ClearReplacements(); 544 ClearReplacements();
539 } 545 }
540 546
541 void DicomModification::Keep(const DicomTag& tag) 547 void DicomModification::Keep(const DicomTag& tag)
542 { 548 {
549 keep_.insert(tag);
543 removals_.erase(tag); 550 removals_.erase(tag);
544 clearings_.erase(tag); 551 clearings_.erase(tag);
545 uids_.erase(tag); 552 uids_.erase(tag);
546 553
547 CancelReplacement(tag); 554 CancelReplacement(tag);
634 bool DicomModification::IsReplaced(const DicomTag& tag) const 641 bool DicomModification::IsReplaced(const DicomTag& tag) const
635 { 642 {
636 return replacements_.find(tag) != replacements_.end(); 643 return replacements_.find(tag) != replacements_.end();
637 } 644 }
638 645
646 bool DicomModification::IsKept(const DicomTag& tag) const
647 {
648 return keep_.find(tag) != keep_.end();
649 }
650
639 const Json::Value& DicomModification::GetReplacement(const DicomTag& tag) const 651 const Json::Value& DicomModification::GetReplacement(const DicomTag& tag) const
640 { 652 {
641 Replacements::const_iterator it = replacements_.find(tag); 653 Replacements::const_iterator it = replacements_.find(tag);
642 654
643 if (it == replacements_.end()) 655 if (it == replacements_.end())
678 } 690 }
679 691
680 bool DicomModification::ArePrivateTagsRemoved() const 692 bool DicomModification::ArePrivateTagsRemoved() const
681 { 693 {
682 return removePrivateTags_; 694 return removePrivateTags_;
695 }
696
697 void DicomModification::SetKeepLabels(bool keep)
698 {
699 keepLabels_ = keep;
700 }
701
702 bool DicomModification::AreLabelsKept() const
703 {
704 return keepLabels_;
683 } 705 }
684 706
685 void DicomModification::SetLevel(ResourceType level) 707 void DicomModification::SetLevel(ResourceType level)
686 { 708 {
687 uidMap_.clear(); 709 uidMap_.clear();
712 { 734 {
713 /** 735 /**
714 * Values below come from the hardcoded UID of Orthanc 1.9.3 736 * Values below come from the hardcoded UID of Orthanc 1.9.3
715 * in DicomModification::RelationshipsVisitor::VisitString() and 737 * in DicomModification::RelationshipsVisitor::VisitString() and
716 * DicomModification::RelationshipsVisitor::RemoveRelationships() 738 * DicomModification::RelationshipsVisitor::RemoveRelationships()
717 * https://hg.orthanc-server.com/orthanc/file/Orthanc-1.9.3/OrthancFramework/Sources/DicomParsing/DicomModification.cpp#l117 739 * https://orthanc.uclouvain.be/hg/orthanc/file/Orthanc-1.9.3/OrthancFramework/Sources/DicomParsing/DicomModification.cpp#l117
718 **/ 740 **/
719 uids_.clear(); 741 uids_.clear();
720 742
721 // (*) "PatientID" and "PatientName" are handled as UIDs since Orthanc 1.9.4 743 // (*) "PatientID" and "PatientName" are handled as UIDs since Orthanc 1.9.4
722 uids_.insert(DICOM_TAG_PATIENT_ID); 744 uids_.insert(DICOM_TAG_PATIENT_ID);
823 * This is Table E.1-1 from PS 3.15-2021b (DICOM Part 15: Security 845 * This is Table E.1-1 from PS 3.15-2021b (DICOM Part 15: Security
824 * and System Management Profiles), "basic profile" column. It was 846 * and System Management Profiles), "basic profile" column. It was
825 * generated automatically by calling: 847 * generated automatically by calling:
826 * "../../../OrthancServer/Resources/GenerateAnonymizationProfile.py 848 * "../../../OrthancServer/Resources/GenerateAnonymizationProfile.py
827 * https://raw.githubusercontent.com/jodogne/dicom-specification/master/2021b/part15.xml" 849 * https://raw.githubusercontent.com/jodogne/dicom-specification/master/2021b/part15.xml"
828 *
829 * http://dicom.nema.org/medical/dicom/2021b/output/chtml/part15/chapter_E.html#table_E.1-1a
830 * http://dicom.nema.org/medical/dicom/2021b/output/chtml/part15/chapter_E.html#table_E.1-1
831 **/ 850 **/
832 851
833 #include "DicomModification_Anonymization2021b.impl.h" 852 #include "DicomModification_Anonymization2021b.impl.h"
834 853
835 // Set the DeidentificationMethod tag 854 // Set the DeidentificationMethod tag
836 ReplaceInternal(DICOM_TAG_DEIDENTIFICATION_METHOD, ORTHANC_DEIDENTIFICATION_METHOD_2021b); 855 ReplaceInternal(DICOM_TAG_DEIDENTIFICATION_METHOD, ORTHANC_DEIDENTIFICATION_METHOD_2021b);
837 } 856 }
838 857
839 858
859 void DicomModification::SetupAnonymization2023b()
860 {
861 /**
862 * This is Table E.1-1 from PS 3.15-2023b (DICOM Part 15: Security
863 * and System Management Profiles), "basic profile" column. It was
864 * generated automatically by calling:
865 * "../../../OrthancServer/Resources/GenerateAnonymizationProfile.py
866 * https://raw.githubusercontent.com/jodogne/dicom-specification/master/2023b/part15.xml"
867 *
868 * http://dicom.nema.org/medical/dicom/current/output/chtml/part15/chapter_E.html#table_E.1-1a
869 * http://dicom.nema.org/medical/dicom/current/output/chtml/part15/chapter_E.html#table_E.1-1
870 **/
871
872 #include "DicomModification_Anonymization2023b.impl.h"
873
874 // Set the DeidentificationMethod tag
875 ReplaceInternal(DICOM_TAG_DEIDENTIFICATION_METHOD, ORTHANC_DEIDENTIFICATION_METHOD_2023b);
876 }
877
878
840 void DicomModification::SetupAnonymization(DicomVersion version) 879 void DicomModification::SetupAnonymization(DicomVersion version)
841 { 880 {
842 isAnonymization_ = true; 881 isAnonymization_ = true;
843 882
883 keep_.clear();
844 removals_.clear(); 884 removals_.clear();
845 clearings_.clear(); 885 clearings_.clear();
846 removedRanges_.clear(); 886 removedRanges_.clear();
847 uids_.clear(); 887 uids_.clear();
848 ClearReplacements(); 888 ClearReplacements();
865 905
866 case DicomVersion_2021b: 906 case DicomVersion_2021b:
867 SetupAnonymization2021b(); 907 SetupAnonymization2021b();
868 break; 908 break;
869 909
910 case DicomVersion_2023b:
911 SetupAnonymization2023b();
912 break;
913
870 default: 914 default:
871 throw OrthancException(ErrorCode_ParameterOutOfRange); 915 throw OrthancException(ErrorCode_ParameterOutOfRange);
872 } 916 }
873 917
874 // Set the PatientIdentityRemoved tag 918 // Set the PatientIdentityRemoved tag
916 if (IsRemoved(DICOM_TAG_PATIENT_ID) || 960 if (IsRemoved(DICOM_TAG_PATIENT_ID) ||
917 IsRemoved(DICOM_TAG_STUDY_INSTANCE_UID) || 961 IsRemoved(DICOM_TAG_STUDY_INSTANCE_UID) ||
918 IsRemoved(DICOM_TAG_SERIES_INSTANCE_UID) || 962 IsRemoved(DICOM_TAG_SERIES_INSTANCE_UID) ||
919 IsRemoved(DICOM_TAG_SOP_INSTANCE_UID)) 963 IsRemoved(DICOM_TAG_SOP_INSTANCE_UID))
920 { 964 {
921 throw OrthancException(ErrorCode_BadRequest); 965 throw OrthancException(ErrorCode_BadRequest, "It is forbidden to remove one of the main Dicom identifiers");
922 } 966 }
923 967
924
925 // Sanity checks at the patient level
926 bool isReplacedPatientId = (IsReplaced(DICOM_TAG_PATIENT_ID) ||
927 uids_.find(DICOM_TAG_PATIENT_ID) != uids_.end());
928
929 if (level_ == ResourceType_Patient && !isReplacedPatientId)
930 {
931 throw OrthancException(ErrorCode_BadRequest,
932 "When modifying a patient, her PatientID is required to be modified");
933 }
934
935 if (!allowManualIdentifiers_) 968 if (!allowManualIdentifiers_)
936 { 969 {
970 // Sanity checks at the patient level
937 if (level_ == ResourceType_Patient && IsReplaced(DICOM_TAG_STUDY_INSTANCE_UID)) 971 if (level_ == ResourceType_Patient && IsReplaced(DICOM_TAG_STUDY_INSTANCE_UID))
938 { 972 {
939 throw OrthancException(ErrorCode_BadRequest, 973 throw OrthancException(ErrorCode_BadRequest,
940 "When modifying a patient, the StudyInstanceUID cannot be manually modified"); 974 "When modifying a patient, the StudyInstanceUID cannot be manually modified");
941 } 975 }
949 if (level_ == ResourceType_Patient && IsReplaced(DICOM_TAG_SOP_INSTANCE_UID)) 983 if (level_ == ResourceType_Patient && IsReplaced(DICOM_TAG_SOP_INSTANCE_UID))
950 { 984 {
951 throw OrthancException(ErrorCode_BadRequest, 985 throw OrthancException(ErrorCode_BadRequest,
952 "When modifying a patient, the SopInstanceUID cannot be manually modified"); 986 "When modifying a patient, the SopInstanceUID cannot be manually modified");
953 } 987 }
954 } 988
955 989 // Sanity checks at the study level
956
957 // Sanity checks at the study level
958 if (level_ == ResourceType_Study && isReplacedPatientId)
959 {
960 throw OrthancException(ErrorCode_BadRequest,
961 "When modifying a study, the parent PatientID cannot be manually modified");
962 }
963
964 if (!allowManualIdentifiers_)
965 {
966 if (level_ == ResourceType_Study && IsReplaced(DICOM_TAG_SERIES_INSTANCE_UID)) 990 if (level_ == ResourceType_Study && IsReplaced(DICOM_TAG_SERIES_INSTANCE_UID))
967 { 991 {
968 throw OrthancException(ErrorCode_BadRequest, 992 throw OrthancException(ErrorCode_BadRequest,
969 "When modifying a study, the SeriesInstanceUID cannot be manually modified"); 993 "When modifying a study, the SeriesInstanceUID cannot be manually modified");
970 } 994 }
972 if (level_ == ResourceType_Study && IsReplaced(DICOM_TAG_SOP_INSTANCE_UID)) 996 if (level_ == ResourceType_Study && IsReplaced(DICOM_TAG_SOP_INSTANCE_UID))
973 { 997 {
974 throw OrthancException(ErrorCode_BadRequest, 998 throw OrthancException(ErrorCode_BadRequest,
975 "When modifying a study, the SopInstanceUID cannot be manually modified"); 999 "When modifying a study, the SopInstanceUID cannot be manually modified");
976 } 1000 }
977 } 1001
978 1002 // Sanity checks at the series level
979
980 // Sanity checks at the series level
981 if (level_ == ResourceType_Series && isReplacedPatientId)
982 {
983 throw OrthancException(ErrorCode_BadRequest,
984 "When modifying a series, the parent PatientID cannot be manually modified");
985 }
986
987 if (level_ == ResourceType_Series && IsReplaced(DICOM_TAG_STUDY_INSTANCE_UID))
988 {
989 throw OrthancException(ErrorCode_BadRequest,
990 "When modifying a series, the parent StudyInstanceUID cannot be manually modified");
991 }
992
993 if (!allowManualIdentifiers_)
994 {
995 if (level_ == ResourceType_Series && IsReplaced(DICOM_TAG_SOP_INSTANCE_UID)) 1003 if (level_ == ResourceType_Series && IsReplaced(DICOM_TAG_SOP_INSTANCE_UID))
996 { 1004 {
997 throw OrthancException(ErrorCode_BadRequest, 1005 throw OrthancException(ErrorCode_BadRequest,
998 "When modifying a series, the SopInstanceUID cannot be manually modified"); 1006 "When modifying a series, the SopInstanceUID cannot be manually modified");
999 } 1007 }
1000 } 1008 }
1001 1009
1002
1003 // Sanity checks at the instance level
1004 if (level_ == ResourceType_Instance && isReplacedPatientId)
1005 {
1006 throw OrthancException(ErrorCode_BadRequest,
1007 "When modifying an instance, the parent PatientID cannot be manually modified");
1008 }
1009
1010 if (level_ == ResourceType_Instance && IsReplaced(DICOM_TAG_STUDY_INSTANCE_UID))
1011 {
1012 throw OrthancException(ErrorCode_BadRequest,
1013 "When modifying an instance, the parent StudyInstanceUID cannot be manually modified");
1014 }
1015
1016 if (level_ == ResourceType_Instance && IsReplaced(DICOM_TAG_SERIES_INSTANCE_UID))
1017 {
1018 throw OrthancException(ErrorCode_BadRequest,
1019 "When modifying an instance, the parent SeriesInstanceUID cannot be manually modified");
1020 }
1021 1010
1022 // (0) Create a summary of the source file, if a custom generator 1011 // (0) Create a summary of the source file, if a custom generator
1023 // is provided 1012 // is provided
1024 if (identifierGenerator_ != NULL) 1013 if (identifierGenerator_ != NULL)
1025 { 1014 {
1292 bool force = GetBooleanValue("Force", request, false); 1281 bool force = GetBooleanValue("Force", request, false);
1293 1282
1294 if (GetBooleanValue("RemovePrivateTags", request, false)) 1283 if (GetBooleanValue("RemovePrivateTags", request, false))
1295 { 1284 {
1296 SetRemovePrivateTags(true); 1285 SetRemovePrivateTags(true);
1286 }
1287
1288 if (GetBooleanValue("KeepLabels", request, false))
1289 {
1290 SetKeepLabels(true);
1297 } 1291 }
1298 1292
1299 if (request.isMember("Remove")) 1293 if (request.isMember("Remove"))
1300 { 1294 {
1301 ParseListOfTags(*this, request["Remove"], TagOperation_Remove, force); 1295 ParseListOfTags(*this, request["Remove"], TagOperation_Remove, force);
1319 // New in Orthanc 1.6.0 1313 // New in Orthanc 1.6.0
1320 if (request.isMember("PrivateCreator")) 1314 if (request.isMember("PrivateCreator"))
1321 { 1315 {
1322 privateCreator_ = SerializationToolbox::ReadString(request, "PrivateCreator"); 1316 privateCreator_ = SerializationToolbox::ReadString(request, "PrivateCreator");
1323 } 1317 }
1318
1319 if (!force)
1320 {
1321 /**
1322 * Sanity checks about the manual replacement of DICOM
1323 * identifiers. Those checks were part of
1324 * "DicomModification::Apply()" in Orthanc <= 1.11.2, and
1325 * couldn't be disabled even if using the "Force" flag. Check
1326 * out:
1327 * https://groups.google.com/g/orthanc-users/c/xMUUZAnBa5g/m/WCEu-U2NBQAJ
1328 **/
1329 bool isReplacedPatientId = (IsReplaced(DICOM_TAG_PATIENT_ID) ||
1330 uids_.find(DICOM_TAG_PATIENT_ID) != uids_.end());
1331
1332 if (level_ == ResourceType_Patient && !isReplacedPatientId)
1333 {
1334 throw OrthancException(ErrorCode_BadRequest,
1335 "When modifying a patient, her PatientID is required to be modified.");
1336 }
1337
1338 if (level_ == ResourceType_Study && isReplacedPatientId)
1339 {
1340 throw OrthancException(ErrorCode_BadRequest,
1341 "When modifying a study, the parent PatientID cannot be manually modified");
1342 }
1343
1344 if (level_ == ResourceType_Series && isReplacedPatientId)
1345 {
1346 throw OrthancException(ErrorCode_BadRequest,
1347 "When modifying a series, the parent PatientID cannot be manually modified");
1348 }
1349
1350 if (level_ == ResourceType_Series && IsReplaced(DICOM_TAG_STUDY_INSTANCE_UID))
1351 {
1352 throw OrthancException(ErrorCode_BadRequest,
1353 "When modifying a series, the parent StudyInstanceUID cannot be manually modified");
1354 }
1355
1356 if (level_ == ResourceType_Instance && isReplacedPatientId)
1357 {
1358 throw OrthancException(ErrorCode_BadRequest,
1359 "When modifying an instance, the parent PatientID cannot be manually modified");
1360 }
1361
1362 if (level_ == ResourceType_Instance && IsReplaced(DICOM_TAG_STUDY_INSTANCE_UID))
1363 {
1364 throw OrthancException(ErrorCode_BadRequest,
1365 "When modifying an instance, the parent StudyInstanceUID cannot be manually modified");
1366 }
1367
1368 if (level_ == ResourceType_Instance && IsReplaced(DICOM_TAG_SERIES_INSTANCE_UID))
1369 {
1370 throw OrthancException(ErrorCode_BadRequest,
1371 "When modifying an instance, the parent SeriesInstanceUID cannot be manually modified");
1372 }
1373 }
1324 } 1374 }
1325 1375
1326 1376
1327 void DicomModification::ParseAnonymizationRequest(bool& patientNameOverridden, 1377 void DicomModification::ParseAnonymizationRequest(bool& patientNameOverridden,
1328 const Json::Value& request) 1378 const Json::Value& request)
1334 1384
1335 bool force = GetBooleanValue("Force", request, false); 1385 bool force = GetBooleanValue("Force", request, false);
1336 1386
1337 // DicomVersion version = DicomVersion_2008; // For Orthanc <= 1.2.0 1387 // DicomVersion version = DicomVersion_2008; // For Orthanc <= 1.2.0
1338 // DicomVersion version = DicomVersion_2017c; // For Orthanc between 1.3.0 and 1.9.3 1388 // DicomVersion version = DicomVersion_2017c; // For Orthanc between 1.3.0 and 1.9.3
1339 DicomVersion version = DicomVersion_2021b; // For Orthanc >= 1.9.4 1389 // DicomVersion version = DicomVersion_2021b; // For Orthanc >= 1.9.4
1390 DicomVersion version = DicomVersion_2023b; // For Orthanc >= 1.12.1
1391
1340 if (request.isMember("DicomVersion")) 1392 if (request.isMember("DicomVersion"))
1341 { 1393 {
1342 if (request["DicomVersion"].type() != Json::stringValue) 1394 if (request["DicomVersion"].type() != Json::stringValue)
1343 { 1395 {
1344 throw OrthancException(ErrorCode_BadFileFormat); 1396 throw OrthancException(ErrorCode_BadFileFormat);
1352 SetupAnonymization(version); 1404 SetupAnonymization(version);
1353 1405
1354 if (GetBooleanValue("KeepPrivateTags", request, false)) 1406 if (GetBooleanValue("KeepPrivateTags", request, false))
1355 { 1407 {
1356 SetRemovePrivateTags(false); 1408 SetRemovePrivateTags(false);
1409 }
1410
1411 if (GetBooleanValue("KeepLabels", request, false))
1412 {
1413 SetKeepLabels(true);
1357 } 1414 }
1358 1415
1359 if (request.isMember("Remove")) 1416 if (request.isMember("Remove"))
1360 { 1417 {
1361 ParseListOfTags(*this, request["Remove"], TagOperation_Remove, force); 1418 ParseListOfTags(*this, request["Remove"], TagOperation_Remove, force);
1583 /** 1640 /**
1584 * Compatibility with jobs serialized using Orthanc between 1641 * Compatibility with jobs serialized using Orthanc between
1585 * 1.5.0 and 1.6.1. This compatibility was broken between 1.7.0 1642 * 1.5.0 and 1.6.1. This compatibility was broken between 1.7.0
1586 * and 1.9.3: Indeed, an exception was thrown in "ReadBoolean()" 1643 * and 1.9.3: Indeed, an exception was thrown in "ReadBoolean()"
1587 * if "KEEP_SOP_INSTANCE_UID" was absent, because of changeset: 1644 * if "KEEP_SOP_INSTANCE_UID" was absent, because of changeset:
1588 * https://hg.orthanc-server.com/orthanc/rev/3860 1645 * https://orthanc.uclouvain.be/hg/orthanc/rev/3860
1589 **/ 1646 **/
1590 keepSopInstanceUid_ = false; 1647 keepSopInstanceUid_ = false;
1591 } 1648 }
1592 1649
1593 if (serialized.isMember(PRIVATE_CREATOR)) 1650 if (serialized.isMember(PRIVATE_CREATOR))
1828 (tag == DICOM_TAG_SERIES_INSTANCE_UID && 1885 (tag == DICOM_TAG_SERIES_INSTANCE_UID &&
1829 !keepSeriesInstanceUid_) || 1886 !keepSeriesInstanceUid_) ||
1830 (tag == DICOM_TAG_SOP_INSTANCE_UID && 1887 (tag == DICOM_TAG_SOP_INSTANCE_UID &&
1831 !keepSopInstanceUid_)); 1888 !keepSopInstanceUid_));
1832 } 1889 }
1890
1891 void DicomModification::GetReplacedTags(std::set<DicomTag>& target) const
1892 {
1893 target.clear();
1894 for (Replacements::const_iterator it = replacements_.begin(); it != replacements_.end(); ++it)
1895 {
1896 target.insert(it->first);
1897 }
1898 }
1833 } 1899 }