PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
kcenon::pacs::dcm_modify::anonymizer Class Reference

DICOM Anonymizer - removes or replaces PHI from datasets. More...

#include <anonymizer.h>

Collaboration diagram for kcenon::pacs::dcm_modify::anonymizer:
Collaboration graph

Public Member Functions

 anonymizer ()=default
 Construct an anonymizer with default options.
 
 anonymizer (anonymize_options opts)
 Construct an anonymizer with custom options.
 
void anonymize (core::dicom_dataset &dataset)
 Anonymize a DICOM dataset in place.
 
uid_mapperget_uid_mapper ()
 Get the UID mapper for consistent UID replacement.
 
const anonymize_optionsoptions () const
 Get the current options.
 
void set_options (anonymize_options opts)
 Set new options.
 

Private Member Functions

void anonymize_patient_info (core::dicom_dataset &dataset)
 
void anonymize_uids (core::dicom_dataset &dataset)
 
void remove_private_tags (core::dicom_dataset &dataset)
 
void remove_additional_phi (core::dicom_dataset &dataset)
 

Private Attributes

anonymize_options options_
 
uid_mapper uid_mapper_
 
std::atomic< uint64_t > patient_counter_ {0}
 

Detailed Description

DICOM Anonymizer - removes or replaces PHI from datasets.

Implements basic DICOM anonymization as specified in DICOM PS3.15. This includes removal/replacement of:

  • Patient identifying information
  • UIDs (to prevent correlation)
  • Dates (optional shifting)
  • Free-text fields that may contain PHI

Definition at line 113 of file anonymizer.h.

Constructor & Destructor Documentation

◆ anonymizer() [1/2]

kcenon::pacs::dcm_modify::anonymizer::anonymizer ( )
default

Construct an anonymizer with default options.

◆ anonymizer() [2/2]

kcenon::pacs::dcm_modify::anonymizer::anonymizer ( anonymize_options opts)
inlineexplicit

Construct an anonymizer with custom options.

Parameters
optsAnonymization options

Definition at line 124 of file anonymizer.h.

124: options_(std::move(opts)) {}

Member Function Documentation

◆ anonymize()

void kcenon::pacs::dcm_modify::anonymizer::anonymize ( core::dicom_dataset & dataset)
inline

Anonymize a DICOM dataset in place.

Parameters
datasetThe dataset to anonymize

Definition at line 130 of file anonymizer.h.

130 {
131 using namespace kcenon::pacs::core;
132 using namespace kcenon::pacs::encoding;
133
134 // Patient identifying information
135 anonymize_patient_info(dataset);
136
137 // UIDs
139 anonymize_uids(dataset);
140 }
141
142 // Dates
144 dataset.remove(tags::patient_birth_date);
145 }
146
147 // Referring physician
149 dataset.remove(tags::referring_physician_name);
150 }
151
152 // Institution
154 dataset.remove(dicom_tag{0x0008, 0x0080}); // InstitutionName
155 dataset.remove(dicom_tag{0x0008, 0x0081}); // InstitutionAddress
156 }
157
158 // Descriptions (may contain PHI in free text)
160 dataset.remove(tags::study_description);
161 dataset.remove(dicom_tag{0x0008, 0x103E}); // SeriesDescription
162 }
163
164 // Address and other contact info
166 dataset.remove(dicom_tag{0x0010, 0x1040}); // PatientAddress
167 dataset.remove(dicom_tag{0x0010, 0x2154}); // PatientTelephoneNumbers
168 }
169
170 // Remove private tags unless explicitly kept
172 remove_private_tags(dataset);
173 }
174
175 // Additional PHI tags
176 remove_additional_phi(dataset);
177 }
void remove_additional_phi(core::dicom_dataset &dataset)
Definition anonymizer.h:271
void anonymize_patient_info(core::dicom_dataset &dataset)
Definition anonymizer.h:198
void anonymize_uids(core::dicom_dataset &dataset)
Definition anonymizer.h:224
void remove_private_tags(core::dicom_dataset &dataset)
Definition anonymizer.h:257
constexpr dicom_tag referring_physician_name
Referring Physician's Name.
constexpr dicom_tag study_description
Study Description.
constexpr dicom_tag patient_birth_date
Patient's Birth Date.
bool remove_referring_physician
Remove referring physician name.
Definition anonymizer.h:91
bool remove_descriptions
Remove study/series descriptions.
Definition anonymizer.h:97
bool remove_address
Remove patient address.
Definition anonymizer.h:88
bool replace_uids
Replace UIDs with new generated UIDs.
Definition anonymizer.h:76
bool remove_institution
Remove institution name.
Definition anonymizer.h:94
bool keep_private_tags
Keep private tags (vendor-specific)
Definition anonymizer.h:100
bool remove_birth_date
Remove patient birth date.
Definition anonymizer.h:85

