dicoms 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,5 @@
1
1
  class DicomS
2
2
  def stats(dicom_directory, options = {})
3
- # TODO: compute histogram of levels
4
3
  dicom_files = find_dicom_files(dicom_directory)
5
4
  if dicom_files.empty?
6
5
  raise "ERROR: no se han encontrado archivos DICOM en: \n #{dicom_directory}"
@@ -24,7 +23,8 @@ class DicomS
24
23
  n: n,
25
24
  min: mins.min,
26
25
  next_min: next_mins.min,
27
- max: maxs.max
26
+ max: maxs.max,
27
+ histogram: compute_histogram(dicom_directory, options)
28
28
  }
29
29
  end
30
30
  end
@@ -1,6 +1,26 @@
1
1
  require 'matrix'
2
2
 
3
3
  class DicomS
4
+ class Error < RuntimeError
5
+ def initialize(code, *args)
6
+ @code = code
7
+ super *args
8
+ end
9
+ attr_reader :code
10
+ end
11
+
12
+ class UnsupportedDICOM < Error
13
+ def initialize(*args)
14
+ super 'unsupported_dicom', *args
15
+ end
16
+ end
17
+
18
+ class InvaliddDICOM < Error
19
+ def initialize(*args)
20
+ super 'invalid_dicom', *args
21
+ end
22
+ end
23
+
4
24
  USE_SLICE_Z = false
