Class: DICOM::Anonymizer
- Inherits:
-
Object
- Object
- DICOM::Anonymizer
- Includes:
- Logging
- Defined in:
- lib/dicom/anonymizer.rb
Overview
For a thorough introduction to the concept of DICOM anonymization, please refer to The DICOM Standard, Part 15: Security and System Management Profiles, Annex E: Attribute Confidentiality Profiles. For guidance on settings for individual data elements, please refer to DICOM PS 3.15, Annex E, Table E.1-1: Application Level Confidentiality Profile Attributes.
This is a convenience class for handling the anonymization (de-identification) of DICOM files.
Instance Attribute Summary collapse
-
#audit_trail ⇒ Object
readonly
An AuditTrail instance used for this anonymization (if specified).
-
#audit_trail_file ⇒ Object
readonly
The file name used for the AuditTrail serialization (if specified).
-
#blank ⇒ Object
A boolean that if set as true will cause all anonymized tags to be blank instead of get some generic value.
-
#delete ⇒ Object
readonly
An hash of elements (represented by tag keys) that will be deleted from the DICOM objects on anonymization.
-
#delete_private ⇒ Object
A boolean that if set as true, will make the anonymization delete all private tags.
-
#encryption ⇒ Object
readonly
The cryptographic hash function to be used for encrypting DICOM values recorded in an audit trail file.
-
#enumeration ⇒ Object
A boolean that if set as true will cause all anonymized tags to be get enumerated values, to enable post-anonymization re-identification by the user.
-
#logger_level ⇒ Object
readonly
The logger level which is applied to DObject operations during anonymization (defaults to Logger::FATAL).
-
#random_file_name ⇒ Object
A boolean that if set as true will cause all anonymized files to be written with random file names (if write_path has been specified).
-
#recursive ⇒ Object
A boolean that if set as true, will cause the anonymization to run on all levels of the DICOM file tag hierarchy.
-
#uid ⇒ Object
A boolean indicating whether or not UIDs shall be replaced when executing the anonymization.
-
#uid_root ⇒ Object
The DICOM UID root to use when generating new UIDs.
-
#write_path ⇒ Object
The path where the anonymized files will be saved.
Instance Method Summary collapse
-
#==(other) ⇒ Boolean
(also: #eql?)
Checks for equality.
-
#anonymize(dicom) ⇒ Array<DObject>
Anonymizes the given DObject or array of DICOM objects with the settings of this Anonymizer instance.
-
#anonymize_path(path) ⇒ Object
Anonymizes any DICOM files found at the given path (file or directory) with the settings of this Anonymizer instance.
-
#delete_tag(tag) ⇒ Object
Specifies that the given tag is to be completely deleted from the anonymized DICOM objects.
-
#enum(tag) ⇒ Boolean, NilClass
Checks the enumeration status of this tag.
-
#hash ⇒ Integer
Computes a hash code for this object.
-
#initialize(options = {}) ⇒ Anonymizer
constructor
Creates an Anonymizer instance.
-
#remove_tag(tag) ⇒ Object
Removes a tag from the list of tags that will be anonymized.
-
#set_tag(tag, options = {}) ⇒ Object
Sets the anonymization settings for the specified tag.
-
#to_anonymizer ⇒ Anonymizer
Returns self.
-
#value(tag) ⇒ String, ...
Gives the value which will be used when anonymizing this tag.
Methods included from Logging
Constructor Details
#initialize(options = {}) ⇒ Anonymizer
To customize logging behaviour, refer to the Logging module documentation.
Creates an Anonymizer instance.
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/dicom/anonymizer.rb', line 68 def initialize(={}) # Transfer options to attributes: @blank = [:blank] @delete_private = [:delete_private] @enumeration = [:enumeration] @logger_level = [:logger_level] || Logger::FATAL @random_file_name = [:random_file_name] @recursive = [:recursive] @uid = [:uid] @uid_root = [:uid_root] ? [:uid_root] : UID_ROOT @write_path = [:write_path] # Array of folders to be processed for anonymization: @folders = Array.new # Folders that will be skipped: @exceptions = Array.new # Data elements which will be anonymized (the array will hold a list of tag strings): @tags = Array.new # Default values to use on anonymized data elements: @values = Array.new # Which data elements will have enumeration applied, if requested by the user: @enumerations = Array.new # We use a Hash to store information from DICOM files if enumeration is desired: @enum_old_hash = Hash.new @enum_new_hash = Hash.new # All the files to be anonymized will be put in this array: @files = Array.new @prefixes = Hash.new # Setup audit trail if requested: if [:audit_trail] @audit_trail_file = [:audit_trail] if File.exists?(@audit_trail_file) && File.size(@audit_trail_file) > 2 # Load the pre-existing audit trail from file: @audit_trail = AuditTrail.read(@audit_trail_file) else # Start from scratch with an empty audit trail: @audit_trail = AuditTrail.new end # Set up encryption if indicated: if [:encryption] require 'digest' if [:encryption].respond_to?(:hexdigest) @encryption = [:encryption] else @encryption = Digest::MD5 end end end # Set the default data elements to be anonymized: set_defaults end |
Instance Attribute Details
#audit_trail ⇒ Object (readonly)
An AuditTrail instance used for this anonymization (if specified).
18 19 20 |
# File 'lib/dicom/anonymizer.rb', line 18 def audit_trail @audit_trail end |
#audit_trail_file ⇒ Object (readonly)
The file name used for the AuditTrail serialization (if specified).
20 21 22 |
# File 'lib/dicom/anonymizer.rb', line 20 def audit_trail_file @audit_trail_file end |
#blank ⇒ Object
A boolean that if set as true will cause all anonymized tags to be blank instead of get some generic value.
22 23 24 |
# File 'lib/dicom/anonymizer.rb', line 22 def blank @blank end |
#delete ⇒ Object (readonly)
An hash of elements (represented by tag keys) that will be deleted from the DICOM objects on anonymization.
24 25 26 |
# File 'lib/dicom/anonymizer.rb', line 24 def delete @delete end |
#delete_private ⇒ Object
A boolean that if set as true, will make the anonymization delete all private tags.
26 27 28 |
# File 'lib/dicom/anonymizer.rb', line 26 def delete_private @delete_private end |
#encryption ⇒ Object (readonly)
The cryptographic hash function to be used for encrypting DICOM values recorded in an audit trail file.
28 29 30 |
# File 'lib/dicom/anonymizer.rb', line 28 def encryption @encryption end |
#enumeration ⇒ Object
A boolean that if set as true will cause all anonymized tags to be get enumerated values, to enable post-anonymization re-identification by the user.
30 31 32 |
# File 'lib/dicom/anonymizer.rb', line 30 def enumeration @enumeration end |
#logger_level ⇒ Object (readonly)
The logger level which is applied to DObject operations during anonymization (defaults to Logger::FATAL).
32 33 34 |
# File 'lib/dicom/anonymizer.rb', line 32 def logger_level @logger_level end |
#random_file_name ⇒ Object
A boolean that if set as true will cause all anonymized files to be written with random file names (if write_path has been specified).
34 35 36 |
# File 'lib/dicom/anonymizer.rb', line 34 def random_file_name @random_file_name end |
#recursive ⇒ Object
A boolean that if set as true, will cause the anonymization to run on all levels of the DICOM file tag hierarchy.
36 37 38 |
# File 'lib/dicom/anonymizer.rb', line 36 def recursive @recursive end |
#uid ⇒ Object
A boolean indicating whether or not UIDs shall be replaced when executing the anonymization.
38 39 40 |
# File 'lib/dicom/anonymizer.rb', line 38 def uid @uid end |
#uid_root ⇒ Object
The DICOM UID root to use when generating new UIDs.
40 41 42 |
# File 'lib/dicom/anonymizer.rb', line 40 def uid_root @uid_root end |
#write_path ⇒ Object
The path where the anonymized files will be saved. If this value is not set, the original DICOM files will be overwritten.
42 43 44 |
# File 'lib/dicom/anonymizer.rb', line 42 def write_path @write_path end |
Instance Method Details
#==(other) ⇒ Boolean Also known as: eql?
Checks for equality.
Other and self are considered equivalent if they are of compatible types and their attributes are equivalent.
127 128 129 130 131 |
# File 'lib/dicom/anonymizer.rb', line 127 def ==(other) if other.respond_to?(:to_anonymizer) other.send(:state) == state end end |
#anonymize(dicom) ⇒ Array<DObject>
Anonymizes the given DObject or array of DICOM objects with the settings of this Anonymizer instance.
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/dicom/anonymizer.rb', line 141 def anonymize(dicom) dicom = Array[dicom] unless dicom.respond_to?(:to_ary) if @tags.length > 0 prepare_anonymization dicom.each do |dcm| anonymize_dcm(dcm.to_dcm) end else logger.warn("No tags have been selected for anonymization. Aborting anonymization.") end # Save the audit trail (if used): @audit_trail.write(@audit_trail_file) if @audit_trail logger.info("Anonymization complete.") dicom end |
#anonymize_path(path) ⇒ Object
Anonymizes any DICOM files found at the given path (file or directory) with the settings of this Anonymizer instance.
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/dicom/anonymizer.rb', line 162 def anonymize_path(path) if @tags.length > 0 prepare_anonymization files = DICOM.load_files(path) logger.info("#{files.length} DICOM files have been prepared for anonymization.") files.each do |f| dcm = anonymize_file(f) write(dcm) end else logger.warn("No tags have been selected for anonymization. Aborting anonymization.") end # Save the audit trail (if used): @audit_trail.write(@audit_trail_file) if @audit_trail logger.info("Anonymization complete.") end |
#delete_tag(tag) ⇒ Object
Specifies that the given tag is to be completely deleted from the anonymized DICOM objects.
186 187 188 189 190 |
# File 'lib/dicom/anonymizer.rb', line 186 def delete_tag(tag) raise ArgumentError, "Expected String, got #{tag.class}." unless tag.is_a?(String) raise ArgumentError, "Expected a valid tag of format 'GGGG,EEEE', got #{tag}." unless tag.tag? @delete[tag] = true end |
#enum(tag) ⇒ Boolean, NilClass
Checks the enumeration status of this tag.
197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/dicom/anonymizer.rb', line 197 def enum(tag) raise ArgumentError, "Expected String, got #{tag.class}." unless tag.is_a?(String) raise ArgumentError, "Expected a valid tag of format 'GGGG,EEEE', got #{tag}." unless tag.tag? pos = @tags.index(tag) if pos return @enumerations[pos] else logger.warn("The specified tag (#{tag}) was not found in the list of tags to be anonymized.") return nil end end |
#hash ⇒ Integer
Two objects with the same attributes will have the same hash code.
Computes a hash code for this object.
215 216 217 |
# File 'lib/dicom/anonymizer.rb', line 215 def hash state.hash end |
#remove_tag(tag) ⇒ Object
Removes a tag from the list of tags that will be anonymized.
225 226 227 228 229 230 231 232 233 234 |
# File 'lib/dicom/anonymizer.rb', line 225 def remove_tag(tag) raise ArgumentError, "Expected String, got #{tag.class}." unless tag.is_a?(String) raise ArgumentError, "Expected a valid tag of format 'GGGG,EEEE', got #{tag}." unless tag.tag? pos = @tags.index(tag) if pos @tags.delete_at(pos) @values.delete_at(pos) @enumerations.delete_at(pos) end end |
#set_tag(tag, options = {}) ⇒ Object
Sets the anonymization settings for the specified tag. If the tag is already present in the list of tags to be anonymized, its settings are updated, and if not, a new tag entry is created.
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 |
# File 'lib/dicom/anonymizer.rb', line 246 def set_tag(tag, ={}) raise ArgumentError, "Expected String, got #{tag.class}." unless tag.is_a?(String) raise ArgumentError, "Expected a valid tag of format 'GGGG,EEEE', got #{tag}." unless tag.tag? pos = @tags.index(tag) if pos # Update existing values: @values[pos] = [:value] if [:value] @enumerations[pos] = [:enum] if [:enum] != nil else # Add new elements: @tags << tag @values << ([:value] ? [:value] : default_value(tag)) @enumerations << ([:enum] ? [:enum] : false) end end |
#to_anonymizer ⇒ Anonymizer
Returns self.
266 267 268 |
# File 'lib/dicom/anonymizer.rb', line 266 def to_anonymizer self end |
#value(tag) ⇒ String, ...
If enumeration is selected for a string type tag, a number will be appended in addition to the string that is returned here.
Gives the value which will be used when anonymizing this tag.
278 279 280 281 282 283 284 285 286 287 288 |
# File 'lib/dicom/anonymizer.rb', line 278 def value(tag) raise ArgumentError, "Expected String, got #{tag.class}." unless tag.is_a?(String) raise ArgumentError, "Expected a valid tag of format 'GGGG,EEEE', got #{tag}." unless tag.tag? pos = @tags.index(tag) if pos return @values[pos] else logger.warn("The specified tag (#{tag}) was not found in the list of tags to be anonymized.") return nil end end |