dicom 0.4 → 0.5

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,4 +1,24 @@
1
- =0.4
1
+ = 0.5
2
+
3
+ === 4th May, 2009
4
+
5
+ * Several small changes have been made to achieve compatibility with both Ruby versions 1.8 and 1.9.
6
+ * Implemented a change in syntax for several methods with a goal of simplification.
7
+ * Implemented a change in syntax for some methods, variables and messages in order
8
+ to better match the terminology used in the official DICOM documents.
9
+ * Added a new attr_reader :errors, an array that holds any warnings issued during your
10
+ interaction with DObject.
11
+ * DObject has received new attr_readers for the arrays holding information on the DICOM object.
12
+ See documentation for details.
13
+ * Several methods have been cleaned up, making execution in some cases somewhat snappier.
14
+ * Several methods have been made more robust.
15
+ * Added new keyword :partial to the get_pos() method, which will enable search for partial string matches.
16
+ * Added new keyword :array to the get_value() and get_raw() methods which enables easy extraction of
17
+ multiple values of a given tag to an array (relevant for tags present at multiple places in a DICOM file)
18
+ * Fixed a bug where exception folders where ignored in the Anonymizer class.
19
+
20
+
21
+ = 0.4
2
22
 
3
23
  === 3rd February, 2009
4
24
 
@@ -22,6 +42,7 @@
22
42
  * Introducing the Anonymizer class, which takes advantage of the new write capability in Ruby DICOM
23
43
  to offer a fairly powerful and customizable tool for anonymizing your DICOM files.
24
44
 
45
+
25
46
  = 0.3
26
47
 
27
48
  === 12th October, 2008
@@ -48,28 +69,29 @@
48
69
  * DRead class is more resistant to breaking if it is handed a faulty file to read, and will return an error message instead of halting execution.
49
70
  * Added option to load DICOM object in verbose or silent mode.
50
71
 
51
- = 0.1
52
-
53
- === 20th July, 2008
54
-
55
- First public release.
56
- The library does have several known issues and lacks some features I would like it to have, but it does offer basic functionality and should be usable for people interested in working with DICOM files in Ruby. The reading algorithm has been tested succesfully with some 40 different DICOM files, so it should be fairly robust.
57
-
58
- Features:
59
- * Reads DICOM files
60
- * Retrieve tags, formatted
61
- * Retrieve tags, unformatted
62
- * Retrieve image data as NArray object
63
- * Retrieve image data as RMagick object
64
- * Print file properties
65
- * Print tag information
66
-
67
-
68
- Known issues:
69
- * 12 bit image data not supported
70
- * Color images not supported in NArray and RMagick retrieve methods
71
- * Unpacking compressed image data has basic support but is not properly tested yet.
72
- * Reading Big Endian has basic, but not full, support.
73
- * Reading on a Big Endian system is not tested.
74
- * Reading of multiple frame image data to RMagick does not work in all cases.
72
+
73
+ = 0.1
74
+
75
+ === 20th July, 2008
76
+
77
+ First public release.
78
+ The library does have several known issues and lacks some features I would like it to have, but it does offer basic functionality and should be usable for people interested in working with DICOM files in Ruby. The reading algorithm has been tested succesfully with some 40 different DICOM files, so it should be fairly robust.
79
+
80
+ Features:
81
+ * Reads DICOM files
82
+ * Retrieve tags, formatted
83
+ * Retrieve tags, unformatted
84
+ * Retrieve image data as NArray object
85
+ * Retrieve image data as RMagick object
86
+ * Print file properties
87
+ * Print tag information
88
+
89
+
90
+ Known issues:
91
+ * 12 bit image data not supported
92
+ * Color images not supported in NArray and RMagick retrieve methods
93
+ * Unpacking compressed image data has basic support but is not properly tested yet.
94
+ * Reading Big Endian files has fairly good, but possibly not full, support.
95
+ * Reading on a Big Endian system is not tested.
96
+ * Reading of multiple frame image data to RMagick does not work in all cases.
75
97
  * Retrieving images when file contains two or more unrelated images may not be handled correctly.
data/DOCUMENTATION CHANGED
@@ -1,7 +1,7 @@
1
1
  DICOM is a small library for reading, editing and writing DICOM files.
2
2
  It is written completely in Ruby and has no external dependencies.
