rbbt-util 5.2.3 → 5.2.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZjIwN2RhYmRjNDg2MjMzMWNmYWU4NGQ5ZDUyYjcyNGU4MmExMzJhYw==
5
+ data.tar.gz: !binary |-
6
+ NzAyMmUyMjg3ZWRmY2I1N2EwNDk1OGVlNTBmNWUyNmIyNTUxN2QwNg==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ M2M0OTlkODVmMjY1ZWNjZWIzYjhjMTE2M2MyOGNiNWY5YjZiYjNiNDdkMTQx
10
+ MjkyNTk0MWRkZGM4ZjU3OTVjOTQ3ODg3YmNhNjVmZjljZDlmZGU3YTI4YWIw
11
+ MmFkZjcwMTE5OGFlNmI3MjRkZWI0NTQwZDBlZTg3ZTUwMWJhYjY=
12
+ data.tar.gz: !binary |-
13
+ ZTIxNTBhZGQyZjg0ZjNiYjhlZjU3MTQ4M2YzMzgyNWNlZWE4MWMxNDg2OWUw
14
+ MzRlMzQyMzkyZWJiNDM1NjQ3ODljNmUwYjg1ZjJhYzYxOWE3MTZjZjc1ZDM3
15
+ OTI1ZjMzMTNmZDE4Mzc4OTQ3NDJmY2UyYTQzNWRjZDg0MjhlOWI=
data/bin/rbbt CHANGED
@@ -1,8 +1,30 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'rbbt'
4
+ require 'rbbt/util/simpleopt'
4
5
 
5
- $rbbt_command_dir = Rbbt.share.rbbt_commands
6
+ options = SOPT.get("--log* Log level from 0 (debug) 7 (errors):--command_dir* Directory from where to load commands")
7
+
8
+ if options[:log]
9
+ Log.severity = options[:log].to_i
10
+ end
11
+
12
+ if options[:command_dir]
13
+ $rbbt_command_dir = Path.setup(options[:command_dir])
14
+ else
15
+ $rbbt_command_dir = Rbbt.share.rbbt_commands
16
+ end
17
+
18
+ SOPT.synopsys = "rbbt <command> <subcommand> ... -a --arg1 --arg2='value'"
19
+ SOPT.summary = "Ruby bioinformatics toolkit"
20
+ SOPT.description = <<-EOF
21
+ This command controls many aspects of the Rbbt framework, from configuration tasks to running applications.
22
+
23
+ Commands are implemented in separate files under the Rbbt path#{
24
+ } '#{$rbbt_command_dir}'. Known locations are: #{
25
+ ([$rbbt_command_dir] + $rbbt_command_dir.find_all) * ", "
26
+ }. You can place your own commads at #{$rbbt_command_dir.find(:user)}.
27
+ EOF
6
28
 
7
29
  def commands(prev)
8
30
  rbbt_command_dir = $rbbt_command_dir
@@ -35,6 +57,10 @@ while ARGV.any?
35
57
  end
36
58
  end
37
59
 
60
+ puts SOPT.doc
61
+
62
+ puts "## COMMANDS"
63
+ puts
38
64
  puts "Command:"
39
65
  puts
40
66
  puts " #{File.basename($0)} #{prev * " "}"
data/bin/rbbt_monitor.rb CHANGED
@@ -50,6 +50,8 @@ def list_jobs(options)
50
50
  end
51
51
 
52
52
  color = case
53
+ when (not info)
54
+ Log::SEVERITY_COLOR[3]
53
55
  when info[:status] == :error
54
56
  Log::SEVERITY_COLOR[3]
55
57
  when (info[:pid] and not running? info)
@@ -57,6 +59,8 @@ def list_jobs(options)
57
59
  end
58
60
 
59
61
  case
62
+ when (not info)
63
+ print_job file, info, color
60
64
  when (not omit_ok)
61
65
  print_job file, info, color
62
66
  when options[:zombies]
@@ -89,9 +93,9 @@ def clean_jobs(options)
89
93
  case
90
94
  when options[:all]
91
95
  remove_job file
92
- when (options[:zombies] and info[:pid] and not running? info)
96
+ when (options[:errors] and (not info or info[:status] == :error))
93
97
  remove_job file
94
- when (options[:errors] and info[:status] == :error)
98
+ when (options[:zombies] and info[:pid] and not running? info)
95
99
  remove_job file
96
100
  end
97
101
 
data/lib/rbbt/persist.rb CHANGED
@@ -249,11 +249,11 @@ module Persist
249
249
 
250
250
  else
251
251
  if is_persisted?(path, persist_options)
252
- Log.debug "Persist up-to-date: #{ path } - #{persist_options.inspect[0..100]}"
252
+ Log.low "Persist up-to-date: #{ path } - #{persist_options.inspect[0..100]}"
253
253
  return nil if persist_options[:no_load]
254
254
  return load_file(path, type)
255
255
  else
256
- Log.debug "Persist create: #{ path } - #{persist_options.inspect[0..100]}"
256
+ Log.medium "Persist create: #{ path } - #{persist_options.inspect[0..100]}"
257
257
  end
258
258
  begin
259
259
  res = yield
@@ -262,8 +262,8 @@ module Persist
262
262
  end
263
263
  res
264
264
  rescue
265
- Log.high "Error in persist. Erasing '#{ path }'"
266
- FileUtils.rm path if File.exists? path
265
+ Log.high "Error in persist. #{File.exists?(path) ? "Erasing '#{ path }'" : ""}"
266
+ FileUtils.rm path if File.exists? path
267
267
  raise $!
268
268
  end
269
269
  end
@@ -158,7 +158,7 @@ module Persist
158
158
  lock_filename = Persist.persistence_path(path, {:dir => Rbbt.tmp.tsv_open_locks.find})
159
159
  return Misc.lock(lock_filename) do open_tokyocabinet(path, false); end
160
160
  else
161
- Log.debug "TSV persistence creating: #{ path }"
161
+ Log.medium "TSV persistence creating: #{ path }"
162
162
  end
163
163
 
164
164
  FileUtils.rm path if File.exists? path
@@ -48,13 +48,16 @@ module TSV
48
48
  end
49
49
 
50
50
  # Merge two files with the same keys and different fields
51
- def self.merge_different_fields(file1, file2, output, sep = "\t")
51
+ def self.merge_different_fields(file1, file2, output, sep = "\t", monitor = false)
52
52
  case
53
53
  when (String === file1 and not file1 =~ /\n/ and file1.length < 250 and File.exists?(file1))
54
+ size = CMD.cmd("wc -l '#{file1}'").read.to_f if monitor
54
55
  file1 = CMD.cmd("sort -k1,1 -t'#{sep}' #{ file1 } | grep -v '^#{sep}' ", :pipe => true)
55
56
  when (String === file1 or StringIO === file1)
57
+ size = file1.length if monitor
56
58
  file1 = CMD.cmd("sort -k1,1 -t'#{sep}' | grep -v '^#{sep}'", :in => file1, :pipe => true)
57
59
  when TSV === file1
60
+ size = file1.size if monitor
58
61
  file1 = CMD.cmd("sort -k1,1 -t'#{sep}' | grep -v '^#{sep}'", :in => file1.to_s(:sort, true), :pipe => true)
59
62
  end
60
63
 
@@ -88,6 +91,8 @@ module TSV
88
91
  cols2 = parts2.length
89
92
  end
90
93
 
94
+ progress_monitor = Progress::Bar.new(size, 0, 100, "Merging fields") if monitor
95
+
91
96
  key = key1 < key2 ? key1 : key2
92
97
  parts = [""] * (cols1 + cols2)
93
98
  while not (done1 and done2)
@@ -99,6 +104,7 @@ module TSV
99
104
  while key1.nil? and not done1
100
105
  if file1.eof?; done1 = true; else key1, *parts1 = file1.gets.sub("\n",'').split(sep, -1) end
101
106
  end
107
+ progress_monitor.tick if monitor
102
108
  end
103
109
  while (not done2 and key2 == key)
104
110
  parts2.each_with_index do |part, i|
@@ -151,7 +157,7 @@ module TSV
151
157
  end
152
158
 
153
159
  other_filename = other.respond_to?(:filename) ? other.filename : other.inspect
154
- Log.medium("Attaching fields:#{fields.inspect} from #{other_filename}.")
160
+ Log.low("Attaching fields:#{fields.inspect} from #{other_filename}.")
155
161
 
156
162
  case
157
163
  when key_field == other.key_field
@@ -229,7 +229,7 @@ module TSV
229
229
 
230
230
  traversal_ids = path.collect{|p| p.first}
231
231
 
232
- Log.low "Found Traversal: #{traversal_ids * " => "}"
232
+ Log.debug "Found Traversal: #{traversal_ids * " => "}"
233
233
 
234
234
  data_key, data_file = path.shift
235
235
  data_index = if data_key == data_file.key_field
data/lib/rbbt/util/log.rb CHANGED
@@ -25,7 +25,7 @@ module Log
25
25
  # @severity
26
26
  #end
27
27
 
28
- SEVERITY_COLOR = ["0;37m", "0;32m", "0;33m", "0;31m", "1;0m" ].collect{|e| "\033[#{e}"}
28
+ SEVERITY_COLOR = ["0;37m", "0;32m", "0;33m", "0;31m","0;37m", "0;32m", "0;33m"].collect{|e| "\033[#{e}"}
29
29
 
