rbbt-util 5.2.3 → 5.2.4

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.
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