3
3
 
4
- Copyright 2008-2009 Christoffer Lervåg (chris.lervag [@nospam] @gmail.com)
4
+ Copyright 2008-2009 Christoffer Lerv�g (chris.lervag [@nospam] @gmail.com)
5
5
 
6
6
  INSTALLATION
7
7
 
@@ -40,11 +40,14 @@ PUBLIC CLASS METHODS
40
40
  Example 3: (Open an empty DICOM object)
41
41
  obj = DICOM::DObject.new(nil)
42
42
 
43
- ACCESSORS
43
+ ACCESSORS (read only)
44
44
  :read_success
45
45
  A boolean that is true if DICOM object was read successfully, and false if not.
46
46
  :write_success
47
47
  A boolean that is true if DICOM object was written successfully, and false if not.
48
+ :errors
49
+ An array holding any error messages, warnings or notices that have been logged
50
+ during your interaction with DObject.
48
51
  :modality
49
52
  A string which holds the description of the modality of the DICOM object that has been read.
50
53
  Example of use:
@@ -52,95 +55,121 @@ ACCESSORS
52
55
  if obj.read_success
53
56
  puts obj.modality
54
57
  end
58
+ The following accessors are the arrays that hold all the information gathered on the DICOM object.
59
+ As such, their length is equal to the number of tags in a DICOM object.
60
+ :names
61
+ :tags
62
+ :types
63
+ :lengths
64
+ :values
65
+ :raw
66
+ :levels
55
67
 
56
68
  PUBLIC INSTANCE METHODS
57
69
 
58
- children(id, options={})
59
- Returns the positions of all tags inside the hierarchy of a sequence or an item.
60
- This is useful if you later want to get the position(s) of a certain tag,
70
+ children(element, options={})
71
+ Returns the positions of all data elements inside the hierarchy of a sequence or an item.
72
+ This is useful if you later want to get the position(s) of a certain element,
61
73
  restricted to the positions inside the given sequence or item.
62
- Example 1: (Return all tag positions that is contained in the following sequence)
74
+ Element may be an array index, element name or element tag.
75
+ Example 1: (Return all element positions that is contained in the following sequence)
63
76
  pos = obj.children("3006,0082")
64
- Example 2: (Return all tag positions that is contained only directly beneath the following sequence)
77
+ Example 2: (Return all element positions that is contained only directly beneath the following sequence)
65
78
  pos = obj.children("3006,0082", :next_only => true)
66
79
 
67
- get_frames()
80
+ get_frames
68
81
  Returns the number of frames present in the image data in the DICOM file.
69
82
 
70
- get_image_magick()
83
+ get_image_magick
71
84
  Returns an array of RMagick image objects, where the size of the array corresponds
72
85
  with the number of frames in the image data.
73
- To call this method the user needs to have performed " require 'RMagick' " in advance.
86
+ To call this method the user needs to have loaded the RMagick bindings in advance (require 'RMagick').
74
87
  Example (retrieve object and display first frame):
75
88
  require 'RMagick'
76
- data = dicom.get_image_magick()
89
+ data = dicom.get_image_magick()
77
90
  data[0].display
78
91
 
79
- get_image_narray()
92
+ get_image_narray
80
93
  Returns a 3d NArray object where the array dimensions are related to [frames, columns, rows].
81
- To call this method the user needs to have performed " require 'narray' " in advance.
94
+ To call this method the user needs to have loaded the NArray library in advance (require 'narray').
82
95
  Example (retrieve object and display first frame):
83
96
  require 'narray'
84
97
  require 'nimage'
85
- data = obj.get_image_narray()
98
+ data = obj.get_image_narray()
86
99
  NImage.show data[0,true,true]
87
100
 
88
- get_image_pos()
89
- Returns the index(es) of the tag(s) that contain image data.
101
+ get_image_pos
102
+ Returns the index(es) of the data element(s) that contain image data.
90
103
 
91
- get_pos(id, options={})
92
- Returns the index(es) of the tag(s) in the DICOM file that match the supplied tag ID.
104
+ get_pos(string, options={})
105
+ Returns the index(es) of the data element(s) in the DICOM file that match
106
+ the supplied element tag or name.
93
107
  Example 1: (Find all occurences of the specified tag in the object)