30
30
  def self.log(message, severity = MEDIUM)
31
31
  message ||= ""
@@ -19,6 +19,38 @@ end
19
19
  module Misc
20
20
  class FieldNotFoundError < StandardError;end
21
21
 
22
+ def self.correct_icgc_mutation(pos, ref, mut_str)
23
+ mut = mut_str
24
+ mut = '-' * (mut_str.length - 1) if mut =~/^-[ACGT]/
25
+ [pos, [mut]]
26
+ end
27
+
28
+ def self.correct_vcf_mutation(pos, ref, mut_str)
29
+ muts = mut_str.nil? ? [] : mut_str.split(',')
30
+
31
+ while ref.length >= 1 and muts.reject{|m| m[0] == ref[0]}.empty?
32
+ ref = ref[1..-1]
33
+ pos = pos + 1
34
+ muts = muts.collect{|m| m[1..-1]}
35
+ end
36
+
37
+ muts = muts.collect do |m|
38
+ case
39
+ when ref.empty?
40
+ "+" << m
41
+ when (m.length < ref.length and (m.empty? or ref.index(m)))
42
+ "-" * (ref.length - m.length)
43
+ when (ref.length == 1 and m.length == 1)
44
+ m
45
+ else
46
+ Log.debug "Cannot understand: #{[ref, m]} (#{ muts })"
47
+ '-' * ref.length + m
48
+ end
49
+ end
50
+
51
+ [pos, muts]
52
+ end
53
+
22
54
  def self.pid_exists?(pid)
23
55
  return false if pid.nil?
24
56
  begin
@@ -1,17 +1,178 @@
1
1
  module SOPT
2
+ class << self
3
+ attr_accessor :command, :summary, :synopsys, :description
4
+ attr_accessor :inputs, :input_shortcuts, :input_types, :input_descriptions, :input_defaults
5
+
6
+ def command
7
+ @command ||= File.basename($0)
8
+ end
9
+
10
+ def summary
11
+ @summary ||= ""
12
+ end
13
+
14
+ def synopsys
15
+ @synopsys ||= begin
16
+ "#{command} " <<
17
+ inputs.collect{|name|
18
+ "[" << input_format(name, input_types[name] || :string, input_defaults[name], input_shortcuts[name]).sub(/:$/,'') << "]"
19
+ } * " "
20
+ end
21
+ end
22
+
23
+ def description
24
+ @description ||= "Missing"
25
+ end
26
+
27
+
28
+ def shortcuts
29
+ @shortcuts ||= []
30
+ end
31
+
32
+ def all
33
+ @all ||= {}
34
+ end
35
+
36
+ def inputs
37
+ @inputs ||= []
38
+ end
39
+
40
+ def input_shortcuts
41
+ @input_shortcuts ||= {}
42
+ end
43
+
44
+ def input_types
45
+ @input_types ||= {}
46
+ end
47
+
48
+ def input_descriptions
49
+ @input_descriptions ||= {}
50
+ end
51
+
52
+ def input_defaults
53
+ @input_defaults ||= {}
54
+ end
55
+
56
+
57
+ def reset
58
+ @shortcuts = []
59
+ @all = {}
60
+ end
61
+
62
+ def record(info)
63
+ input = info[:long].sub("--", '')
64
+ inputs << input
65
+ input_types[input] = info[:arg] ? :string : :boolean
66
+ input_descriptions[input] = info[:description]
67
+ input_defaults[input] = info[:default]
68
+ input_shortcuts[input] = info[:short]? info[:short].sub("-",'') : nil
69
+ end
70
+ end
71
+
72
+
73
+ def self.short_for(name)
74
+ short = []
75
+ chars = name.to_s.chars.to_a
76
+
77
+ short << chars.shift
78
+ shortcuts = input_shortcuts.values.compact.flatten
79
+ while shortcuts.include? short * "" and chars.any?
80
+ short << chars.shift
81
+ end
82
+ return nil if chars.empty?
83
+
84
+ short * ""
85
+ end
86
+
87
+ def self.input_format(name, type = nil, default = nil, short = "")
88
+ short = short_for(name) if not short.nil? and short.empty?
89
+
90
+ input_str = short.nil? ? "--#{name}" : "-#{short}, --#{name}"
91
+ input_str << case type
92
+ when nil
93
+ "#{default != nil ? " (default '#{default}')" : ""}:"
94
+ when :boolean
95
+ "[=false]#{default != nil ? " (default '#{default}')" : ""}:"
96
+ when :tsv, :text
97
+ "=<filename.#{type}|->#{default != nil ? " (default '#{default}')" : ""}; Use '-' for STDIN:"
98
+ when :array
99
+ "=<string[,string]*|filename.list|->#{default != nil ? " (default '#{default}')" : ""}; Use '-' for STDIN:"
100
+ else
101
+ "=<#{ type }>#{default != nil ? " (default '#{default}')" : ""}:"
102
+ end
103
+ end
104
+
105
+ def self.input_doc(inputs, input_types = nil, input_descriptions = nil, input_defaults = nil, input_shortcuts = nil)
106
+ type = description = default = nil
107
+ shortcut = ""
108
+ inputs.collect do |name|
109
+
110
+ type = input_types[name] unless input_types.nil?
111
+ description = input_descriptions[name] unless input_descriptions.nil?
112
+ default = input_defaults[name] unless input_defaults.nil?
113
+ shortcut = input_shortcuts[name] unless input_shortcuts.nil?
114
+
115
+ type = :string if type.nil?
116
+
117
+ str = " * " << SOPT.input_format(name, type.to_sym, default, shortcut) << "\n"
118
+ str << " " << description << "\n" if description and not description.empty?
119
+ str
120
+ end * "\n"
121
+ end
122
+
123
+ def self.doc
124
+ doc = <<-EOF
125
+ #{command}(1) -- #{summary}
126
+ #{"=" * (command.length + summary.length + 7)}
127
+
128
+ ## SYNOPSYS
129
+
130
+ #{synopsys}
131
+
132
+ ## DESCRIPTION
133
+
134
+ #{description}
135
+
136
+ ## OPTIONS
137
+
138
+ #{input_doc(inputs, input_types, input_descriptions, input_defaults, input_shortcuts)}
139
+ EOF
140
+ end
141
+
2
142
  def self.name(info)
3
143
  (info[:long] || info[:short]).sub(/^-*/,'')
4
144
  end
5
145
 
6
146
  def self.parse(opts)
7
147
  info = {}
148
+
8
149
  opts.split(/:/).each do |opt|
9
- short, long = opt.sub(/\*$/,'').split('--').values_at(0,1)
10
- i= {
11
- :arg => !!opt.match(/\*$/),
12
- }
13
- i[:short] = short unless short.nil? || short.empty?
14
- i[:long] = '--' + long unless long.nil? || long.empty?
150
+ next if opt.strip.empty?
151
+
152
+ short, long = opt.strip.sub(/(^[^\s]*)\*/,'\1').split('--').values_at(0,1)
153
+ long, short = short, nil if long.nil?
154
+
155
+ if long.index(" ")
156
+ long, description = long.match(/^([^\s]+)\s+(.*)/).values_at 1, 2
157
+ else
158
+ description = nil
159
+ end
160
+
161
+ i= { :arg => !!opt.match(/^[^\s]*\*/) }
162
+
163
+ i[:short] = short unless short.nil? || short.empty?
164
+ i[:long] = '--' + long unless long.nil? || long.empty?
165
+ i[:description] = description unless description.nil? || description.empty?
166
+
167
+ if shortcuts.include? short
168
+ i[:short] = short_for(i[:long])
169
+ Log.debug("Short for #{ long } is taken. Changed to #{i[:short]}")
170
+ else
171
+ shortcuts << i[:short] if short
172
+ end
173
+
174
+ record(i)
175
+
15
176
  info[name(i)] = i
16
177
  end
17
178
 
@@ -51,7 +212,7 @@ module SOPT
51
212
  end
52
213
  options[name.to_sym] = value
53
214
  else
54
- options[name.to_sym] = true
215
+ options[name.to_sym] = value == "false" ? false : true
55
216
  end
56
217
  else
57
218
  rest << orig_arg
data/lib/rbbt/workflow.rb CHANGED
@@ -41,14 +41,14 @@ module Workflow
41
41
  when ((File.exists?(wf_name.find) and not File.directory?(wf_name.find)) or File.exists?(wf_name.find + '.rb'))
42
42
  $LOAD_PATH.unshift(File.join(File.expand_path(File.dirname(wf_name.find)), 'lib'))
43
43
  require wf_name.find
44
- Log.debug "Workflow loaded from file: #{ wf_name }"
44
+ Log.medium "Workflow loaded from file: #{ wf_name }"
45
45
  return true
46
46
 
47
47
  # Points to workflow dir
48
48
  when (File.exists?(wf_name.find) and File.directory?(wf_name.find) and File.exists?(File.join(wf_name.find, 'workflow.rb')))
49
49
  $LOAD_PATH.unshift(File.join(File.expand_path(wf_name.find), 'lib'))
50
50
  require File.join(wf_name.find, 'workflow.rb')
51
- Log.debug "Workflow loaded from directory: #{ wf_name }"
51
+ Log.medium "Workflow loaded from directory: #{ wf_name }"
52
52
  return true