References anonymize_patient_info(), anonymize_uids(), kcenon::pacs::dcm_modify::anonymize_options::keep_private_tags, options_, kcenon::pacs::core::tags::patient_birth_date, kcenon::pacs::core::tags::referring_physician_name, kcenon::pacs::core::dicom_dataset::remove(), remove_additional_phi(), kcenon::pacs::dcm_modify::anonymize_options::remove_address, kcenon::pacs::dcm_modify::anonymize_options::remove_birth_date, kcenon::pacs::dcm_modify::anonymize_options::remove_descriptions, kcenon::pacs::dcm_modify::anonymize_options::remove_institution, remove_private_tags(), kcenon::pacs::dcm_modify::anonymize_options::remove_referring_physician, kcenon::pacs::dcm_modify::anonymize_options::replace_uids, and kcenon::pacs::core::tags::study_description.

Here is the call graph for this function:

◆ anonymize_patient_info()

void kcenon::pacs::dcm_modify::anonymizer::anonymize_patient_info ( core::dicom_dataset & dataset)
inlineprivate

Definition at line 198 of file anonymizer.h.

198 {
199 using namespace kcenon::pacs::core;
200 using namespace kcenon::pacs::encoding;
201
202 // Patient Name
203 if (!options_.patient_name_replacement.empty()) {
204 dataset.set_string(tags::patient_name, vr_type::PN,
206 } else {
207 dataset.remove(tags::patient_name);
208 }
209
210 // Patient ID
212 std::to_string(++patient_counter_);
213 dataset.set_string(tags::patient_id, vr_type::LO, patient_id);
214
215 // Patient's Birth Name, Mother's Maiden Name
216 dataset.remove(dicom_tag{0x0010, 0x1005}); // PatientBirthName
217 dataset.remove(dicom_tag{0x0010, 0x1060}); // PatientMotherBirthName
218
219 // Other patient IDs
220 dataset.remove(dicom_tag{0x0010, 0x1000}); // OtherPatientIDs
221 dataset.remove(dicom_tag{0x0010, 0x1001}); // OtherPatientNames
222 }
std::atomic< uint64_t > patient_counter_
Definition anonymizer.h:293
constexpr dicom_tag patient_id
Patient ID.
constexpr dicom_tag patient_name
Patient's Name.
std::string patient_name_replacement
Replace patient name with this value (empty = remove)
Definition anonymizer.h:79
std::string patient_id_prefix
Replace patient ID with this prefix + counter.
Definition anonymizer.h:82

References options_, patient_counter_, kcenon::pacs::core::tags::patient_id, kcenon::pacs::dcm_modify::anonymize_options::patient_id_prefix, kcenon::pacs::core::tags::patient_name, kcenon::pacs::dcm_modify::anonymize_options::patient_name_replacement, kcenon::pacs::core::dicom_dataset::remove(), and kcenon::pacs::core::dicom_dataset::set_string().

Referenced by anonymize().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ anonymize_uids()

void kcenon::pacs::dcm_modify::anonymizer::anonymize_uids ( core::dicom_dataset & dataset)
inlineprivate

Definition at line 224 of file anonymizer.h.

224 {
225 using namespace kcenon::pacs::core;
226 using namespace kcenon::pacs::encoding;
227
228 // Study Instance UID
229 auto study_uid = dataset.get_string(tags::study_instance_uid);
230 if (!study_uid.empty()) {
231 dataset.set_string(tags::study_instance_uid, vr_type::UI,
232 uid_mapper_.map(study_uid));
233 }
234
235 // Series Instance UID
236 auto series_uid = dataset.get_string(tags::series_instance_uid);
237 if (!series_uid.empty()) {
238 dataset.set_string(tags::series_instance_uid, vr_type::UI,
239 uid_mapper_.map(series_uid));
240 }
241
242 // SOP Instance UID
243 auto sop_uid = dataset.get_string(tags::sop_instance_uid);
244 if (!sop_uid.empty()) {
245 dataset.set_string(tags::sop_instance_uid, vr_type::UI,
246 uid_mapper_.map(sop_uid));
247 }
248
249 // Frame of Reference UID
250 auto frame_uid = dataset.get_string(dicom_tag{0x0020, 0x0052});
251 if (!frame_uid.empty()) {
252 dataset.set_string(dicom_tag{0x0020, 0x0052}, vr_type::UI,
253 uid_mapper_.map(frame_uid));
254 }
255 }
std::string map(const std::string &original_uid)
Get or create a replacement UID for the original UID.
Definition anonymizer.h:38
constexpr dicom_tag sop_instance_uid
SOP Instance UID.
constexpr dicom_tag study_instance_uid
Study Instance UID.
constexpr dicom_tag series_instance_uid
Series Instance UID.

References kcenon::pacs::core::dicom_dataset::get_string(), kcenon::pacs::dcm_modify::uid_mapper::map(), kcenon::pacs::core::tags::series_instance_uid, kcenon::pacs::core::dicom_dataset::set_string(), kcenon::pacs::core::tags::sop_instance_uid, kcenon::pacs::core::tags::study_instance_uid, and uid_mapper_.

Referenced by anonymize().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_uid_mapper()

uid_mapper & kcenon::pacs::dcm_modify::anonymizer::get_uid_mapper ( )
inline

Get the UID mapper for consistent UID replacement.

Returns
Reference to the UID mapper

Definition at line 183 of file anonymizer.h.

183{ return uid_mapper_; }

References uid_mapper_.

◆ options()

const anonymize_options & kcenon::pacs::dcm_modify::anonymizer::options ( ) const
inline

Get the current options.

Returns
Reference to the options

Definition at line 189 of file anonymizer.h.

189{ return options_; }

References options_.

◆ remove_additional_phi()

void kcenon::pacs::dcm_modify::anonymizer::remove_additional_phi ( core::dicom_dataset & dataset)
inlineprivate

Definition at line 271 of file anonymizer.h.

271 {
272 // Accession Number (may be linked to hospital records)
273 dataset.remove(core::dicom_tag{0x0008, 0x0050});
274
275 // Patient comments
276 dataset.remove(core::dicom_tag{0x0010, 0x4000});
277
278 // Study comments
279 dataset.remove(core::dicom_tag{0x0032, 0x4000});
280
281 // Requested Procedure Description
282 dataset.remove(core::dicom_tag{0x0032, 0x1060});
283
284 // Performed Procedure Step Description
285 dataset.remove(core::dicom_tag{0x0040, 0x0254});
286
287 // Device Serial Number
288 dataset.remove(core::dicom_tag{0x0018, 0x1000});
289 }

References kcenon::pacs::core::dicom_dataset::remove().

Referenced by anonymize().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ remove_private_tags()

void kcenon::pacs::dcm_modify::anonymizer::remove_private_tags ( core::dicom_dataset & dataset)
inlineprivate

Definition at line 257 of file anonymizer.h.

257 {
258 std::vector<core::dicom_tag> private_tags;
259
260 for (const auto& [tag, element] : dataset) {
261 if (tag.is_private()) {
262 private_tags.push_back(tag);
263 }
264 }
265
266 for (const auto& tag : private_tags) {
267 dataset.remove(tag);
268 }
269 }

References kcenon::pacs::core::dicom_dataset::remove().

Referenced by anonymize().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_options()

void kcenon::pacs::dcm_modify::anonymizer::set_options ( anonymize_options opts)
inline

Set new options.

Parameters
optsNew options

Definition at line 195 of file anonymizer.h.

195{ options_ = std::move(opts); }

References options_.

Member Data Documentation

◆ options_

anonymize_options kcenon::pacs::dcm_modify::anonymizer::options_
private

Definition at line 291 of file anonymizer.h.

Referenced by anonymize(), anonymize_patient_info(), options(), and set_options().

◆ patient_counter_

std::atomic<uint64_t> kcenon::pacs::dcm_modify::anonymizer::patient_counter_ {0}
private

Definition at line 293 of file anonymizer.h.

293{0};

Referenced by anonymize_patient_info().

◆ uid_mapper_

uid_mapper kcenon::pacs::dcm_modify::anonymizer::uid_mapper_
private

Definition at line 292 of file anonymizer.h.

Referenced by anonymize_uids(), and get_uid_mapper().


The documentation for this class was generated from the following file: