rpipe 0.0.1

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.
Files changed (104) hide show
  1. data/.document +5 -0
  2. data/.gitignore +23 -0
  3. data/LICENSE +20 -0
  4. data/README +0 -0
  5. data/README.rdoc +33 -0
  6. data/Rakefile +78 -0
  7. data/VERSION +1 -0
  8. data/bin/create_driver.rb +79 -0
  9. data/bin/rpipe +131 -0
  10. data/bin/swallow_batch_run.rb +21 -0
  11. data/lib/core_additions.rb +5 -0
  12. data/lib/custom_methods/JohnsonMerit220Visit1Preproc.m +26 -0
  13. data/lib/custom_methods/JohnsonMerit220Visit1Preproc.rb +43 -0
  14. data/lib/custom_methods/JohnsonMerit220Visit1Preproc_job.m +80 -0
  15. data/lib/custom_methods/JohnsonMerit220Visit1Stats.m +74 -0
  16. data/lib/custom_methods/JohnsonMerit220Visit1Stats.rb +63 -0
  17. data/lib/custom_methods/JohnsonMerit220Visit1Stats_job.m +63 -0
  18. data/lib/custom_methods/JohnsonTbiLongitudinalSnodPreproc.m +26 -0
  19. data/lib/custom_methods/JohnsonTbiLongitudinalSnodPreproc.rb +41 -0
  20. data/lib/custom_methods/JohnsonTbiLongitudinalSnodPreproc_job.m +69 -0
  21. data/lib/custom_methods/JohnsonTbiLongitudinalSnodStats.m +76 -0
  22. data/lib/custom_methods/JohnsonTbiLongitudinalSnodStats.rb +67 -0
  23. data/lib/custom_methods/JohnsonTbiLongitudinalSnodStats_job.m +59 -0
  24. data/lib/custom_methods/ReconWithHello.rb +7 -0
  25. data/lib/default_logger.rb +13 -0
  26. data/lib/default_methods/default_preproc.rb +76 -0
  27. data/lib/default_methods/default_recon.rb +80 -0
  28. data/lib/default_methods/default_stats.rb +94 -0
  29. data/lib/default_methods/recon/physionoise_helper.rb +69 -0
  30. data/lib/default_methods/recon/raw_sequence.rb +109 -0
  31. data/lib/generators/job_generator.rb +36 -0
  32. data/lib/generators/preproc_job_generator.rb +31 -0
  33. data/lib/generators/recon_job_generator.rb +76 -0
  34. data/lib/generators/stats_job_generator.rb +70 -0
  35. data/lib/generators/workflow_generator.rb +128 -0
  36. data/lib/global_additions.rb +18 -0
  37. data/lib/logfile.rb +310 -0
  38. data/lib/matlab_helpers/CreateFunctionalVolumeStruct.m +6 -0
  39. data/lib/matlab_helpers/import_csv.m +32 -0
  40. data/lib/matlab_helpers/matlab_queue.rb +37 -0
  41. data/lib/matlab_helpers/prepare_onsets_xls.m +30 -0
  42. data/lib/rpipe.rb +254 -0
  43. data/rpipe.gemspec +177 -0
  44. data/spec/generators/preproc_job_generator_spec.rb +27 -0
  45. data/spec/generators/recon_job_generator_spec.rb +33 -0
  46. data/spec/generators/stats_job_generator_spec.rb +50 -0
  47. data/spec/generators/workflow_generator_spec.rb +97 -0
  48. data/spec/helper_spec.rb +40 -0
  49. data/spec/integration/johnson.merit220.visit1_spec.rb +47 -0
  50. data/spec/integration/johnson.tbi.longitudinal.snod_spec.rb +48 -0
  51. data/spec/logfile_spec.rb +96 -0
  52. data/spec/matlab_queue_spec.rb +40 -0
  53. data/spec/merit220_stats_spec.rb +81 -0
  54. data/spec/physio_spec.rb +98 -0
  55. data/test/drivers/merit220_workflow_sample.yml +15 -0
  56. data/test/drivers/mrt00000.yml +65 -0
  57. data/test/drivers/mrt00015.yml +62 -0
  58. data/test/drivers/mrt00015_hello.yml +41 -0
  59. data/test/drivers/mrt00015_withphys.yml +81 -0
  60. data/test/drivers/tbi000.yml +129 -0
  61. data/test/drivers/tbi000_separatevisits.yml +137 -0
  62. data/test/drivers/tmp.yml +58 -0
  63. data/test/fixtures/faces3_recognitionA.mat +0 -0
  64. data/test/fixtures/faces3_recognitionA.txt +86 -0
  65. data/test/fixtures/faces3_recognitionA_equal.csv +25 -0
  66. data/test/fixtures/faces3_recognitionA_unequal.csv +21 -0
  67. data/test/fixtures/faces3_recognitionB_incmisses.txt +86 -0
  68. data/test/fixtures/physionoise_regressors/EPI__fMRI_Task1_CPd3R_40.txt +13360 -0
  69. data/test/fixtures/physionoise_regressors/EPI__fMRI_Task1_CPd3_40.txt +13360 -0
  70. data/test/fixtures/physionoise_regressors/EPI__fMRI_Task1_CPttl_40.txt +13360 -0
  71. data/test/fixtures/physionoise_regressors/EPI__fMRI_Task1_CRTd3R_40.txt +13360 -0
  72. data/test/fixtures/physionoise_regressors/EPI__fMRI_Task1_CRTd3_40.txt +13360 -0
  73. data/test/fixtures/physionoise_regressors/EPI__fMRI_Task1_CRTttl_40.txt +13360 -0
  74. data/test/fixtures/physionoise_regressors/EPI__fMRI_Task1_HalfTR_CRTd3R_40.txt +334 -0
  75. data/test/fixtures/physionoise_regressors/EPI__fMRI_Task1_HalfTR_CRTd3_40.txt +334 -0
  76. data/test/fixtures/physionoise_regressors/EPI__fMRI_Task1_HalfTR_CRTttl_40.txt +334 -0
  77. data/test/fixtures/physionoise_regressors/EPI__fMRI_Task1_HalfTR_RRT_40.txt +334 -0
  78. data/test/fixtures/physionoise_regressors/EPI__fMRI_Task1_HalfTR_RVT_40.txt +334 -0
  79. data/test/fixtures/physionoise_regressors/EPI__fMRI_Task1_HalfTR_card_spline_40.txt +334 -0
  80. data/test/fixtures/physionoise_regressors/EPI__fMRI_Task1_HalfTR_resp_spline_40.txt +334 -0
  81. data/test/fixtures/physionoise_regressors/EPI__fMRI_Task1_RRT_40.txt +9106 -0
  82. data/test/fixtures/physionoise_regressors/EPI__fMRI_Task1_RVT_40.txt +9106 -0
  83. data/test/fixtures/physionoise_regressors/EPI__fMRI_Task1_TR_CRTd3R_40.txt +167 -0
  84. data/test/fixtures/physionoise_regressors/EPI__fMRI_Task1_TR_CRTd3_40.txt +167 -0
  85. data/test/fixtures/physionoise_regressors/EPI__fMRI_Task1_TR_CRTttl_40.txt +167 -0
  86. data/test/fixtures/physionoise_regressors/EPI__fMRI_Task1_TR_RRT_40.txt +167 -0
  87. data/test/fixtures/physionoise_regressors/EPI__fMRI_Task1_TR_RVT_40.txt +167 -0
  88. data/test/fixtures/physionoise_regressors/EPI__fMRI_Task1_TR_card_spline_40.txt +167 -0
  89. data/test/fixtures/physionoise_regressors/EPI__fMRI_Task1_TR_resp_spline_40.txt +167 -0
  90. data/test/fixtures/physionoise_regressors/EPI__fMRI_Task1_card_spline_40.txt +13360 -0
  91. data/test/fixtures/physionoise_regressors/EPI__fMRI_Task1_resp_spline_40.txt +9106 -0
  92. data/test/fixtures/physionoise_regressors/EPI__fMRI_Task1_resp_spline_downsampled_40.txt +9106 -0
  93. data/test/fixtures/ruport_summary.yml +123 -0
  94. data/test/fixtures/valid_scans.yaml +35 -0
  95. data/test/helper.rb +10 -0
  96. data/test/test_dynamic_method_inclusion.rb +10 -0
  97. data/test/test_includes.rb +11 -0
  98. data/test/test_integrative_johnson.merit220.visit1.rb +31 -0
  99. data/test/test_preproc.rb +11 -0
  100. data/test/test_recon.rb +11 -0
  101. data/test/test_rpipe.rb +19 -0
  102. data/vendor/output_catcher.rb +93 -0
  103. data/vendor/trollop.rb +781 -0
  104. metadata +260 -0
