brainmap-ImageData 0.1.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.
- data/ImageData.gemspec +32 -0
- data/LICENSE +3 -0
- data/Manifest +15 -0
- data/README.rdoc +43 -0
- data/Rakefile +18 -0
- data/lib/CLUs/import_study.rb +161 -0
- data/lib/CLUs/import_visit.rb +73 -0
- data/lib/mysql_tools.rb +33 -0
- data/lib/raw_image_dataset.rb +131 -0
- data/lib/raw_image_file.rb +411 -0
- data/lib/series_description.rb +81 -0
- data/lib/visit_raw_data_directory.rb +356 -0
- data/test/raw_image_dataset_test.rb +46 -0
- data/test/raw_image_file_test.rb +135 -0
- data/test/visit_duplication_test.rb +24 -0
- data/test/visit_test.rb +77 -0
- metadata +85 -0
data/ImageData.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{ImageData}
|
5
|
+
s.version = "0.1.0"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Kristopher J. Kosmatka"]
|
9
|
+
s.date = %q{2009-08-06}
|
10
|
+
s.description = %q{Extraction of MRI metadata and insertion into compatible sqlite3 databases.}
|
11
|
+
s.email = %q{kk4@medicine.wisc.edu}
|
12
|
+
s.extra_rdoc_files = ["lib/CLUs/import_study.rb", "lib/CLUs/import_visit.rb", "lib/mysql_tools.rb", "lib/raw_image_dataset.rb", "lib/raw_image_file.rb", "lib/series_description.rb", "lib/visit_raw_data_directory.rb", "LICENSE", "README.rdoc"]
|
13
|
+
s.files = ["lib/CLUs/import_study.rb", "lib/CLUs/import_visit.rb", "lib/mysql_tools.rb", "lib/raw_image_dataset.rb", "lib/raw_image_file.rb", "lib/series_description.rb", "lib/visit_raw_data_directory.rb", "LICENSE", "Manifest", "Rakefile", "README.rdoc", "test/raw_image_dataset_test.rb", "test/raw_image_file_test.rb", "test/visit_duplication_test.rb", "test/visit_test.rb", "ImageData.gemspec"]
|
14
|
+
s.has_rdoc = true
|
15
|
+
s.homepage = %q{http://github.com/brainmap/ImageData}
|
16
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "ImageData", "--main", "README.rdoc"]
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
s.rubyforge_project = %q{imagedata}
|
19
|
+
s.rubygems_version = %q{1.3.1}
|
20
|
+
s.summary = %q{Extraction of MRI metadata and insertion into compatible sqlite3 databases.}
|
21
|
+
s.test_files = ["test/raw_image_dataset_test.rb", "test/raw_image_file_test.rb", "test/visit_duplication_test.rb", "test/visit_test.rb"]
|
22
|
+
|
23
|
+
if s.respond_to? :specification_version then
|
24
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
25
|
+
s.specification_version = 2
|
26
|
+
|
27
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
28
|
+
else
|
29
|
+
end
|
30
|
+
else
|
31
|
+
end
|
32
|
+
end
|
data/LICENSE
ADDED
data/Manifest
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
lib/CLUs/import_study.rb
|
2
|
+
lib/CLUs/import_visit.rb
|
3
|
+
lib/mysql_tools.rb
|
4
|
+
lib/raw_image_dataset.rb
|
5
|
+
lib/raw_image_file.rb
|
6
|
+
lib/series_description.rb
|
7
|
+
lib/visit_raw_data_directory.rb
|
8
|
+
LICENSE
|
9
|
+
Manifest
|
10
|
+
Rakefile
|
11
|
+
README.rdoc
|
12
|
+
test/raw_image_dataset_test.rb
|
13
|
+
test/raw_image_file_test.rb
|
14
|
+
test/visit_duplication_test.rb
|
15
|
+
test/visit_test.rb
|
data/README.rdoc
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
== ImageData
|
2
|
+
|
3
|
+
A small library that can be used to extract metadata from large collections of research MR imaging data sets. Support is also provided to insert the metadata into a Wisconsin ADRC Imaging Core compatible database. Several
|
4
|
+
command line utilities are provided as well as a minimal API that is useful for building ruby on rails rake tasks.
|
5
|
+
|
6
|
+
You will most likely be interested in either:
|
7
|
+
|
8
|
+
= import_visit.rb CLU
|
9
|
+
|
10
|
+
== Synopsis
|
11
|
+
A simple utility for importing imaging data collected during one visit into the WADRC Data Tools web
|
12
|
+
application. Data from a visit is contained in one big directory that may have many subdirectories.
|
13
|
+
Each individual imaging scan may be composed of an entire directory of dicom files or one single p-file.
|
14
|
+
This utility scans through all of the image data sets and retrieved meta-data about the scans from their
|
15
|
+
header information.
|
16
|
+
|
17
|
+
== Examples
|
18
|
+
import_visit.rb /path/to/raw/mri/data study.codename /path/to/db/db.sqlite3
|
19
|
+
|
20
|
+
== Usage
|
21
|
+
import_visit.rb <raw_data_directory> <scan_procedure_codename> <database_file>
|
22
|
+
|
23
|
+
For help use: import_visit.rb -h
|
24
|
+
|
25
|
+
== Options
|
26
|
+
-h, --help Displays help message
|
27
|
+
-v, --visit Visit raw data directory, absolute path
|
28
|
+
-p, --scan_procedure scan_procedure codename, e.g. johnson.alz.visit1
|
29
|
+
-d, --database Database file into which information will imported
|
30
|
+
|
31
|
+
== Author
|
32
|
+
K.J. Kosmatka, kk4@medicine.wisc.edu
|
33
|
+
|
34
|
+
== Copyright
|
35
|
+
Copyright (c) 2009 WADRC Imaging Core.
|
36
|
+
|
37
|
+
|
38
|
+
or:
|
39
|
+
|
40
|
+
|
41
|
+
= VisitRawDirectory class
|
42
|
+
|
43
|
+
see the doc directory
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#
|
2
|
+
# To change this template, choose Tools | Templates
|
3
|
+
# and open the template in the editor.
|
4
|
+
|
5
|
+
require 'rubygems'
|
6
|
+
require 'rake'
|
7
|
+
require 'echoe'
|
8
|
+
|
9
|
+
Echoe.new('ImageData', '0.1.0') do |p|
|
10
|
+
p.description = "Extraction of MRI metadata and insertion into compatible sqlite3 databases."
|
11
|
+
p.url = "http://github.com/brainmap/ImageData"
|
12
|
+
p.author = "Kristopher J. Kosmatka"
|
13
|
+
p.email = "kk4@medicine.wisc.edu"
|
14
|
+
p.ignore_pattern = ["nbproject/*"]
|
15
|
+
p.development_dependencies = []
|
16
|
+
end
|
17
|
+
|
18
|
+
Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
|
@@ -0,0 +1,161 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# == Synopsis
|
4
|
+
# A simple utility for importing imaging data for an entire study into the WADRC Data Tools web
|
5
|
+
# application. Scans each visit within a particular protocol and inserts all the appropriat meta-data
|
6
|
+
# into the given database. Can be run as a command line utility, or the function can be required by other packages.
|
7
|
+
#
|
8
|
+
# == Examples
|
9
|
+
# import_study.rb alz_1 /path/to/the/rails/db/production.sqlite3
|
10
|
+
#
|
11
|
+
# == Usage
|
12
|
+
# import_visit.rb <study_code> <database_file>
|
13
|
+
#
|
14
|
+
# Study codes are one of:
|
15
|
+
# alz_1, alz_2, cms_wais, cms_uwmr, esprit_1, esprit_2, gallagher_pd, pib_pilot, ries_pilot, ries_1,
|
16
|
+
# tbi1000_1, tbi1000_2, tbi1000_3, tbiva, wrap140
|
17
|
+
#
|
18
|
+
# For help use: import_visit.rb -h
|
19
|
+
#
|
20
|
+
# == Options
|
21
|
+
# -h, --help Displays help message
|
22
|
+
#
|
23
|
+
# == Author
|
24
|
+
# K.J. Kosmatka, kk4@medicine.wisc.edu
|
25
|
+
#
|
26
|
+
# == Copyright
|
27
|
+
# Copyright (c) 2009 WADRC Imaging Core.
|
28
|
+
#
|
29
|
+
|
30
|
+
$:.unshift File.join(File.dirname(__FILE__),'..')
|
31
|
+
|
32
|
+
require 'visit_raw_data_directory'
|
33
|
+
require 'pathname'
|
34
|
+
require 'logger'
|
35
|
+
|
36
|
+
#:stopdoc:
|
37
|
+
STUDIES = {
|
38
|
+
:alz_1 => { :dir => '/Data/vtrak1/raw/alz_2000',
|
39
|
+
:logfile => 'alz.visit1.scan.log',
|
40
|
+
:filter => /^alz...$|^alz..._[AB]/i,
|
41
|
+
:codename => 'johnson.alz.visit1'
|
42
|
+
},
|
43
|
+
:alz_2 => { :dir => '/Data/vtrak1/raw/alz_2000',
|
44
|
+
:logfile => 'alz.visit2.scan.log',
|
45
|
+
:filter => /^alz..._2$/,
|
46
|
+
:codename => 'johnson.alz.visit2'
|
47
|
+
},
|
48
|
+
:cms_wais => { :dir => '/Data/vtrak1/raw/cms/wais',
|
49
|
+
:logfile => 'cms.wais.scan.log',
|
50
|
+
:filter => /^pc/,
|
51
|
+
:codename => 'johnson.cms.visit1.wais'
|
52
|
+
},
|
53
|
+
:cms_uwmr => { :dir => '/Data/vtrak1/raw/cms/uwmr',
|
54
|
+
:logfile => 'cms.uwmr.scan.log',
|
55
|
+
:filter => /^cms...$/,
|
56
|
+
:codename => 'johnson.cms.visit1.uwmr'
|
57
|
+
},
|
58
|
+
:esprit_1 => { :dir => '/Data/vtrak1/raw/esprit/baseline',
|
59
|
+
:logfile => 'esprit.baseline.scan.log',
|
60
|
+
:filter => /^esp3/,
|
61
|
+
:codename => 'carlsson.esprit.visit1.baseline'
|
62
|
+
},
|
63
|
+
:esprit_2 => { :dir => '/Data/vtrak1/raw/esprit/9month',
|
64
|
+
:logfile => 'esprit.9month.scan.log',
|
65
|
+
:filter => /^esp3/,
|
66
|
+
:codename => 'carlsson.esprit.visit2.9month'
|
67
|
+
},
|
68
|
+
:gallagher_pd => { :dir => '/Data/vtrak1/raw/gallagher_pd',
|
69
|
+
:logfile => 'gallagher.scan.log',
|
70
|
+
:filter => /^pd..._/,
|
71
|
+
:codename => 'gallagher.pd.visit1'
|
72
|
+
},
|
73
|
+
:pib_pilot => { :dir => '/Data/vtrak1/raw/pib_pilot_mri',
|
74
|
+
:logfile => 'pib.mri.pilot.scan.log',
|
75
|
+
:filter => /^cpr0/,
|
76
|
+
:codename => 'johnson.pibmripilot.visit1.uwmr'
|
77
|
+
},
|
78
|
+
:ries_1 => { :dir => '/Data/vtrak1/raw/ries.aware.visit1',
|
79
|
+
:logfile => 'ries.aware.visit1.scan.log',
|
80
|
+
:filter => /^awr0/,
|
81
|
+
:codename => 'ries.aware.visit1'
|
82
|
+
},
|
83
|
+
:ries_pilot => { :dir => '/Data/vtrak1/raw/ries.aware.visit1',
|
84
|
+
:logfile => 'ries.aware.pilot.scan.log',
|
85
|
+
:filter => /^awrP/,
|
86
|
+
:codename => 'ries.aware.pilot'
|
87
|
+
},
|
88
|
+
:tbi1000_1 => { :dir => '/Data/vtrak1/raw/tbi_1000',
|
89
|
+
:logfile => 'tbi1000.visit1.scan.log',
|
90
|
+
:filter => /^tbi...$/,
|
91
|
+
:codename => 'johnson.tbi1000.visit1'
|
92
|
+
},
|
93
|
+
:tbi1000_2 => { :dir => '/Data/vtrak1/raw/tbi_1000',
|
94
|
+
:logfile => 'tbi1000.visit2.scan.log',
|
95
|
+
:filter => /^tbi..._2/,
|
96
|
+
:codename => 'johnson.tbi1000.visit2'
|
97
|
+
},
|
98
|
+
:tbi1000_3 => { :dir => '/Data/vtrak1/raw/tbi_aware',
|
99
|
+
:logfile => 'tbiaware.visit3.scan.log',
|
100
|
+
:filter => /^tbi..._3$/,
|
101
|
+
:codename => 'johnson.tbiaware.visit3'
|
102
|
+
},
|
103
|
+
:tbiva => { :dir => '/Data/vtrak1/raw/johnson.tbi-va.visit1',
|
104
|
+
:logfile => 'tbiva.scan.log',
|
105
|
+
:filter => /^tbi/,
|
106
|
+
:codename => 'johnson.tbiva.visit1'
|
107
|
+
},
|
108
|
+
:wrap140 => { :dir => '/Data/vtrak1/raw/wrap140',
|
109
|
+
:logfile => 'wrap140.scan.log',
|
110
|
+
:filter => /^wrp/,
|
111
|
+
:codename => 'johnson.wrap140.visit1'
|
112
|
+
}
|
113
|
+
}
|
114
|
+
#:startdoc:
|
115
|
+
|
116
|
+
|
117
|
+
# == Function
|
118
|
+
# Imports an entire study.
|
119
|
+
#
|
120
|
+
# == Arguments
|
121
|
+
# study -- a hash specifying the following keys:
|
122
|
+
# :dir => the directory holding all the individual visit directories for this study
|
123
|
+
# :logfile => a file name where logging can be written
|
124
|
+
# :filter => a regex that matches all of the visit directory names that should be scanned
|
125
|
+
# :codename => the study codename, e.g. 'johnson.alz.visit1'
|
126
|
+
#
|
127
|
+
# dbfile -- the database into which meta-data will be inserted
|
128
|
+
#
|
129
|
+
def import_study(study, dbfile)
|
130
|
+
studydir = Pathname.new(study[:dir])
|
131
|
+
log = Logger.new(study[:logfile], shift_age = 7, shift_size = 1048576)
|
132
|
+
|
133
|
+
studydir.entries.each do |visit|
|
134
|
+
next if visit.to_s =~ /^\./
|
135
|
+
next unless visit.to_s =~ study[:filter]
|
136
|
+
visitdir = studydir + visit
|
137
|
+
v = VisitRawDataDirectory.new( visitdir.to_s, study[:codename] )
|
138
|
+
begin
|
139
|
+
v.scan
|
140
|
+
v.db_insert!(dbfile)
|
141
|
+
rescue Exception => e
|
142
|
+
puts "There was a problem scanning a dataset in #{visitdir}... skipping."
|
143
|
+
puts "Exception message: #{e.message}"
|
144
|
+
LOG.error "There was a problem scanning a dataset in #{visitdir}... skipping."
|
145
|
+
LOG.error "Exception message: #{e.message}"
|
146
|
+
ensure
|
147
|
+
v = nil
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
|
153
|
+
|
154
|
+
if __FILE__ == $0
|
155
|
+
study = STUDIES[ARGV[0].to_sym]
|
156
|
+
dbfile = ARGV[1]
|
157
|
+
import_study(study, dbfile)
|
158
|
+
end
|
159
|
+
|
160
|
+
|
161
|
+
|
@@ -0,0 +1,73 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# == Synopsis
|
4
|
+
# A simple utility for importing imaging data collected during one visit into the WADRC Data Tools web
|
5
|
+
# application. Data from a visit is contained in one big directory that may have many subdirectories.
|
6
|
+
# Each individual imaging scan may be composed of an entire directory of dicom files or one single p-file.
|
7
|
+
# This utility scans through all of the image data sets and retrieved meta-data about the scans from their
|
8
|
+
# header information.
|
9
|
+
#
|
10
|
+
# == Examples
|
11
|
+
# import_visit.rb /Data/vtrak1/raw/alz_2000/alz001 johnson.alz.visit1 /path/to/the/rails/db/production.sqlite3
|
12
|
+
# import_visit.rb /Data/vtrak1/raw/wrap140/wrp001_5917_03042008 johnson.wrap140.visit1 /path/to/the/rails/db/production.sqlite3
|
13
|
+
#
|
14
|
+
# == Usage
|
15
|
+
# import_visit.rb <raw_data_directory> <scan_procedure_codename> <database_file>
|
16
|
+
#
|
17
|
+
# For help use: import_visit.rb -h
|
18
|
+
#
|
19
|
+
# == Options
|
20
|
+
# -h, --help Displays help message
|
21
|
+
# -v, --visit Visit raw data directory, absolute path
|
22
|
+
# -p, --scan_procedure scan_procedure codename, e.g. johnson.alz.visit1
|
23
|
+
# -d, --database Database file into which information will imported
|
24
|
+
#
|
25
|
+
# == Author
|
26
|
+
# K.J. Kosmatka, kk4@medicine.wisc.edu
|
27
|
+
#
|
28
|
+
# == Copyright
|
29
|
+
# Copyright (c) 2009 WADRC Imaging Core.
|
30
|
+
#
|
31
|
+
|
32
|
+
$:.unshift File.join(File.dirname(__FILE__),'..')
|
33
|
+
|
34
|
+
require 'visit_raw_data_directory'
|
35
|
+
require 'pathname'
|
36
|
+
require 'rdoc/usage'
|
37
|
+
|
38
|
+
|
39
|
+
# == Function
|
40
|
+
# Imports imaging data collected during a single visit into the WADRC Data Tools web application database.
|
41
|
+
#
|
42
|
+
# == Usage
|
43
|
+
# import_visit(raw_directory, scan_procedure_codename, database)
|
44
|
+
#
|
45
|
+
# == Example
|
46
|
+
# import_visit('/Data/vtrak1/raw/alz_2000/alz001','johnson.alz.visit1','/path/to/the/rails/db/production.sqlite3')
|
47
|
+
#
|
48
|
+
def import_visit(raw_directory, scan_procedure_codename, database)
|
49
|
+
v = VisitRawDataDirectory.new(raw_directory, scan_procedure_codename)
|
50
|
+
puts "+++ Importing #{v.visit_directory} as part of #{v.scan_procedure_name} +++"
|
51
|
+
begin
|
52
|
+
v.scan
|
53
|
+
puts v
|
54
|
+
v.db_insert!(database)
|
55
|
+
rescue Exception => e
|
56
|
+
puts "There was a problem scanning a dataset in #{visitdir}... skipping."
|
57
|
+
puts "Exception message: #{e.message}"
|
58
|
+
LOG.error "There was a problem scanning a dataset in #{visitdir}... skipping."
|
59
|
+
LOG.error "Exception message: #{e.message}"
|
60
|
+
ensure
|
61
|
+
v = nil
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
if __FILE__ == $0
|
68
|
+
RDoc::usage() if ARGV[0] == '-h'
|
69
|
+
raw_directory = ARGV[0]
|
70
|
+
scan_procedure_codename = ARGV[1]
|
71
|
+
database = ARGV[2]
|
72
|
+
import_visit(raw_directory, scan_procedure_codename, database)
|
73
|
+
end
|
data/lib/mysql_tools.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'mysql'
|
2
|
+
|
3
|
+
class Mysql
|
4
|
+
def summary
|
5
|
+
self.list_tables.each do |tbl|
|
6
|
+
next if tbl =~ /^tws/
|
7
|
+
puts "+" * 160
|
8
|
+
puts "%80s" % tbl
|
9
|
+
puts "+" * 160
|
10
|
+
columns = self.query("select * from #{tbl}").fetch_hash.keys
|
11
|
+
columns.in_chunks_of(6).each do |chunk|
|
12
|
+
puts "%-25s " * chunk.size % chunk
|
13
|
+
end
|
14
|
+
puts "\n\n"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
class Array
|
22
|
+
def chunks(number_of_chunks)
|
23
|
+
chunks_of( (self.size/number_of_chunks.to_f).ceil )
|
24
|
+
end
|
25
|
+
def in_chunks_of(chunk_size)
|
26
|
+
nchunks = (self.size/chunk_size.to_f).ceil
|
27
|
+
chunks = Array.new(nchunks) { [] }
|
28
|
+
self.each_with_index do |item,index|
|
29
|
+
chunks[ index/chunk_size ] << item
|
30
|
+
end
|
31
|
+
return chunks
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
|
2
|
+
require 'rubygems'
|
3
|
+
require 'sqlite3'
|
4
|
+
|
5
|
+
=begin rdoc
|
6
|
+
A #Dataset defines a single 3D or 4D image, i.e. either a volume or a time series
|
7
|
+
of volumes. This encapsulation will provide easy manipulation of groups of raw
|
8
|
+
image files including basic reconstruction.
|
9
|
+
=end
|
10
|
+
class RawImageDataset
|
11
|
+
|
12
|
+
# The directory that contains all the raw images and related files that make up
|
13
|
+
# this data set.
|
14
|
+
attr_reader :directory
|
15
|
+
# An array of #RawImageFile objects that compose the complete data set.
|
16
|
+
attr_reader :raw_image_files
|
17
|
+
# From the first raw image file in the dataset
|
18
|
+
attr_reader :series_description
|
19
|
+
# From the first raw image file in the dataset
|
20
|
+
attr_reader :rmr_number
|
21
|
+
# From the first raw image file in the dataset
|
22
|
+
attr_reader :timestamp
|
23
|
+
# A key string unique to a dataset composed of the rmr number and the timestamp.
|
24
|
+
attr_reader :dataset_key
|
25
|
+
# the file scanned
|
26
|
+
attr_reader :scanned_file
|
27
|
+
|
28
|
+
|
29
|
+
=begin rdoc
|
30
|
+
* dir: The directory containing the files.
|
31
|
+
* files: An array of #RawImageFile objects that compose the complete data set.
|
32
|
+
|
33
|
+
Initialization raises errors in several cases:
|
34
|
+
* directory doesn't exist => IOError
|
35
|
+
* any of the raw image files is not actually a RawImageFile => IndexError
|
36
|
+
* series description, rmr number, or timestamp cannot be extracted from the first RawImageFile => IndexError
|
37
|
+
=end
|
38
|
+
def initialize(directory, raw_image_files)
|
39
|
+
@directory = File.expand_path(directory)
|
40
|
+
raise(IOError, "#{@directory} not found.") if not File.directory?(@directory)
|
41
|
+
raise(IOError, "No raw image files supplied.") if (raw_image_files.nil? or raw_image_files.empty?)
|
42
|
+
raw_image_files.each do |im|
|
43
|
+
raise(IndexError, im.to_s + " is not a RawImageFile") if im.class.to_s != "RawImageFile"
|
44
|
+
end
|
45
|
+
@raw_image_files = raw_image_files
|
46
|
+
@series_description = @raw_image_files.first.series_description
|
47
|
+
raise(IndexError, "No series description found") if @series_description.nil?
|
48
|
+
@rmr_number = @raw_image_files.first.rmr_number
|
49
|
+
raise(IndexError, "No rmr found") if @rmr_number.nil?
|
50
|
+
@timestamp = get_earliest_timestamp
|
51
|
+
raise(IndexError, "No timestamp found") if @timestamp.nil?
|
52
|
+
@dataset_key = @rmr_number + "::" + @timestamp.to_s
|
53
|
+
@scanned_file = @raw_image_files.first.filename
|
54
|
+
raise(IndexError, "No scanned file found") if @scanned_file.nil?
|
55
|
+
end
|
56
|
+
|
57
|
+
=begin rdoc
|
58
|
+
Generates an SQL insert statement for this dataset that can be used to populate
|
59
|
+
the Johnson Lab rails TransferScans application database backend. The motivation
|
60
|
+
for this is that many dataset inserts can be collected into one db transaction
|
61
|
+
at the visit level, or even higher when doing a whole file system scan.
|
62
|
+
=end
|
63
|
+
def db_insert(visit_id)
|
64
|
+
"INSERT INTO image_datasets
|
65
|
+
(rmr, series_description, path, timestamp, created_at, updated_at, visit_id,
|
66
|
+
glob, rep_time, bold_reps, slices_per_volume, scanned_file)
|
67
|
+
VALUES ('#{@rmr_number}', '#{@series_description}', '#{@directory}', '#{@timestamp.to_s}', '#{DateTime.now}',
|
68
|
+
'#{DateTime.now}', '#{visit_id}', '#{self.glob}', '#{@raw_image_files.first.rep_time}',
|
69
|
+
'#{@raw_image_files.first.bold_reps}', '#{@raw_image_files.first.num_slices}', '#{@scanned_file}')"
|
70
|
+
end
|
71
|
+
|
72
|
+
def db_update(dataset_id)
|
73
|
+
"UPDATE image_datasets SET
|
74
|
+
rmr = '#{@rmr_number}',
|
75
|
+
series_description = '#{@series_description}',
|
76
|
+
path = '#{@directory}',
|
77
|
+
timestamp = '#{@timestamp.to_s}',
|
78
|
+
updated_at = '#{DateTime.now.to_s}',
|
79
|
+
glob = '#{self.glob}',
|
80
|
+
rep_time = '#{@raw_image_files.first.rep_time}',
|
81
|
+
bold_reps = '#{@raw_image_files.first.bold_reps}',
|
82
|
+
slices_per_volume = '#{@raw_image_files.first.num_slices}',
|
83
|
+
scanned_file = '#{@scanned_file}'
|
84
|
+
WHERE id = '#{dataset_id}'"
|
85
|
+
end
|
86
|
+
|
87
|
+
def db_fetch
|
88
|
+
"SELECT * FROM image_datasets
|
89
|
+
WHERE rmr = '#{@rmr_number}'
|
90
|
+
AND path = '#{@directory}'
|
91
|
+
AND timestamp LIKE '#{@timestamp.to_s.split(/\+|Z/).first}%'"
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
|
96
|
+
=begin rdoc
|
97
|
+
Returns a globbing wildcard that is used by to3D to gather files for
|
98
|
+
reconstruction. If no compatible glob is found for the data set, nil is returned.
|
99
|
+
This is always the case for pfiles. For example if the first file in a data set is I.001, then:
|
100
|
+
<tt>dataset.glob</tt>
|
101
|
+
<tt>=> "I.*"</tt>
|
102
|
+
including the quotes, which are necessary becuase some data sets (functional dicoms)
|
103
|
+
have more component files than shell commands can handle.
|
104
|
+
=end
|
105
|
+
def glob
|
106
|
+
case @raw_image_files.first.filename
|
107
|
+
when /^E.*dcm$/
|
108
|
+
return 'E*.dcm'
|
109
|
+
when /\.dcm$/
|
110
|
+
return '*.dcm'
|
111
|
+
when /^I\./
|
112
|
+
return 'I.*'
|
113
|
+
when /^I/
|
114
|
+
return 'I*.dcm'
|
115
|
+
when /\.0/
|
116
|
+
return '*.0*'
|
117
|
+
else
|
118
|
+
return nil
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
private
|
123
|
+
|
124
|
+
# Gets the earliest timestamp among the raw image files in this dataset.
|
125
|
+
def get_earliest_timestamp
|
126
|
+
@timestamp = (@raw_image_files.sort_by { |i| i.timestamp }).first.timestamp
|
127
|
+
end
|
128
|
+
|
129
|
+
|
130
|
+
end
|
131
|
+
#### END OF CLASS ####
|