comparison Core/DicomParsing/DicomModification.cpp @ 2506:51b91ead6c38

Preservation of UID relationships while anonymizing
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 26 Mar 2018 17:09:42 +0200
parents 878b59270859
children 2e6b7862ccf2
comparison
equal deleted inserted replaced
2505:a4f885670da7 2506:51b91ead6c38
35 #include "DicomModification.h" 35 #include "DicomModification.h"
36 36
37 #include "../Logging.h" 37 #include "../Logging.h"
38 #include "../OrthancException.h" 38 #include "../OrthancException.h"
39 #include "FromDcmtkBridge.h" 39 #include "FromDcmtkBridge.h"
40 #include "ITagVisitor.h"
40 41
41 #include <memory> // For std::auto_ptr 42 #include <memory> // For std::auto_ptr
42 43
43 44
44 static const std::string ORTHANC_DEIDENTIFICATION_METHOD_2008 = 45 static const std::string ORTHANC_DEIDENTIFICATION_METHOD_2008 =
47 static const std::string ORTHANC_DEIDENTIFICATION_METHOD_2017c = 48 static const std::string ORTHANC_DEIDENTIFICATION_METHOD_2017c =
48 "Orthanc " ORTHANC_VERSION " - PS 3.15-2017c Table E.1-1 Basic Profile"; 49 "Orthanc " ORTHANC_VERSION " - PS 3.15-2017c Table E.1-1 Basic Profile";
49 50
50 namespace Orthanc 51 namespace Orthanc
51 { 52 {
53 class DicomModification::RelationshipsVisitor : public ITagVisitor
54 {
55 private:
56 DicomModification& that_;
57
58 bool IsEnabled(const DicomTag& tag) const
59 {
60 return (!that_.IsCleared(tag) &&
61 !that_.IsRemoved(tag) &&
62 !that_.IsReplaced(tag));
63 }
64
65 void RemoveIfEnabled(ParsedDicomFile& dicom,
66 const DicomTag& tag) const
67 {
68 if (IsEnabled(tag))
69 {
70 dicom.Remove(tag);
71 }
72 }
73
74
75 public:
76 RelationshipsVisitor(DicomModification& that) :
77 that_(that)
78 {
79 }
80
81 virtual void VisitUnknown(const std::vector<DicomTag>& parentTags,
82 const std::vector<size_t>& parentIndexes,
83 const DicomTag& tag,
84 ValueRepresentation vr)
85 {
86 }
87
88 virtual void VisitBinary(const std::vector<DicomTag>& parentTags,
89 const std::vector<size_t>& parentIndexes,
90 const DicomTag& tag,
91 ValueRepresentation vr,
92 const void* data,
93 size_t size)
94 {
95 }
96
97 virtual void VisitInteger(const std::vector<DicomTag>& parentTags,
98 const std::vector<size_t>& parentIndexes,
99 const DicomTag& tag,
100 ValueRepresentation vr,
101 int64_t value)
102 {
103 }
104
105 virtual void VisitDouble(const std::vector<DicomTag>& parentTags,
106 const std::vector<size_t>& parentIndexes,
107 const DicomTag& tag,
108 ValueRepresentation vr,
109 double value)
110 {
111 }
112
113 virtual void VisitAttribute(const std::vector<DicomTag>& parentTags,
114 const std::vector<size_t>& parentIndexes,
115 const DicomTag& tag,
116 ValueRepresentation vr,
117 const DicomTag& value)
118 {
119 }
120
121 virtual Action VisitString(std::string& newValue,
122 const std::vector<DicomTag>& parentTags,
123 const std::vector<size_t>& parentIndexes,
124 const DicomTag& tag,
125 ValueRepresentation vr,
126 const std::string& value)
127 {
128 if ((tag == DICOM_TAG_FRAME_OF_REFERENCE_UID ||
129 tag == DICOM_TAG_REFERENCED_FRAME_OF_REFERENCE_UID ||
130 tag == DICOM_TAG_REFERENCED_SOP_INSTANCE_UID ||
131 tag == DICOM_TAG_RELATED_FRAME_OF_REFERENCE_UID) &&
132 IsEnabled(tag))
133 {
134 newValue = that_.MapDicomIdentifier(Toolbox::StripSpaces(value), ResourceType_Instance);
135 return Action_Replace;
136 }
137 else
138 {
139 return Action_None;
140 }
141 }
142
143 void RemoveRelationships(ParsedDicomFile& dicom) const
144 {
145 // Sequences containing the UID relationships
146 RemoveIfEnabled(dicom, DICOM_TAG_REFERENCED_IMAGE_SEQUENCE);
147 RemoveIfEnabled(dicom, DICOM_TAG_SOURCE_IMAGE_SEQUENCE);
148
149 // Individual tags
150 RemoveIfEnabled(dicom, DICOM_TAG_FRAME_OF_REFERENCE_UID);
151
152 // The tags below should never occur at the first level of the
153 // hierarchy, but remove them anyway
154 RemoveIfEnabled(dicom, DICOM_TAG_REFERENCED_FRAME_OF_REFERENCE_UID);
155 RemoveIfEnabled(dicom, DICOM_TAG_REFERENCED_SOP_INSTANCE_UID);
156 RemoveIfEnabled(dicom, DICOM_TAG_RELATED_FRAME_OF_REFERENCE_UID);
157 }
158 };
159
160
52 bool DicomModification::CancelReplacement(const DicomTag& tag) 161 bool DicomModification::CancelReplacement(const DicomTag& tag)
53 { 162 {
54 Replacements::iterator it = replacements_.find(tag); 163 Replacements::iterator it = replacements_.find(tag);
55 164
56 if (it != replacements_.end()) 165 if (it != replacements_.end())
108 replacements_.erase(it); 217 replacements_.erase(it);
109 } 218 }
110 } 219 }
111 220
112 221
113 void DicomModification::MapDicomIdentifier(ParsedDicomFile& dicom, 222
114 ResourceType level) 223 std::string DicomModification::MapDicomIdentifier(const std::string& original,
224 ResourceType level)
225 {
226 std::string mapped;
227
228 UidMap::const_iterator previous = uidMap_.find(std::make_pair(level, original));
229
230 if (previous == uidMap_.end())
231 {
232 mapped = FromDcmtkBridge::GenerateUniqueIdentifier(level);
233 uidMap_.insert(std::make_pair(std::make_pair(level, original), mapped));
234 }
235 else
236 {
237 mapped = previous->second;
238 }
239
240 return mapped;
241 }
242
243
244 void DicomModification::MapDicomTags(ParsedDicomFile& dicom,
245 ResourceType level)
115 { 246 {
116 std::auto_ptr<DicomTag> tag; 247 std::auto_ptr<DicomTag> tag;
117 248
118 switch (level) 249 switch (level)
119 { 250 {
137 if (!dicom.GetTagValue(original, *tag)) 268 if (!dicom.GetTagValue(original, *tag))
138 { 269 {
139 original = ""; 270 original = "";
140 } 271 }
141 272
142 std::string mapped; 273 std::string mapped = MapDicomIdentifier(Toolbox::StripSpaces(original), level);
143 274
144 UidMap::const_iterator previous = uidMap_.find(std::make_pair(level, original)); 275 dicom.Replace(*tag, mapped,
145 if (previous == uidMap_.end()) 276 false /* don't try and decode data URI scheme for UIDs */,
146 { 277 DicomReplaceMode_InsertIfAbsent);
147 mapped = FromDcmtkBridge::GenerateUniqueIdentifier(level); 278 }
148 uidMap_.insert(std::make_pair(std::make_pair(level, original), mapped)); 279
149 }
150 else
151 {
152 mapped = previous->second;
153 }
154
155 dicom.Replace(*tag, mapped, false /* don't try and decode data URI scheme for UIDs */, DicomReplaceMode_InsertIfAbsent);
156 }
157 280
158 DicomModification::DicomModification() : 281 DicomModification::DicomModification() :
159 removePrivateTags_(false), 282 removePrivateTags_(false),
160 level_(ResourceType_Instance), 283 level_(ResourceType_Instance),
161 allowManualIdentifiers_(true), 284 allowManualIdentifiers_(true),
162 keepStudyInstanceUid_(false), 285 keepStudyInstanceUid_(false),
163 keepSeriesInstanceUid_(false) 286 keepSeriesInstanceUid_(false),
287 updateReferencedRelationships_(true)
164 { 288 {
165 } 289 }
166 290
167 DicomModification::~DicomModification() 291 DicomModification::~DicomModification()
168 { 292 {
324 removals_.insert(DicomTag(0x0008, 0x1048)); // Physician(s) of Record 448 removals_.insert(DicomTag(0x0008, 0x1048)); // Physician(s) of Record
325 removals_.insert(DicomTag(0x0008, 0x1050)); // Performing Physicians' Name 449 removals_.insert(DicomTag(0x0008, 0x1050)); // Performing Physicians' Name
326 removals_.insert(DicomTag(0x0008, 0x1060)); // Name of Physician(s) Reading Study 450 removals_.insert(DicomTag(0x0008, 0x1060)); // Name of Physician(s) Reading Study
327 removals_.insert(DicomTag(0x0008, 0x1070)); // Operators' Name 451 removals_.insert(DicomTag(0x0008, 0x1070)); // Operators' Name
328 removals_.insert(DicomTag(0x0008, 0x1080)); // Admitting Diagnoses Description 452 removals_.insert(DicomTag(0x0008, 0x1080)); // Admitting Diagnoses Description
329 removals_.insert(DicomTag(0x0008, 0x1155)); // Referenced SOP Instance UID 453 //removals_.insert(DicomTag(0x0008, 0x1155)); // Referenced SOP Instance UID => RelationshipsVisitor
330 removals_.insert(DicomTag(0x0008, 0x2111)); // Derivation Description 454 removals_.insert(DicomTag(0x0008, 0x2111)); // Derivation Description
331 //removals_.insert(DicomTag(0x0010, 0x0010)); // Patient's Name => cf. below (*) 455 //removals_.insert(DicomTag(0x0010, 0x0010)); // Patient's Name => cf. below (*)
332 //removals_.insert(DicomTag(0x0010, 0x0020)); // Patient ID => cf. below (*) 456 //removals_.insert(DicomTag(0x0010, 0x0020)); // Patient ID => cf. below (*)
333 removals_.insert(DicomTag(0x0010, 0x0030)); // Patient's Birth Date 457 removals_.insert(DicomTag(0x0010, 0x0030)); // Patient's Birth Date
334 removals_.insert(DicomTag(0x0010, 0x0032)); // Patient's Birth Time 458 removals_.insert(DicomTag(0x0010, 0x0032)); // Patient's Birth Time
346 removals_.insert(DicomTag(0x0018, 0x1000)); // Device Serial Number 470 removals_.insert(DicomTag(0x0018, 0x1000)); // Device Serial Number
347 removals_.insert(DicomTag(0x0018, 0x1030)); // Protocol Name 471 removals_.insert(DicomTag(0x0018, 0x1030)); // Protocol Name
348 //removals_.insert(DicomTag(0x0020, 0x000d)); // Study Instance UID => set in Apply() 472 //removals_.insert(DicomTag(0x0020, 0x000d)); // Study Instance UID => set in Apply()
349 //removals_.insert(DicomTag(0x0020, 0x000e)); // Series Instance UID => set in Apply() 473 //removals_.insert(DicomTag(0x0020, 0x000e)); // Series Instance UID => set in Apply()
350 removals_.insert(DicomTag(0x0020, 0x0010)); // Study ID 474 removals_.insert(DicomTag(0x0020, 0x0010)); // Study ID
351 removals_.insert(DicomTag(0x0020, 0x0052)); // Frame of Reference UID 475 //removals_.insert(DicomTag(0x0020, 0x0052)); // Frame of Reference UID => cf. RelationshipsVisitor
352 removals_.insert(DicomTag(0x0020, 0x0200)); // Synchronization Frame of Reference UID 476 removals_.insert(DicomTag(0x0020, 0x0200)); // Synchronization Frame of Reference UID
353 removals_.insert(DicomTag(0x0020, 0x4000)); // Image Comments 477 removals_.insert(DicomTag(0x0020, 0x4000)); // Image Comments
354 removals_.insert(DicomTag(0x0040, 0x0275)); // Request Attributes Sequence 478 removals_.insert(DicomTag(0x0040, 0x0275)); // Request Attributes Sequence
355 removals_.insert(DicomTag(0x0040, 0xa124)); // UID 479 removals_.insert(DicomTag(0x0040, 0xa124)); // UID
356 removals_.insert(DicomTag(0x0040, 0xa730)); // Content Sequence 480 removals_.insert(DicomTag(0x0040, 0xa730)); // Content Sequence
357 removals_.insert(DicomTag(0x0088, 0x0140)); // Storage Media File-set UID 481 removals_.insert(DicomTag(0x0088, 0x0140)); // Storage Media File-set UID
358 removals_.insert(DicomTag(0x3006, 0x0024)); // Referenced Frame of Reference UID 482 //removals_.insert(DicomTag(0x3006, 0x0024)); // Referenced Frame of Reference UID => RelationshipsVisitor
359 removals_.insert(DicomTag(0x3006, 0x00c2)); // Related Frame of Reference UID 483 //removals_.insert(DicomTag(0x3006, 0x00c2)); // Related Frame of Reference UID => RelationshipsVisitor
360 484
361 // Some more removals (from the experience of DICOM files at the CHU of Liege) 485 // Some more removals (from the experience of DICOM files at the CHU of Liege)
362 removals_.insert(DicomTag(0x0010, 0x1040)); // Patient's Address 486 removals_.insert(DicomTag(0x0010, 0x1040)); // Patient's Address
363 removals_.insert(DicomTag(0x0032, 0x1032)); // Requesting Physician 487 removals_.insert(DicomTag(0x0032, 0x1032)); // Requesting Physician
364 removals_.insert(DicomTag(0x0010, 0x2154)); // PatientTelephoneNumbers 488 removals_.insert(DicomTag(0x0010, 0x2154)); // PatientTelephoneNumbers
365 removals_.insert(DicomTag(0x0010, 0x2000)); // Medical Alerts 489 removals_.insert(DicomTag(0x0010, 0x2000)); // Medical Alerts
366 490
367 // Set the DeidentificationMethod tag 491 // Set the DeidentificationMethod tag
368 ReplaceInternal(DICOM_TAG_DEIDENTIFICATION_METHOD, ORTHANC_DEIDENTIFICATION_METHOD_2008); 492 ReplaceInternal(DICOM_TAG_DEIDENTIFICATION_METHOD, ORTHANC_DEIDENTIFICATION_METHOD_2008);
369 } 493 }
370
371
372 #if 0
373 /**
374 * This is a manual implementation by Alain Mazy. Only kept for reference.
375 * https://bitbucket.org/sjodogne/orthanc/commits/c6defdc4c611fca2ab528ba2c6937a742e0329a8?at=issue-46-anonymization
376 **/
377
378 void DicomModification::SetupAnonymization2011()
379 {
380 // This is Table E.1-1 from PS 3.15-2011 - DICOM Part 15: Security and System Management Profiles
381 // https://raw.githubusercontent.com/jodogne/dicom-specification/master/2011/11_15pu.pdf
382
383 removals_.insert(DicomTag(0x0000, 0x1000)); // Affected SOP Instance UID
384 removals_.insert(DicomTag(0x0000, 0x1001)); // Requested SOP Instance UID
385 removals_.insert(DicomTag(0x0002, 0x0003)); // Media Storage SOP Instance UID => TODO: replace with a non-zero length UID that is internally consistent within a set of Instances
386 removals_.insert(DicomTag(0x0004, 0x1511)); // Referenced SOP Instance UID in File
387 removals_.insert(DicomTag(0x0008, 0x0010)); // Irradiation Event UID
388 removals_.insert(DicomTag(0x0008, 0x0014)); // Instance Creator UID
389 //removals_.insert(DicomTag(0x0008, 0x0018)); // SOP Instance UID => set in Apply()
390 clearings_.insert(DicomTag(0x0008, 0x0020)); // Study Date
391 clearings_.insert(DicomTag(0x0008, 0x0021)); // Series Date
392 clearings_.insert(DicomTag(0x0008, 0x0030)); // Study Time
393 clearings_.insert(DicomTag(0x0008, 0x0031)); // Series Time
394 removals_.insert(DicomTag(0x0008, 0x0022)); // Acquisition Date
395 removals_.insert(DicomTag(0x0008, 0x0023)); // Content Date
396 removals_.insert(DicomTag(0x0008, 0x0024)); // Overlay Date
397 removals_.insert(DicomTag(0x0008, 0x0025)); // Curve Date
398 removals_.insert(DicomTag(0x0008, 0x002a)); // Acquisition DateTime
399 removals_.insert(DicomTag(0x0008, 0x0032)); // Acquisition Time
400 removals_.insert(DicomTag(0x0008, 0x0033)); // Content Time
401 removals_.insert(DicomTag(0x0008, 0x0034)); // Overlay Time
402 removals_.insert(DicomTag(0x0008, 0x0035)); // Curve Time
403 removals_.insert(DicomTag(0x0008, 0x0050)); // Accession Number
404 removals_.insert(DicomTag(0x0008, 0x0058)); // Failed SOP Instance UID List
405 removals_.insert(DicomTag(0x0008, 0x0080)); // Institution Name
406 removals_.insert(DicomTag(0x0008, 0x0081)); // Institution Address
407 removals_.insert(DicomTag(0x0008, 0x0082)); // Institution Code Sequence
408 removals_.insert(DicomTag(0x0008, 0x0090)); // Referring Physician's Name
409 removals_.insert(DicomTag(0x0008, 0x0092)); // Referring Physician's Address
410 removals_.insert(DicomTag(0x0008, 0x0094)); // Referring Physician's Telephone Numbers
411 removals_.insert(DicomTag(0x0008, 0x0096)); // Referring Physician's Identification Sequence
412 removals_.insert(DicomTag(0x0008, 0x010d)); // Context Group Extension Creator UID
413 removals_.insert(DicomTag(0x0008, 0x0201)); // Timezone Offset From UTC
414 removals_.insert(DicomTag(0x0008, 0x0300)); // Current Patient Location
415 removals_.insert(DicomTag(0x0008, 0x1010)); // Station Name
416 removals_.insert(DicomTag(0x0008, 0x1030)); // Study Description
417 removals_.insert(DicomTag(0x0008, 0x103e)); // Series Description
418 removals_.insert(DicomTag(0x0008, 0x1040)); // Institutional Department Name
419 removals_.insert(DicomTag(0x0008, 0x1048)); // Physician(s) of Record
420 removals_.insert(DicomTag(0x0008, 0x1049)); // Physician(s) of Record Identification Sequence
421 removals_.insert(DicomTag(0x0008, 0x1050)); // Performing Physicians' Name
422 removals_.insert(DicomTag(0x0008, 0x1052)); // Performing Physicians Identification Sequence
423 removals_.insert(DicomTag(0x0008, 0x1060)); // Name of Physician(s) Reading Study
424 removals_.insert(DicomTag(0x0008, 0x1062)); // Physician Reading Study Identification Sequence
425 removals_.insert(DicomTag(0x0008, 0x1070)); // Operators' Name
426 removals_.insert(DicomTag(0x0008, 0x1072)); // Operators' Identification Sequence
427 removals_.insert(DicomTag(0x0008, 0x1080)); // Admitting Diagnoses Description
428 removals_.insert(DicomTag(0x0008, 0x1084)); // Admitting Diagnoses Code Sequence
429 removals_.insert(DicomTag(0x0008, 0x1110)); // Referenced Study Sequence
430 removals_.insert(DicomTag(0x0008, 0x1111)); // Referenced Performed Procedure Step Sequence
431 removals_.insert(DicomTag(0x0008, 0x1120)); // Referenced Patient Sequence
432 removals_.insert(DicomTag(0x0008, 0x1140)); // Referenced Image Sequence
433 removals_.insert(DicomTag(0x0008, 0x1155)); // Referenced SOP Instance UID
434 removals_.insert(DicomTag(0x0008, 0x1195)); // Transaction UID
435 removals_.insert(DicomTag(0x0008, 0x2111)); // Derivation Description
436 removals_.insert(DicomTag(0x0008, 0x2112)); // Source Image Sequence
437 removals_.insert(DicomTag(0x0008, 0x4000)); // Identifying Comments
438 removals_.insert(DicomTag(0x0008, 0x9123)); // Creator Version UID
439 //removals_.insert(DicomTag(0x0010, 0x0010)); // Patient's Name => cf. below (*)
440 //removals_.insert(DicomTag(0x0010, 0x0020)); // Patient ID => cf. below (*)
441 removals_.insert(DicomTag(0x0010, 0x0030)); // Patient's Birth Date
442 removals_.insert(DicomTag(0x0010, 0x0032)); // Patient's Birth Time
443 clearings_.insert(DicomTag(0x0010, 0x0040)); // Patient's Sex
444 removals_.insert(DicomTag(0x0010, 0x0050)); // Patient's Insurance Plan Code Sequence
445 removals_.insert(DicomTag(0x0010, 0x0101)); // Patient's Primary Language Code Sequence
446 removals_.insert(DicomTag(0x0010, 0x0102)); // Patient's Primary Language Modifier Code Sequence
447 removals_.insert(DicomTag(0x0010, 0x1000)); // Other Patient Ids
448 removals_.insert(DicomTag(0x0010, 0x1001)); // Other Patient Names
449 removals_.insert(DicomTag(0x0010, 0x1002)); // Other Patient IDs Sequence
450 removals_.insert(DicomTag(0x0010, 0x1005)); // Patient's Birth Name
451 removals_.insert(DicomTag(0x0010, 0x1010)); // Patient's Age
452 removals_.insert(DicomTag(0x0010, 0x1020)); // Patient's Size
453 removals_.insert(DicomTag(0x0010, 0x1030)); // Patient's Weight
454 removals_.insert(DicomTag(0x0010, 0x1040)); // Patient's Address
455 removals_.insert(DicomTag(0x0010, 0x1050)); // Insurance Plan Identification
456 removals_.insert(DicomTag(0x0010, 0x1060)); // Patient's Mother's Birth Name
457 removals_.insert(DicomTag(0x0010, 0x1080)); // Military Rank
458 removals_.insert(DicomTag(0x0010, 0x1081)); // Branch of Service
459 removals_.insert(DicomTag(0x0010, 0x1090)); // Medical Record Locator
460 removals_.insert(DicomTag(0x0010, 0x2000)); // Medical Alerts
461 removals_.insert(DicomTag(0x0010, 0x2110)); // Allergies
462 removals_.insert(DicomTag(0x0010, 0x2150)); // Country of Residence
463 removals_.insert(DicomTag(0x0010, 0x2152)); // Region of Residence
464 removals_.insert(DicomTag(0x0010, 0x2154)); // PatientTelephoneNumbers
465 removals_.insert(DicomTag(0x0010, 0x2160)); // Ethnic Group
466 removals_.insert(DicomTag(0x0010, 0x2180)); // Occupation
467 removals_.insert(DicomTag(0x0010, 0x21a0)); // Smoking Status
468 removals_.insert(DicomTag(0x0010, 0x21b0)); // Additional Patient's History
469 removals_.insert(DicomTag(0x0010, 0x21c0)); // Pregnancy Status
470 removals_.insert(DicomTag(0x0010, 0x21d0)); // Last Menstrual Date
471 removals_.insert(DicomTag(0x0010, 0x21f0)); // Patient's Religious Preference
472 removals_.insert(DicomTag(0x0010, 0x2203)); // Patient's Sex Neutered
473 removals_.insert(DicomTag(0x0010, 0x2297)); // Responsible Person
474 removals_.insert(DicomTag(0x0010, 0x2299)); // Responsible Organization
475 removals_.insert(DicomTag(0x0010, 0x4000)); // Patient Comments
476 removals_.insert(DicomTag(0x0018, 0x0010)); // Contrast Bolus Agent
477 removals_.insert(DicomTag(0x0018, 0x1000)); // Device Serial Number
478 removals_.insert(DicomTag(0x0018, 0x1002)); // Device UID
479 removals_.insert(DicomTag(0x0018, 0x1004)); // Plate ID
480 removals_.insert(DicomTag(0x0018, 0x1005)); // Generator ID
481 removals_.insert(DicomTag(0x0018, 0x1007)); // Cassette ID
482 removals_.insert(DicomTag(0x0018, 0x1008)); // Gantry ID
483 removals_.insert(DicomTag(0x0018, 0x1030)); // Protocol Name
484 removals_.insert(DicomTag(0x0018, 0x1400)); // Acquisition Device Processing Description
485 removals_.insert(DicomTag(0x0018, 0x4000)); // Acquisition Comments
486 removals_.insert(DicomTag(0x0018, 0x700a)); // Detector ID
487 removals_.insert(DicomTag(0x0018, 0xa003)); // Contribution Description
488 removals_.insert(DicomTag(0x0018, 0x9424)); // Acquisition Protocol Description
489 //removals_.insert(DicomTag(0x0020, 0x000d)); // Study Instance UID => set in Apply()
490 //removals_.insert(DicomTag(0x0020, 0x000e)); // Series Instance UID => set in Apply()
491 removals_.insert(DicomTag(0x0020, 0x0010)); // Study ID
492 removals_.insert(DicomTag(0x0020, 0x0052)); // Frame of Reference UID
493 removals_.insert(DicomTag(0x0020, 0x0200)); // Synchronization Frame of Reference UID
494 removals_.insert(DicomTag(0x0020, 0x3401)); // Modifying Device ID
495 removals_.insert(DicomTag(0x0020, 0x3404)); // Modifying Device Manufacturer
496 removals_.insert(DicomTag(0x0020, 0x3406)); // Modified Image Description
497 removals_.insert(DicomTag(0x0020, 0x4000)); // Image Comments
498 removals_.insert(DicomTag(0x0020, 0x9158)); // Frame Comments
499 removals_.insert(DicomTag(0x0020, 0x9161)); // Concatenation UID
500 removals_.insert(DicomTag(0x0020, 0x9164)); // Dimension Organization UID
501 //removals_.insert(DicomTag(0x0028, 0x1199)); // Palette Color Lookup Table UID => TODO: replace with a non-zero length UID that is internally consistent within a set of Instances
502 //removals_.insert(DicomTag(0x0028, 0x1214)); // Large Palette Color Lookup Table UID => TODO: replace with a non-zero length UID that is internally consistent within a set of Instances
503 removals_.insert(DicomTag(0x0028, 0x4000)); // Image Presentation Comments
504 removals_.insert(DicomTag(0x0032, 0x0012)); // Study ID Issuer
505 removals_.insert(DicomTag(0x0032, 0x1020)); // Scheduled Study Location
506 removals_.insert(DicomTag(0x0032, 0x1021)); // Scheduled Study Location AE Title
507 removals_.insert(DicomTag(0x0032, 0x1030)); // Reason for Study
508 removals_.insert(DicomTag(0x0032, 0x1032)); // Requesting Physician
509 removals_.insert(DicomTag(0x0032, 0x1033)); // Requesting Service
510 removals_.insert(DicomTag(0x0032, 0x1060)); // Requesting Procedure Description
511 removals_.insert(DicomTag(0x0032, 0x1070)); // Requested Contrast Agent
512 removals_.insert(DicomTag(0x0032, 0x4000)); // Study Comments
513 removals_.insert(DicomTag(0x0038, 0x0010)); // Admission ID
514 removals_.insert(DicomTag(0x0038, 0x0011)); // Issuer of Admission ID
515 removals_.insert(DicomTag(0x0038, 0x001e)); // Scheduled Patient Institution Residence
516 removals_.insert(DicomTag(0x0038, 0x0020)); // Admitting Date
517 removals_.insert(DicomTag(0x0038, 0x0021)); // Admitting Time
518 removals_.insert(DicomTag(0x0038, 0x0040)); // Discharge Diagnosis Description
519 removals_.insert(DicomTag(0x0038, 0x0050)); // Special Needs
520 removals_.insert(DicomTag(0x0038, 0x0060)); // Service Episode ID
521 removals_.insert(DicomTag(0x0038, 0x0061)); // Issuer of Service Episode ID
522 removals_.insert(DicomTag(0x0038, 0x0062)); // Service Episode Description
523 removals_.insert(DicomTag(0x0038, 0x0400)); // Patient's Institution Residence
524 removals_.insert(DicomTag(0x0038, 0x0500)); // Patient State
525 removals_.insert(DicomTag(0x0038, 0x4000)); // Visit Comments
526 removals_.insert(DicomTag(0x0038, 0x1234)); // Referenced Patient Alias Sequence
527 removals_.insert(DicomTag(0x0040, 0x0001)); // Scheduled Station AE Title
528 removals_.insert(DicomTag(0x0040, 0x0002)); // Scheduled Procedure Step Start Date
529 removals_.insert(DicomTag(0x0040, 0x0003)); // Scheduled Procedure Step Start Time
530 removals_.insert(DicomTag(0x0040, 0x0004)); // Scheduled Procedure Step End Date
531 removals_.insert(DicomTag(0x0040, 0x0005)); // Scheduled Procedure Step End Time
532 removals_.insert(DicomTag(0x0040, 0x0006)); // Scheduled Performing Physician Name
533 removals_.insert(DicomTag(0x0040, 0x0007)); // Scheduled Procedure Step Description
534 removals_.insert(DicomTag(0x0040, 0x000b)); // Scheduled Performing Physician Identification Sequence
535 removals_.insert(DicomTag(0x0040, 0x0010)); // Scheduled Station Name
536 removals_.insert(DicomTag(0x0040, 0x0011)); // Scheduled Procedure Step Location
537 removals_.insert(DicomTag(0x0040, 0x0012)); // Pre-Medication
538 removals_.insert(DicomTag(0x0040, 0x0241)); // Performed Station AE Title
539 removals_.insert(DicomTag(0x0040, 0x0242)); // Performed Station Name
540 removals_.insert(DicomTag(0x0040, 0x0243)); // Performed Location
541 removals_.insert(DicomTag(0x0040, 0x0244)); // Performed Procedure Step Start Date
542 removals_.insert(DicomTag(0x0040, 0x0245)); // Performed Procedure Step Start Time
543 removals_.insert(DicomTag(0x0040, 0x0248)); // Performed Station Name Code Sequence
544 removals_.insert(DicomTag(0x0040, 0x0253)); // Performed Procedure Step ID
545 removals_.insert(DicomTag(0x0040, 0x0254)); // Performed Procedure Step Description
546 removals_.insert(DicomTag(0x0040, 0x0275)); // Request Attributes Sequence
547 removals_.insert(DicomTag(0x0040, 0x0280)); // Comments on Performed Procedure Step
548 removals_.insert(DicomTag(0x0040, 0x0555)); // Acquisition Context Sequence
549 removals_.insert(DicomTag(0x0040, 0x1001)); // Requested Procedure ID
550 removals_.insert(DicomTag(0x0040, 0x1010)); // Names of Intended Recipient of Results
551 removals_.insert(DicomTag(0x0040, 0x1011)); // Intended Recipient of Results Identification Sequence
552 removals_.insert(DicomTag(0x0040, 0x1004)); // Patient Transport Arrangements
553 removals_.insert(DicomTag(0x0040, 0x1005)); // Requested Procedure Location
554 removals_.insert(DicomTag(0x0040, 0x1101)); // Person Identification Code Sequence
555 removals_.insert(DicomTag(0x0040, 0x1102)); // Person Address
556 removals_.insert(DicomTag(0x0040, 0x1103)); // Person Telephone Numbers
557 removals_.insert(DicomTag(0x0040, 0x1400)); // Requested Procedure Comments
558 removals_.insert(DicomTag(0x0040, 0x2001)); // Reason for Imaging Service Request
559 removals_.insert(DicomTag(0x0040, 0x2008)); // Order Entered By
560 removals_.insert(DicomTag(0x0040, 0x2009)); // Order Enterer Location
561 removals_.insert(DicomTag(0x0040, 0x2010)); // Order Callback Phone Number
562 removals_.insert(DicomTag(0x0040, 0x2016)); // Placer Order Number of Imaging Service Request
563 removals_.insert(DicomTag(0x0040, 0x2017)); // Filler Order Number of Imaging Service Request
564 removals_.insert(DicomTag(0x0040, 0x2400)); // Imaging Service Request Comments
565 removals_.insert(DicomTag(0x0040, 0x4023)); // Referenced General Purpose Scheduled Procedure Step Transaction UID
566 removals_.insert(DicomTag(0x0040, 0x4025)); // Scheduled Station Name Code Sequence
567 removals_.insert(DicomTag(0x0040, 0x4027)); // Scheduled Station Geographic Location Code Sequence
568 removals_.insert(DicomTag(0x0040, 0x4030)); // Performed Station Geographic Location Code Sequence
569 removals_.insert(DicomTag(0x0040, 0x4034)); // Scheduled Human Performers Sequence
570 removals_.insert(DicomTag(0x0040, 0x4035)); // Actual Human Performers Sequence
571 removals_.insert(DicomTag(0x0040, 0x4036)); // Human Performers Organization
572 removals_.insert(DicomTag(0x0040, 0x4037)); // Human Performers Name
573 removals_.insert(DicomTag(0x0040, 0xa027)); // Verifying Organization
574 removals_.insert(DicomTag(0x0040, 0xa073)); // Verifying Observer Sequence
575 removals_.insert(DicomTag(0x0040, 0xa075)); // Verifying Observer Name
576 removals_.insert(DicomTag(0x0040, 0xa078)); // Author Observer Sequence
577 removals_.insert(DicomTag(0x0040, 0xa07a)); // Participant Sequence
578 removals_.insert(DicomTag(0x0040, 0xa07c)); // Custodial Organization Sequence
579 removals_.insert(DicomTag(0x0040, 0xa088)); // Verifying Observer Identification Code Sequence
580 removals_.insert(DicomTag(0x0040, 0xa123)); // Person Name
581 removals_.insert(DicomTag(0x0040, 0xa124)); // UID
582 removals_.insert(DicomTag(0x0040, 0xa730)); // Content Sequence
583 removals_.insert(DicomTag(0x0040, 0x3001)); // Confidentiality Constraint on Patient Data Description
584 removals_.insert(DicomTag(0x0040, 0xdb0c)); // Template Extension Organization UID
585 removals_.insert(DicomTag(0x0040, 0xdb0d)); // Template Extension Creator UID
586 removals_.insert(DicomTag(0x0070, 0x0001)); // Graphic Annotation Sequence
587 removals_.insert(DicomTag(0x0070, 0x0084)); // Content Creator's Name
588 removals_.insert(DicomTag(0x0070, 0x0086)); // Content Creator's Identification Code Sequence
589 removals_.insert(DicomTag(0x0070, 0x031a)); // Fiducial UID
590 removals_.insert(DicomTag(0x0088, 0x0140)); // Storage Media File-set UID
591 removals_.insert(DicomTag(0x0088, 0x0200)); // Icon Image Sequence
592 removals_.insert(DicomTag(0x0088, 0x0904)); // Topic Title
593 removals_.insert(DicomTag(0x0088, 0x0906)); // Topic Subject
594 removals_.insert(DicomTag(0x0088, 0x0910)); // Topic Author
595 removals_.insert(DicomTag(0x0088, 0x0912)); // Topic Key Words
596 removals_.insert(DicomTag(0x0400, 0x0100)); // Digital Signature UID
597 removals_.insert(DicomTag(0x0400, 0x0402)); // Referenced Digital Signature Sequence
598 removals_.insert(DicomTag(0x0400, 0x0403)); // Referenced SOP Instance MAC Sequence
599 removals_.insert(DicomTag(0x0400, 0x0404)); // MAC
600 removals_.insert(DicomTag(0x0400, 0x0550)); // Modified Attributes Sequence
601 removals_.insert(DicomTag(0x0400, 0x0561)); // Original Attributes Sequence
602 removals_.insert(DicomTag(0x2030, 0x0020)); // Text String
603 removals_.insert(DicomTag(0x3006, 0x0024)); // Referenced Frame of Reference UID
604 removals_.insert(DicomTag(0x3006, 0x00c2)); // Related Frame of Reference UID
605 removals_.insert(DicomTag(0x300a, 0x0013)); // Dose Reference UID
606 removals_.insert(DicomTag(0x300e, 0x0008)); // Reviewer Name
607 removals_.insert(DicomTag(0x4000, 0x0010)); // Arbitrary
608 removals_.insert(DicomTag(0x4000, 0x4000)); // Text Comments
609 removals_.insert(DicomTag(0x4008, 0x0042)); // Results ID Issuer
610 removals_.insert(DicomTag(0x4008, 0x0102)); // Interpretation Recorder
611 removals_.insert(DicomTag(0x4008, 0x010a)); // Interpretation Transcriber
612 removals_.insert(DicomTag(0x4008, 0x010b)); // Interpretation Text
613 removals_.insert(DicomTag(0x4008, 0x010c)); // Interpretation Author
614 removals_.insert(DicomTag(0x4008, 0x0111)); // Interpretation Approver Sequence
615 removals_.insert(DicomTag(0x4008, 0x0114)); // Physician Approving Interpretation
616 removals_.insert(DicomTag(0x4008, 0x0115)); // Interpretation Diagnosis Description
617 removals_.insert(DicomTag(0x4008, 0x0118)); // Results Distribution List Sequence
618 removals_.insert(DicomTag(0x4008, 0x0119)); // Distribution Name
619 removals_.insert(DicomTag(0x4008, 0x011a)); // Distribution Address
620 removals_.insert(DicomTag(0x4008, 0x0202)); // Interpretation ID Issuer
621 removals_.insert(DicomTag(0x4008, 0x0300)); // Impressions
622 removals_.insert(DicomTag(0x4008, 0x4000)); // Results Comments
623 removals_.insert(DicomTag(0xfffa, 0xfffa)); // Digital Signature Sequence
624 removals_.insert(DicomTag(0xfffc, 0xfffc)); // Data Set Trailing Padding
625 //removals_.insert(DicomTag(0x60xx, 0x4000)); // Overlay Comments => TODO
626 //removals_.insert(DicomTag(0x60xx, 0x3000)); // Overlay Data => TODO
627
628 // Set the DeidentificationMethod tag
629 ReplaceInternal(DICOM_TAG_DEIDENTIFICATION_METHOD, ORTHANC_DEIDENTIFICATION_METHOD_2011);
630 }
631 #endif
632
633 494
634 495
635 void DicomModification::SetupAnonymization2017c() 496 void DicomModification::SetupAnonymization2017c()
636 { 497 {
637 /** 498 /**
643 **/ 504 **/
644 505
645 // TODO: (50xx,xxxx) with rule X // Curve Data 506 // TODO: (50xx,xxxx) with rule X // Curve Data
646 // TODO: (60xx,3000) with rule X // Overlay Data 507 // TODO: (60xx,3000) with rule X // Overlay Data
647 // TODO: (60xx,4000) with rule X // Overlay Comments 508 // TODO: (60xx,4000) with rule X // Overlay Comments
648 // Tag (0x0008, 0x0018) is set in Apply() // SOP Instance UID 509 // Tag (0x0008, 0x0018) is set in Apply() /* U */ // SOP Instance UID
649 // Tag (0x0010, 0x0010) is set below (*) // Patient's Name 510 // Tag (0x0008, 0x1140) => RelationshipsVisitor /* X/Z/U* */ // Referenced Image Sequence
650 // Tag (0x0010, 0x0020) is set below (*) // Patient ID 511 // Tag (0x0008, 0x1155) => RelationshipsVisitor /* U */ // Referenced SOP Instance UID
651 // Tag (0x0020, 0x000d) is set in Apply() // Study Instance UID 512 // Tag (0x0008, 0x2112) => RelationshipsVisitor /* X/Z/U* */ // Source Image Sequence
652 // Tag (0x0020, 0x000e) is set in Apply() // Series Instance UID 513 // Tag (0x0010, 0x0010) is set below (*) /* Z */ // Patient's Name
514 // Tag (0x0010, 0x0020) is set below (*) /* Z */ // Patient ID
515 // Tag (0x0020, 0x000d) is set in Apply() /* U */ // Study Instance UID
516 // Tag (0x0020, 0x000e) is set in Apply() /* U */ // Series Instance UID
517 // Tag (0x0020, 0x0052) => RelationshipsVisitor /* U */ // Frame of Reference UID
518 // Tag (0x3006, 0x0024) => RelationshipsVisitor /* U */ // Referenced Frame of Reference UID
519 // Tag (0x3006, 0x00c2) => RelationshipsVisitor /* U */ // Related Frame of Reference UID
653 clearings_.insert(DicomTag(0x0008, 0x0020)); // Study Date 520 clearings_.insert(DicomTag(0x0008, 0x0020)); // Study Date
654 clearings_.insert(DicomTag(0x0008, 0x0023)); /* Z/D */ // Content Date 521 clearings_.insert(DicomTag(0x0008, 0x0023)); /* Z/D */ // Content Date
655 clearings_.insert(DicomTag(0x0008, 0x0030)); // Study Time 522 clearings_.insert(DicomTag(0x0008, 0x0030)); // Study Time
656 clearings_.insert(DicomTag(0x0008, 0x0033)); /* Z/D */ // Content Time 523 clearings_.insert(DicomTag(0x0008, 0x0033)); /* Z/D */ // Content Time
657 clearings_.insert(DicomTag(0x0008, 0x0050)); // Accession Number 524 clearings_.insert(DicomTag(0x0008, 0x0050)); // Accession Number
709 removals_.insert(DicomTag(0x0008, 0x1080)); // Admitting Diagnoses Description 576 removals_.insert(DicomTag(0x0008, 0x1080)); // Admitting Diagnoses Description
710 removals_.insert(DicomTag(0x0008, 0x1084)); // Admitting Diagnoses Code Sequence 577 removals_.insert(DicomTag(0x0008, 0x1084)); // Admitting Diagnoses Code Sequence
711 removals_.insert(DicomTag(0x0008, 0x1110)); /* X/Z */ // Referenced Study Sequence 578 removals_.insert(DicomTag(0x0008, 0x1110)); /* X/Z */ // Referenced Study Sequence
712 removals_.insert(DicomTag(0x0008, 0x1111)); /* X/Z/D */ // Referenced Performed Procedure Step Sequence 579 removals_.insert(DicomTag(0x0008, 0x1111)); /* X/Z/D */ // Referenced Performed Procedure Step Sequence
713 removals_.insert(DicomTag(0x0008, 0x1120)); // Referenced Patient Sequence 580 removals_.insert(DicomTag(0x0008, 0x1120)); // Referenced Patient Sequence
714 removals_.insert(DicomTag(0x0008, 0x1140)); /* X/Z/U* */ // Referenced Image Sequence
715 removals_.insert(DicomTag(0x0008, 0x1155)); /* TODO UID */ // Referenced SOP Instance UID
716 removals_.insert(DicomTag(0x0008, 0x1195)); /* TODO UID */ // Transaction UID 581 removals_.insert(DicomTag(0x0008, 0x1195)); /* TODO UID */ // Transaction UID
717 removals_.insert(DicomTag(0x0008, 0x2111)); // Derivation Description 582 removals_.insert(DicomTag(0x0008, 0x2111)); // Derivation Description
718 removals_.insert(DicomTag(0x0008, 0x2112)); /* X/Z/U* */ // Source Image Sequence
719 removals_.insert(DicomTag(0x0008, 0x3010)); /* TODO UID */ // Irradiation Event UID 583 removals_.insert(DicomTag(0x0008, 0x3010)); /* TODO UID */ // Irradiation Event UID
720 removals_.insert(DicomTag(0x0008, 0x4000)); // Identifying Comments 584 removals_.insert(DicomTag(0x0008, 0x4000)); // Identifying Comments
721 removals_.insert(DicomTag(0x0010, 0x0021)); // Issuer of Patient ID 585 removals_.insert(DicomTag(0x0010, 0x0021)); // Issuer of Patient ID
722 removals_.insert(DicomTag(0x0010, 0x0032)); // Patient's Birth Time 586 removals_.insert(DicomTag(0x0010, 0x0032)); // Patient's Birth Time
723 removals_.insert(DicomTag(0x0010, 0x0050)); // Patient's Insurance Plan Code Sequence 587 removals_.insert(DicomTag(0x0010, 0x0050)); // Patient's Insurance Plan Code Sequence
767 removals_.insert(DicomTag(0x0018, 0x700a)); /* X/D */ // Detector ID 631 removals_.insert(DicomTag(0x0018, 0x700a)); /* X/D */ // Detector ID
768 removals_.insert(DicomTag(0x0018, 0x9424)); // Acquisition Protocol Description 632 removals_.insert(DicomTag(0x0018, 0x9424)); // Acquisition Protocol Description
769 removals_.insert(DicomTag(0x0018, 0x9516)); /* X/D */ // Start Acquisition DateTime 633 removals_.insert(DicomTag(0x0018, 0x9516)); /* X/D */ // Start Acquisition DateTime
770 removals_.insert(DicomTag(0x0018, 0x9517)); /* X/D */ // End Acquisition DateTime 634 removals_.insert(DicomTag(0x0018, 0x9517)); /* X/D */ // End Acquisition DateTime
771 removals_.insert(DicomTag(0x0018, 0xa003)); // Contribution Description 635 removals_.insert(DicomTag(0x0018, 0xa003)); // Contribution Description
772 removals_.insert(DicomTag(0x0020, 0x0052)); /* TODO UID */ // Frame of Reference UID
773 removals_.insert(DicomTag(0x0020, 0x0200)); /* TODO UID */ // Synchronization Frame of Reference UID 636 removals_.insert(DicomTag(0x0020, 0x0200)); /* TODO UID */ // Synchronization Frame of Reference UID
774 removals_.insert(DicomTag(0x0020, 0x3401)); // Modifying Device ID 637 removals_.insert(DicomTag(0x0020, 0x3401)); // Modifying Device ID
775 removals_.insert(DicomTag(0x0020, 0x3404)); // Modifying Device Manufacturer 638 removals_.insert(DicomTag(0x0020, 0x3404)); // Modifying Device Manufacturer
776 removals_.insert(DicomTag(0x0020, 0x3406)); // Modified Image Description 639 removals_.insert(DicomTag(0x0020, 0x3406)); // Modified Image Description
777 removals_.insert(DicomTag(0x0020, 0x4000)); // Image Comments 640 removals_.insert(DicomTag(0x0020, 0x4000)); // Image Comments
893 removals_.insert(DicomTag(0x0400, 0x0403)); // Referenced SOP Instance MAC Sequence 756 removals_.insert(DicomTag(0x0400, 0x0403)); // Referenced SOP Instance MAC Sequence
894 removals_.insert(DicomTag(0x0400, 0x0404)); // MAC 757 removals_.insert(DicomTag(0x0400, 0x0404)); // MAC
895 removals_.insert(DicomTag(0x0400, 0x0550)); // Modified Attributes Sequence 758 removals_.insert(DicomTag(0x0400, 0x0550)); // Modified Attributes Sequence
896 removals_.insert(DicomTag(0x0400, 0x0561)); // Original Attributes Sequence 759 removals_.insert(DicomTag(0x0400, 0x0561)); // Original Attributes Sequence
897 removals_.insert(DicomTag(0x2030, 0x0020)); // Text String 760 removals_.insert(DicomTag(0x2030, 0x0020)); // Text String
898 removals_.insert(DicomTag(0x3006, 0x0024)); /* TODO UID */ // Referenced Frame of Reference UID
899 removals_.insert(DicomTag(0x3006, 0x00c2)); /* TODO UID */ // Related Frame of Reference UID
900 removals_.insert(DicomTag(0x3008, 0x0105)); // Source Serial Number 761 removals_.insert(DicomTag(0x3008, 0x0105)); // Source Serial Number
901 removals_.insert(DicomTag(0x300a, 0x0013)); /* TODO UID */ // Dose Reference UID 762 removals_.insert(DicomTag(0x300a, 0x0013)); /* TODO UID */ // Dose Reference UID
902 removals_.insert(DicomTag(0x300c, 0x0113)); // Reason for Omission Description 763 removals_.insert(DicomTag(0x300c, 0x0113)); // Reason for Omission Description
903 removals_.insert(DicomTag(0x300e, 0x0008)); /* X/Z */ // Reviewer Name 764 removals_.insert(DicomTag(0x300e, 0x0008)); /* X/Z */ // Reviewer Name
904 removals_.insert(DicomTag(0x4000, 0x0010)); // Arbitrary 765 removals_.insert(DicomTag(0x4000, 0x0010)); // Arbitrary
1104 { 965 {
1105 LOG(WARNING) << "Modifying a study while keeping its original StudyInstanceUID: This should be avoided!"; 966 LOG(WARNING) << "Modifying a study while keeping its original StudyInstanceUID: This should be avoided!";
1106 } 967 }
1107 else 968 else
1108 { 969 {
1109 MapDicomIdentifier(toModify, ResourceType_Study); 970 MapDicomTags(toModify, ResourceType_Study);
1110 } 971 }
1111 } 972 }
1112 973
1113 if (level_ <= ResourceType_Series && 974 if (level_ <= ResourceType_Series &&
1114 !IsReplaced(DICOM_TAG_SERIES_INSTANCE_UID)) 975 !IsReplaced(DICOM_TAG_SERIES_INSTANCE_UID))
1117 { 978 {
1118 LOG(WARNING) << "Modifying a series while keeping its original SeriesInstanceUID: This should be avoided!"; 979 LOG(WARNING) << "Modifying a series while keeping its original SeriesInstanceUID: This should be avoided!";
1119 } 980 }
1120 else 981 else
1121 { 982 {
1122 MapDicomIdentifier(toModify, ResourceType_Series); 983 MapDicomTags(toModify, ResourceType_Series);
1123 } 984 }
1124 } 985 }
1125 986
1126 if (level_ <= ResourceType_Instance && // Always true 987 if (level_ <= ResourceType_Instance && // Always true
1127 !IsReplaced(DICOM_TAG_SOP_INSTANCE_UID)) 988 !IsReplaced(DICOM_TAG_SOP_INSTANCE_UID))
1128 { 989 {
1129 MapDicomIdentifier(toModify, ResourceType_Instance); 990 MapDicomTags(toModify, ResourceType_Instance);
991 }
992
993 // (6) Update the "referenced" relationships
994 {
995 RelationshipsVisitor visitor(*this);
996
997 if (updateReferencedRelationships_)
998 {
999 toModify.Apply(visitor);
1000 }
1001 else
1002 {
1003 visitor.RemoveRelationships(toModify);
1004 }
1130 } 1005 }
1131 } 1006 }
1132 } 1007 }