metamri 0.2.2 → 0.2.3
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.
- 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
|