94
108
  pos = obj.get_pos("3006,0080")
95
109
  Example 2: (Find all occurences of the specified tag inside the specified sequence)
96
110
  selection = obj.children("3006,0082")
97
111
  pos = obj.get_pos("3006,0080", :array => selection)
98
-
99
- get_raw(id)
100
- Returns the raw data of the DICOM tag that matches the supplied tag ID.
101
- The ID may be a tag index, tag name or tag label.
102
-
103
- get_value(id)
104
- Returns the value (processed raw data) of the DICOM tag that matches the supplied tag ID.
105
- The ID may be a tag index, tag name or tag label.
112
+ Example 3: (Using the :partial argument to find position of all elements containing a specific string)
113
+ pos = obj.get_pos("0010", :partial => true)
114
+ pos = obj.get_pos("Name", :partial => true)
115
+
116
+ get_raw(element, options={})
117
+ Returns the raw data of the requested DICOM data element.
118
+ Element may be an array index, element name or element tag.
119
+ If you wish to return multiple data values of a tag that occurs several times in the file,
120
+ use the keyword :array => true .
121
+ Example: (Returns all data values in a array)
122
+ contour_data = obj.get_raw("3006,0050", :array => true)
123
+
124
+ get_value(element)
125
+ Returns the value (processed raw data) of the requested DICOM data element.
126
+ Element may be an array index, element name or element tag.
127
+ If you wish to return multiple values of a tag that occurs several times in the file,
128
+ use the keyword :array => true .
129
+ Example: (Returns all data values in a array)
130
+ contour_data = obj.get_value("3006,0050", :array => true)
106
131
 
107
132
  image_to_file(file)
108
133
  Dumps the pixel data of the DICOM object directly to the specified file.
109
134
  This is useful if you wish to extract this data to process it with another program.
110
135
 
111
- parents(id)
136
+ parents(element)
112
137
  Returns the positions of all parents of this tag in the hierarchy.
113
138
  This is useful if you want to know the position of the items or sequence tags that 'hold' your tag.
139
+ Element may be an array index, element name or element tag.
114
140
  Example:
115
141
  pos = obj.parents("300C,0006")
116
142
 
117
- print(id, options={})
118
- Prints the information of one or many tag(s):
143
+ print(pos, options={})
144
+ Prints the information gathered on one or several/all tag(s) in the DICOM object:
119
145
  (index, [hierarchy level,] label, name, type, length, value)
120
146
  The method can print to both screen or to a text file. If print to file is chosen,
121
147
  the text file will be put in the folder of the original DICOM file with a '.txt' extension.
122
- The ID may be a tag name, label or position, or it might be an array of positions.
148
+ The argument pos may be a number (array position), an array of numbers, or true.
123
149
  Example 1: (Print all tags to file, with both tree visualization and level numbers)
124
150
  obj.print(true, :levels => true, :tree => true, :file => true)
125
151
  Example 2: (Print an array of tags to screen, no level or tree visualization)
126
152
  obj.print([4,5,6])
127
153
 
128
- print_all()
154
+ print_all
129
155
  Prints information of all tags stored in the DICOM object to the screen.
130
156
 
131
- print_properties()
157
+ print_properties
132
158
  Prints the key structural properties of the DICOM file to the screen.
133
159
 
134
- remove_tag(tag)
135
- Removes the specified tag from the DICOM object. You can use this method
136
- if you are editing a DICOM object and wants to get rid of some tags.
160
+ remove(element)
161
+ Removes the specified data element from the DICOM object. You can use this method
162
+ if you are editing a DICOM object and wants to get rid of one or more elements.
163
+ Element may be an array index, element name or element tag.
137
164
 
138
- set_value(value, options={})
139
- This method can be used both to edit an existing tag, or to create new tags in your DICOM object.
165
+ set_value(value, element, options={})
166
+ This method can be used both to edit an existing data element, or to create
167
+ new data elements in your DICOM object.
168
+ Element may be an array index, element name or element tag.
140
169
  Example 1: (Edit patient name)
141
- obj.set_value("Anonymous", :label => "0010,0010", :create => false)
170
+ obj.set_value("Anonymous", "0010,0010", :create => false)
142
171
  Example 2: (Insert binary data for a specific tag)
