rpipe 0.1.6 → 0.1.7
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/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
|