data/rpipe.gemspec ADDED
@@ -0,0 +1,177 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{rpipe}
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Kristopher Kosmatka", "Erik Kastman"]
12
+ s.date = %q{2010-07-15}
13
+ s.description = %q{Neuroimaging preprocessing the Ruby way}
14
+ s.email = %q{kjkosmatka@gmail.com}
15
+ s.executables = ["rpipe", "swallow_batch_run.rb", "create_driver.rb"]
16
+ s.extra_rdoc_files = [
17
+ "LICENSE",
18
+ "README",
19
+ "README.rdoc"
20
+ ]
21
+ s.files = [
22
+ ".document",
23
+ ".gitignore",
24
+ "LICENSE",
25
+ "README",
26
+ "README.rdoc",
27
+ "Rakefile",
28
+ "VERSION",
29
+ "bin/create_driver.rb",
30
+ "bin/rpipe",
31
+ "bin/swallow_batch_run.rb",
32
+ "lib/core_additions.rb",
33
+ "lib/custom_methods/JohnsonMerit220Visit1Preproc.m",
34
+ "lib/custom_methods/JohnsonMerit220Visit1Preproc.rb",
35
+ "lib/custom_methods/JohnsonMerit220Visit1Preproc_job.m",
36
+ "lib/custom_methods/JohnsonMerit220Visit1Stats.m",
37
+ "lib/custom_methods/JohnsonMerit220Visit1Stats.rb",
38
+ "lib/custom_methods/JohnsonMerit220Visit1Stats_job.m",
39
+ "lib/custom_methods/JohnsonTbiLongitudinalSnodPreproc.m",
40
+ "lib/custom_methods/JohnsonTbiLongitudinalSnodPreproc.rb",
41
+ "lib/custom_methods/JohnsonTbiLongitudinalSnodPreproc_job.m",
42
+ "lib/custom_methods/JohnsonTbiLongitudinalSnodStats.m",
43
+ "lib/custom_methods/JohnsonTbiLongitudinalSnodStats.rb",
44
+ "lib/custom_methods/JohnsonTbiLongitudinalSnodStats_job.m",
45
+ "lib/custom_methods/ReconWithHello.rb",
46
+ "lib/default_logger.rb",
47
+ "lib/default_methods/default_preproc.rb",
48
+ "lib/default_methods/default_recon.rb",
49
+ "lib/default_methods/default_stats.rb",
50
+ "lib/default_methods/recon/physionoise_helper.rb",
51
+ "lib/default_methods/recon/raw_sequence.rb",
52
+ "lib/generators/job_generator.rb",
53
+ "lib/generators/preproc_job_generator.rb",
54
+ "lib/generators/recon_job_generator.rb",
55
+ "lib/generators/stats_job_generator.rb",
56
+ "lib/generators/workflow_generator.rb",
57
+ "lib/global_additions.rb",
58
+ "lib/logfile.rb",
59
+ "lib/matlab_helpers/CreateFunctionalVolumeStruct.m",
60
+ "lib/matlab_helpers/import_csv.m",
61
+ "lib/matlab_helpers/matlab_queue.rb",
62
+ "lib/matlab_helpers/prepare_onsets_xls.m",
63
+ "lib/rpipe.rb",
64
+ "rpipe.gemspec",
65
+ "spec/generators/preproc_job_generator_spec.rb",
66
+ "spec/generators/recon_job_generator_spec.rb",
67
+ "spec/generators/stats_job_generator_spec.rb",
68
+ "spec/generators/workflow_generator_spec.rb",
69
+ "spec/helper_spec.rb",
70
+ "spec/integration/johnson.merit220.visit1_spec.rb",
71
+ "spec/integration/johnson.tbi.longitudinal.snod_spec.rb",
72
+ "spec/logfile_spec.rb",
73
+ "spec/matlab_queue_spec.rb",
74
+ "spec/merit220_stats_spec.rb",
75
+ "spec/physio_spec.rb",
76
+ "test/drivers/merit220_workflow_sample.yml",
77
+ "test/drivers/mrt00000.yml",
78
+ "test/drivers/mrt00015.yml",
79
+ "test/drivers/mrt00015_hello.yml",
80
+ "test/drivers/mrt00015_withphys.yml",
81
+ "test/drivers/tbi000.yml",
82
+ "test/drivers/tbi000_separatevisits.yml",
83
+ "test/drivers/tmp.yml",
84
+ "test/fixtures/faces3_recognitionA.mat",
85
+ "test/fixtures/faces3_recognitionA.txt",
86
+ "test/fixtures/faces3_recognitionA_equal.csv",
87
+ "test/fixtures/faces3_recognitionA_unequal.csv",
88
+ "test/fixtures/faces3_recognitionB_incmisses.txt",
89
+ "test/fixtures/physionoise_regressors/EPI__fMRI_Task1_CPd3R_40.txt",
90
+ "test/fixtures/physionoise_regressors/EPI__fMRI_Task1_CPd3_40.txt",
91
+ "test/fixtures/physionoise_regressors/EPI__fMRI_Task1_CPttl_40.txt",
92
+ "test/fixtures/physionoise_regressors/EPI__fMRI_Task1_CRTd3R_40.txt",
93
+ "test/fixtures/physionoise_regressors/EPI__fMRI_Task1_CRTd3_40.txt",
94
+ "test/fixtures/physionoise_regressors/EPI__fMRI_Task1_CRTttl_40.txt",
95
+ "test/fixtures/physionoise_regressors/EPI__fMRI_Task1_HalfTR_CRTd3R_40.txt",
96
+ "test/fixtures/physionoise_regressors/EPI__fMRI_Task1_HalfTR_CRTd3_40.txt",
97
+ "test/fixtures/physionoise_regressors/EPI__fMRI_Task1_HalfTR_CRTttl_40.txt",
98
+ "test/fixtures/physionoise_regressors/EPI__fMRI_Task1_HalfTR_RRT_40.txt",
99
+ "test/fixtures/physionoise_regressors/EPI__fMRI_Task1_HalfTR_RVT_40.txt",
100
+ "test/fixtures/physionoise_regressors/EPI__fMRI_Task1_HalfTR_card_spline_40.txt",
101
+ "test/fixtures/physionoise_regressors/EPI__fMRI_Task1_HalfTR_resp_spline_40.txt",
102
+ "test/fixtures/physionoise_regressors/EPI__fMRI_Task1_RRT_40.txt",
103
+ "test/fixtures/physionoise_regressors/EPI__fMRI_Task1_RVT_40.txt",
104
+ "test/fixtures/physionoise_regressors/EPI__fMRI_Task1_TR_CRTd3R_40.txt",
105
+ "test/fixtures/physionoise_regressors/EPI__fMRI_Task1_TR_CRTd3_40.txt",
106
+ "test/fixtures/physionoise_regressors/EPI__fMRI_Task1_TR_CRTttl_40.txt",
107
+ "test/fixtures/physionoise_regressors/EPI__fMRI_Task1_TR_RRT_40.txt",
108
+ "test/fixtures/physionoise_regressors/EPI__fMRI_Task1_TR_RVT_40.txt",
109
+ "test/fixtures/physionoise_regressors/EPI__fMRI_Task1_TR_card_spline_40.txt",
110
+ "test/fixtures/physionoise_regressors/EPI__fMRI_Task1_TR_resp_spline_40.txt",
111
+ "test/fixtures/physionoise_regressors/EPI__fMRI_Task1_card_spline_40.txt",
112
+ "test/fixtures/physionoise_regressors/EPI__fMRI_Task1_resp_spline_40.txt",
113
+ "test/fixtures/physionoise_regressors/EPI__fMRI_Task1_resp_spline_downsampled_40.txt",
114
+ "test/fixtures/ruport_summary.yml",
115
+ "test/fixtures/valid_scans.yaml",
116
+ "test/helper.rb",
117
+ "test/test_dynamic_method_inclusion.rb",
118
+ "test/test_includes.rb",
119
+ "test/test_integrative_johnson.merit220.visit1.rb",
120
+ "test/test_preproc.rb",
121
+ "test/test_recon.rb",
122
+ "test/test_rpipe.rb",
123
+ "vendor/output_catcher.rb",
124
+ "vendor/trollop.rb"
125
+ ]
126
+ s.homepage = %q{http://github.com/brainmap/rpipe}
127
+ s.rdoc_options = ["--charset=UTF-8"]
128
+ s.require_paths = ["lib"]
129
+ s.rubygems_version = %q{1.3.7}
130
+ s.summary = %q{Neuroimaging preprocessing the Ruby way}
131
+ s.test_files = [
132
+ "spec/generators/preproc_job_generator_spec.rb",
133
+ "spec/generators/stats_job_generator_spec.rb",
134
+ "spec/generators/recon_job_generator_spec.rb",
135
+ "spec/generators/workflow_generator_spec.rb",
136
+ "spec/matlab_queue_spec.rb",
137
+ "spec/logfile_spec.rb",
138
+ "spec/physio_spec.rb",
139
+ "spec/integration/johnson.merit220.visit1_spec.rb",
140
+ "spec/integration/johnson.tbi.longitudinal.snod_spec.rb",
141
+ "spec/merit220_stats_spec.rb",
142
+ "spec/helper_spec.rb",
143
+ "test/helper.rb",
144
+ "test/test_dynamic_method_inclusion.rb",
145
+ "test/test_includes.rb",
146
+ "test/test_integrative_johnson.merit220.visit1.rb",
147
+ "test/test_preproc.rb",
148
+ "test/test_recon.rb",
149
+ "test/test_rpipe.rb"
150
+ ]
151
+
152
+ if s.respond_to? :specification_version then
153
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
154
+ s.specification_version = 3
155
+
156
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
157
+ s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
158
+ s.add_runtime_dependency(%q<metamri>, [">= 0"])
159
+ s.add_runtime_dependency(%q<log4r>, [">= 0"])
160
+ s.add_runtime_dependency(%q<POpen4>, [">= 0"])
161
+ s.add_runtime_dependency(%q<ruport>, [">= 0"])
162
+ else
163
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
164
+ s.add_dependency(%q<metamri>, [">= 0"])
165
+ s.add_dependency(%q<log4r>, [">= 0"])
166
+ s.add_dependency(%q<POpen4>, [">= 0"])
167
+ s.add_dependency(%q<ruport>, [">= 0"])
168
+ end
169
+ else
170
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
171
+ s.add_dependency(%q<metamri>, [">= 0"])
172
+ s.add_dependency(%q<log4r>, [">= 0"])
173
+ s.add_dependency(%q<POpen4>, [">= 0"])
174
+ s.add_dependency(%q<ruport>, [">= 0"])
175
+ end
176
+ end
177
+
@@ -0,0 +1,27 @@
1
+ require 'helper_spec'
2
+ require 'generators/preproc_job_generator'
3
+
4
+ describe "PreprocJobGenerator creates a Preproc Job Driver Spec" do
5
+ before(:all) do
6
+ @scans = YAML.load_file(File.join(File.dirname(__FILE__), '..', 'fixtures', 'valid_scans.yaml'))
7
+ @valid_preproc_job_spec = {"step"=>"preprocess", "bold_reps"=>[164, 164, 164]}
8
+ end
9
+
10
+ it "should create a valid job spec with no custom method" do
11
+ preproc_job_spec = PreprocJobGenerator.new({'scans' => @scans}).build
12
+ preproc_job_spec.should == @valid_preproc_job_spec
13
+ end
14
+
15
+ it "should create a valid job spec with a custom method defined" do
16
+ valid_preproc_job_spec = @valid_preproc_job_spec.dup
17
+ valid_preproc_job_spec['method'] = 'Merit220Preprocess'
18
+ preproc_job_spec = PreprocJobGenerator.new({'method' => 'Merit220Preprocess', 'scans' => @scans}).build
19
+ preproc_job_spec.should == valid_preproc_job_spec
20
+ end
21
+
22
+
23
+ it "should raise a DriverConfigError if scans are not specified." do
24
+ lambda { PreprocJobGenerator.new({}).build }.should raise_error DriverConfigError
25
+ end
26
+
27
+ end
@@ -0,0 +1,33 @@
1
+ require 'helper_spec'
2
+ require 'generators/recon_job_generator'
3
+
4
+ describe "Recon Job Generator creates a Recon Job Driver Spec" do
5
+ before(:all) do
6
+ @rawdir = File.join($MRI_DATA, 'johnson.merit220.visit1', 'mrt00000', 'dicoms')
7
+ @scans = YAML.load_file(File.join(File.dirname(__FILE__), '..', 'fixtures', 'valid_scans.yaml'))
8
+
9
+ @valid_recon_job_spec = {
10
+ "step"=>"reconstruct",
11
+ "scans"=> @scans
12
+ }
13
+ end
14
+
15
+ it "should create a valid job spec" do
16
+ recon_job_spec = ReconJobGenerator.new({'rawdir' => @rawdir}).build
17
+ recon_job_spec.should == @valid_recon_job_spec
18
+ end
19
+
20
+ it "should raise an IOError if the raw dir isn't found." do
21
+ lambda { ReconJobGenerator.new({'rawdir' => '/bad/path/to/raw/dir'}).build }.should raise_error IOError
22
+ end
23
+
24
+ it "should raise a DriverConfigError if the raw dir isn't specified." do
25
+ lambda { ReconJobGenerator.new({}).build }.should raise_error DriverConfigError
26
+ end
27
+
28
+ after(:all) do
29
+ # FileUtils.rm_r([@valid_workflow_spec['origdir'], @valid_workflow_spec['procdir'], @valid_workflow_spec['statsdir']])
30
+ end
31
+
32
+
33
+ end
@@ -0,0 +1,50 @@
1
+ require 'helper_spec'
2
+ require 'generators/stats_job_generator'
3
+
4
+ describe "StatsJobGenerator creates a Stats Job Driver Spec" do
5
+ before(:all) do
6
+ @subid = 'mrt00000'
7
+ @scans = YAML.load_file(File.join(File.dirname(__FILE__), '..', 'fixtures', 'valid_scans.yaml'))
8
+ rootdir = Pathname.new(File.join(File.dirname(__FILE__), '..', '..')).realpath.to_s
9
+ @valid_stats_job_spec = {
10
+ "step"=>"stats",
11
+ "responses"=> {
12
+ "logfiles" => ["mrt00000_abc_01012010_faces3_recognitionB.txt", "mrt00000_abc_01012010_faces3_recognitionA.txt"],
13
+ "directory"=> File.join($MRI_DATA, 'responses')
14
+ },
15
+ "conditions"=> ["new_correct", "new_incorrect", "old_correct", "old_incorrect"],
16
+ "regressorsfiles"=> ["rp_amrt00000_EPI-fMRI-Task1.txt", "rp_amrt00000_EPI-fMRI-Task2.txt"],
17
+ "bold_reps"=>[164, 164]
18
+ }
19
+
20
+ @valid_options = {
21
+ 'conditions' => ['new_correct', 'new_incorrect', 'old_correct', 'old_incorrect'],
22
+ 'subid' => @subid,
23
+ 'responses_dir' => File.join($MRI_DATA, 'responses'),
24
+ 'scans' => @scans
25
+ }
26
+ end
27
+
28
+ it "should create a valid job spec with no custom method" do
29
+ stats_job_spec = StatsJobGenerator.new(@valid_options).build
30
+ stats_job_spec.should == @valid_stats_job_spec
31
+ end
32
+
33
+ it "should create a valid job spec with a custom method defined" do
34
+ valid_stats_job_spec = @valid_stats_job_spec.dup
35
+ valid_stats_job_spec['method'] = 'Merit220Preprocess'
36
+ stats_job_spec = StatsJobGenerator.new(@valid_options.merge({'method' => 'Merit220Preprocess'})).build
37
+ stats_job_spec.should == valid_stats_job_spec
38
+ end
39
+
40
+
41
+ it "should raise a DriverConfigError if required keys are not specified." do
42
+ missing_options = ['subid', 'scans', 'conditions'].collect do |key|
43
+ @valid_options.dup.reject {|k,v| key == k }
44
+ end
45
+ missing_options.each do |options|
46
+ lambda { StatsJobGenerator.new(options).build }.should raise_error DriverConfigError
47
+ end
48
+ end
49
+
50
+ end
@@ -0,0 +1,97 @@
1
+ require 'helper_spec'
2
+ require 'generators/workflow_generator'
3
+
4
+ describe "Workflow Generator" do
5
+ before(:each) do
6
+ @fixtures_dir = File.join File.dirname(__FILE__), '..', 'fixtures'
7
+ @drivers_dir = File.join File.dirname(__FILE__), '..', 'drivers'
8
+ @workflow_driver = YAML.load_file(File.join @drivers_dir, 'merit220_workflow_sample.yml')
9
+ @rawdir = File.join $MRI_DATA, 'johnson.merit220.visit1', 'mrt00000', 'dicoms'
10
+ @scans = YAML.load_file(File.join @fixtures_dir, 'valid_scans.yaml')
11
+ rootdir = Pathname.new(File.join(File.dirname(__FILE__), '..', '..')).realpath.to_s
12
+ @valid_recon_job_spec = {"step"=>"reconstruct", "scans"=> @scans}
13
+ @valid_preproc_job_spec = {"step"=>"preprocess", "bold_reps"=>[164, 164, 164], "method" => "JohnsonMerit220Visit1Preproc"}
14
+ @valid_stats_job_spec = {
15
+ "step"=>"stats",
16
+ "responses"=> {
17
+ "logfiles" => ["mrt00000_abc_01012010_faces3_recognitionB.txt", "mrt00000_abc_01012010_faces3_recognitionA.txt"],
18
+ "directory"=> File.join($MRI_DATA, 'responses')
19
+ },
20
+ "conditions"=> ["new_correct", "new_incorrect", "old_correct", "old_incorrect"],
21
+ "regressorsfiles"=> ["rp_amrt00000_EPI-fMRI-Task1.txt", "rp_amrt00000_EPI-fMRI-Task2.txt"],
22
+ "bold_reps"=>[164, 164],
23
+ "method" => "Merit220Stats"
24
+ }
25
+
26
+
27
+ @valid_job_params = [@valid_recon_job_spec, @valid_preproc_job_spec, @valid_stats_job_spec]
28
+
29
+ @origdir = Dir.mktmpdir('orig_')
30
+ @procdir = Dir.mktmpdir('proc_')
31
+ @statsdir = Dir.mktmpdir('stats_')
32
+
33
+ @valid_workflow_spec = {
34
+ "study_procedure" => "johnson.merit220.visit1",
35
+ "subid" => "mrt00000",
36
+ "rawdir" => @rawdir,
37
+ "origdir" => @origdir,
38
+ "procdir" => @procdir,
39
+ "statsdir" => @statsdir,
40
+ "collision" => "destroy",
41
+ "jobs" => @valid_job_params
42
+ }
43
+
44
+ @valid_workflow_options = {
45
+ 'responses_dir' => File.join($MRI_DATA, 'responses')
46
+ }.merge @workflow_driver
47
+ # @valid_pipe = RPipe.new(@valid_workflow_spec)
48
+
49
+ @valid_directory_format = "/Data/vtrak1/preprocessed/visits/johnson.merit220.visit1/<subid>/fmri/orig"
50
+ @valid_multiple_substitution_directory_format = "/Data/vtrak1/preprocessed/visits/<study_procedure>/<subid>/fmri/orig"
51
+ end
52
+
53
+ it "should be valid when assigned known directories without study procedure." do
54
+ options = @valid_workflow_options.merge(
55
+ {'origdir' => @origdir, 'procdir' => @procdir, 'statsdir' => @statsdir})
56
+ options.delete('study_procedure')
57
+ options
58
+
59
+ pp workflow = WorkflowGenerator.new(@rawdir, options).build
60
+ workflow.should == @valid_workflow_spec
61
+ end
62
+
63
+ it "should parse directory format with one substitution" do
64
+ workflow = WorkflowGenerator.new(@rawdir, @valid_workflow_options)
65
+ dir = workflow.parse_directory_format(@valid_directory_format)
66
+ dir.should == "/Data/vtrak1/preprocessed/visits/johnson.merit220.visit1/#{@valid_workflow_spec['subid']}/fmri/orig"
67
+ end
68
+
69
+ it "should parse directory format with multiple substitutions" do
70
+ workflow = WorkflowGenerator.new(@rawdir, @valid_workflow_options)
71
+ dir = workflow.parse_directory_format(@valid_multiple_substitution_directory_format)
72
+ dir.should == "/Data/vtrak1/preprocessed/visits/#{@valid_workflow_spec['study_procedure']}/#{@valid_workflow_spec['subid']}/fmri/orig"
73
+ end
74
+
75
+ it "should parse directory format when directories are not explicitly given" do
76
+ pp options = @valid_workflow_options.dup.delete_if{|key, val| %w{origdir procdir statsdir}.include? key }
77
+ workflow = WorkflowGenerator.new(@rawdir, options)
78
+ dir = workflow.parse_directory_format(@valid_directory_format)
79
+ dir.should == "/Data/vtrak1/preprocessed/visits/#{@valid_workflow_spec['study_procedure']}/#{@valid_workflow_spec['subid']}/fmri/orig"
80
+ end
81
+
82
+ it "should guess a properly formed study procedure directory" do
83
+ workflow = WorkflowGenerator.new(@rawdir, @valid_workflow_options)
84
+ workflow.guess_study_procedure_from(@rawdir).should == 'johnson.merit220.visit1'
85
+ end
86
+
87
+ it "should raise a ScriptError if study procedure directory cannot be guessed" do
88
+ workflow = WorkflowGenerator.new(@rawdir, @valid_workflow_options)
89
+ lambda {workflow.guess_study_procedure_from('/bad/study/directory')}.should raise_error ScriptError, /Could not guess/
90
+ end
91
+
92
+ after(:each) do
93
+ FileUtils.rm_r([@valid_workflow_spec['origdir'], @valid_workflow_spec['procdir'], @valid_workflow_spec['statsdir']])
94
+ end
95
+
96
+
97
+ end
@@ -0,0 +1,40 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems' unless ENV['NO_RUBYGEMS']
5
+ gem 'rspec'
6
+ require 'spec'
7
+ end
8
+
9
+ require 'tmpdir'
10
+ require 'fileutils'
11
+ require 'yaml'
12
+ require 'pp'
13
+ require 'rubygems'
14
+
15
+ require 'global_additions'
16
+ require 'core_additions'
17
+
18
+ $MRI_DATA = ENV['MRI_DATA'] || '/Data/vtrak1/raw/test/fixtures/rpipe'
19
+
20
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
21
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__)))
22
+ $LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'custom_methods')))
23
+ $LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'matlab_helpers')))
24
+
25
+
26
+
27
+ #### Add Directory Comparisons to Dir ####
28
+ class Dir
29
+ def self.compare_directories(dir1, dir2)
30
+ d1 = Dir.entries(dir1).sort
31
+ d2 = Dir.entries(dir2).sort
32
+
33
+ d1.should == d2
34
+ d1.each_with_index do |entry, i|
35
+ next if entry.to_s =~ /\.*/
36
+ File.compare(entry, d2[i]).should be_true
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,47 @@
1
+ require 'helper_spec'
2
+ require 'rpipe'
3
+
4
+ describe "Integration Processing for Johnson.Merit220" do
5
+ before(:all) do
6
+ @driver_file = File.join(File.dirname(__FILE__), '..', 'drivers', 'mrt00000.yml')
7
+ @driver = YAML.load_file(@driver_file)
8
+ @driver['rawdir'] = File.join($MRI_DATA, 'johnson.merit220.visit1', 'mrt00000', 'dicoms')
9
+ @driver['origdir'] = Dir.mktmpdir('orig_')
10
+ @driver['procdir'] = Dir.mktmpdir('proc_')
11
+ @driver['statsdir'] = Dir.mktmpdir('stats_')
12
+ @driver['jobs'][2]['responses']['directory'] = File.join($MRI_DATA, 'responses')
13
+ @valid_responses_options = @driver['jobs'][2]['responses']
14
+ @pipe = RPipe.new(@driver)
15
+ @job = @pipe.stats_jobs.first
16
+
17
+ @completed_orig_directory = File.join($MRI_DATA, 'integration', 'mrt00000_orig')
18
+ @completed_proc_directory = File.join($MRI_DATA, 'integration', 'mrt00000_proc')
19
+ @completed_stats_directory = File.join($MRI_DATA, 'integration', 'mrt00000_stats')
20
+
21
+ end
22
+
23
+ it "should reconstruct raw data" do
24
+ pipe = RPipe.new(@driver)
25
+ p = pipe.recon_jobs.first
26
+ p.perform
27
+ @origdir = @driver['origdir'] if Dir.compare_directories(@driver['origdir'], @completed_orig_directory)
28
+ end
29
+
30
+ it "should preprocess raw data" do
31
+ @driver['origdir'] = @origdir || Pathname.new(@completed_orig_directory).recursive_local_copy
32
+ pipe = RPipe.new(@driver)
33
+ p = pipe.preproc_jobs.first
34
+ p.perform
35
+ @procdir = @driver['procdir'] if Dir.compare_directories(@driver['procdir'], @completed_proc_directory)
36
+ end
37
+
38
+ it "should run stats on processed data" do
39
+ @driver['procdir'] = @procdir || @completed_proc_directory
40
+ pipe = RPipe.new(@driver)
41
+ s = pipe.stats_jobs.first
42
+ s.perform
43
+ @statsdir = @driver['statsdir'] if Dir.compare_directories(@driver['statsdir'], @completed_stats_directory)
44
+ end
45
+
46
+ end
47
+
@@ -0,0 +1,48 @@
1
+ require 'helper_spec'
2
+ require 'rpipe'
3
+
4
+ describe "Integration Processing for Johnson.Tbi.Longitudinal.Snod" do
5
+ before(:all) do
6
+ @driver_file = File.join(File.dirname(__FILE__), '..', 'drivers', 'tbi000.yml')
7
+
8
+ @pipe = RPipe.new(@driver_file)
9
+ @driver = @pipe.workflow_spec
10
+
11
+ @completed_orig_directory = File.join($MRI_DATA, 'integration', 'tbi000_orig')
12
+ @completed_proc_directory = File.join($MRI_DATA, 'integration', 'tbi000_proc')
13
+ @completed_stats_directory = File.join($MRI_DATA, 'integration', 'tbi000_stats')
14
+
15
+ end
16
+
17
+ it "should reconstruct raw data" do
18
+ pipe = RPipe.new(@driver)
19
+
20
+ # pipe.recon_jobs.first.perform
21
+ pipe.recon_jobs.each do |recon_job|
22
+ recon_job.perform
23
+ end
24
+
25
+ # Use instance variables to pass on local directories to subsequent tests if this one was successful.
26
+ @origdir = @driver['origdir'] if Dir.compare_directories(@driver['origdir'], @completed_orig_directory)
27
+ end
28
+
29
+ it "should preprocess reconstructed data" do
30
+ # Realignment alters the headers of images during Estimate, so you must
31
+ # use a local copy that hasn't been run before for correct results.
32
+ @driver['origdir'] = @origdir || Pathname.new(@completed_orig_directory).recursive_local_copy
33
+ pipe = RPipe.new(@driver)
34
+ p = pipe.preproc_jobs.first
35
+ p.perform
36
+ @procdir = @driver['procdir'] if Dir.compare_directories(@driver['procdir'], @completed_proc_directory)
37
+ end
38
+
39
+ it "should run stats on processed data" do
40
+ @driver['procdir'] = @procdir || @completed_proc_directory
41
+ pipe = RPipe.new(@driver)
42
+ s = pipe.stats_jobs.first
43
+ s.perform
44
+ @statsdir = @driver['statsdir'] if Dir.compare_directories(File.join(@driver['statsdir'], 'v1'), @completed_stats_directory)
45
+ end
46
+
47
+ end
48
+
@@ -0,0 +1,96 @@
1
+ require 'helper_spec'
2
+ require 'logfile'
3
+ require 'pp'
4
+ require 'yaml'
5
+
6
+ describe "Test Logfile Helper" do
7
+ before(:all) do
8
+ @fixture_prefix = 'faces3_recognitionA'
9
+ @fixture_prefix_combined = 'faces3_recognitionB_incmisses'
10
+ @temp_prefix = 'temp_faces3_recog'
11
+
12
+ @textfile = File.join(File.dirname(__FILE__), 'fixtures', @fixture_prefix + '.txt')
13
+ @textfile_combined = File.join(File.dirname(__FILE__), 'fixtures', @fixture_prefix_combined + '.txt')
14
+ @csvfile_equal = File.join(File.dirname(__FILE__), 'fixtures', @fixture_prefix + '_equal.csv')
15
+ @csvfile_unequal = File.join(File.dirname(__FILE__), 'fixtures', @fixture_prefix + '_unequal.csv')
16
+ @matfile = File.join(File.dirname(__FILE__), 'fixtures', @fixture_prefix + '.mat')
17
+
18
+ @equal_length_conditions = [:new, :old]
19
+ @unequal_length_conditions = [:new_correct, :new_incorrect, :old_correct, :old_incorrect]
20
+ @collapseable_conditions = [:new_correct, :new_incorrect, :new_misses, :old_correct, :old_incorrect, :old_misses]
21
+ @combined_conditions = [:new_correct, :new_incorrect, :old_correct, :old_incorrect, {:misses => [:new_misses, :old_misses]}]
22
+
23
+ @ruport_summary = YAML.load_file(File.join(File.dirname(__FILE__), 'fixtures', 'ruport_summary.yml'))
24
+ @correct_combined_vectors = {:old_correct=>[8.99945, 13.0001, 18.99695, 22.4986, 34.5006, 49.99595, 53.9966, 59.50275, 88.4972, 91.4998, 103.0028, 120.1117, 137.886, 141.88665, 147.41775], :old_incorrect=>[5.4978, 27.49735, 62.497, 72.50285, 105.99705], :misses=>[116.55185, 123.11425, 131.36515, 135.3575], :new_correct=>[0.0, 2.99425, 15.9938, 25.50115, 30.49995, 36.4968, 40.9965, 46.50265, 56.0011, 65.00055, 69.50025, 74.499, 77.5016, 79.99685, 85.50295, 96.9976, 100.9983, 110.5217, 113.02525, 144.9142, 151.91745, 155.91815, 158.4128], :new_incorrect=>[126.10855]}
25
+ end
26
+
27
+ it "should take a text file with vectors of equal length and convert it to a condition csv" do
28
+ log = Logfile.new(@textfile, *@equal_length_conditions)
29
+ puts log.to_csv
30
+ log.write_csv(@temp_prefix + '.csv')
31
+ File.exist?(@temp_prefix + '.csv').should be_true
32
+ end
33
+
34
+ it "should take a text file with vectors of unequal length and convert it to a condition csv" do
35
+ log = Logfile.new(@textfile, *@unequal_length_conditions)
36
+ puts log.to_csv
37
+ log.write_csv(@temp_prefix + '.csv')
38
+ File.exist?(@temp_prefix + '.csv').should be_true
39
+ pp log.vectors.values
40
+ log.vectors.values.transpose.should have_at_least(10).lines
41
+ end
42
+
43
+ it "should combine logfile vectors" do
44
+ log = Logfile.new(@textfile, *@collapseable_conditions)
45
+ log.combine_vectors(:misses, [:new_misses, :old_misses])
46
+ log.write_csv(@temp_prefix + '.csv')
47
+ File.exist?(@temp_prefix + '.csv').should be_true
48
+ pp log.vectors
49
+ log.vectors.values.transpose.should have_at_least(10).lines
50
+ end
51
+
52
+
53
+ it "should take a condition csv with vectors of equal length and convert it to multiple conditions file" do
54
+ log = Logfile.new(@textfile, *@equal_length_conditions)
55
+ log.csv_filename = @csvfile_equal # Use CSV Fixture to test only multiple conditions creation.
56
+ log.write_mat(@temp_prefix)
57
+ File.exist?(@temp_prefix + '.mat').should be_true
58
+ end
59
+
60
+ it "should take a condition csv with vectors of unequal length and convert it to multiple conditions file" do
61
+ log = Logfile.new(@textfile, *@unequal_length_conditions)
62
+ log.csv_filename = @csvfile_unequal
63
+ log.write_mat(@temp_prefix)
64
+ File.exist?(@temp_prefix + '.mat').should be_true
65
+ end
66
+
67
+ it "should sort logfiles based on file creation time" do
68
+ [Logfile.new(@textfile), Logfile.new(@textfile)].sort
69
+ end
70
+
71
+ it "should raise an error if the logfile can't be found" do
72
+ lambda { Logfile.new('bad_path_to_logfile.csv')}.should raise_error(IOError)
73
+ end
74
+
75
+ it "should raise an error if it could not set conditions when they are given" do
76
+ lambda { Logfile.new(@textfile, nil) }.should raise_error(ScriptError, /Could not set conditions/i)
77
+ end
78
+
79
+ it "should summarize a directory of logfiles" do
80
+ summary = Logfile.summarize_directory(File.join(File.dirname(__FILE__), 'fixtures'))
81
+ summary.column_names.should == ["enum", "task", "version", "ctime", "Total Count", " Hits", " Misses", " Hit%", " Correct", " Incorrect", " Accuracy%", " RT min", " RT max", " RT avg", " RT stdev", " old_stimuli", " old_hits", " old_misses", " old_hit_percent", " old_correct_count", " old_incorrect_count", " old_accuracy", " old_rt_min", " old_rt_max", " old_rt_avg", " old_rt_stdev", " old_correct", " old_correct_rt_min", " old_correct_rt_max", " old_correct_rt_avg", " old_correct_rt_stdev", " old_incorrect", " old_incorrect_rt_min", " old_incorrect_rt_max", " old_incorrect_rt_avg", " old_incorrect_rt_stdev", " new_stimuli", " new_hits", " new_misses", " new_hit_percent", " new_correct_count", " new_incorrect_count", " new_accuracy", " new_rt_min", " new_rt_max", " new_rt_avg", " new_rt_stdev", " new_correct", " new_correct_rt_min", " new_correct_rt_max", " new_correct_rt_avg", " new_correct_rt_stdev", " new_incorrect", " new_incorrect_rt_min", " new_incorrect_rt_max", " new_incorrect_rt_avg", " new_incorrect_rt_stdev", " "]
82
+ summary.length.should == 2
83
+ summary.data == @ruport_summary.data
84
+ end
85
+
86
+ it "should extract combined conditions in a hash" do
87
+ log = Logfile.new(@textfile_combined, *@combined_conditions)
88
+ log.conditions.each {|condition| log.condition_vectors[condition.to_s].should == @correct_combined_vectors[condition.to_s] }
89
+ end
90
+
91
+ after(:each) do
92
+ ['.txt', '.csv', '.mat'].each do |ext|
93
+ File.delete(@temp_prefix + ext) if File.exist?(@temp_prefix + ext)
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,40 @@
1
+ require 'helper_spec'
2
+ require 'matlab_queue'
3
+ require 'pp'
4
+
5
+ describe "Test Matlab Queue Operations" do
6
+ before(:each) do
7
+ @q = q = MatlabQueue.new
8
+ end
9
+
10
+ it "should add a command" do
11
+ @q.length.should equal 0
12
+
13
+ @q.commands << "1 + 2"
14
+ @q.length.should equal 1
15
+
16
+ @q.commands << "2 + 3"
17
+ @q.length.should equal 2
18
+
19
+ @q.to_s.should == "1 + 2; 2 + 3"
20
+ end
21
+
22
+ it "should add to the path" do
23
+ @q.paths.length.should equal 0
24
+ @q.paths << File.dirname(__FILE__)
25
+ @q.paths.length.should equal 1
26
+ end
27
+
28
+ it "should generate a good string with paths and commands" do
29
+ @q.paths << File.dirname(__FILE__)
30
+ @q.commands << "1 + 2"
31
+ @q.to_s.should == "addpath(genpath('#{File.dirname(__FILE__)}')); 1 + 2"
32
+ end
33
+
34
+ it "should run matlab successfully." do
35
+ @q.paths << File.dirname(__FILE__)
36
+ @q.commands << "1 + 2"
37
+ @q.run!.should be_true
38
+ @q.success.should be_true
39
+ end
40
+ end