rpipe 0.1.6 → 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/default_methods/default_recon.rb +11 -21
- data/lib/default_methods/recon/raw_sequence.rb +24 -6
- data/lib/generators/recon_job_generator.rb +2 -2
- data/lib/rpipe.rb +1 -3
- data/lib/rpipe/version.rb +2 -2
- data/rpipe.gemspec +1 -0
- data/spec/physio_spec.rb +98 -98
- metadata +29 -15
@@ -4,7 +4,8 @@ require 'default_methods/recon/raw_sequence'
|
|
4
4
|
# require 'default_methods/recon/physionoise_helper'
|
5
5
|
|
6
6
|
module DefaultRecon
|
7
|
-
|
7
|
+
DEFAULT_VOLUME_SKIP = 3 # Default number of volumes to strip from beginning of functional scans.
|
8
|
+
|
8
9
|
# Reconstructs, strips, and slice timing corrects all scans specified in the recon_spec.
|
9
10
|
# This function assumes a destination directory is set up in the filesystem and begins writing
|
10
11
|
# to it with no further checking. It will overwrite data if it already exists, be careful.
|
@@ -16,6 +17,9 @@ module DefaultRecon
|
|
16
17
|
@scans.each_with_index do |scan_spec, i|
|
17
18
|
outfile = "%s_%s.nii" % [@subid, scan_spec['label']]
|
18
19
|
|
20
|
+
# Set Discarded Acquisitions - Volumes to Skip from Recon Spec, Scan Spec or Default
|
21
|
+
@volumes_to_skip = @volume_skip || scan_spec['volume_skip'] || scan_spec['volumes_to_skip'] || DEFAULT_VOLUME_SKIP
|
22
|
+
|
19
23
|
reconstruct_scan(scan_spec, outfile)
|
20
24
|
|
21
25
|
if scan_spec['type'] == "func"
|
@@ -42,30 +46,16 @@ module DefaultRecon
|
|
42
46
|
# filenaming, I0002.dcm is second file in series,
|
43
47
|
def reconstruct_scan(scan_spec, outfile)
|
44
48
|
if scan_spec['dir']
|
45
|
-
sequence = DicomRawSequence.new(scan_spec, @rawdir)
|
46
|
-
File.delete('tmp.nii') if File.exist? 'tmp.nii'
|
47
|
-
sequence.prepare('tmp.nii')
|
48
|
-
strip_leading_volumes('tmp.nii', outfile, @volume_skip, scan_spec['bold_reps'])
|
49
|
+
sequence = DicomRawSequence.new(scan_spec, @rawdir, @volumes_to_skip)
|
49
50
|
elsif scan_spec['pfile']
|
50
|
-
sequence = PfileRawSequence.new(scan_spec, @rawdir)
|
51
|
-
|
52
|
-
else
|
51
|
+
sequence = PfileRawSequence.new(scan_spec, @rawdir, @volumes_to_skip)
|
52
|
+
else
|
53
53
|
raise ConfigError, "Scan must list either a pfile or a dicom directory."
|
54
54
|
end
|
55
|
+
|
56
|
+
sequence.prepare(outfile)
|
55
57
|
end
|
56
|
-
|
57
|
-
# Removes the specified number of volumes from the beginning of a 4D functional nifti file.
|
58
|
-
# In most cases this will be 3 volumes. Writes result in current working directory.
|
59
|
-
def strip_leading_volumes(infile, outfile, volume_skip, bold_reps)
|
60
|
-
$Log.info "Stripping #{volume_skip.to_s} leading volumes: #{infile}"
|
61
|
-
cmd_fmt = "fslroi %s %s %s %s"
|
62
|
-
cmd_options = [infile, outfile, volume_skip.to_s, bold_reps.to_s]
|
63
|
-
cmd = cmd_fmt % cmd_options
|
64
|
-
unless run(cmd)
|
65
|
-
raise ScriptError, "Failed to strip volumes: #{cmd}"
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
58
|
+
|
69
59
|
# Uses to3d to slice time correct a 4D functional nifti file. Writes result in the current working directory.
|
70
60
|
def slice_time_correct(infile, alt_direction = "alt+z")
|
71
61
|
$Log.info "Slice Timing Correction: #{infile}"
|
@@ -4,10 +4,24 @@ module DefaultRecon
|
|
4
4
|
# them from their raw state (dicoms or pfiles) to Nifti files suitable for
|
5
5
|
# processing.
|
6
6
|
class RawSequence
|
7
|
-
def initialize(scan_spec, rawdir)
|
7
|
+
def initialize(scan_spec, rawdir, volumes_to_skip)
|
8
8
|
@scan_spec = scan_spec
|
9
9
|
@rawdir = rawdir
|
10
|
+
@volumes_to_skip = volumes_to_skip
|
10
11
|
end
|
12
|
+
|
13
|
+
# Removes the specified number of volumes from the beginning of a 4D functional nifti file.
|
14
|
+
# In most cases this will be 3 volumes. Writes result in current working directory.
|
15
|
+
def strip_leading_volumes(infile, outfile, volume_skip, bold_reps)
|
16
|
+
$Log.info "Stripping #{volume_skip.to_s} leading volumes: #{infile}"
|
17
|
+
cmd_fmt = "fslroi %s %s %s %s"
|
18
|
+
cmd_options = [infile, outfile, volume_skip.to_s, bold_reps.to_s]
|
19
|
+
cmd = cmd_fmt % cmd_options
|
20
|
+
unless run(cmd)
|
21
|
+
raise ScriptError, "Failed to strip volumes: #{cmd}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
11
25
|
end
|
12
26
|
|
13
27
|
# Manage a folder of Raw Dicoms for Nifti file conversion
|
@@ -16,9 +30,14 @@ module DefaultRecon
|
|
16
30
|
def prepare_and_convert_sequence(outfile)
|
17
31
|
@scandir = File.join(@rawdir, @scan_spec['dir'])
|
18
32
|
$Log.info "Dicom Reconstruction: #{@scandir}"
|
33
|
+
|
34
|
+
File.delete('tmp.nii') if File.exist? 'tmp.nii'
|
35
|
+
|
19
36
|
Pathname.new(@scandir).all_dicoms do |dicoms|
|
20
|
-
convert_sequence(dicoms,
|
37
|
+
convert_sequence(dicoms, 'tmp.nii')
|
21
38
|
end
|
39
|
+
|
40
|
+
strip_leading_volumes('tmp.nii', outfile, @volumes_to_skip, @scan_spec['bold_reps'])
|
22
41
|
end
|
23
42
|
|
24
43
|
alias_method :prepare, :prepare_and_convert_sequence
|
@@ -67,8 +86,8 @@ module DefaultRecon
|
|
67
86
|
# Reconstucts a PFile from Raw to Nifti File
|
68
87
|
class PfileRawSequence < RawSequence
|
69
88
|
# Create a local unzipped copy of the Pfile and prepare Scanner Reference Data for reconstruction
|
70
|
-
def initialize(scan_spec, rawdir)
|
71
|
-
super(scan_spec, rawdir)
|
89
|
+
def initialize(scan_spec, rawdir, volumes_to_skip)
|
90
|
+
super(scan_spec, rawdir, volumes_to_skip)
|
72
91
|
|
73
92
|
base_pfile_path = File.join(@rawdir, @scan_spec['pfile'])
|
74
93
|
pfile_path = File.exist?(base_pfile_path) ? base_pfile_path : base_pfile_path + '.bz2'
|
@@ -86,9 +105,8 @@ module DefaultRecon
|
|
86
105
|
# Outfile may include a '.nii' extension - a nifti file will be constructed
|
87
106
|
# directly in this case.
|
88
107
|
def reconstruct_sequence(outfile)
|
89
|
-
volumes_to_skip = @scan_spec['volumes_to_skip'] ||= 3
|
90
108
|
epirecon_cmd_format = "epirecon_ex -f %s -NAME %s -skip %d -scltype=0"
|
91
|
-
epirecon_cmd_options = [@pfile_data, outfile, volumes_to_skip]
|
109
|
+
epirecon_cmd_options = [@pfile_data, outfile, @volumes_to_skip]
|
92
110
|
epirecon_cmd = epirecon_cmd_format % epirecon_cmd_options
|
93
111
|
raise ScriptError, "Problem running #{epirecon_cmd}" unless run(epirecon_cmd)
|
94
112
|
end
|
@@ -1,5 +1,5 @@
|
|
1
|
-
gem 'activeresource', '<=2.3.8'
|
2
|
-
$LOAD_PATH.unshift('~/projects/metamri/lib').unshift('~/code/metamri/lib')
|
1
|
+
# gem 'activeresource', '<=2.3.8'
|
2
|
+
# $LOAD_PATH.unshift('~/projects/metamri/lib').unshift('~/code/metamri/lib')
|
3
3
|
require 'metamri'
|
4
4
|
require 'generators/job_generator'
|
5
5
|
|
data/lib/rpipe.rb
CHANGED
@@ -147,8 +147,6 @@ class Reconstruction < JobStep
|
|
147
147
|
require 'default_methods/default_recon'
|
148
148
|
include DefaultRecon
|
149
149
|
|
150
|
-
VOLUME_SKIP = 3 # number of volumes to strip from beginning of functional scans.
|
151
|
-
|
152
150
|
attr_accessor :scans, :volume_skip
|
153
151
|
|
154
152
|
# Instances are initialized with a properly configured hash containing all the information needed to drive
|
@@ -156,7 +154,7 @@ class Reconstruction < JobStep
|
|
156
154
|
def initialize(workflow_spec, recon_spec)
|
157
155
|
super(workflow_spec, recon_spec)
|
158
156
|
raise ScriptError, "At least one scan must be specified." if @scans.nil?
|
159
|
-
@volume_skip = recon_spec['volume_skip']
|
157
|
+
@volume_skip = recon_spec['volume_skip']
|
160
158
|
|
161
159
|
job_requires 'rawdir', 'origdir', 'scans'
|
162
160
|
end
|
data/lib/rpipe/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module Rpipe
|
2
|
-
VERSION = "0.1.
|
3
|
-
end
|
2
|
+
VERSION = "0.1.7"
|
3
|
+
end
|
data/rpipe.gemspec
CHANGED
@@ -13,6 +13,7 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.homepage = "http://github.com/brainmap/rpipe"
|
14
14
|
|
15
15
|
s.add_development_dependency "thoughtbot-shoulda", ">= 0"
|
16
|
+
s.add_development_dependency "rspec", "~>1.3.2"
|
16
17
|
s.add_dependency "metamri", '~>0.2.9'
|
17
18
|
s.add_dependency "log4r", '~>1.1.9'
|
18
19
|
s.add_dependency "POpen4", '~>0.1.4'
|
data/spec/physio_spec.rb
CHANGED
@@ -1,98 +1,98 @@
|
|
1
|
-
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '../../physionoise/lib'))
|
2
|
-
|
3
|
-
require 'helper_spec'
|
4
|
-
require 'rpipe'
|
5
|
-
require 'physionoise'
|
6
|
-
|
7
|
-
|
8
|
-
describe "Test Phyiosnoise" do
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
end
|
1
|
+
# $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '../../physionoise/lib'))
|
2
|
+
#
|
3
|
+
# require 'helper_spec'
|
4
|
+
# require 'rpipe'
|
5
|
+
# require 'physionoise'
|
6
|
+
#
|
7
|
+
#
|
8
|
+
# describe "Test Phyiosnoise" do
|
9
|
+
# before(:each) do
|
10
|
+
# @runs_dir = File.join($MRI_DATA, 'mrt00000', 'dicoms')
|
11
|
+
# job_params = {
|
12
|
+
# "scans" => [{
|
13
|
+
# "label"=>"task1",
|
14
|
+
# "dir"=>"s07_epi",
|
15
|
+
# "z_slices"=>36,
|
16
|
+
# "rep_time"=>2.0,
|
17
|
+
# "type"=>"func",
|
18
|
+
# "physio_files"=> {
|
19
|
+
# :phys_directory => "../cardiac", # Relative to rawdir
|
20
|
+
# :series_description => "EPI fMRI Task1",
|
21
|
+
# :respiration_signal => "RESPData_epiRT_0211201009_21_22_80",
|
22
|
+
# :respiration_trigger => "RESPTrig_epiRT_0211201009_21_22_80",
|
23
|
+
# :cardiac_signal => "PPGData_epiRT_0211201009_21_22_80",
|
24
|
+
# :cardiac_trigger => "PPGTrig_epiRT_0211201009_21_22_80"
|
25
|
+
# },
|
26
|
+
# "bold_reps"=>167,
|
27
|
+
# "task"=>"Faces3B"
|
28
|
+
# }]
|
29
|
+
# }
|
30
|
+
#
|
31
|
+
# workflow_spec = {
|
32
|
+
# "subid"=>"mrt00000",
|
33
|
+
# "rawdir"=> @runs_dir,
|
34
|
+
# "origdir"=> Dir.mktmpdir('orig_'),
|
35
|
+
# "procdir"=> Dir.mktmpdir('proc_'),
|
36
|
+
# "statsdir"=> Dir.mktmpdir('stats_'),
|
37
|
+
# "collision"=> "destroy"
|
38
|
+
# }
|
39
|
+
#
|
40
|
+
# @valid_physionoise_run_spec = [{
|
41
|
+
# :run_directory=> @runs_dir,
|
42
|
+
# :bold_reps=>167, :respiration_signal=>"RESPData_epiRT_0211201009_21_22_80",
|
43
|
+
# :respiration_trigger=>"RESPTrig_epiRT_0211201009_21_22_80",
|
44
|
+
# :cardiac_signal=>"PPGData_epiRT_0211201009_21_22_80",
|
45
|
+
# :cardiac_trigger=>"PPGTrig_epiRT_0211201009_21_22_80",
|
46
|
+
# :phys_directory=> File.join(@runs_dir, '..', 'cardiac'),
|
47
|
+
# :rep_time=>2.0,
|
48
|
+
# :series_description=>"EPI fMRI Task1"
|
49
|
+
# }]
|
50
|
+
#
|
51
|
+
# @recon_job = Reconstruction.new(workflow_spec, job_params)
|
52
|
+
# @scan_spec = @recon_job.scans.first
|
53
|
+
#
|
54
|
+
# @physionoise_fixture_dir = File.join(File.dirname(__FILE__), 'fixtures', 'physionoise_regressors')
|
55
|
+
#
|
56
|
+
# end
|
57
|
+
#
|
58
|
+
# it "should create physionoise regressors from Cardiac and Respiration Data" # do
|
59
|
+
# # Dir.chdir @recon_job.origdir do
|
60
|
+
# # @recon_job.create_physiosnoise_regressors(@scan_spec)
|
61
|
+
# # end
|
62
|
+
# #
|
63
|
+
# # Dir.compare_directories(@recon_job.origdir, @physionoise_fixture_dir).should be_true
|
64
|
+
#
|
65
|
+
# # end
|
66
|
+
#
|
67
|
+
# it "should correctly build a spec for passing to physionoise" # do
|
68
|
+
# # @recon_job.build_physionoise_run_spec(@scan_spec).should == @valid_physionoise_run_spec
|
69
|
+
# # end
|
70
|
+
#
|
71
|
+
# it "should correctly build a physionoise python command" # do
|
72
|
+
# # @valid_physionoise_run_spec.each do |run|
|
73
|
+
# # puts Physionoise.build_run_cmd(run)
|
74
|
+
# # end
|
75
|
+
# # end
|
76
|
+
#
|
77
|
+
# it "should build a 3dRetroicor string" # do
|
78
|
+
# # valid_cmd = "3dretroicor -prefix ptask1.nii -card #{@runs_dir}/../cardiac/PPGData_epiRT_0211201009_21_22_80 -resp #{@runs_dir}/../cardiac/RESPData_epiRT_0211201009_21_22_80 task1.nii"
|
79
|
+
# # valid_outfile = "p#{@scan_spec['label']}.nii"
|
80
|
+
# # test_cmd, test_outfile = @recon_job.build_retroicor_cmd(@scan_spec['physio_files'], "#{@scan_spec['label']}.nii")
|
81
|
+
# #
|
82
|
+
# # valid_cmd.should == test_cmd
|
83
|
+
# # valid_outfile.should == test_outfile
|
84
|
+
# # end
|
85
|
+
#
|
86
|
+
# it "should raise an error building a 3dRetroicor string if improperly configured" # do
|
87
|
+
# # physio_files = @scan_spec['physio_files']
|
88
|
+
# # physio_files.delete(:cardiac_signal)
|
89
|
+
# #
|
90
|
+
# # lambda {@recon_job.build_retroicor_cmd(physio_files, "#{@scan_spec['label']}.nii") }.should raise_error ScriptError, /Missing .* cardiac/
|
91
|
+
# # end
|
92
|
+
#
|
93
|
+
# it "should raise an IOError building a 3dRetroicor string with bad files"
|
94
|
+
#
|
95
|
+
# after(:each) do
|
96
|
+
# FileUtils.rm_r([@recon_job.origdir, @recon_job.procdir, @recon_job.statsdir])
|
97
|
+
# end
|
98
|
+
# end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rpipe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 7
|
10
|
+
version: 0.1.7
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Kristopher Kosmatka
|
@@ -16,8 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date:
|
20
|
-
default_executable:
|
19
|
+
date: 2012-02-01 00:00:00 Z
|
21
20
|
dependencies:
|
22
21
|
- !ruby/object:Gem::Dependency
|
23
22
|
name: thoughtbot-shoulda
|
@@ -34,9 +33,25 @@ dependencies:
|
|
34
33
|
type: :development
|
35
34
|
version_requirements: *id001
|
36
35
|
- !ruby/object:Gem::Dependency
|
37
|
-
name:
|
36
|
+
name: rspec
|
38
37
|
prerelease: false
|
39
38
|
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 31
|
44
|
+
segments:
|
45
|
+
- 1
|
46
|
+
- 3
|
47
|
+
- 2
|
48
|
+
version: 1.3.2
|
49
|
+
type: :development
|
50
|
+
version_requirements: *id002
|
51
|
+
- !ruby/object:Gem::Dependency
|
52
|
+
name: metamri
|
53
|
+
prerelease: false
|
54
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
40
55
|
none: false
|
41
56
|
requirements:
|
42
57
|
- - ~>
|
@@ -48,11 +63,11 @@ dependencies:
|
|
48
63
|
- 9
|
49
64
|
version: 0.2.9
|
50
65
|
type: :runtime
|
51
|
-
version_requirements: *
|
66
|
+
version_requirements: *id003
|
52
67
|
- !ruby/object:Gem::Dependency
|
53
68
|
name: log4r
|
54
69
|
prerelease: false
|
55
|
-
requirement: &
|
70
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
56
71
|
none: false
|
57
72
|
requirements:
|
58
73
|
- - ~>
|
@@ -64,11 +79,11 @@ dependencies:
|
|
64
79
|
- 9
|
65
80
|
version: 1.1.9
|
66
81
|
type: :runtime
|
67
|
-
version_requirements: *
|
82
|
+
version_requirements: *id004
|
68
83
|
- !ruby/object:Gem::Dependency
|
69
84
|
name: POpen4
|
70
85
|
prerelease: false
|
71
|
-
requirement: &
|
86
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
72
87
|
none: false
|
73
88
|
requirements:
|
74
89
|
- - ~>
|
@@ -80,11 +95,11 @@ dependencies:
|
|
80
95
|
- 4
|
81
96
|
version: 0.1.4
|
82
97
|
type: :runtime
|
83
|
-
version_requirements: *
|
98
|
+
version_requirements: *id005
|
84
99
|
- !ruby/object:Gem::Dependency
|
85
100
|
name: ruport
|
86
101
|
prerelease: false
|
87
|
-
requirement: &
|
102
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
88
103
|
none: false
|
89
104
|
requirements:
|
90
105
|
- - ~>
|
@@ -96,7 +111,7 @@ dependencies:
|
|
96
111
|
- 3
|
97
112
|
version: 1.6.3
|
98
113
|
type: :runtime
|
99
|
-
version_requirements: *
|
114
|
+
version_requirements: *id006
|
100
115
|
description: Functional MRI Processing Pipeline for the WADRC
|
101
116
|
email: ekk@medicine.wisc.edu
|
102
117
|
executables:
|
@@ -217,7 +232,6 @@ files:
|
|
217
232
|
- test/test_rpipe.rb
|
218
233
|
- vendor/output_catcher.rb
|
219
234
|
- vendor/trollop.rb
|
220
|
-
has_rdoc: true
|
221
235
|
homepage: http://github.com/brainmap/rpipe
|
222
236
|
licenses: []
|
223
237
|
|
@@ -247,7 +261,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
247
261
|
requirements: []
|
248
262
|
|
249
263
|
rubyforge_project:
|
250
|
-
rubygems_version: 1.
|
264
|
+
rubygems_version: 1.8.11
|
251
265
|
signing_key:
|
252
266
|
specification_version: 3
|
253
267
|
summary: Neuroimaging preprocessing the Ruby way
|