5
25
  METADATA_TYPES = {
6
26
  # Note: for axisx, axisy, axisz decode_vector should be used
@@ -141,7 +161,7 @@ class DicomS
141
161
  ny = dicom.num_rows # dicom.rows.value.to_i
142
162
 
143
163
  unless dicom.samples_per_pixel.value.to_i == 1
144
- raise "Invalid DICOM format"
164
+ raise InvalidDICOM, "Invalid image format"
145
165
  end
146
166
  Settings[
147
167
  dx: dx, dy: dy, x: x, y: y, z: z,
@@ -169,7 +189,7 @@ class DicomS
169
189
  file = File.basename(name)
170
190
  number_pattern = /\d+/
171
191
  match = number_pattern.match(file)
172
- raise "Invalid DICOM file name" unless match
192
+ raise UnsupportedDICOM, "Invalid DICOM file name" unless match
173
193
  number = match[0]
174
194
  file = file.sub(number_pattern, "%d")
175
195
  if match.begin(0) == 0
@@ -345,5 +365,31 @@ class DicomS
345
365
  ts = DICOM::LIBRARY.uid(dicom.transfer_syntax)
346
366
  ts.name if ts.compressed_pixels?
347
367
  end
368
+
369
+ def terminal_size
370
+ if $stdout.respond_to?(:tty?) && $stdout.tty? && $stdout.respond_to?(:winsize)
371
+ $stdout.winsize
372
+ else
373
+ size = [ENV['LINES'] || ENV['ROWS'], ENV['COLUMNS']]
374
+ if size[1].to_i > 0
375
+ size
376
+ else
377
+ if defined?(Readline) && Readline.respond_to?(:get_screen_size)
378
+ size = Readline.get_screen_size
379
+ if size[1].to_i > 0
380
+ size
381
+ elsif ENV['ANSICON'] =~ /\((.*)x(.*)\)/
382
+ size = [$2, $1]
383
+ if size[1].to_i > 0
384
+ size
385
+ else
386
+ [27, 80]
387
+ end
388
+ end
389
+ end
390
+ end
391
+ end
392
+ end
393
+
348
394
  end
349
395
  end
@@ -17,6 +17,12 @@ class DicomS
17
17
  # values which are mapped to the output limits.
18
18
  # These values may be raw or rescaled depending on the min_max_rescaled? method
19
19
  #
20
+ # Derived classes should also provide a method
21
+ #
22
+ # transfer_rescaled_pixels(dicom, data, min, max)
23
+ #
24
+ # To apply the transfer conversion to data which has been only rescaled
25
+ #
20
26
  class Transfer
21
27
  USE_DATA = false
22
28
 
@@ -70,8 +76,8 @@ class DicomS
70
76
  when :unsigned
71
77
  min, max = Transfer.min_max_limits(dicom)
72
78
  if min < 0
73
- min = 0
74
79
  max -= min
80
+ min = 0
75
81
  end
76
82
  [min, max]
77
83
  else
@@ -96,6 +102,7 @@ class DicomS
96
102
  def initialize(options = {})
97
103
  @center = options[:center]
98
104
  @width = options[:width]
105
+ @float_arith = options[:float] || FLOAT_MAPPING
99
106
  super options
100
107
  end
101
108
 
@@ -116,6 +123,14 @@ class DicomS
116
123
  map_to_output dicom, data, min, max
117
124
  end
118
125
 
126
+ # Apply the transfer map to data which has been only rescaled
127
+ def transfer_rescaled_pixels(dicom, pixels, min, max)
128
+ # clip pixels to min, max # wouldn't be needed if map_to_output did output clipping...
129
+ pixels[pixels < min] = min
130
+ pixels[pixels > max] = max
131
+ map_to_output dicom, pixels, min, max
132
+ end
133
+
119
134
  # def image(dicom, min, max)
120
135
  # center = (min + max)/2
121
136
  # width = max - min
@@ -128,7 +143,7 @@ class DicomS
128
143
  output_min, output_max = min_max_limits(dicom)
129
144
  output_range = output_max - output_min
130
145
  input_range = max - min
131
- float_arith = FLOAT_MAPPING || output_range < input_range
146
+ float_arith = @float_arith || output_range < input_range
132
147
  data_type = data.typecode
133
148
  data = data.to_type(NArray::SFLOAT) if float_arith
134
149
  data.sbt! min
@@ -179,6 +194,7 @@ class DicomS
179
194
  @rescale = options[:rescale]
180
195
  @ignore_min = options[:ignore_min]
181
196
  @extension_factor = options[:extend] || 0.0
197
+ @float_arith = options[:float] || FLOAT_MAPPING
182
198
  super options
183
199
  end
184
200
 
@@ -196,16 +212,12 @@ class DicomS
196
212
  [minimum, maximum]
197
213
  end
198
214
 
199
- def min_max_rescaled?
200
- @rescale
201
- end
202
-
203
- def processed_data(dicom, min, max)
215
+ # Apply the transfer map to data which has been only rescaled
216
+ def transfer_rescaled_pixels(dicom, data, min, max)
204
217
  output_min, output_max = min_max_limits(dicom)
205
218
  output_range = output_max - output_min
206
219
  input_range = max - min
207
- float_arith = FLOAT_MAPPING || output_range < input_range
208
- data = dicom_narray(dicom, level: false, remap: @rescale)
220
+ float_arith = @float_arith || output_range < input_range
209
221
  data_type = data.typecode
210
222
  data = data.to_type(NArray::SFLOAT) if float_arith
211
223
  data.sbt! min
@@ -217,6 +229,15 @@ class DicomS
217
229
  data
218
230
  end
219
231
 
232
+ def processed_data(dicom, min, max)
233
+ data = dicom_narray(dicom, level: false, remap: @rescale)
234
+ transfer_rescaled_pixels dicom, data, min, max
235
+ end
236
+
237
+ def min_max_rescaled?
238
+ @rescale
239
+ end
240
+
220
241
  private
221
242
 
222
243
  def data_range(dicom)
@@ -320,20 +341,7 @@ class DicomS
320
341
  end
321
342
 
322
343
  def min_max(sequence)
323
- min_max_limits(sequence.first)
324
- end
325
-
326
- def map_to_output(dicom, data, min, max)
327
- if @rescale
328
- intercept = dicom_rescale_intercept(dicom)
329
- slope = dicom_rescale_slope(dicom)
330
- if slope != 1 || intercept != 0
331
- return super
332
- end
333
- end
334
- data = dicom_narray(dicom)
335
- data.add! -min if min < 0
336
- data
344
+ Transfer.min_max_limits(sequence.first)
337
345
  end
338
346
  end
339
347
  end
@@ -1,3 +1,3 @@
1
1
  class DicomS
2
- VERSION = "1.0.0"
2
+ VERSION = "1.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dicoms
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Javier Goizueta
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-09-17 00:00:00.000000000 Z
11
+ date: 2015-10-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dicom
@@ -94,6 +94,34 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0.19'
97
+ - !ruby/object:Gem::Dependency
98
+ name: solver
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: 0.2.0
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: 0.2.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: histogram
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 0.2.4
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 0.2.4
97
125
  - !ruby/object:Gem::Dependency
98
126
  name: bundler
99
127
  requirement: !ruby/object:Gem::Requirement
@@ -159,7 +187,10 @@ files:
159
187
  - lib/dicoms.rb
160
188
  - lib/dicoms/cli.rb
161
189
  - lib/dicoms/command_options.rb
190
+ - lib/dicoms/explode.rb
162
191
  - lib/dicoms/extract.rb
192
+ - lib/dicoms/histogram.rb
193
+ - lib/dicoms/info.rb
163
194
  - lib/dicoms/meta_codec.rb
164
195
  - lib/dicoms/pack.rb
165
196
  - lib/dicoms/progress.rb
@@ -168,6 +199,7 @@ files:
168
199
  - lib/dicoms/sequence.rb
169
200
  - lib/dicoms/shared_files.rb
170
201
  - lib/dicoms/shared_settings.rb
202
+ - lib/dicoms/sigmoid.rb
171
203
  - lib/dicoms/stats.rb
172
204
  - lib/dicoms/support.rb
173
205
  - lib/dicoms/transfer.rb