143
- obj.set_value(data, :pos => 52, :bin => true, :create => false)
172
+ obj.set_value(data, 52, :bin => true, :create => false)
144
173
 
145
174
  set_image_magick(object)
146
175
  Inserts a RMagick image object to the pixel data tag of your DICOM object.
@@ -150,10 +179,10 @@ PUBLIC INSTANCE METHODS
150
179
  This can be useful if you have processed some image data using a custom program
151
180
  and just wants to put that data back into a DICOM object.
152
181
 
153
- write_file(file)
182
+ write(file)
154
183
  Writes the DICOM object to the specified file.
155
184
  Example:
156
- obj.write_file(myPath + "test_file.dcm")
185
+ obj.write(myPath + "test_file.dcm")
157
186
 
158
187
 
159
188
  CLASS Anonymizer
@@ -165,7 +194,7 @@ PUBLIC CLASS METHODS
165
194
  Example:
166
195
  a = DICOM::Anonymizer.new
167
196
 
168
- ACCESSORS
197
+ ACCESSORS (Read & write)
169
198
  :blank
170
199
  A boolean that you can set if you want to all anonymization tags to be blank
171
200
  instead of having some generic value.
@@ -211,7 +240,7 @@ PUBLIC INSTANCE METHODS
211
240
  Verbose (=true/false) will apply to the read/update/write process that takes place in DObject, and not
212
241
  the messages of the Anonymization script itself.
213
242
 
214
- print()
243
+ print
215
244
  Prints the list of tags that have been selected for anonymization, along with the values
216
245
  that the original tags will be replaced with. If enumeration is selected, this method will also
217
246
  print which tags have been selected for enumeration.
data/README CHANGED
@@ -4,42 +4,42 @@ RUBY DICOM
4
4
  SUMMARY
5
5
  --------
6
6
 
7
- This is a fairly basic library for reading DICOM files in Ruby. Digital Imaging and Communications in Medicine (DICOM) is a standard for handling, storing, printing, and transmitting information in medical imaging. It includes a file format definition and a network communications protocol. The library supports reading, editing and writing the file format.
7
+ This is a fairly basic library for handling DICOM files in Ruby. Digital Imaging and Communications in Medicine (DICOM) is a standard for handling, storing, printing, and transmitting information in medical imaging. It includes a file format definition and a network communications protocol. Ruby DICOM supports reading from, editing and writing to this file format.
8
8
 
9
9
  BASIC USAGE
10
10
  -----------
11
11
 
12
12
  require 'dicom'
13
13
  # Read file:
14
- dcm = DICOM::DObject.new("myFile.dcm")
15
- # Display some key information about the file:
14
+ dcm = DICOM::DObject.new("myFile.dcm")
15
+ # Display some key information about the file:
16
16
  dcm.print_properties()
17
17
  # Print all tags to screen:
18
18
  dcm.print(true)
19
- # Retrieve a tag value:
19
+ # Retrieve a data element value:
20
20
  name = dcm.get_value("0010.0010")
21
21
  # Retrieve pixel data:
22
22
  pixels = dcm.get_value("7FE0.0010")
23
- # Load pixel data in a RMagick object and display on screen:
23
+ # Load pixel data to a RMagick object and display it on screen:
24
24
  image = dcm.get_image_magick()
25
25
  image[0].display
26
- # Load pixel data in a NArray object and display on screen:
26
+ # Load pixel data to a NArray object and display it on screen:
27
27
  image = dcm.get_image_narray()
28
- NImage.show image[0,true,true]
29
-
30
- Tip:
31
- When playing around with Ruby DICOM in irb, you may be annoyed
32
- with all the information that is printed to screen, regardless
33
- if you have specified verbose as false. This is because in irb
34
- every variable loaded in the program is automatically printed.
35
- A hack to avoid this effect is to append ";0" after a command.
36
- Example:
28
+ NImage.show image[0,true,true]
29
+
30
+ Tip:
31
+ When playing around with Ruby DICOM in irb, you may be annoyed
32
+ with all the information that is printed to screen, regardless
33
+ if you have specified verbose as false. This is because in irb
34
+ every variable loaded in the program is automatically printed.
35
+ A hack to avoid this effect is to append ";0" after a command.
36
+ Example:
37
37
  dcm = DICOM::DObject.new("myFile.dcm") ;0