53
53
 
54
54
  else
@@ -61,7 +61,7 @@ module Workflow
61
61
  when ((File.exists?(wf_name) and not File.directory?(wf_name)) or File.exists?(wf_name + '.rb'))
62
62
  $LOAD_PATH.unshift(File.join(File.expand_path(File.dirname(wf_name)), 'lib'))
63
63
  require wf_name
64
- Log.debug "Workflow loaded from file: #{ wf_name }"
64
+ Log.medium "Workflow loaded from file: #{ wf_name }"
65
65
  return true
66
66
 
67
67
  when (defined?(Rbbt) and Rbbt.etc.workflow_dir.exists?)
@@ -69,21 +69,21 @@ module Workflow
69
69
  dir = File.join(dir, wf_name)
70
70
  $LOAD_PATH.unshift(File.join(File.expand_path(dir), 'lib'))
71
71
  require File.join(dir, 'workflow.rb')
72
- Log.debug "Workflow #{wf_name} loaded from workflow_dir: #{ dir }"
72
+ Log.medium "Workflow #{wf_name} loaded from workflow_dir: #{ dir }"
73
73
  return true
74
74
 
75
75
  when defined?(Rbbt)
76
76
  path = Rbbt.workflows[wf_name].find
77
77
  $LOAD_PATH.unshift(File.join(File.expand_path(path), 'lib'))
78
78
  require File.join(path, 'workflow.rb')
79
- Log.debug "Workflow #{wf_name} loaded from Rbbt.workflows: #{ path }"
79
+ Log.medium "Workflow #{wf_name} loaded from Rbbt.workflows: #{ path }"
80
80
  return true
81
81
 
82
82
  else
83
83
  path = File.join(ENV['HOME'], '.workflows', wf_name)
84
84
  $LOAD_PATH.unshift(File.join(File.expand_path(path), 'lib'))
85
85
  require File.join(path, 'workflow.rb')
86
- Log.debug "Workflow #{wf_name} loaded from .workflows: #{ path }"
86
+ Log.medium "Workflow #{wf_name} loaded from .workflows: #{ path }"
87
87
  return true
88
88
  end
89
89
  end
@@ -211,6 +211,7 @@ module Workflow
211
211
  path = File.join(workdir, id)
212
212
  task = task_for path
213
213
  step = Step.new path, tasks[task.to_sym]
214
+ step.info
214
215
  if step.info.include? :dependencies
215
216
  step.dependencies = step.info[:dependencies].collect do |task, job|
216
217
  load_id(File.join(task.to_s, job))
@@ -68,16 +68,14 @@ class Step
68
68
 
69
69
  def join
70
70
  if @pid.nil?
71
- while not done? do
72
- sleep 5
73
- end
71
+ self
74
72
  else
75
- Log.debug "Waiting for pid: #{@pid}"
76
73
  begin
77
- Process.waitpid @pid
74
+ Log.debug "Waiting for pid: #{@pid}"
75
+ Process.waitpid @pid
78
76
  rescue Errno::ECHILD
79
77
  Log.debug "Process #{ @pid } already finished: #{ path }"
80
- end
78
+ end if Misc.pid_exists? @pid
81
79
  @pid = nil
82
80
  end
83
81
  self
@@ -108,7 +106,8 @@ class Step
108
106
  end
109
107
  }
110
108
 
111
- log(:started, "Starting task #{task.name || ""} [#{Process.pid}]")
109
+ Log.medium("Starting task #{task.name || ""} [#{Process.pid}]: #{ path }")
110
+ set_info :status, :started
112
111
 
113
112
  set_info :started, Time.now
114
113
 
@@ -147,6 +146,8 @@ class Step
147
146
  end
148
147
 
149
148
  set_info :status, :done
149
+ set_info :done, Time.now
150
+ Log.medium("Completed task #{task.name || ""} [#{Process.pid}]: #{ path }")
150
151
  res
151
152
  end
152
153
 
@@ -164,6 +165,12 @@ class Step
164
165
  FileUtils.mkdir_p File.dirname(path) unless File.exists? File.dirname(path)
165
166
  begin
166
167
  run
168
+ rescue Exception
169
+ Log.debug("Exception caught on forked process: #{$!.message}")
170
+ exit -1
171
+ end
172
+
173
+ begin
167
174
  children_pids = info[:children_pids]
168
175
  if children_pids
169
176
  children_pids.each do |pid|
@@ -177,7 +184,7 @@ class Step
177
184
  end
178
185
  end
179
186
  rescue Exception
180
- Log.debug("Exception caught on forked process: #{$!.message}")
187
+ Log.debug("Exception waiting for children: #{$!.message}")
181
188
  exit -1
182
189
  end
183
190
  set_info :pid, nil
