BioDSL 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (197) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/BioDSL.gemspec +64 -0
  4. data/LICENSE +339 -0
  5. data/README.md +205 -0
  6. data/Rakefile +94 -0
  7. data/examples/fastq_to_fasta.rb +8 -0
  8. data/lib/BioDSL/cary.rb +242 -0
  9. data/lib/BioDSL/command.rb +133 -0
  10. data/lib/BioDSL/commands/add_key.rb +110 -0
  11. data/lib/BioDSL/commands/align_seq_mothur.rb +194 -0
  12. data/lib/BioDSL/commands/analyze_residue_distribution.rb +222 -0
  13. data/lib/BioDSL/commands/assemble_pairs.rb +336 -0
  14. data/lib/BioDSL/commands/assemble_seq_idba.rb +230 -0
  15. data/lib/BioDSL/commands/assemble_seq_ray.rb +345 -0
  16. data/lib/BioDSL/commands/assemble_seq_spades.rb +252 -0
  17. data/lib/BioDSL/commands/classify_seq.rb +217 -0
  18. data/lib/BioDSL/commands/classify_seq_mothur.rb +226 -0
  19. data/lib/BioDSL/commands/clip_primer.rb +318 -0
  20. data/lib/BioDSL/commands/cluster_otus.rb +181 -0
  21. data/lib/BioDSL/commands/collapse_otus.rb +170 -0
  22. data/lib/BioDSL/commands/collect_otus.rb +150 -0
  23. data/lib/BioDSL/commands/complement_seq.rb +117 -0
  24. data/lib/BioDSL/commands/count.rb +135 -0
  25. data/lib/BioDSL/commands/count_values.rb +149 -0
  26. data/lib/BioDSL/commands/degap_seq.rb +253 -0
  27. data/lib/BioDSL/commands/dereplicate_seq.rb +168 -0
  28. data/lib/BioDSL/commands/dump.rb +157 -0
  29. data/lib/BioDSL/commands/filter_rrna.rb +239 -0
  30. data/lib/BioDSL/commands/genecall.rb +237 -0
  31. data/lib/BioDSL/commands/grab.rb +535 -0
  32. data/lib/BioDSL/commands/index_taxonomy.rb +226 -0
  33. data/lib/BioDSL/commands/mask_seq.rb +175 -0
  34. data/lib/BioDSL/commands/mean_scores.rb +168 -0
  35. data/lib/BioDSL/commands/merge_pair_seq.rb +175 -0
  36. data/lib/BioDSL/commands/merge_table.rb +225 -0
  37. data/lib/BioDSL/commands/merge_values.rb +113 -0
  38. data/lib/BioDSL/commands/plot_heatmap.rb +233 -0
  39. data/lib/BioDSL/commands/plot_histogram.rb +306 -0
  40. data/lib/BioDSL/commands/plot_matches.rb +282 -0
  41. data/lib/BioDSL/commands/plot_residue_distribution.rb +278 -0
  42. data/lib/BioDSL/commands/plot_scores.rb +285 -0
  43. data/lib/BioDSL/commands/random.rb +153 -0
  44. data/lib/BioDSL/commands/read_fasta.rb +222 -0
  45. data/lib/BioDSL/commands/read_fastq.rb +414 -0
  46. data/lib/BioDSL/commands/read_table.rb +329 -0
  47. data/lib/BioDSL/commands/reverse_seq.rb +113 -0
  48. data/lib/BioDSL/commands/slice_align.rb +400 -0
  49. data/lib/BioDSL/commands/slice_seq.rb +151 -0
  50. data/lib/BioDSL/commands/sort.rb +223 -0
  51. data/lib/BioDSL/commands/split_pair_seq.rb +220 -0
  52. data/lib/BioDSL/commands/split_values.rb +165 -0
  53. data/lib/BioDSL/commands/trim_primer.rb +314 -0
  54. data/lib/BioDSL/commands/trim_seq.rb +192 -0
  55. data/lib/BioDSL/commands/uchime_ref.rb +170 -0
  56. data/lib/BioDSL/commands/uclust.rb +286 -0
  57. data/lib/BioDSL/commands/unique_values.rb +145 -0
  58. data/lib/BioDSL/commands/usearch_global.rb +171 -0
  59. data/lib/BioDSL/commands/usearch_local.rb +171 -0
  60. data/lib/BioDSL/commands/write_fasta.rb +207 -0
  61. data/lib/BioDSL/commands/write_fastq.rb +191 -0
  62. data/lib/BioDSL/commands/write_table.rb +419 -0
  63. data/lib/BioDSL/commands/write_tree.rb +167 -0
  64. data/lib/BioDSL/commands.rb +31 -0
  65. data/lib/BioDSL/config.rb +55 -0
  66. data/lib/BioDSL/csv.rb +307 -0
  67. data/lib/BioDSL/debug.rb +42 -0
  68. data/lib/BioDSL/fasta.rb +133 -0
  69. data/lib/BioDSL/fastq.rb +77 -0
  70. data/lib/BioDSL/filesys.rb +137 -0
  71. data/lib/BioDSL/fork.rb +145 -0
  72. data/lib/BioDSL/hamming.rb +128 -0
  73. data/lib/BioDSL/helpers/aux_helper.rb +44 -0
  74. data/lib/BioDSL/helpers/email_helper.rb +66 -0
  75. data/lib/BioDSL/helpers/history_helper.rb +40 -0
  76. data/lib/BioDSL/helpers/log_helper.rb +55 -0
  77. data/lib/BioDSL/helpers/options_helper.rb +405 -0
  78. data/lib/BioDSL/helpers/status_helper.rb +132 -0
  79. data/lib/BioDSL/helpers.rb +35 -0
  80. data/lib/BioDSL/html_report.rb +200 -0
  81. data/lib/BioDSL/math.rb +55 -0
  82. data/lib/BioDSL/mummer.rb +216 -0
  83. data/lib/BioDSL/pipeline.rb +354 -0
  84. data/lib/BioDSL/seq/ambiguity.rb +66 -0
  85. data/lib/BioDSL/seq/assemble.rb +240 -0
  86. data/lib/BioDSL/seq/backtrack.rb +252 -0
  87. data/lib/BioDSL/seq/digest.rb +99 -0
  88. data/lib/BioDSL/seq/dynamic.rb +263 -0
  89. data/lib/BioDSL/seq/homopolymer.rb +59 -0
  90. data/lib/BioDSL/seq/kmer.rb +293 -0
  91. data/lib/BioDSL/seq/levenshtein.rb +113 -0
  92. data/lib/BioDSL/seq/translate.rb +109 -0
  93. data/lib/BioDSL/seq/trim.rb +188 -0
  94. data/lib/BioDSL/seq.rb +742 -0
  95. data/lib/BioDSL/serializer.rb +98 -0
  96. data/lib/BioDSL/stream.rb +113 -0
  97. data/lib/BioDSL/taxonomy.rb +691 -0
  98. data/lib/BioDSL/test.rb +42 -0
  99. data/lib/BioDSL/tmp_dir.rb +68 -0
  100. data/lib/BioDSL/usearch.rb +301 -0
  101. data/lib/BioDSL/verbose.rb +42 -0
  102. data/lib/BioDSL/version.rb +31 -0
  103. data/lib/BioDSL.rb +81 -0
  104. data/test/BioDSL/commands/test_add_key.rb +105 -0
  105. data/test/BioDSL/commands/test_align_seq_mothur.rb +99 -0
  106. data/test/BioDSL/commands/test_analyze_residue_distribution.rb +134 -0
  107. data/test/BioDSL/commands/test_assemble_pairs.rb +459 -0
  108. data/test/BioDSL/commands/test_assemble_seq_idba.rb +50 -0
  109. data/test/BioDSL/commands/test_assemble_seq_ray.rb +51 -0
  110. data/test/BioDSL/commands/test_assemble_seq_spades.rb +50 -0
  111. data/test/BioDSL/commands/test_classify_seq.rb +50 -0
  112. data/test/BioDSL/commands/test_classify_seq_mothur.rb +59 -0
  113. data/test/BioDSL/commands/test_clip_primer.rb +377 -0
  114. data/test/BioDSL/commands/test_cluster_otus.rb +128 -0
  115. data/test/BioDSL/commands/test_collapse_otus.rb +81 -0
  116. data/test/BioDSL/commands/test_collect_otus.rb +82 -0
  117. data/test/BioDSL/commands/test_complement_seq.rb +78 -0
  118. data/test/BioDSL/commands/test_count.rb +103 -0
  119. data/test/BioDSL/commands/test_count_values.rb +85 -0
  120. data/test/BioDSL/commands/test_degap_seq.rb +96 -0
  121. data/test/BioDSL/commands/test_dereplicate_seq.rb +92 -0
  122. data/test/BioDSL/commands/test_dump.rb +109 -0
  123. data/test/BioDSL/commands/test_filter_rrna.rb +128 -0
  124. data/test/BioDSL/commands/test_genecall.rb +50 -0
  125. data/test/BioDSL/commands/test_grab.rb +398 -0
  126. data/test/BioDSL/commands/test_index_taxonomy.rb +62 -0
  127. data/test/BioDSL/commands/test_mask_seq.rb +98 -0
  128. data/test/BioDSL/commands/test_mean_scores.rb +111 -0
  129. data/test/BioDSL/commands/test_merge_pair_seq.rb +115 -0
  130. data/test/BioDSL/commands/test_merge_table.rb +131 -0
  131. data/test/BioDSL/commands/test_merge_values.rb +83 -0
  132. data/test/BioDSL/commands/test_plot_heatmap.rb +185 -0
  133. data/test/BioDSL/commands/test_plot_histogram.rb +194 -0
  134. data/test/BioDSL/commands/test_plot_matches.rb +157 -0
  135. data/test/BioDSL/commands/test_plot_residue_distribution.rb +309 -0
  136. data/test/BioDSL/commands/test_plot_scores.rb +308 -0
  137. data/test/BioDSL/commands/test_random.rb +88 -0
  138. data/test/BioDSL/commands/test_read_fasta.rb +229 -0
  139. data/test/BioDSL/commands/test_read_fastq.rb +552 -0
  140. data/test/BioDSL/commands/test_read_table.rb +327 -0
  141. data/test/BioDSL/commands/test_reverse_seq.rb +79 -0
  142. data/test/BioDSL/commands/test_slice_align.rb +218 -0
  143. data/test/BioDSL/commands/test_slice_seq.rb +131 -0
  144. data/test/BioDSL/commands/test_sort.rb +128 -0
  145. data/test/BioDSL/commands/test_split_pair_seq.rb +164 -0
  146. data/test/BioDSL/commands/test_split_values.rb +95 -0
  147. data/test/BioDSL/commands/test_trim_primer.rb +329 -0
  148. data/test/BioDSL/commands/test_trim_seq.rb +150 -0
  149. data/test/BioDSL/commands/test_uchime_ref.rb +113 -0
  150. data/test/BioDSL/commands/test_uclust.rb +139 -0
  151. data/test/BioDSL/commands/test_unique_values.rb +98 -0
  152. data/test/BioDSL/commands/test_usearch_global.rb +123 -0
  153. data/test/BioDSL/commands/test_usearch_local.rb +125 -0
  154. data/test/BioDSL/commands/test_write_fasta.rb +159 -0
  155. data/test/BioDSL/commands/test_write_fastq.rb +166 -0
  156. data/test/BioDSL/commands/test_write_table.rb +411 -0
  157. data/test/BioDSL/commands/test_write_tree.rb +122 -0
  158. data/test/BioDSL/helpers/test_options_helper.rb +272 -0
  159. data/test/BioDSL/seq/test_assemble.rb +98 -0
  160. data/test/BioDSL/seq/test_backtrack.rb +176 -0
  161. data/test/BioDSL/seq/test_digest.rb +71 -0
  162. data/test/BioDSL/seq/test_dynamic.rb +133 -0
  163. data/test/BioDSL/seq/test_homopolymer.rb +58 -0
  164. data/test/BioDSL/seq/test_kmer.rb +134 -0
  165. data/test/BioDSL/seq/test_translate.rb +75 -0
  166. data/test/BioDSL/seq/test_trim.rb +101 -0
  167. data/test/BioDSL/test_cary.rb +176 -0
  168. data/test/BioDSL/test_command.rb +45 -0
  169. data/test/BioDSL/test_csv.rb +514 -0
  170. data/test/BioDSL/test_debug.rb +42 -0
  171. data/test/BioDSL/test_fasta.rb +154 -0
  172. data/test/BioDSL/test_fastq.rb +46 -0
  173. data/test/BioDSL/test_filesys.rb +145 -0
  174. data/test/BioDSL/test_fork.rb +85 -0
  175. data/test/BioDSL/test_math.rb +41 -0
  176. data/test/BioDSL/test_mummer.rb +79 -0
  177. data/test/BioDSL/test_pipeline.rb +187 -0
  178. data/test/BioDSL/test_seq.rb +790 -0
  179. data/test/BioDSL/test_serializer.rb +72 -0
  180. data/test/BioDSL/test_stream.rb +55 -0
  181. data/test/BioDSL/test_taxonomy.rb +336 -0
  182. data/test/BioDSL/test_test.rb +42 -0
  183. data/test/BioDSL/test_tmp_dir.rb +58 -0
  184. data/test/BioDSL/test_usearch.rb +33 -0
  185. data/test/BioDSL/test_verbose.rb +42 -0
  186. data/test/helper.rb +82 -0
  187. data/www/command.html.haml +14 -0
  188. data/www/css.html.haml +55 -0
  189. data/www/input_files.html.haml +3 -0
  190. data/www/layout.html.haml +12 -0
  191. data/www/output_files.html.haml +3 -0
  192. data/www/overview.html.haml +15 -0
  193. data/www/pipeline.html.haml +4 -0
  194. data/www/png.html.haml +2 -0
  195. data/www/status.html.haml +9 -0
  196. data/www/time.html.haml +11 -0
  197. metadata +503 -0