38
-
38
+
39
39
  COPYRIGHT
40
40
  ---------
41
41
 
42
- Copyright 2008-2009 Christoffer Lervåg
42
+ Copyright 2008-2009 Christoffer Lerv�g
43
43
 
44
44
  This program is free software: you can redistribute it and/or modify
45
45
  it under the terms of the GNU General Public License as published by
@@ -59,12 +59,12 @@ ABOUT ME
59
59
  --------
60
60
 
61
61
  Name:
62
- Christoffer Lervåg
62
+ Christoffer Lerv�g
63
63
 
64
64
  Location:
65
65
  Oslo, Norway
66
66
 
67
67
  Email:
68
68
  chris.lervag [@nospam] @gmail.com
69
- Please don't hesitate to email me if have any thoughts on this project!
70
-
69
+ Please don't hesitate to email me if have any thoughts on this project!
70
+
data/lib/Anonymizer.rb CHANGED
@@ -1,13 +1,13 @@
1
- # Copyright 2008-2009 Christoffer Lerv�g
1
+ # Copyright 2008-2009 Christoffer Lervag
2
2
  module DICOM
3
3
 
4
4
  # Class for anonymizing DICOM files:
5
5
  # A good resource on this topic (report from the DICOM standards committee, work group 18):
6
6
  # ftp://medical.nema.org/medical/dicom/Supps/sup142_03.pdf
7
7
  class Anonymizer
8
-
8
+
9
9
  attr_accessor :blank, :enumeration, :identity_file, :verbose, :write_path
10
-
10
+
11
11
  # Initialize the Anonymizer instance:
12
12
  def initialize(opts={})
13
13
  # Default verbosity is true: # NB: verbosity is not used currently
@@ -22,11 +22,11 @@ module DICOM
22
22
  # Array of folders to be processed for anonymization:
23
23
  @folders = Array.new
24
24
  @exceptions = Array.new
25
- # Tags that will be anonymized:
25
+ # Data elements which will be anonymized (the array will hold a list of tag strings):
26
26
  @tags = Array.new
27
- # Default values to use on anonymized tags:
27
+ # Default values to use on anonymized data elements:
28
28
  @values = Array.new
29
- # Which tags will have enumeration applied, if requested by the user:
29
+ # Which data elements will have enumeration applied, if requested by the user:
30
30
  @enum = Array.new
31
31
  # We use a hash to store information from DICOM files if enumeration is desired:
32
32
  @enum_old_hash = {}
@@ -35,23 +35,23 @@ module DICOM
35
35
  @files = Array.new
36
36
  # Write paths will be determined later and put in this array:
37
37
  @write_paths = Array.new
38
- # Set the default tags to be anonymized:
38
+ # Set the default data elements to be anonymized:
39
39
  set_defaults()
40
40
  end # of method initialize
41
-
42
-
41
+
42
+
43
43
  # Adds a folder who's files will be anonymized:
44
44
  def add_folder(path)
45
45
  @folders += [path] if path
46
46
  end
47
-
48
-
47
+
48
+
49
49
  # Adds an exception folder that is to be avoided when anonymizing:
50
50
  def add_exception(path)
51
51
  @exceptions += [path] if path
52
52
  end
53
-
54
-
53
+
54
+
55
55
  # Adds a tag to the list of tags that will be anonymized:
56
56
  def add_tag(tag, opts={})
57
57
  # Options and defaults:
@@ -60,7 +60,7 @@ module DICOM
60
60
  if tag
61
61
  if tag.is_a?(String)
62
62
  if tag.length == 9
63
- # Add tag information:
63
+ # Add anonymization information for this tag:
64
64
  @tags += [tag]
65
65
  @values += [value]
66
66
  @enum += [enum]
@@ -74,8 +74,8 @@ module DICOM
74
74
  puts "Warning: No tag supplied. Nothing to add."
75
75
  end
76
76
  end # of method add_tag
77
-
78
-
77
+
78
+
79
79
  # Set enumeration status for a specific tag (toggle true/false)
80
80
  def change_enum(tag, enum)
81
81
  pos = @tags.index(tag)
@@ -89,8 +89,8 @@ module DICOM
89
89
  puts "Specified tag not found in anonymization array. No changes made."
90
90
  end
91
91
  end # of method change_enum