@@ -1,28 +1,11 @@
1
+ require 'rbbt/util/simpleopt'
1
2
 
2
3
  module Task
3
4
  def doc(deps = nil)
4
-
5
5
  puts "## #{ name }:"
6
6
  puts "\n" << description if description and not description.empty?
7
- puts
8
-
9
- inputs.each do |name|
10
- short = name.to_s.chars.first
11
-
12
- description = input_descriptions[name]
13
- default = input_defaults[name]
14
- type = input_types[name]
15
-
16
-
17
- if type.to_sym == :boolean
18
- puts " * -#{short}, --#{name}[=<true|false>]#{default != nil ? " (default: #{default})" : ""}:"
19
- else
20
- puts " * -#{short}, --#{name}=<#{ type }>#{default != nil ? " (default: #{default})" : ""}:"
21
- end
22
-
23
- puts " " << description if description and not description.empty?
24
- puts
25
- end
7
+ puts
8
+ puts SOPT.input_doc(inputs, input_types, input_descriptions, input_defaults)
26
9
 
27
10
  if deps and deps.any?
28
11
  puts
@@ -31,22 +14,7 @@ module Task
31
14
  deps.each do |dep|
32
15
  puts " #{dep.name}:"
33
16
  puts
34
- dep.inputs.each do |name|
35
- short = name.to_s.chars.first
36
-
37
- description = dep.input_descriptions[name]
38
- default = dep.input_defaults[name]
39
- type = dep.input_types[name]
40
-
41
- if type.to_sym == :boolean
42
- puts " * -#{short}, --#{name}[=<true|false>]#{default != nil ? " (default: #{default})" : ""}:"
43
- else
44
- puts " * -#{short}, --#{name}=<#{ type }>#{default != nil ? " (default: #{default})" : ""}:"
45
- end
46
-
47
- puts " " << description if description and not description.empty?
48
- puts
49
- end
17
+ puts SOPT.input_doc(dep.inputs, dep.input_types, dep.input_descriptions, dep.input_defaults)
50
18
  end
51
19
  end
52
20
  end
@@ -14,5 +14,6 @@ app_dir = app_dir[app]
14
14
  server = options[:server] || 'thin'
15
15
 
16
16
  Misc.in_dir(app_dir) do
17
- `#{options.include?(:environment)? "env RACK_ENV=#{options[:environment]}" : ""} #{server} start -p #{options[:port]} #{ARGV.collect{|a| "'#{a}'"} * " "}`
17
+ `env RBBT_LOG=#{Log.severity} #{options.include?(:environment)? "env RACK_ENV=#{options[:environment]}" : ""} \
18
+ #{server} start -p #{options[:port]} #{ARGV.collect{|a| "'#{a}'"} * " "}`
18
19
  end
@@ -5,6 +5,9 @@ require 'rbbt/workflow'
5
5
  require 'rbbt/workflow/usage'
6
6
 
7
7
  def usage(workflow = nil, task = nil)
8
+ puts SOPT.doc
9
+ puts "## WORKFLOW"
10
+ puts
8
11
  if workflow.nil?
9
12
  puts "No workflow specified"
10
13
  exit -1
@@ -14,6 +17,9 @@ def usage(workflow = nil, task = nil)
14
17
  workflow.load_tasks if workflow.respond_to? :load_tasks
15
18
  workflow.doc
16
19
  else
20
+ puts workflow.to_s
21
+ puts "=" * workflow.to_s.length
22
+ puts
17
23
  workflow.doc(task)
18
24
  end
19
25
 
@@ -94,7 +100,14 @@ def fix_options(workflow, task, job_options)
94
100
  job_options_cleaned
95
101
  end
96
102
 
97
- options = SOPT.get "-t--task*:--profile:-l--log*:-h--help:-n--name*:-cl--clean:-rcl-recursive_clean:-pn--printname:-as--array_separator*"
103
+ options = SOPT.get <<EOF
104
+ -h--help Show this help:
105
+ -as--array_separator* Change the character that separates elements of Arrays, ',', '|', or '\\n' by default:
106
+ -cl--clean Clean the last step of the job so that it gets recomputed:
107
+ -rcl--recursive_clean Clean the last step and its dependencies to recompute the job completely:
108
+ -n--name* Job name to use. The name 'Default' is used by default:
109
+ -pn--printname Print the name of the job and exit without starting it:
110
+ EOF
98
111
 
99
112
  workflow = ARGV.shift
100
113
  usage if workflow.nil?
@@ -103,9 +116,9 @@ task = ARGV.shift
103
116
 
104
117
 
105
118
  # Set log, fork, clean, recursive_clean and help
106
- Log.severity = options[:log].to_i if options.include? :log
107
119
  help = !!options.delete(:help)
108
120
  do_fork = !!options.delete(:fork)
121
+ do_exec = !!options.delete(:exec)
109
122
  clean = !!options.delete(:clean)
110
123
  recursive_clean = !!options.delete(:recursive_clean)
111
124
  $array_separator = options.delete(:array_separator)
@@ -155,7 +168,7 @@ job_options = fix_options(workflow, task, job_options)
155
168
  job = workflow.job(task.name, name, job_options)
156
169
 
157
170
  # clean job
158
- if clean and job.done?
171
+ if clean and job.done? != false
159
172
  job.clean
160
173
  sleep 1
161
174
  job = workflow.job(task.name, name, job_options)
@@ -168,6 +181,21 @@ if recursive_clean and job.done?
168
181
  end
169
182
 
170
183
  # run
184
+ if do_exec
185
+ res = job.exec
186
+ case
187
+ when Array === res
188
+ puts res * "\n"
189
+ when TSV === res
190
+ puts res
191
+ when Hash === res
192
+ puts res.to_yaml
193
+ else
194
+ puts res
195
+ end
196
+ exit 0
197
+ end
198
+
171
199
  if do_fork
172
200
  job.fork
173
201
  while not job.done?
@@ -175,30 +203,21 @@ if do_fork
175
203
  sleep 2
176
204
  end
177
205
  raise job.messages.last if job.error?
178
- if $array_separator
179
- res = job.load(:sep2 => $array_separator)
180
- else
181
- res = job.load
182
- end
183
206
  else
184
- res = job.run
207
+ res = job.run(true)
185
208
  end
186
209
 
187
210
  if options.delete(:printname)
188
211
  puts job.name
189
- exit
212
+ exit 0
190
213
  else
191
214
  Log.low "Job name: #{job.name}"
192
215
  end
193
216
 
194
- case
195
- when Array === res
196
- puts res * "\n"
197
- when TSV === res
198
- puts res
199
- when Hash === res
200
- puts res.to_yaml
217
+ if Step === res
218
+ puts Open.read(res.path)
201
219
  else
202
220
  puts res
203
221
  end
204
222
 
223
+ exit 0
@@ -420,6 +420,22 @@ row2 b bbb bbbb bb
420
420
  end
421
421
  end
422
422
 
423
+ def test_flat_key
424
+ content =<<-EOF
425
+ #Id ValueA
426
+ row1 a aa aaa
427
+ row2 b bbb bbbb bb aa
428
+ EOF
429
+
430
+ TmpFile.with_file(content) do |filename|
431
+ tsv = TSV.open(filename, :sep => /\s+/, :merge => true, :type => :flat, :key_field => "ValueA")
432
+ assert_equal ["row1"], tsv["a"]
433
+ assert_equal ["row1", "row2"], tsv["aa"]
434
+ end
435
+ end
436
+
437
+
438
+
423
439
  def test_zipped
424
440
  content =<<-EOF
425
441
  #Id ValueA ValueB
@@ -220,4 +220,8 @@ class TestMisc < Test::Unit::TestCase
220
220
  assert_equal "ACRONIM_test", Misc.snake_case(str1)
221
221
  assert_equal "ACRONIM_test", Misc.snake_case(str2)
222
222
  end
223
+
224
+ def test_correct_vcf_mutations
225
+ assert_equal [737407, ["-----", "-----G", "-----GTTAAT"]], Misc.correct_vcf_mutation(737406, "GTTAAT", "G,GG,GGTTAAT")
226
+ end
223
227
  end
metadata CHANGED
@@ -1,20 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbbt-util
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.2.3
5
- prerelease:
4
+ version: 5.2.4
6
5
  platform: ruby
7
6
  authors:
8
7
  - Miguel Vazquez
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-05-22 00:00:00.000000000 Z
11
+ date: 2013-05-27 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: rake
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ! '>='
20
18
  - !ruby/object:Gem::Version
@@ -22,7 +20,6 @@ dependencies:
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - ! '>='
28
25
  - !ruby/object:Gem::Version
@@ -30,7 +27,6 @@ dependencies:
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: spreadsheet
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
31
  - - ! '>='
36
32
  - !ruby/object:Gem::Version
@@ -38,7 +34,6 @@ dependencies:
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
38
  - - ! '>='
44
39
  - !ruby/object:Gem::Version
@@ -46,7 +41,6 @@ dependencies:
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: ruby-prof
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
45
  - - ! '>='
52
46
  - !ruby/object:Gem::Version
@@ -54,7 +48,6 @@ dependencies:
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
52
  - - ! '>='
60
53
  - !ruby/object:Gem::Version
@@ -62,7 +55,6 @@ dependencies:
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: tokyocabinet
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
59
  - - ! '>='
68
60
  - !ruby/object:Gem::Version
@@ -70,7 +62,6 @@ dependencies:
70
62
  type: :runtime
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
66
  - - ! '>='
76
67
  - !ruby/object:Gem::Version
@@ -78,7 +69,6 @@ dependencies:
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: progress-monitor
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
73
  - - ! '>='
84
74
  - !ruby/object:Gem::Version
@@ -86,7 +76,6 @@ dependencies:
86
76
  type: :runtime
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
80
  - - ! '>='
92
81
  - !ruby/object:Gem::Version
@@ -94,7 +83,6 @@ dependencies:
94
83
  - !ruby/object:Gem::Dependency
95
84
  name: lockfile
96
85
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
86
  requirements:
99
87
  - - ! '>='
100
88
  - !ruby/object:Gem::Version
@@ -102,7 +90,6 @@ dependencies:
102
90
  type: :runtime
103
91
  prerelease: false
104
92
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
93
  requirements:
107
94
  - - ! '>='
108
95
  - !ruby/object:Gem::Version
@@ -110,7 +97,6 @@ dependencies:
110
97
  - !ruby/object:Gem::Dependency
111
98
  name: RubyInline
112
99
  requirement: !ruby/object:Gem::Requirement
113
- none: false
114
100
  requirements:
115
101
  - - ! '>='
116
102
  - !ruby/object:Gem::Version
@@ -118,7 +104,6 @@ dependencies:
118
104
  type: :runtime
119
105
  prerelease: false
120
106
  version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
107
  requirements:
123
108
  - - ! '>='
124
109
  - !ruby/object:Gem::Version
@@ -126,7 +111,6 @@ dependencies:
126
111
  - !ruby/object:Gem::Dependency
127
112
  name: narray
128
113
  requirement: !ruby/object:Gem::Requirement
129
- none: false
130
114
  requirements:
131
115
  - - ! '>='
132
116
  - !ruby/object:Gem::Version
@@ -134,7 +118,6 @@ dependencies:
134
118
  type: :runtime
135
119
  prerelease: false
136
120
  version_requirements: !ruby/object:Gem::Requirement
137
- none: false
138
121
  requirements:
139
122
  - - ! '>='
140
123
  - !ruby/object:Gem::Version
@@ -142,7 +125,6 @@ dependencies:
142
125
  - !ruby/object:Gem::Dependency
143
126
  name: simplews
144
127
  requirement: !ruby/object:Gem::Requirement
145
- none: false
146
128
  requirements:
147
129
  - - ! '>='
148
130
  - !ruby/object:Gem::Version
@@ -150,7 +132,6 @@ dependencies:
150
132
  type: :runtime
151
133
  prerelease: false
152
134
  version_requirements: !ruby/object:Gem::Requirement
153
- none: false
154
135
  requirements:
155
136
  - - ! '>='
156
137
  - !ruby/object:Gem::Version
@@ -158,7 +139,6 @@ dependencies:
158
139
  - !ruby/object:Gem::Dependency
159
140
  name: highline
160
141
  requirement: !ruby/object:Gem::Requirement
161
- none: false
162
142
  requirements:
163
143
  - - ! '>='
164
144
  - !ruby/object:Gem::Version
@@ -166,7 +146,6 @@ dependencies:
166
146
  type: :runtime
167
147
  prerelease: false
168
148
  version_requirements: !ruby/object:Gem::Requirement
169
- none: false
170
149
  requirements:
171
150
  - - ! '>='
172
151
  - !ruby/object:Gem::Version
@@ -286,27 +265,26 @@ files:
286
265
  - bin/rbbt_dangling_locks.rb
287
266
  homepage: http://github.com/mikisvaz/rbbt-util
288
267
  licenses: []
268
+ metadata: {}
289
269
  post_install_message:
290
270
  rdoc_options: []
291
271
  require_paths:
292
272
  - lib
293
273
  required_ruby_version: !ruby/object:Gem::Requirement
294
- none: false
295
274
  requirements:
296
275
  - - ! '>='
297
276
  - !ruby/object:Gem::Version
298
277
  version: '0'
299
278
  required_rubygems_version: !ruby/object:Gem::Requirement
300
- none: false
301
279
  requirements:
302
280
  - - ! '>='
303
281
  - !ruby/object:Gem::Version
304
282
  version: '0'
305
283
  requirements: []
306
284
  rubyforge_project:
307
- rubygems_version: 1.8.24
285
+ rubygems_version: 2.0.3
308
286
  signing_key:
309
- specification_version: 3
287
+ specification_version: 4
310
288
  summary: Utilities for the Ruby Bioinformatics Toolkit (rbbt)
311
289
  test_files:
312
290
  - test/rbbt/tsv/test_accessor.rb