metamri 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +1 -0
- data/VERSION +1 -1
- data/lib/metamri/core_additions.rb +61 -5
- data/lib/metamri/dicom_additions.rb +63 -0
- data/lib/metamri/raw_image_dataset.rb +36 -11
- data/lib/metamri/raw_image_dataset_resource.rb +1 -1
- data/lib/metamri/visit_raw_data_directory.rb +16 -2
- data/lib/metamri.rb +6 -6
- data/metamri.gemspec +7 -3
- data/spec/helper_spec.rb +7 -7
- data/spec/unit/dicom_additions_spec.rb +68 -0
- data/spec/unit/nifti_builder_spec.rb +4 -5
- data/spec/unit/raw_image_dataset_spec.rb +1 -1
- data/spec/unit/raw_image_dataset_thumbnail_spec.rb +1 -1
- data/spec/unit/raw_image_file_spec.rb +1 -1
- metadata +9 -5
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.3
|
@@ -74,8 +74,7 @@ class Pathname
|
|
74
74
|
def all_dicoms
|
75
75
|
local_copies = []
|
76
76
|
Dir.mktmpdir do |tempdir|
|
77
|
-
begin
|
78
|
-
|
77
|
+
# begin
|
79
78
|
entries.each do |leaf|
|
80
79
|
branch = self + leaf
|
81
80
|
if leaf.to_s =~ /^I\.(\.bz2)?$|\.dcm(\.bz2)?$|\.[0-9]+(\.bz2)?$/
|
@@ -85,9 +84,10 @@ class Pathname
|
|
85
84
|
|
86
85
|
yield local_copies
|
87
86
|
|
88
|
-
ensure
|
89
|
-
|
90
|
-
|
87
|
+
# ensure
|
88
|
+
# No ensure needed since Dir.mktmpdir will implode after a block.
|
89
|
+
# local_copies.each { |lc| lc.delete if lc.exist? }
|
90
|
+
# end
|
91
91
|
end
|
92
92
|
|
93
93
|
return
|
@@ -147,6 +147,62 @@ class Pathname
|
|
147
147
|
|
148
148
|
end
|
149
149
|
|
150
|
+
# Find hash differences.
|
151
|
+
class Hash
|
152
|
+
def diff(other)
|
153
|
+
self.keys.inject({}) do |memo, key|
|
154
|
+
unless self[key] == other[key]
|
155
|
+
memo[key] = [self[key], other[key]]
|
156
|
+
end
|
157
|
+
memo
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def similar(other)
|
162
|
+
self.keys.inject({}) do |memo, key|
|
163
|
+
if self[key] == other[key]
|
164
|
+
memo[key] = self[key]
|
165
|
+
end
|
166
|
+
memo
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
# Method from ftools - requiring fileutils instead for Ruby 1.9 compatibility
|
172
|
+
# and explicitly adding this single method.
|
173
|
+
class File
|
174
|
+
BUFSIZE = 8 * 1024
|
175
|
+
def self.compare(from, to, verbose = false)
|
176
|
+
$stderr.print from, " <=> ", to, "\n" if verbose
|
177
|
+
|
178
|
+
return false if stat(from).size != stat(to).size
|
179
|
+
|
180
|
+
from = open(from, "rb")
|
181
|
+
to = open(to, "rb")
|
182
|
+
|
183
|
+
ret = false
|
184
|
+
fr = tr = ''
|
185
|
+
|
186
|
+
begin
|
187
|
+
while fr == tr
|
188
|
+
fr = from.read(BUFSIZE)
|
189
|
+
if fr
|
190
|
+
tr = to.read(fr.size)
|
191
|
+
else
|
192
|
+
ret = to.read(BUFSIZE)
|
193
|
+
ret = !ret || ret.length == 0
|
194
|
+
break
|
195
|
+
end
|
196
|
+
end
|
197
|
+
rescue
|
198
|
+
ret = false
|
199
|
+
ensure
|
200
|
+
to.close
|
201
|
+
from.close
|
202
|
+
end
|
203
|
+
ret
|
204
|
+
end
|
205
|
+
end
|
150
206
|
# =begin rdoc
|
151
207
|
# Monkey-patch Float to avoid rounding errors.
|
152
208
|
# For more in-depth discussion, see: http://www.ruby-forum.com/topic/179361
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# Dicom Additions is a test extension of DICOM to allow for gathering common tags
|
2
|
+
class DicomGroup
|
3
|
+
# Array of DObjects to aggregate
|
4
|
+
attr_accessor :dobjects
|
5
|
+
# Hash of tags shared by all DICOMs in Directory
|
6
|
+
attr_reader :tags
|
7
|
+
# DICOM::DObject containing all common tags of the group
|
8
|
+
attr_reader :common
|
9
|
+
|
10
|
+
# Initialize with an array of strings or DICOM::DObjects to aggregate
|
11
|
+
def initialize(dicomgroup)
|
12
|
+
if dicomgroup.select {|dcm| dcm.is_a? DICOM::DObject }.empty?
|
13
|
+
@dobjects = dicomgroup.collect {|dcm| DICOM::DObject.new(dcm)}
|
14
|
+
else
|
15
|
+
@dobjects = dicomgroup
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Return a hash of tags and values of elements common to all DICOMs in the group.
|
20
|
+
def find_common_tags
|
21
|
+
@dobjects.inject(@dobjects.first.to_hash) do |memo, dobj|
|
22
|
+
memo = memo.similar(dobj.to_hash)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Return a new DICOM::DObject containing elements common (identical tags and values) to all DICOMs in the group.
|
27
|
+
def find_common_elements
|
28
|
+
@dobjects.inject do |memo, dobj|
|
29
|
+
memo.remove_elements_that_differ_from dobj
|
30
|
+
memo
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
# Reopen DObject to make tag hash
|
37
|
+
class DICOM::DObject
|
38
|
+
# Return hash of {tags => values}
|
39
|
+
def to_hash
|
40
|
+
taghash = {}
|
41
|
+
@tags.each_key {|k| taghash[k] = value(k) }
|
42
|
+
return taghash
|
43
|
+
end
|
44
|
+
|
45
|
+
# Remove elements from a dobj that aren't identical to self's tags.
|
46
|
+
def remove_elements_that_differ_from(other_dobj)
|
47
|
+
@tags.each_key do |k|
|
48
|
+
unless @tags[k].eql? other_dobj[k]
|
49
|
+
# pp k, [@tags[k].value, other_dobj[k].value]
|
50
|
+
remove k
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
# Reopen DataElement to compare
|
58
|
+
class DICOM::DataElement
|
59
|
+
# Compare data elements on their tag and value
|
60
|
+
def eql?(other)
|
61
|
+
@tag == other.instance_eval("@tag") && @value == other.value && @bin == other.instance_eval("@bin")
|
62
|
+
end
|
63
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'sqlite3'
|
3
|
-
require '
|
3
|
+
require 'fileutils'
|
4
4
|
require 'metamri/nifti_builder'
|
5
5
|
|
6
6
|
|
@@ -42,8 +42,11 @@ class RawImageDataset
|
|
42
42
|
attr_reader :dicom_series_uid
|
43
43
|
# DICOM Study UID
|
44
44
|
attr_reader :dicom_study_uid
|
45
|
+
# Tag Hash of DICOM Keys
|
46
|
+
attr_reader :dicom_taghash
|
45
47
|
# Array of Read Error Strings
|
46
48
|
attr_reader :read_errors
|
49
|
+
|
47
50
|
|
48
51
|
# * dir: The directory containing the files.
|
49
52
|
# * files: An array of #RawImageFile objects that compose the complete data set.
|
@@ -102,7 +105,10 @@ class RawImageDataset
|
|
102
105
|
validates_metainfo_for :dicom_series_uid if dicom?
|
103
106
|
|
104
107
|
@dicom_study_uid = @raw_image_files.first.dicom_study_uid
|
105
|
-
validates_metainfo_for :dicom_study_uid if dicom?
|
108
|
+
validates_metainfo_for :dicom_study_uid if dicom?
|
109
|
+
|
110
|
+
@dicom_taghash = @raw_image_files.first.dicom_taghash
|
111
|
+
validates_metainfo_for :dicom_taghash if dicom?
|
106
112
|
|
107
113
|
$LOG ||= Logger.new(STDOUT)
|
108
114
|
end
|
@@ -154,15 +160,14 @@ class RawImageDataset
|
|
154
160
|
AND timestamp LIKE '#{@timestamp.to_s.split(/\+|Z/).first}%'"
|
155
161
|
end
|
156
162
|
|
157
|
-
|
158
|
-
Returns a hash of attributes used for insertion into active record.
|
159
|
-
Options: :thumb => FileHandle to thumbnail includes a thumbnail.
|
160
|
-
=end
|
163
|
+
|
164
|
+
# Returns a hash of attributes used for insertion into active record.
|
165
|
+
# Options: :thumb => FileHandle to thumbnail includes a thumbnail.
|
161
166
|
def attributes_for_active_record(options = {})
|
162
167
|
thumbnail = options.has_key?(:thumb) ? options[:thumb] : nil
|
163
168
|
|
164
169
|
unless (thumbnail.class == File || thumbnail == nil)
|
165
|
-
raise(IOError, "Thumbnail #{options[:thumb]} must be a #File.")
|
170
|
+
raise(IOError, "Thumbnail #{options[:thumb]} must be a #File instead of #{thumbnail.class}.")
|
166
171
|
end
|
167
172
|
{ :rmr => @rmr_number,
|
168
173
|
:series_description => @series_description,
|
@@ -173,7 +178,9 @@ Options: :thumb => FileHandle to thumbnail includes a thumbnail.
|
|
173
178
|
:bold_reps => @raw_image_files.first.bold_reps,
|
174
179
|
:slices_per_volume => @raw_image_files.first.num_slices,
|
175
180
|
:scanned_file => @scanned_file,
|
176
|
-
:thumbnail => thumbnail
|
181
|
+
:thumbnail => thumbnail,
|
182
|
+
:dicom_series_uid => @dicom_series_uid,
|
183
|
+
:dicom_taghash => @dicom_taghash
|
177
184
|
}
|
178
185
|
end
|
179
186
|
|
@@ -338,11 +345,29 @@ private
|
|
338
345
|
end
|
339
346
|
|
340
347
|
# Ensure that metadata is present in instance variables.
|
341
|
-
#
|
348
|
+
#
|
349
|
+
# Raises an IndexError if supplied instance variable is nil unless :optional,
|
350
|
+
# and adds a message to the @read_errors array.
|
351
|
+
#
|
352
|
+
# === Parameters
|
353
|
+
#
|
354
|
+
# * <tt>info_variable</tt> -- A string (not including the @ sign) to check to ensure not blank and not empty.
|
355
|
+
#
|
356
|
+
# === Options
|
357
|
+
#
|
358
|
+
# * <tt>:msg</tt> -- An optional message to be added to @read_errors (defaults to "Couldn't find <info_variable>")
|
359
|
+
# * <tt>:optional</tt> -- A boolean to allow adding the error to the array as a warning but not breaking with an error.
|
360
|
+
#
|
361
|
+
# === Examples
|
362
|
+
#
|
363
|
+
# validates_metainfo_for :study_description, :msg => "No study description found", :optional => true
|
364
|
+
#
|
342
365
|
def validates_metainfo_for(info_variable, options = {})
|
343
366
|
raise StandardError, "#{info_variable} must be a symbol" unless info_variable.kind_of? Symbol
|
344
|
-
|
345
|
-
|
367
|
+
data = self.instance_variable_get("@" + info_variable.to_s)
|
368
|
+
if data.nil? || data.empty?
|
369
|
+
message = options[:msg] || "Couldn't find #{info_variable.to_s}"
|
370
|
+
@read_errors << message
|
346
371
|
raise IndexError, message unless options[:optional]
|
347
372
|
end
|
348
373
|
end
|
@@ -132,7 +132,7 @@ class RawImageDatasetResource < ActiveResource::Base
|
|
132
132
|
:headers => { :relative_dataset_path => 'Dataset', :series_description => 'Series Details', :file_count => "File Count", :image_dataset_quality_checks_tablerow => "Quality Checks"},
|
133
133
|
:fields => [:relative_dataset_path, :series_description, :file_count, :image_dataset_quality_checks_tablerow],
|
134
134
|
:description => false, # Turn off rendering row count description at bottom.
|
135
|
-
:resize =>
|
135
|
+
:resize => true
|
136
136
|
)
|
137
137
|
rescue NameError => e
|
138
138
|
raise e
|
@@ -56,6 +56,8 @@ class VisitRawDataDirectory
|
|
56
56
|
attr_accessor :scanid
|
57
57
|
# The id of the visit to be used when doing reverse-lookup in data panda.
|
58
58
|
attr_accessor :database_id
|
59
|
+
# DICOM Study UID (Visit/Study Unique Identifier)
|
60
|
+
attr_reader :dicom_study_uid
|
59
61
|
|
60
62
|
PREPROCESS_REPOSITORY_DIRECTORY = '/Data/vtrak1/preprocessed/visits'
|
61
63
|
# DATAPANDA_SERVER = 'http://localhost:3000'
|
@@ -88,7 +90,9 @@ class VisitRawDataDirectory
|
|
88
90
|
flash "Scanning visit raw data directory #{@visit_directory}" if $LOG.level <= Logger::INFO
|
89
91
|
default_options = {:ignore_patterns => []}
|
90
92
|
options = default_options.merge(options)
|
91
|
-
|
93
|
+
unless options[:ignore_patterns].empty?
|
94
|
+
puts "Ignoring directories matching: #{options[:ignore_patterns].join(", ")}" if $LOG.level <= Logger::INFO
|
95
|
+
end
|
92
96
|
|
93
97
|
d = Pathname.new(@visit_directory)
|
94
98
|
d.each_subdirectory do |dd|
|
@@ -107,6 +111,7 @@ class VisitRawDataDirectory
|
|
107
111
|
@rmr_number = get_rmr_number
|
108
112
|
@scanner_source = get_scanner_source
|
109
113
|
@study_id = get_study_id
|
114
|
+
@dicom_study_uid = get_dicom_study_uid
|
110
115
|
flash "Completed scanning #{@visit_directory}" if $LOG.level <= Logger::DEBUG
|
111
116
|
else
|
112
117
|
raise(IndexError, "No datasets could be scanned for directory #{@visit_directory}")
|
@@ -120,7 +125,8 @@ class VisitRawDataDirectory
|
|
120
125
|
:rmr => @rmr_number,
|
121
126
|
:path => @visit_directory,
|
122
127
|
:scanner_source => @scanner_source ||= get_scanner_source,
|
123
|
-
:scan_number => @study_id
|
128
|
+
:scan_number => @study_id,
|
129
|
+
:dicom_study_uid => @dicom_study_uid
|
124
130
|
}
|
125
131
|
end
|
126
132
|
|
@@ -393,6 +399,14 @@ Returns an array of the created nifti files.
|
|
393
399
|
# raise(IOError, "No valid study id / exam number found.")
|
394
400
|
end
|
395
401
|
|
402
|
+
# retrieves exam number / scan id from first #RawImageDataset
|
403
|
+
def get_dicom_study_uid
|
404
|
+
@datasets.each do |ds|
|
405
|
+
return ds.dicom_study_uid unless ds.dicom_study_uid.nil?
|
406
|
+
end
|
407
|
+
raise(IOError, "No valid study uid found from DICOMS.")
|
408
|
+
end
|
409
|
+
|
396
410
|
def get_scan_procedure_based_on_raw_directory
|
397
411
|
case @visit_directory
|
398
412
|
when /alz_2000.*_2$/
|
data/lib/metamri.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
$: << File.dirname(__FILE__)
|
2
2
|
|
3
|
-
begin
|
4
|
-
|
5
|
-
|
3
|
+
# begin
|
4
|
+
# require 'rubygems'
|
5
|
+
# gem 'activeresource', '<= 2.3.8'
|
6
6
|
require 'active_resource'
|
7
|
-
end
|
7
|
+
# end
|
8
8
|
|
9
9
|
|
10
10
|
require 'metamri/core_additions'
|
@@ -14,6 +14,7 @@ require 'metamri/visit_raw_data_directory'
|
|
14
14
|
require 'metamri/raw_image_dataset_resource'
|
15
15
|
require 'metamri/visit_raw_data_directory_resource'
|
16
16
|
require 'metamri/image_dataset_quality_check_resource'
|
17
|
+
require 'metamri/dicom_additions'
|
17
18
|
|
18
19
|
# require 'metamri/raw_image_dataset_thumbnail'
|
19
20
|
# TODO Move raw_image_dataset_thumbnail out of metamri.
|
@@ -24,5 +25,4 @@ rescue LoadError
|
|
24
25
|
puts "Hirb must be installed for pretty output. Use 'sudo gem install hirb'"
|
25
26
|
end
|
26
27
|
|
27
|
-
module Metamri
|
28
|
-
end
|
28
|
+
# module Metamri; end
|
data/metamri.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{metamri}
|
8
|
-
s.version = "0.2.
|
8
|
+
s.version = "0.2.3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Kristopher J. Kosmatka"]
|
12
|
-
s.date = %q{2011-
|
12
|
+
s.date = %q{2011-02-25}
|
13
13
|
s.description = %q{Extraction of MRI metadata and insertion into compatible sqlite3 databases.}
|
14
14
|
s.email = %q{kk4@medicine.wisc.edu}
|
15
15
|
s.executables = ["convert_visit.rb", "import_visit.rb", "import_respiratory_files.rb", "import_study.rb", "list_visit"]
|
@@ -17,6 +17,7 @@ Gem::Specification.new do |s|
|
|
17
17
|
"README.rdoc"
|
18
18
|
]
|
19
19
|
s.files = [
|
20
|
+
".rspec",
|
20
21
|
"Manifest",
|
21
22
|
"README.rdoc",
|
22
23
|
"Rakefile",
|
@@ -28,6 +29,7 @@ Gem::Specification.new do |s|
|
|
28
29
|
"bin/list_visit",
|
29
30
|
"lib/metamri.rb",
|
30
31
|
"lib/metamri/core_additions.rb",
|
32
|
+
"lib/metamri/dicom_additions.rb",
|
31
33
|
"lib/metamri/image_dataset_quality_check_resource.rb",
|
32
34
|
"lib/metamri/mysql_tools.rb",
|
33
35
|
"lib/metamri/nifti_builder.rb",
|
@@ -40,6 +42,7 @@ Gem::Specification.new do |s|
|
|
40
42
|
"lib/metamri/visit_raw_data_directory_resource.rb",
|
41
43
|
"metamri.gemspec",
|
42
44
|
"spec/helper_spec.rb",
|
45
|
+
"spec/unit/dicom_additions_spec.rb",
|
43
46
|
"spec/unit/nifti_builder_spec.rb",
|
44
47
|
"spec/unit/raw_image_dataset_spec.rb",
|
45
48
|
"spec/unit/raw_image_dataset_thumbnail_spec.rb",
|
@@ -57,10 +60,11 @@ Gem::Specification.new do |s|
|
|
57
60
|
]
|
58
61
|
s.homepage = %q{http://github.com/brainmap/metamri}
|
59
62
|
s.require_paths = ["lib"]
|
60
|
-
s.rubygems_version = %q{1.4.
|
63
|
+
s.rubygems_version = %q{1.4.2}
|
61
64
|
s.summary = %q{MRI metadata}
|
62
65
|
s.test_files = [
|
63
66
|
"spec/helper_spec.rb",
|
67
|
+
"spec/unit/dicom_additions_spec.rb",
|
64
68
|
"spec/unit/nifti_builder_spec.rb",
|
65
69
|
"spec/unit/raw_image_dataset_spec.rb",
|
66
70
|
"spec/unit/raw_image_dataset_thumbnail_spec.rb",
|
data/spec/helper_spec.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
begin
|
2
|
-
require 'spec'
|
3
|
-
rescue LoadError
|
4
|
-
require 'rubygems' unless ENV['NO_RUBYGEMS']
|
5
|
-
gem 'rspec'
|
6
|
-
require 'spec'
|
7
|
-
end
|
1
|
+
# begin
|
2
|
+
# require 'spec'
|
3
|
+
# rescue LoadError
|
4
|
+
# require 'rubygems' unless ENV['NO_RUBYGEMS']
|
5
|
+
# gem 'rspec'
|
6
|
+
# require 'spec'
|
7
|
+
# end
|
8
8
|
|
9
9
|
require 'tmpdir'
|
10
10
|
require 'fileutils'
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'helper_spec'
|
2
|
+
require 'metamri'
|
3
|
+
|
4
|
+
describe 'DicomGroup' do
|
5
|
+
before(:each) do
|
6
|
+
@group_array = Dir.glob('/tmp/s01_assetcal/s01_assetcal.0*')[0..1]
|
7
|
+
@group = DicomGroup.new(@group_array)
|
8
|
+
@common = DicomGroup.new(@group_array).find_common_elements
|
9
|
+
@test_output_file = File.join(Dir.tmpdir, 'test.dcm')
|
10
|
+
end
|
11
|
+
it 'should initialize a DicomGroup' do
|
12
|
+
grp = DicomGroup.new(@group_array)
|
13
|
+
grp.should be_an_instance_of DicomGroup
|
14
|
+
grp.dobjects.length.should == 2
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should convert files in array to DICOM::DObjects' do
|
18
|
+
@group.dobjects.first.should be_an_instance_of DICOM::DObject
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should generate a hash of tags with common values' do
|
22
|
+
tags = @group.find_common_tags
|
23
|
+
tags.length.should == 310
|
24
|
+
tags.should be_a_kind_of Hash
|
25
|
+
tags.should_not be_empty
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should remove differing tags' do
|
29
|
+
object_lengths = @group.dobjects.map{|dobj| dobj.to_hash.length}
|
30
|
+
common_dobj = @group.find_common_elements
|
31
|
+
common_dobj.to_hash.length.should be < @group.dobjects.map { |dobj| dobj.to_hash.length }.max
|
32
|
+
# @group.dobjects.map {|dobj| dobj.to_hash.length }.should == object_lengths
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should set the DICOM string of common tags' do
|
36
|
+
# Create a dicom object to test to make sure that we can read the string.
|
37
|
+
# segments = @common.encode_segments(4*1024)
|
38
|
+
# @common.send(:insert_missing_meta)
|
39
|
+
# File.open('/tmp/dcmstring', 'wb') {|f| f.puts segments}
|
40
|
+
# puts dcm = DICOM::DObject.new(segments, :bin => true)
|
41
|
+
# puts dcm.errors
|
42
|
+
# dcm.read_success.should be_true
|
43
|
+
# dcm.print_all
|
44
|
+
|
45
|
+
@common.write(@test_output_file)
|
46
|
+
@common.write_success.should be_true
|
47
|
+
File.exist?(@test_output_file).should be_true
|
48
|
+
d = DICOM::DObject.new(@test_output_file)
|
49
|
+
d.stream.string.should == 'a'
|
50
|
+
end
|
51
|
+
|
52
|
+
# after(:each) do
|
53
|
+
# File.delete(@test_output_file) if File.exist?(@test_output_file)
|
54
|
+
# end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
describe 'DICOM::DObject' do
|
59
|
+
before(:all) do
|
60
|
+
@group_array = Dir.glob('/tmp/s01_assetcal/s01_assetcal.0*')[0..1]
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should respond to to_hash" do
|
64
|
+
tags = DICOM::DObject.new(@group_array.first).to_hash
|
65
|
+
tags.should be_a_kind_of Hash
|
66
|
+
tags.should have_key '0019,1081'
|
67
|
+
end
|
68
|
+
end
|
@@ -1,9 +1,8 @@
|
|
1
1
|
$:.unshift File.join(File.dirname(__FILE__),'..','lib')
|
2
2
|
|
3
|
+
require 'helper_spec'
|
4
|
+
|
3
5
|
require 'rubygems'
|
4
|
-
require 'spec'
|
5
|
-
require 'fileutils'
|
6
|
-
require 'tmpdir'
|
7
6
|
require 'metamri'
|
8
7
|
|
9
8
|
VISIT_FIXTURE_SRC = '/Data/vtrak1/raw/johnson.tbi-va.visit1/tbiva034_10019_04212010'
|
@@ -48,8 +47,8 @@ describe "Convert Unknown Dicoms to Nifti Files" do
|
|
48
47
|
@dataset_unzipped.to_nifti('/tmp/', 'filename.nii', :input_directory => @dataset_unzipped.directory)[0].should == "to3d -session /tmp/ -prefix filename.nii #{@dataset_unzipped.directory}/'*.dcm'"
|
49
48
|
nifti_conversion_command, nifti_output_file = @dataset_unzipped.to_nifti!('/tmp/', 'filename.nii', :input_directory => @dataset_unzipped.directory)
|
50
49
|
nifti_conversion_command.should == "to3d -session /tmp/ -prefix filename.nii #{@dataset_unzipped.directory}/'*.dcm'"
|
50
|
+
File.exist?(nifti_output_file).should be_true
|
51
51
|
@test_niftis << nifti_output_file
|
52
|
-
@output_directories << '/tmp'
|
53
52
|
end
|
54
53
|
|
55
54
|
it "should convert all anatomicals in a visit raw directory using original, unzipped files." do
|
@@ -106,7 +105,7 @@ describe "Convert Unknown Dicoms to Nifti Files" do
|
|
106
105
|
end
|
107
106
|
|
108
107
|
after(:each) do
|
109
|
-
@test_niftis.flatten.each { |nifti| File.delete(nifti) } unless @test_niftis.empty?
|
108
|
+
@test_niftis.flatten.each { |nifti| File.delete(nifti) if File.exist?(nifti) } unless @test_niftis.empty?
|
110
109
|
[@output_directories, Dir.tmpdir, '/tmp'].flatten.each do |temp_dir|
|
111
110
|
Dir.foreach(temp_dir) {|f| File.delete(File.join(temp_dir, f)) if File.extname(f) == '.nii'}
|
112
111
|
end
|
@@ -20,7 +20,7 @@ describe RawImageDataset, "for a single valid DICOM file" do
|
|
20
20
|
ds.raw_image_files.first.should == @valid_raw_image_file
|
21
21
|
ds.rmr_number.should == "ID"
|
22
22
|
ds.scanned_file.should == @valid_dicom_basename
|
23
|
-
ds.scanner_source.should == "
|
23
|
+
ds.scanner_source.should == "Institution"
|
24
24
|
ds.series_description.should == "Ax FSPGR BRAVO T1"
|
25
25
|
ds.study_id.should == "1405"
|
26
26
|
ds.timestamp.should == DateTime.parse("Wed, 10 Nov 2010 00:00:00 +0000")
|
@@ -35,7 +35,7 @@ describe RawImageFile, "reads a dicom header and extracts metadata" do
|
|
35
35
|
image.series_description.should == "Ax FSPGR BRAVO T1"
|
36
36
|
image.slice_spacing.should == "1"
|
37
37
|
image.slice_thickness.should == "1"
|
38
|
-
image.source.should == "
|
38
|
+
image.source.should == "Institution"
|
39
39
|
# Don't compare floats due to rounding errors, but compare all the other tags in dicom_taghash
|
40
40
|
image.dicom_taghash.reject{|k,v| v[:value].kind_of? Float }.should == valid_dicom_taghash.reject{|k,v| v[:value].kind_of? Float }
|
41
41
|
image.dicom_study_uid.should == "1.2.840.113619.6.260.4.1294724594.737.1289407877.724"
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: metamri
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 17
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
9
|
+
- 3
|
10
|
+
version: 0.2.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Kristopher J. Kosmatka
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-02-25 00:00:00 -06:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -73,6 +73,7 @@ extensions: []
|
|
73
73
|
extra_rdoc_files:
|
74
74
|
- README.rdoc
|
75
75
|
files:
|
76
|
+
- .rspec
|
76
77
|
- Manifest
|
77
78
|
- README.rdoc
|
78
79
|
- Rakefile
|
@@ -84,6 +85,7 @@ files:
|
|
84
85
|
- bin/list_visit
|
85
86
|
- lib/metamri.rb
|
86
87
|
- lib/metamri/core_additions.rb
|
88
|
+
- lib/metamri/dicom_additions.rb
|
87
89
|
- lib/metamri/image_dataset_quality_check_resource.rb
|
88
90
|
- lib/metamri/mysql_tools.rb
|
89
91
|
- lib/metamri/nifti_builder.rb
|
@@ -96,6 +98,7 @@ files:
|
|
96
98
|
- lib/metamri/visit_raw_data_directory_resource.rb
|
97
99
|
- metamri.gemspec
|
98
100
|
- spec/helper_spec.rb
|
101
|
+
- spec/unit/dicom_additions_spec.rb
|
99
102
|
- spec/unit/nifti_builder_spec.rb
|
100
103
|
- spec/unit/raw_image_dataset_spec.rb
|
101
104
|
- spec/unit/raw_image_dataset_thumbnail_spec.rb
|
@@ -140,12 +143,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
140
143
|
requirements: []
|
141
144
|
|
142
145
|
rubyforge_project:
|
143
|
-
rubygems_version: 1.4.
|
146
|
+
rubygems_version: 1.4.2
|
144
147
|
signing_key:
|
145
148
|
specification_version: 3
|
146
149
|
summary: MRI metadata
|
147
150
|
test_files:
|
148
151
|
- spec/helper_spec.rb
|
152
|
+
- spec/unit/dicom_additions_spec.rb
|
149
153
|
- spec/unit/nifti_builder_spec.rb
|
150
154
|
- spec/unit/raw_image_dataset_spec.rb
|
151
155
|
- spec/unit/raw_image_dataset_thumbnail_spec.rb
|