92
-
93
-
92
+
93
+
94
94
  # Changes the value used in anonymization for a specific tag:
95
95
  def change_value(tag, value)
96
96
  pos = @tags.index(tag)
@@ -104,8 +104,8 @@ module DICOM
104
104
  puts "Specified tag not found in anonymization array. No changes made."
105
105
  end
106
106
  end # of method change_value
107
-
108
-
107
+
108
+
109
109
  # Executes the anonymization process:
110
110
  def execute(verbose=false)
111
111
  # Search through the folders to gather all the files to be anonymized:
@@ -132,7 +132,7 @@ module DICOM
132
132
  # existing information associated with each tag:
133
133
  create_enum_hash() if @enumeration
134
134
  # Start the read/update/write process:
135
- puts "Initiating read/update/write process..."
135
+ puts "Initiating read/update/write process (This may take some time)..."
136
136
  # Monitor whether every file read/write was successful:
137
137
  all_read = true
138
138
  all_write = true
@@ -158,10 +158,10 @@ module DICOM
158
158
  value = @values[j]
159
159
  end # of if @blank..else..
160
160
  # Update DICOM object with new value:
161
- obj.set_value(value, :create => false, :label => @tags[j])
161
+ obj.set_value(value, @tags[j], :create => false)
162
162
  end
163
163
  # Write DICOM file:
164
- obj.write_file(@write_paths[i])
164
+ obj.write(@write_paths[i])
165
165
  all_write = false unless obj.write_success
166
166
  else
167
167
  all_read = false
@@ -195,15 +195,15 @@ module DICOM
195
195
  end
196
196
  puts "*******************************************************"
197
197
  end # of method execute
198
-
199
-
198
+
199
+
200
200
  # Prints a list of which tags are currently selected for anonymization along with
201
201
  # replacement values that will be used and enumeration status.
202
202
  def print()
203
203
  # Extract the string lengths which are needed to make the formatting nice:
204
204
  names = Array.new
205
205
  types = Array.new
206
- label_lengths = Array.new
206
+ tag_lengths = Array.new
207
207
  name_lengths = Array.new
208
208
  type_lengths = Array.new
209
209
  value_lengths = Array.new
@@ -211,14 +211,14 @@ module DICOM
211
211
  arr = @lib.get_name_vr(@tags[i])
212
212
  names += [arr[0]]
213
213
  types += [arr[1]]
214
- label_lengths[i] = @tags[i].length
214
+ tag_lengths[i] = @tags[i].length
215
215
  name_lengths[i] = names[i].length
216
216
  type_lengths[i] = types[i].length
217
217
  value_lengths[i] = @values[i].to_s.length unless @blank
218
218
  value_lengths[i] = "" if @blank
219
219
  end
220
220
  # To give the printed output a nice format we need to check the string lengths of some of these arrays:
221
- label_maxL = label_lengths.max
221
+ tag_maxL = tag_lengths.max
222
222
  name_maxL = name_lengths.max
223
223
  type_maxL = type_lengths.max
224
224
  value_maxL = value_lengths.max
@@ -227,7 +227,7 @@ module DICOM
227
227
  @tags.each_index do |i|
228
228
  # Configure empty spaces:
229
229
  s = " "
230
- f1 = " "*(label_maxL-@tags[i].length+1)
230
+ f1 = " "*(tag_maxL-@tags[i].length+1)
231
231
  f2 = " "*(name_maxL-names[i].length+1)
232
232
  f3 = " "*(type_maxL-types[i].length+1)
233
233
  f4 = " " if @blank
@@ -240,7 +240,7 @@ module DICOM
240
240
  if @blank
241
241
  value = ""
242
242
  else
243
- value = @values [i]
243
+ value = @values[i]
244
244
  end
245
245
  tag = @tags[i]
246
246
  lines += [tag + f1 + names[i] + f2 + types[i] + f3 + value.to_s + f4 + enum.to_s ]
@@ -250,8 +250,8 @@ module DICOM
250
250
  puts line
251
251
  end
252
252
  end # of method print_tags
253
-
254
-
253
+
254
+
255
255
  # Removes a tag from the list of tags that will be anonymized:
256
256
  def remove_tag(tag)
257
257
  pos = @tags.index(tag)