@@ -0,0 +1,405 @@
1
+ # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< #
2
+ # #
3
+ # Copyright (C) 2007-2015 Martin Asser Hansen (mail@maasha.dk). #
4
+ # #
5
+ # This program is free software; you can redistribute it and/or #
6
+ # modify it under the terms of the GNU General Public License #
7
+ # as published by the Free Software Foundation; either version 2 #
8
+ # of the License, or (at your option) any later version. #
9
+ # #
10
+ # This program is distributed in the hope that it will be useful, #
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of #
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
13
+ # GNU General Public License for more details. #
14
+ # #
15
+ # You should have received a copy of the GNU General Public License #
16
+ # along with this program; if not, write to the Free Software #
17
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, #
18
+ # USA. #
19
+ # #
20
+ # http://www.gnu.org/copyleft/gpl.html #
21
+ # #
22
+ # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< #
23
+ # #
24
+ # This software is part of BioDSL (www.github.com/maasha/BioDSL). #
25
+ # #
26
+ # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< #
27
+ module BioDSL
28
+ # Module containing methods to check options in various ways.
29
+ module OptionsHelper
30
+ require 'csv'
31
+
32
+ BioDSL::OptionError = Class.new(StandardError)
33
+
34
+ private
35
+
36
+ # Method that fails if options include any non-allowed options.
37
+ #
38
+ # @param options [Hash] The Hash with options to be checked.
39
+ # @param allowed [Symbol, Array] One or more allowed options.
40
+ #
41
+ # @example That raises:
42
+ # options_allowed({foo: 'bar'}, :foobar)
43
+ #
44
+ # @example That passes:
45
+ # options_allowed({foo: 'bar'}, :foo, :one)
46
+ #
47
+ # @raise [BioDSL::OptionError] If non-allowed options located.
48
+ def options_allowed(options, *allowed)
49
+ options.each_key do |option|
50
+ unless allowed.include? option
51
+ fail BioDSL::OptionError, "Disallowed option: #{option}. " \
52
+ "Allowed options: #{allowed.join(', ')}"
53
+ end
54
+ end
55
+ end
56
+
57
+ # Method that raises if options include any non-allowed values.
58
+ #
59
+ # @param options [Hash] The Hash with options to be checked.
60
+ # @param allowed [Symbol, Array] One or more allowed options.
61
+ #
62
+ # @example That raises:
63
+ # options_allowed_values({foo: 'bar'}, foo: 1)
64
+ #
65
+ # @example That passes:
66
+ # options_allowed_values({foo: 'bar'}, foo: ['bar', 'rab'])
67
+ #
68
+ # @raise [BioDSL::OptionError] If non-allowed options located.
69
+ def options_allowed_values(options, allowed)
70
+ allowed.each do |key, values|
71
+ next unless options[key]
72
+
73
+ unless values.include? options[key]
74
+ fail BioDSL::OptionError, 'Disallowed option value: ' \
75
+ "#{options[key]}. Allowed options: #{values.join(', ')}"
76
+ end
77
+ end
78
+ end
79
+
80
+ # Method that raises if options don't include all required options.
81
+ #
82
+ # @param options [Hash] The Hash with options to be checked.
83
+ # @param required [Symbol, Array] One or more required options.
84
+ #
85
+ # @example That raises:
86
+ # options_required({foo: 'bar'}, foo: 1)
87
+ #
88
+ # @example That passes:
89
+ # options_required({foo: 'bar', one: 'two'}, :foo, :one)
90
+ #
91
+ # @raise [BioDSL::OptionError] Unless all required options are given.
92
+ def options_required(options, *required)
93
+ required.each do |option|
94
+ unless options[option]
95
+ fail BioDSL::OptionError, "Required option missing: #{option}. " \
96
+ "Required options: #{required.join(', ')}"
97
+ end
98
+ end
99
+ end
100
+
101
+ # Method that raises if options include multiple required options.
102
+ #
103
+ # @param options [Hash] The Hash with options to be checked.
104
+ # @param unique [Symbol, Array] Options that must be unique.
105
+ #
106
+ # @example That raises:
107
+ # options_required_unique({foo: 'bar', one: 'two'}, :foo, :one)
108
+ #
109
+ # @example That passes:
110
+ # options_required_unique({foo: 'bar', one: 'two'}, :foo)
111
+ #
112
+ # @raise [BioDSL::OptionError] If multiple required options are found.
113
+ def options_required_unique(options, *unique)
114
+ return unless unique.select { |option| options[option] }.size > 1
115
+
116
+ fail BioDSL::OptionError, 'Multiple required uniques options ' \
117
+ "used: #{unique.join(', ')}"
118
+ end
119
+
120
+ # Method that raises if options include non-unique options.
121
+ #
122
+ # @param options [Hash] Hash with options to check.
123
+ # @param unique [Symbol, Array] List of options that must be unique.
124
+ #
125
+ # @example That raises:
126
+ # options_unique({foo: 'bar', one: 1}, :foo, :one)
127
+ #
128
+ # @example That passes:
129
+ # options_unique({foo: 'bar', one: 'two'}, :foo)
130
+ #
131
+ # @example That passes:
132
+ # options_unique({}, :foo)
133
+ #
134
+ # @raise [BioDSL::OptionError] If non-unique options are found.
135
+ def options_unique(options, *unique)
136
+ return unless unique.select { |option| options[option] }.size > 1
137
+
138
+ fail BioDSL::OptionError, 'Multiple uniques options used: ' \
139
+ "#{unique.join(', ')}"
140
+ end
141
+
142
+ # Method that raises if options include lists with duplicate elements.
143
+ #
144
+ # @param options [Hash] Hash with options to check.
145
+ # @param lists [Symbol, Array] Lists whos element to check for duplicates.
146
+ #
147
+ # @example That raises:
148
+ # options_unique_list({foo: [0, 0]}, :foo)
149
+ #
150
+ # @example That passes:
151
+ # options_unique_list({foo: [0, 1]}, :foo)
152
+ #
153
+ # @raise [BioDSL::OptionError] If duplicate elements are found.
154
+ def options_list_unique(options, *lists)
155
+ lists.each do |list|
156
+ if options[list] && options[list].uniq.size != options[list].size
157
+ fail BioDSL::OptionError, 'Duplicate elements found in list ' \
158
+ "#{list}: #{options[list]}"
159
+ end
160
+ end
161
+ end
162
+
163
+ # Method that raises if one option is given without some other.
164
+ # Example: options_tie gzip: :output, bzip2: :output
165
+ #
166
+ # @param options [Hash] Hash with options to check.
167
+ # @param others [Hash] Hash with key/value pairs denoting ties.
168
+ #
169
+ # @example That raises:
170
+ # options_tie({gzip: true}, gzip: :output)
171
+ #
172
+ # @example That passes:
173
+ # options_tie({output: "foo", gzip: true}, gzip: :output)
174
+ #
175
+ # @raise [BioDSL::OptionError] If option found without it's tie.
176
+ def options_tie(options, others)
177
+ others.each do |option, other|
178
+ if options[option] && !options[other]
179
+ fail BioDSL::OptionError, "Tie option: #{other} not in options: " \
180
+ "#{options.keys.join(', ')}"
181
+ end
182
+ end
183
+ end
184
+
185
+ # Method that raises if conflicting options are used.
186
+ # Example: select: :evaluate, reject: :evaluate
187
+ #
188
+ # @param options [Hash] Hash with options to check.
189
+ # @param conflicts [Hash] Hash with conflicting key/value pairs.
190
+ #
191
+ # @example That raises:
192
+ # options_tie({reject: true, select: true}, reject: :select)
193
+ #
194
+ # @example That passes:
195
+ # options_tie({reject: true}, reject: :select)
196
+ #
197
+ # @raise [BioDSL::OptionError] If conflicting options are found.
198
+ def options_conflict(options, conflicts)
199
+ conflicts.each do |option, conflict|
200
+ if options[option] && options[conflict]
201
+ fail BioDSL::OptionError, "Conflicting options: #{option}, " \
202
+ "#{conflict}"
203
+ end
204
+ end
205
+ end
206
+
207
+ # Method that fails if given files don't exist.
208
+ #
209
+ # @param options [Hash]
210
+ # Hash with options to check.
211
+ #
212
+ # @param args [Symbol, Array]
213
+ # Symbol or Array of Symbols which are keys in the option Hash and whos
214
+ # values to check.
215
+ #
216
+ # @example With a given Symbol.
217
+ # options_files_exist(options, :input)
218
+ #
219
+ # @example With a given Array.
220
+ # options_files_exist(options, [:input1, :input2])
221
+ #
222
+ # @raise [BioDSL::OptionError] on non-existing files.
223
+ def options_files_exist(options, *args)
224
+ args.each do |arg|
225
+ next unless options[arg]
226
+ files = (options[arg].is_a? Array) ? options[arg] : [options[arg]]
227
+
228
+ files.each do |file|
229
+ file = glob_check(file, arg) if file.include? '*'
230
+
231
+ unless File.file? File.expand_path(file)
232
+ fail BioDSL::OptionError, "For option #{arg} - no such file: " \
233
+ "#{file}"
234
+ end
235
+ end
236
+ end
237
+ end
238
+
239
+ # Method that fails if files exist unless the force option flag is set.
240
+ #
241
+ # @param options [Hash]
242
+ # Hash with options to check.
243
+ #
244
+ # @param args [Symbol, Array]
245
+ # Symbol or Array of Symbols which are keys in the option Hash and whos
246
+ # values to check.
247
+ #
248
+ # @example That raises
249
+ # options_files_exist_force({file: __FILE__}}, :file)
250
+ #
251
+ # @example That passes
252
+ # options_files_exist_force({file: __FILE__, force: true}, :file)
253
+ #
254
+ # @raise [BioDSL::OptionError]
255
+ # If files exist and the force option flag is not set
256
+ def options_files_exist_force(options, *args)
257
+ args.each do |arg|
258
+ next unless options[arg]
259
+
260
+ files = (options[arg].is_a? Array) ? options[arg] : [options[arg]]
261
+
262
+ files.each do |file|
263
+ if File.file?(file) && !options[:force]
264
+ fail BioDSL::OptionError, "File exist: #{file} - use " \
265
+ "'force: true' to override"
266
+ end
267
+ end
268
+ end
269
+ end
270
+
271
+ # Method that fails if given directories don't exist.
272
+ #
273
+ # @param options [Hash]
274
+ # Hash with options to check.
275
+ #
276
+ # @param args [Symbol, Array]
277
+ # Symbol or Array of Symbols which are keys in the option Hash and whos
278
+ # values to check.
279
+ #
280
+ # @example With a given Symbol.
281
+ # options_dirs_exist(options, :input)
282
+ #
283
+ # @example With a given Array.
284
+ # options_dirs_exist(options, [:input1, :input2])
285
+ #
286
+ # @raise [BioDSL::OptionError] on non-existing directories.
287
+ def options_dirs_exist(options, *args)
288
+ args.each do |arg|
289
+ next unless options[arg]
290
+
291
+ dirs = (options[arg].is_a? Array) ? options[arg] : [options[arg]]
292
+
293
+ dirs.each do |dir|
294
+ unless File.directory? File.expand_path(dir)
295
+ fail BioDSL::OptionError, "For option #{arg} - no such " \
296
+ "directory: #{dir}"
297
+ end
298
+ end
299
+ end
300
+ end
301
+
302
+ # Assert a given expression.
303
+ #
304
+ # @param options [Hash] Hash with options to check.
305
+ #
306
+ # @param expression [String] Expersion to assert.
307
+ #
308
+ # @example That raises:
309
+ # options_assert({min: 0}, ':min > 0')
310
+ #
311
+ # @example That passes:
312
+ # options_assert({{min: 0}, ':min == 0')
313
+ #
314
+ # @raise [BioDSL::OptionError] If assertion fails.
315
+ def options_assert(options, expression)
316
+ options.each do |key, value|
317
+ expression.gsub!(/:#{key}/, value.to_s)
318
+ end
319
+
320
+ return if expression[0] == ':'
321
+ return if eval expression
322
+
323
+ fail BioDSL::OptionError, "Assertion failed: #{expression}"
324
+ end
325
+
326
+ # Expand a given glob expression into lists of paths.
327
+ #
328
+ # @param expr [String] Comma sperated glob expressions.
329
+ #
330
+ # @example
331
+ # options_glob('foo*')
332
+ # # => ['foo.rb', 'foo.txt']
333
+ #
334
+ # @return [Array] List of expanded paths.
335
+ def options_glob(expr)
336
+ paths = []
337
+ list = expr.is_a?(Array) ? expr.join(',') : expr
338
+
339
+ list.split(/, */).each do |glob|
340
+ if glob.include? '*'
341
+ paths += Dir.glob(glob).sort.select { |file| File.file? file }
342
+ else
343
+ paths << glob
344
+ end
345
+ end
346
+
347
+ paths
348
+ end
349
+
350
+ # Load options from rc file and use these unless given or default options
351
+ # are specified. Option precedence: specified > default > rc.
352
+ #
353
+ # @param options [Hash] Hash with options to check.
354
+ # @param command [Symbol] Command for which to load options.
355
+ # @param file [String] Path to file with defaults.
356
+ #
357
+ # @example
358
+ # options = {}
359
+ # options_load_rc(options, :some_option)
360
+ # options == {option1: 'value1', option2: 'value2'}
361
+ def options_load_rc(options, command, file = BioDSL::Config::RC_FILE)
362
+ return unless File.exist? file
363
+
364
+ rc_options = Hash.new { |h, k| h[k] = [] }
365
+ rc_table = ::CSV.read(file, col_sep: "\s").
366
+ select { |row| row.first && row.first.to_sym == command }
367
+
368
+ add_to_rc_options(rc_table, rc_options, options)
369
+ add_to_options(rc_options, options)
370
+ end
371
+
372
+ # Check if a glob expressoin, a string with a *, matches any files and fail
373
+ # if that is not the case.
374
+ #
375
+ # @param glob [String] Glob expression (containing *) to check.
376
+ #
377
+ # @param key [Symbol] Option Hash key whos value is the glob expression.
378
+ #
379
+ # @raise [BioDSL::OptionError] If the glob expression fail to match.
380
+ #
381
+ # @return [String] The first mathing file.
382
+ def glob_check(glob, key)
383
+ first = Dir.glob(glob).select { |f| File.file? f }.first
384
+ fail BioDSL::OptionError, "For option #{key} - glob expression: " \
385
+ "#{glob} didn't match any files" if first.nil?
386
+ first
387
+ end
388
+
389
+ def add_to_options(rc_options, options)
390
+ rc_options.each do |key, value|
391
+ if value.size == 1
392
+ options[key] = value.first
393
+ else
394
+ options[key] = value
395
+ end
396
+ end
397
+ end
398
+
399
+ def add_to_rc_options(rc_table, rc_options, options)
400
+ rc_table.each do |row|
401
+ options.key?(row[1].to_sym) || rc_options[row[1].to_sym] << row[2]
402
+ end
403
+ end
404
+ end
405
+ end
@@ -0,0 +1,132 @@
1
+ # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< #
2
+ # #
3
+ # Copyright (C) 2007-2015 Martin Asser Hansen (mail@maasha.dk). #
4
+ # #
5
+ # This program is free software; you can redistribute it and/or #
6
+ # modify it under the terms of the GNU General Public License #
7
+ # as published by the Free Software Foundation; either version 2 #
8
+ # of the License, or (at your option) any later version. #
9
+ # #
10
+ # This program is distributed in the hope that it will be useful, #
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of #
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
13
+ # GNU General Public License for more details. #
14
+ # #
15
+ # You should have received a copy of the GNU General Public License #
16
+ # along with this program; if not, write to the Free Software #
17
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, #
18
+ # USA. #
19
+ # #
20
+ # http://www.gnu.org/copyleft/gpl.html #
21
+ # #
22
+ # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< #
23
+ # #
24
+ # This software is part of BioDSL (www.github.com/maasha/BioDSL). #
25
+ # #
26
+ # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< #
27
+
28
+ module BioDSL
29
+ # Namespace with methods to record and manipulate cammand status.
30
+ module StatusHelper
31
+ require 'tempfile'
32
+ require 'terminal-table'
33
+
34
+ # Given a list of symbols initialize all as status hash keys with the value
35
+ # 0.
36
+ #
37
+ # @param status [Hash] Status hash.
38
+ # @param args [Array] List of symbols.
39
+ def status_init(status, args)
40
+ args.each { |arg| status[arg] = 0 }
41
+ @status = status
42
+ end
43
+
44
+ # Track the status progress of a running command in a seperate thread and
45
+ # output the status at speficied intervals.
46
+ #
47
+ # @param commands [Array] List of commands whos status should be output.
48
+ # @param block [Proc] Track the command in the given block.
49
+ #
50
+ # @raise [RunTimeError] If no block is given.
51
+ def status_progress(commands, &block)
52
+ fail 'No block given' unless block
53
+
54
+ thread = Thread.new do
55
+ print "\e[H\e[2J" # Console code to clear screen
56
+
57
+ loop do
58
+ progress_print(commands)
59
+
60
+ sleep BioDSL::Config::STATUS_PROGRESS_INTERVAL
61
+ end
62
+ end
63
+
64
+ block.call
65
+
66
+ thread.terminate
67
+
68
+ progress_print(commands)
69
+ end
70
+
71
+ private
72
+
73
+ # Print the progress table to terminal.
74
+ #
75
+ # @param commands [Array] List of commands whos status should be output.
76
+ def progress_print(commands)
77
+ print "\e[1;1H" # Console code to move cursor to 1,1 coordinate.
78
+ puts "Started: #{commands.first.status[:time_start]}"
79
+ puts status_tabulate(commands)
80
+ end
81
+
82
+ # Create status table.
83
+ #
84
+ # @param commands [Array] List of commands whos status should be output.
85
+ #
86
+ # @return [String] Status table.
87
+ def status_tabulate(commands)
88
+ return unless commands.first.status[:records_in]
89
+
90
+ table = Terminal::Table.new
91
+ table.style = {border_x: '', border_y: '', border_i: ''}
92
+ table.rows = status_rows(commands)
93
+
94
+ table.align_column(1, :right)
95
+ table.align_column(2, :right)
96
+
97
+ table.to_s
98
+ end
99
+
100
+ # Compile rows with table data.
101
+ #
102
+ # @param commands [Array] List of commands whos status should be output.
103
+ #
104
+ # @return [Array] List of rows.
105
+ def status_rows(commands)
106
+ rows = [%w(name records_in records_out time_elapsed status)]
107
+
108
+ commands.each do |command|
109
+ update_time(command)
110
+
111
+ row = []
112
+ row << command.name
113
+ row << command.status[:records_in].commify
114
+ row << command.status[:records_out].commify
115
+ row << command.status[:time_elapsed]
116
+ row << command.run_status
117
+ rows << row
118
+ end
119
+
120
+ rows
121
+ end
122
+
123
+ # Update the time_stop and time_elapsed for a given command.
124
+ #
125
+ # @param command [BioDSL::Command] Command object.
126
+ def update_time(command)
127
+ command.status[:time_stop] = Time.now unless command.run_status == 'done'
128
+
129
+ command.calc_time_elapsed
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,35 @@
1
+ # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< #
2
+ # #
3
+ # Copyright (C) 2007-2015 Martin Asser Hansen (mail@maasha.dk). #
4
+ # #
5
+ # This program is free software; you can redistribute it and/or #
6
+ # modify it under the terms of the GNU General Public License #
7
+ # as published by the Free Software Foundation; either version 2 #
8
+ # of the License, or (at your option) any later version. #
9
+ # #
10
+ # This program is distributed in the hope that it will be useful, #
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of #
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
13
+ # GNU General Public License for more details. #
14
+ # #
15
+ # You should have received a copy of the GNU General Public License #
16
+ # along with this program; if not, write to the Free Software #
17
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, #
18
+ # USA. #
19
+ # #
20
+ # http://www.gnu.org/copyleft/gpl.html #
21
+ # #
22
+ # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< #
23
+ # #
24
+ # This software is part of BioDSL (www.github.com/maasha/BioDSL). #
25
+ # #
26
+ # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< #
27
+
28
+ # Namespace for BioDSL.
29
+ module BioDSL
30
+ require 'BioDSL/helpers/history_helper'
31
+ require 'BioDSL/helpers/log_helper'
32
+ require 'BioDSL/helpers/options_helper'
33
+ require 'BioDSL/helpers/status_helper'
34
+ require 'BioDSL/helpers/aux_helper'
35
+ end