@@ -263,12 +263,12 @@ module DICOM
263
263
  puts "Specified tag not found in anonymization array. No changes made."
264
264
  end
265
265
  end # of method remove_tag
266
-
267
-
266
+
267
+
268
268
  # The following methods are private:
269
269
  private
270
-
271
-
270
+
271
+
272
272
  # Finds the common path in an array of files, by performing a recursive search.
273
273
  # Returns the index of the last folder in str_arr that is common in all file paths.
274
274
  def common_path(str_arr, index)
@@ -288,8 +288,8 @@ module DICOM
288
288
  end
289
289
  return result
290
290
  end # of method common_path
291
-
292
-
291
+
292
+
293
293
  # Creates a hash that is used for storing information used when enumeration is desired.
294
294
  def create_enum_hash()
295
295
  @enum.each_index do |i|
@@ -297,8 +297,8 @@ module DICOM
297
297
  @enum_new_hash[@tags[i]] = Array.new
298
298
  end
299
299
  end
300
-
301
-
300
+
301
+
302
302
  # Handles enumeration for current DICOM tag:
303
303
  def get_enumeration_value(current, j)
304
304
  # Is enumeration requested for this tag?
@@ -324,8 +324,8 @@ module DICOM
324
324
  end # of if @enum[j]..else..
325
325
  return value
326
326
  end # of method handle_enumeration
327
-
328
-
327
+
328
+
329
329
  # Discover all the files contained in the specified directory and all its sub-directories:
330
330
  def load_files()
331
331
  # Load find library:
@@ -334,10 +334,14 @@ module DICOM
334
334
  for dir in @folders
335
335
  Find.find(dir) do |path|
336
336
  if FileTest.directory?(path)
337
- if @exceptions.include?(File.basename(path))
338
- Find.prune # Don't look any further into this directory.
339
- else
337
+ proceed = true
338
+ @exceptions.each do |e|
339
+ proceed = false if e == path
340
+ end
341
+ if proceed
340
342
  next
343
+ else
344
+ Find.prune # Don't look any further into this directory.
341
345
  end
342
346
  else
343
347
  @files += [path] # Store the file in our array
@@ -345,13 +349,14 @@ module DICOM
345
349
  end
346
350
  end # of for dir...
347
351
  end # of method load_files
348
-
349
-
352
+
353
+
350
354
  # Analyses the write_path and the 'read' file path to determine if the have some common root.
351
355
  # If there are parts of file that exist also in write path, it will not add those parts to write_path.
352
356
  def process_write_paths()
353
- # First make sure @write_path ends with a "/" (represented by decimal 47):
354
- @write_path = @write_path + "/" unless @write_path[@write_path.length-1] == 47
357
+ # First make sure @write_path ends with a "/":
358
+ last_character = @write_path[(@write_path.length-1)..(@write_path.length-1)]
359
+ @write_path = @write_path + "/" unless last_character == "/"
355
360
  # Separate behaviour if we have one, or several files in our array:
356
361
  if @files.length == 1
357
362
  # One file.
@@ -379,8 +384,8 @@ module DICOM
379
384
  end
380
385
  end # of if @files.length..
381
386
  end # of method process_write_paths
382
-
383
-
387
+
388
+
384
389
  # Default tags that will be anonymized, along with some settings for each:
385
390
  def set_defaults()
386
391
  data = [
@@ -403,14 +408,14 @@ module DICOM
403
408
  @values = data[1]
404
409
  @enum = data[2]
405
410
  end # of method set_defaults
406
-
407
-
411
+
412
+
408
413
  # Writes an identity file, which allows reidentification of DICOM files that have been anonymized
409
414
  # using the enumeration feature. Values will be saved in a text file, using semi colon delineation.
410
415
  def write_identity_file()
411
416
  # Open file and prepare to write text:
412
417
  File.open( @identity_file, 'w' ) do |output|
413
- # Cycle through each
418
+ # Cycle through each
414
419
  @tags.each_index do |i|
415
420
  if @enum[i]
416
421
  # This tag has had enumeration. Gather original and anonymized values:
@@ -427,7 +432,7 @@ module DICOM
427
432
  end # of @tags.each...
428
433
  end # of File.open...
429
434
  end # of method write...
430
-
431
-
435
+
436
+
432
437
  end # of class
433
438
  end # of module