rbbt-util 4.1.0 → 4.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/run_workflow.rb +4 -1
- data/lib/rbbt/annotations.rb +138 -53
- data/lib/rbbt/persist.rb +30 -12
- data/lib/rbbt/persist/tsv.rb +1 -1
- data/lib/rbbt/resource/path.rb +1 -1
- data/lib/rbbt/tsv.rb +7 -1
- data/lib/rbbt/tsv/accessor.rb +21 -16
- data/lib/rbbt/tsv/attach/util.rb +1 -10
- data/lib/rbbt/tsv/manipulate.rb +21 -3
- data/lib/rbbt/tsv/parser.rb +24 -5
- data/lib/rbbt/tsv/util.rb +1 -1
- data/lib/rbbt/util/chain_methods.rb +12 -23
- data/lib/rbbt/util/misc.rb +133 -144
- data/lib/rbbt/util/named_array.rb +113 -0
- data/lib/rbbt/util/open.rb +17 -10
- data/lib/rbbt/workflow/accessor.rb +9 -1
- data/lib/rbbt/workflow/step.rb +9 -7
- data/share/lib/R/util.R +28 -6
- data/test/rbbt/test_annotations.rb +16 -2
- data/test/rbbt/test_persist.rb +37 -1
- data/test/rbbt/test_tsv.rb +12 -0
- data/test/rbbt/tsv/test_attach.rb +1 -1
- data/test/rbbt/util/test_chain_methods.rb +1 -1
- data/test/rbbt/util/test_misc.rb +10 -0
- metadata +5 -4
data/lib/rbbt/persist/tsv.rb
CHANGED
data/lib/rbbt/resource/path.rb
CHANGED
data/lib/rbbt/tsv.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
|
3
3
|
require 'rbbt/util/misc'
|
4
|
+
require 'rbbt/util/named_array'
|
4
5
|
require 'rbbt/util/log'
|
5
6
|
|
6
7
|
require 'rbbt/persist'
|
@@ -38,10 +39,11 @@ module TSV
|
|
38
39
|
|
39
40
|
filename = get_filename source
|
40
41
|
serializer = Misc.process_options options, :serializer
|
42
|
+
unnamed = Misc.process_options options, :unnamed
|
41
43
|
|
42
44
|
Log.debug "TSV open: #{ filename } - #{options.inspect}"
|
43
45
|
|
44
|
-
Persist.persist_tsv source, filename, options, persist_options do |data|
|
46
|
+
data = Persist.persist_tsv source, filename, options, persist_options do |data|
|
45
47
|
if serializer
|
46
48
|
data.extend TSV unless TSV === data
|
47
49
|
data.serializer = serializer
|
@@ -57,6 +59,10 @@ module TSV
|
|
57
59
|
|
58
60
|
data
|
59
61
|
end
|
62
|
+
|
63
|
+
data.unnamed = unnamed unless unnamed.nil?
|
64
|
+
|
65
|
+
data
|
60
66
|
end
|
61
67
|
|
62
68
|
def self.parse_header(stream, options = {})
|
data/lib/rbbt/tsv/accessor.rb
CHANGED
@@ -68,13 +68,14 @@ module TSV
|
|
68
68
|
|
69
69
|
def tsv_get_brackets(key)
|
70
70
|
value = serialized_get(key)
|
71
|
-
return value if @unnamed or fields.nil?
|
71
|
+
return value if value.nil? or @unnamed or fields.nil?
|
72
72
|
|
73
73
|
case type
|
74
74
|
when :double, :list
|
75
|
-
NamedArray.setup value, fields, key
|
75
|
+
NamedArray.setup value, fields, key, namespace
|
76
76
|
when :flat, :single
|
77
|
-
|
77
|
+
value = value.dup if value.frozen?
|
78
|
+
Entity.formats[fields.first].setup(value, (namespace ? {:namespace => namespace, :organism => namespace} : {}).merge({:format => fields.first})) if defined?(Entity) and Entity.respond_to?(:formats) and Entity.formats.include? fields.first
|
78
79
|
end
|
79
80
|
value
|
80
81
|
end
|
@@ -88,7 +89,7 @@ module TSV
|
|
88
89
|
return keys if @unnamed or key_field.nil?
|
89
90
|
|
90
91
|
if defined?(Entity) and Entity.respond_to?(:formats) and Entity.formats.include? key_field
|
91
|
-
Entity.formats[key_field].setup(keys.collect{|k| k.dup}, :format => key_field)
|
92
|
+
Entity.formats[key_field].setup(keys.collect{|k| k.dup}, (namespace ? {:namespace => namespace, :organism => namespace} : {}).merge({:format => key_field}) )
|
92
93
|
else
|
93
94
|
keys
|
94
95
|
end
|
@@ -100,10 +101,10 @@ module TSV
|
|
100
101
|
|
101
102
|
case type
|
102
103
|
when :double, :list
|
103
|
-
values.each{|value| NamedArray.setup value, fields }
|
104
|
+
values.each{|value| NamedArray.setup value, fields, nil, namespace }
|
104
105
|
when :flat, :single
|
105
106
|
values.each{|value|
|
106
|
-
Entity.formats[fields.first].setup(value, :format => fields.first)
|
107
|
+
Entity.formats[fields.first].setup(value, (namespace ? {:namespace => namespace, :organism => namespace} : {}).merge({:format => fields.first}))
|
107
108
|
} if defined?(Entity) and Entity.respond_to?(:formats) and Entity.formats.include? fields.first
|
108
109
|
end
|
109
110
|
|
@@ -126,13 +127,13 @@ module TSV
|
|
126
127
|
if not fields.nil?
|
127
128
|
case type
|
128
129
|
when :double, :list
|
129
|
-
NamedArray.setup value, fields, key if Array === value
|
130
|
+
NamedArray.setup value, fields, key, namespace if Array === value
|
130
131
|
when :flat, :single
|
131
|
-
Entity.formats[fields.first].setup(value, :format => fields.first) if defined?(Entity) and Entity.respond_to?(:formats) and Entity.formats.include? fields.first
|
132
|
+
Entity.formats[fields.first].setup(value, (namespace ? {:namespace => namespace, :organism => namespace} : {}).merge({:format => fields.first})) if defined?(Entity) and Entity.respond_to?(:formats) and Entity.formats.include? fields.first
|
132
133
|
end
|
133
134
|
end
|
134
135
|
if defined?(Entity) and not key_field.nil? and Entity.respond_to?(:formats) and Entity.formats.include? key_field
|
135
|
-
key = Entity.formats[key_field].setup(key.dup, :format => key_field)
|
136
|
+
key = Entity.formats[key_field].setup(key.dup, (namespace ? {:namespace => namespace, :organism => namespace} : {}).merge({:format => key_field}))
|
136
137
|
end
|
137
138
|
end
|
138
139
|
|
@@ -155,13 +156,13 @@ module TSV
|
|
155
156
|
if not fields.nil?
|
156
157
|
case type
|
157
158
|
when :double, :list
|
158
|
-
NamedArray.setup value, fields, key if Array === value
|
159
|
+
NamedArray.setup value, fields, key, namespace if Array === value
|
159
160
|
when :flat, :single
|
160
|
-
Entity.formats[fields.first].setup(value, :format => fields.first) if defined?(Entity) and Entity.respond_to?(:formats) and Entity.formats.include? fields.first
|
161
|
+
Entity.formats[fields.first].setup(value, (namespace ? {:namespace => namespace, :organism => namespace} : {}).merge({:format => fields.first})) if defined?(Entity) and Entity.respond_to?(:formats) and Entity.formats.include? fields.first
|
161
162
|
end
|
162
163
|
end
|
163
164
|
if defined?(Entity) and not key_field.nil? and Entity.respond_to?(:formats) and Entity.formats.include? key_field
|
164
|
-
key = Entity.formats[key_field].setup(key.dup, :format => key_field)
|
165
|
+
key = Entity.formats[key_field].setup(key.dup, (namespace ? {:namespace => namespace, :organism => namespace} : {}).merge({:format => key_field}))
|
165
166
|
end
|
166
167
|
end
|
167
168
|
|
@@ -215,13 +216,16 @@ module TSV
|
|
215
216
|
if not block_given?
|
216
217
|
if fields == :all
|
217
218
|
if just_keys
|
218
|
-
elems.sort_by{|key, value| key }.collect{|key, values| key}
|
219
|
+
keys = elems.sort_by{|key, value| key }.collect{|key, values| key}
|
220
|
+
Entity.formats[key_field].setup(keys, (namespace ? {:namespace => namespace, :organism => namespace} : {}).merge({:format => key_field})) if defined?(Entity) and Entity.respond_to?(:formats) and Entity.formats.include? key_field
|
219
221
|
else
|
220
222
|
elems.sort_by{|key, value| key }
|
221
223
|
end
|
222
224
|
else
|
223
225
|
if just_keys
|
224
|
-
elems.sort_by{|key, value| value }.collect{|key, value| key}
|
226
|
+
keys = elems.sort_by{|key, value| value }.collect{|key, value| key}
|
227
|
+
Entity.formats[key_field].setup(keys, (namespace ? {:namespace => namespace, :organism => namespace} : {}).merge({:format => fields.first})) if defined?(Entity) and Entity.respond_to?(:formats) and Entity.formats.include? key_field
|
228
|
+
keys
|
225
229
|
else
|
226
230
|
elems.sort_by{|key, value| value }.collect{|key, value| [key, self[key]]}
|
227
231
|
end
|
@@ -299,8 +303,9 @@ if '#{entry}' == 'serializer'
|
|
299
303
|
|
300
304
|
else
|
301
305
|
class << self
|
302
|
-
|
306
|
+
|
303
307
|
define_method :serialized_get do |key|
|
308
|
+
return nil unless self.include? key
|
304
309
|
self.serializer_module.load(tsv_clean_get_brackets(key))
|
305
310
|
end
|
306
311
|
|
@@ -335,7 +340,7 @@ end
|
|
335
340
|
if @fields.nil? or @unnamed
|
336
341
|
@fields
|
337
342
|
else
|
338
|
-
NamedArray.setup @fields, @fields
|
343
|
+
NamedArray.setup @fields, @fields, nil, namespace
|
339
344
|
end
|
340
345
|
end
|
341
346
|
|
data/lib/rbbt/tsv/attach/util.rb
CHANGED
@@ -235,19 +235,10 @@ module TSV
|
|
235
235
|
|
236
236
|
if current_index.nil?
|
237
237
|
current_index = next_file.index(:target => next_key, :fields => [current_key], :persist => persist_input)
|
238
|
+
current_index = current_index.select :key => data_file.keys
|
238
239
|
else
|
239
240
|
next_index = next_file.index :target => next_key, :fields => [current_key], :persist => persist_input
|
240
241
|
|
241
|
-
if TokyoCabinet::HDB === current_index
|
242
|
-
tmp = TSV.setup({}, :key_field => current_index.key_field, :fields => [current_index.fields], :serializer => current_index.serializer, :type => current_index.type, :filename => current_index.filename)
|
243
|
-
current_index.with_unnamed do
|
244
|
-
current_index.each do |key,value|
|
245
|
-
tmp.tsv_clean_set_brackets(key, current_index.tsv_clean_get_brackets(key))
|
246
|
-
end
|
247
|
-
end
|
248
|
-
current_index = tmp
|
249
|
-
end
|
250
|
-
|
251
242
|
next_index.with_unnamed do
|
252
243
|
current_index.with_unnamed do
|
253
244
|
current_index.process current_index.fields.first do |values|
|
data/lib/rbbt/tsv/manipulate.rb
CHANGED
@@ -245,6 +245,7 @@ module TSV
|
|
245
245
|
data.key_field = new_key_field_name
|
246
246
|
data.fields = new_field_names
|
247
247
|
data.filename = filename
|
248
|
+
data.namespace = namespace
|
248
249
|
data.type = type
|
249
250
|
end
|
250
251
|
end
|
@@ -281,9 +282,10 @@ module TSV
|
|
281
282
|
new = TSV.setup({}, :key_field => key_field, :fields => fields, :type => type, :filename => filename, :identifiers => identifiers)
|
282
283
|
|
283
284
|
new.key_field = key_field
|
284
|
-
new.fields = fields.dup
|
285
|
+
new.fields = fields.dup unless fields.nil?
|
285
286
|
new.type = type
|
286
287
|
new.filename = filename
|
288
|
+
new.namespace = namespace
|
287
289
|
|
288
290
|
case
|
289
291
|
when (method.nil? and block_given?)
|
@@ -429,15 +431,31 @@ module TSV
|
|
429
431
|
end
|
430
432
|
|
431
433
|
def add_field(name = nil)
|
434
|
+
old_monitor = @monitor
|
435
|
+
@monitor = {:desc => "Adding field #{ name }"} if TrueClass === monitor
|
436
|
+
|
432
437
|
through do |key, values|
|
433
438
|
new_values = yield(key, values)
|
434
439
|
new_values = [new_values] if type == :double and not Array === new_values
|
435
440
|
|
436
|
-
|
441
|
+
case
|
442
|
+
when (values.nil? and (fields.nil? or fields.empty?))
|
443
|
+
values = [new_values]
|
444
|
+
when values.nil?
|
445
|
+
values = [nil] * fields.length + [new_values]
|
446
|
+
when NamedArray === values
|
447
|
+
values += [new_values]
|
448
|
+
else
|
449
|
+
values << new_values
|
450
|
+
end
|
437
451
|
self[key] = values
|
438
452
|
end
|
453
|
+
@monitor = old_monitor
|
439
454
|
|
440
|
-
|
455
|
+
if not fields.nil? and not name.nil?
|
456
|
+
fields = self.fields + [name]
|
457
|
+
self.fields = fields
|
458
|
+
end
|
441
459
|
|
442
460
|
self
|
443
461
|
end
|
data/lib/rbbt/tsv/parser.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'rbbt/util/cmd'
|
2
2
|
module TSV
|
3
3
|
class Parser
|
4
|
-
attr_accessor :header_hash, :sep, :sep2, :type, :key_position, :field_positions, :cast, :key_field, :fields, :fix, :select, :serializer, :straight, :take_all, :zipped
|
4
|
+
attr_accessor :header_hash, :sep, :sep2, :type, :key_position, :field_positions, :cast, :key_field, :fields, :fix, :select, :serializer, :straight, :take_all, :zipped, :namespace
|
5
5
|
|
6
6
|
class SKIP_LINE < Exception; end
|
7
7
|
class END_PARSING < Exception; end
|
@@ -62,6 +62,16 @@ module TSV
|
|
62
62
|
line.split(@sep, -1)
|
63
63
|
end
|
64
64
|
|
65
|
+
def get_values_single_from_flat(parts)
|
66
|
+
return parts.shift, parts.first if field_positions.nil? and key_position.nil?
|
67
|
+
if key_position == 0
|
68
|
+
[parts.shift, parts]
|
69
|
+
else
|
70
|
+
key = parts.shift
|
71
|
+
[parts, [key]]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
65
75
|
def get_values_single(parts)
|
66
76
|
return parts.shift, parts.first if field_positions.nil? and key_position.nil?
|
67
77
|
key = parts[key_position]
|
@@ -287,7 +297,8 @@ module TSV
|
|
287
297
|
@header_hash = Misc.process_options(options, :header_hash) || "#"
|
288
298
|
@sep = Misc.process_options(options, :sep) || "\t"
|
289
299
|
|
290
|
-
|
300
|
+
header_options = parse_header(stream)
|
301
|
+
options = header_options.merge options
|
291
302
|
|
292
303
|
@type = Misc.process_options(options, :type) || :double
|
293
304
|
merge = Misc.process_options(options, :merge) || false
|
@@ -298,6 +309,7 @@ module TSV
|
|
298
309
|
@fix = Misc.process_options(options, :fix)
|
299
310
|
@select= Misc.process_options options, :select
|
300
311
|
@zipped = Misc.process_options options, :zipped
|
312
|
+
@namespace = Misc.process_options options, :namespace
|
301
313
|
|
302
314
|
case @type
|
303
315
|
when :double
|
@@ -314,9 +326,15 @@ module TSV
|
|
314
326
|
self.instance_eval do alias add_to_data add_to_data_no_merge_double end
|
315
327
|
end
|
316
328
|
when :single
|
317
|
-
|
318
|
-
|
319
|
-
|
329
|
+
if header_options[:type] == :flat
|
330
|
+
self.instance_eval do alias get_values get_values_single_from_flat end
|
331
|
+
self.instance_eval do alias cast_values cast_values_single end
|
332
|
+
self.instance_eval do alias add_to_data add_to_data_no_merge_double end
|
333
|
+
else
|
334
|
+
self.instance_eval do alias get_values get_values_single end
|
335
|
+
self.instance_eval do alias cast_values cast_values_single end
|
336
|
+
self.instance_eval do alias add_to_data add_to_data_no_merge_list end
|
337
|
+
end
|
320
338
|
when :list
|
321
339
|
self.instance_eval do alias get_values get_values_list end
|
322
340
|
self.instance_eval do alias cast_values cast_values_list end
|
@@ -343,6 +361,7 @@ module TSV
|
|
343
361
|
data.type = @type
|
344
362
|
data.key_field = @key_field
|
345
363
|
data.fields = @fields
|
364
|
+
data.namespace = @namespace
|
346
365
|
data
|
347
366
|
end
|
348
367
|
end
|
data/lib/rbbt/tsv/util.rb
CHANGED
@@ -46,7 +46,7 @@ module TSV
|
|
46
46
|
|
47
47
|
path = Persist.persistence_path(filename, persist_options)
|
48
48
|
TmpFile.with_file(values * "\n") do |value_file|
|
49
|
-
cmd = "cat '#{ path }' | grep -w -F -f '#{ value_file }' |cut -f 2 |sort|uniq -c|sed 's/^ *//;s/
|
49
|
+
cmd = "cat '#{ path }' | grep -w -F -f '#{ value_file }' |cut -f 2 |sort|uniq -c|sed 's/^ *//;s/ /\t/'"
|
50
50
|
begin
|
51
51
|
TSV.open(CMD.cmd(cmd), :key_field => 1, :type => :single, :cast => :to_i)
|
52
52
|
rescue
|
@@ -2,6 +2,7 @@ require 'rbbt/util/log'
|
|
2
2
|
require 'set'
|
3
3
|
|
4
4
|
module ChainMethods
|
5
|
+
|
5
6
|
def self.chain_methods_extended(base)
|
6
7
|
if not base.respond_to? :chain_prefix
|
7
8
|
metaclass = class << base
|
@@ -14,10 +15,6 @@ module ChainMethods
|
|
14
15
|
end
|
15
16
|
|
16
17
|
metaclass.module_eval do
|
17
|
-
def setup_chain(object)
|
18
|
-
object.extend self
|
19
|
-
end
|
20
|
-
|
21
18
|
def setup_chains(base)
|
22
19
|
raise "No prefix specified for #{self.to_s}" if self.chain_prefix.nil? or (String === self.chain_prefix and self.chain_prefix.empty?)
|
23
20
|
methods = self.chained_methods
|
@@ -26,17 +23,6 @@ module ChainMethods
|
|
26
23
|
|
27
24
|
prefix = self.chain_prefix
|
28
25
|
|
29
|
-
#do_chain = true
|
30
|
-
#methods.collect{|new_method|
|
31
|
-
# original = new_method.sub(prefix.to_s + '_', '')
|
32
|
-
# clean = prefix.to_s + '_clean_' + original
|
33
|
-
# if base.respond_to? clean
|
34
|
-
# do_chain = false
|
35
|
-
# break
|
36
|
-
# end
|
37
|
-
#}
|
38
|
-
|
39
|
-
|
40
26
|
if not base.respond_to?(:processed_chains) or base.processed_chains.nil? or not base.processed_chains.include? prefix
|
41
27
|
class << base
|
42
28
|
attr_accessor :processed_chains
|
@@ -61,6 +47,7 @@ module ChainMethods
|
|
61
47
|
alias_method clean_method, original
|
62
48
|
rescue
|
63
49
|
end
|
50
|
+
|
64
51
|
alias_method original, new_method
|
65
52
|
end
|
66
53
|
end
|
@@ -73,17 +60,19 @@ module ChainMethods
|
|
73
60
|
alias prev_chain_methods_extended extended if methods.include? "extended"
|
74
61
|
|
75
62
|
def extended(base)
|
76
|
-
|
63
|
+
if self.respond_to? :prev_chain_methods_extended
|
64
|
+
prev_chain_methods_extended(base)
|
65
|
+
end
|
77
66
|
setup_chains(base)
|
78
67
|
end
|
79
68
|
end
|
80
69
|
end
|
81
|
-
end
|
82
|
-
|
83
|
-
base.chain_prefix = base.to_s.downcase.to_sym
|
84
|
-
end
|
85
|
-
|
86
|
-
def self.extended(base)
|
87
|
-
chain_methods_extended(base)
|
88
70
|
end
|
71
|
+
|
72
|
+
base.chain_prefix = base.to_s.downcase.to_sym
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.extended(base)
|
76
|
+
chain_methods_extended(base)
|
77
|
+
end
|
89
78
|
end
|
data/lib/rbbt/util/misc.rb
CHANGED
@@ -7,6 +7,65 @@ require 'net/smtp'
|
|
7
7
|
module Misc
|
8
8
|
class FieldNotFoundError < StandardError;end
|
9
9
|
|
10
|
+
def self.ensembl_server(organism)
|
11
|
+
date = organism.split("/")[1]
|
12
|
+
if date.nil?
|
13
|
+
"www.ensembl.org"
|
14
|
+
else
|
15
|
+
"#{ date }.archive.ensembl.org"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.filename?(string)
|
20
|
+
String === string and string.length > 0 and string.length < 250 and File.exists?(string)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.max(list)
|
24
|
+
max = nil
|
25
|
+
list.each do |v|
|
26
|
+
next if v.nil?
|
27
|
+
max = v if max.nil? or v > max
|
28
|
+
end
|
29
|
+
max
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.google_venn(list1, list2, list3, name1 = nil, name2 = nil, name3 = nil, total = nil)
|
33
|
+
name1 ||= "list 1"
|
34
|
+
name2 ||= "list 2"
|
35
|
+
name3 ||= "list 3"
|
36
|
+
|
37
|
+
sizes = [list1, list2, list3, list1 & list2, list1 & list3, list2 & list3, list1 & list2 & list3].collect{|l| l.length}
|
38
|
+
|
39
|
+
total = total.length if Array === total
|
40
|
+
|
41
|
+
label = "#{name1}: #{sizes[0]} (#{name2}: #{sizes[3]}, #{name3}: #{sizes[4]})"
|
42
|
+
label << "|#{name2}: #{sizes[1]} (#{name1}: #{sizes[3]}, #{name3}: #{sizes[5]})"
|
43
|
+
label << "|#{name3}: #{sizes[2]} (#{name1}: #{sizes[4]}, #{name2}: #{sizes[5]})"
|
44
|
+
if total
|
45
|
+
label << "| INTERSECTION: #{sizes[6]} TOTAL: #{total}"
|
46
|
+
else
|
47
|
+
label << "| INTERSECTION: #{sizes[6]}"
|
48
|
+
end
|
49
|
+
|
50
|
+
max = total || sizes.max
|
51
|
+
sizes = sizes.collect{|v| (v.to_f/max * 100).to_i.to_f / 100}
|
52
|
+
url = "https://chart.googleapis.com/chart?cht=v&chs=500x300&chd=t:#{sizes * ","}&chco=FF6342,ADDE63,63C6DE,FFFFFF&chdl=#{label}"
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.sum(list)
|
56
|
+
list.compact.inject(0.0){|acc,e| acc += e}
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.mean(list)
|
60
|
+
sum(list) / list.compact.length
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.sd(list)
|
64
|
+
return nil if list.length < 3
|
65
|
+
mean = mean(list)
|
66
|
+
Math.sqrt(list.compact.inject(0.0){|acc,e| d = e - mean; acc += d * d}) / (list.compact.length - 1)
|
67
|
+
end
|
68
|
+
|
10
69
|
def self.consolidate(list)
|
11
70
|
list.inject(nil){|acc,e|
|
12
71
|
if acc.nil?
|
@@ -34,7 +93,7 @@ module Misc
|
|
34
93
|
IndiferentHash.setup(options)
|
35
94
|
options = Misc.add_defaults options, :from_alias => nil, :to_alias => nil, :server => 'localhost', :port => 25, :user => nil, :pass => nil, :auth => :login
|
36
95
|
IndiferentHash.setup(options)
|
37
|
-
|
96
|
+
|
38
97
|
server, port, user, pass, from_alias, to_alias, auth = Misc.process_options options, :server, :port, :user, :pass, :from_alias, :to_alias, :auth
|
39
98
|
|
40
99
|
msg = <<-END_OF_MESSAGE
|
@@ -43,11 +102,11 @@ To: #{to_alias} <#{to}>
|
|
43
102
|
Subject: #{subject}
|
44
103
|
|
45
104
|
#{message}
|
46
|
-
|
105
|
+
END_OF_MESSAGE
|
47
106
|
|
48
|
-
|
49
|
-
|
50
|
-
|
107
|
+
Net::SMTP.start(server, port, server, user, pass, auth) do |smtp|
|
108
|
+
smtp.send_message msg, from, to
|
109
|
+
end
|
51
110
|
end
|
52
111
|
|
53
112
|
def self.counts(array)
|
@@ -55,9 +114,34 @@ Subject: #{subject}
|
|
55
114
|
array.each do |e|
|
56
115
|
counts[e] += 1
|
57
116
|
end
|
117
|
+
|
118
|
+
class << counts; self;end.class_eval do
|
119
|
+
def to_s
|
120
|
+
sort{|a,b| a[1] == b[1] ? a[0] <=> b[0] : a[1] <=> b[1]}.collect{|k,c| "%3d\t%s" % [c, k]} * "\n"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
58
124
|
counts
|
59
125
|
end
|
60
126
|
|
127
|
+
def self.proportions(array)
|
128
|
+
total = array.length
|
129
|
+
|
130
|
+
proportions = Hash.new 0
|
131
|
+
|
132
|
+
array.each do |e|
|
133
|
+
proportions[e] += 1.0 / total
|
134
|
+
end
|
135
|
+
|
136
|
+
class << proportions; self;end.class_eval do
|
137
|
+
def to_s
|
138
|
+
sort{|a,b| a[1] == b[1] ? a[0] <=> b[0] : a[1] <=> b[1]}.collect{|k,c| "%3d\t%s" % [c, k]} * "\n"
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
proportions
|
143
|
+
end
|
144
|
+
|
61
145
|
IUPAC2BASE = {
|
62
146
|
"A" => ["A"],
|
63
147
|
"C" => ["C"],
|
@@ -85,6 +169,29 @@ Subject: #{subject}
|
|
85
169
|
"U" => "A",
|
86
170
|
}
|
87
171
|
|
172
|
+
THREE_TO_ONE_AA_CODE = {
|
173
|
+
"ala" => "A",
|
174
|
+
"arg" => "R",
|
175
|
+
"asn" => "N",
|
176
|
+
"asp" => "D",
|
177
|
+
"cys" => "C",
|
178
|
+
"glu" => "E",
|
179
|
+
"gln" => "Q",
|
180
|
+
"gly" => "G",
|
181
|
+
"his" => "H",
|
182
|
+
"ile" => "I",
|
183
|
+
"leu" => "L",
|
184
|
+
"lys" => "K",
|
185
|
+
"met" => "M",
|
186
|
+
"phe" => "F",
|
187
|
+
"pro" => "P",
|
188
|
+
"ser" => "S",
|
189
|
+
"thr" => "T",
|
190
|
+
"trp" => "W",
|
191
|
+
"tyr" => "Y",
|
192
|
+
"val" => "V"
|
193
|
+
}
|
194
|
+
|
88
195
|
def self.IUPAC_to_base(iupac)
|
89
196
|
IUPAC2BASE[iupac]
|
90
197
|
end
|
@@ -259,7 +366,7 @@ Subject: #{subject}
|
|
259
366
|
|
260
367
|
def self.lock(file, *args)
|
261
368
|
FileUtils.mkdir_p File.dirname(File.expand_path(file)) unless File.exists? File.dirname(File.expand_path(file))
|
262
|
-
lockfile = Lockfile.new(file + '.lock')
|
369
|
+
lockfile = Lockfile.new(file + '.lock', :max_age => 1200, :suspend => 240)
|
263
370
|
lockfile.lock do
|
264
371
|
yield file, *args
|
265
372
|
end
|
@@ -344,24 +451,34 @@ Subject: #{subject}
|
|
344
451
|
end
|
345
452
|
|
346
453
|
def self.hash2md5(hash)
|
347
|
-
|
454
|
+
str = ""
|
348
455
|
hash.keys.sort_by{|k| k.to_s}.each do |k|
|
349
456
|
next if k == :monitor or k == "monitor" or k == :in_situ_persistence or k == "in_situ_persistence"
|
350
457
|
v = hash[k]
|
351
458
|
case
|
352
|
-
when
|
353
|
-
|
354
|
-
|
355
|
-
|
459
|
+
when Hash === v
|
460
|
+
str << k.to_s << "=>" << hash2md5(v)
|
461
|
+
when Symbol === v
|
462
|
+
str << k.to_s << "=>" << v.to_s
|
463
|
+
when String === v
|
464
|
+
str << k.to_s << "=>" << v
|
356
465
|
else
|
357
|
-
|
466
|
+
v_ins = v.inspect
|
467
|
+
|
468
|
+
case
|
469
|
+
when v_ins =~ /:0x0/
|
470
|
+
str << k.to_s << "=>" << v_ins.sub(/:0x[a-f0-9]+@/,'')
|
471
|
+
else
|
472
|
+
str << k.to_s << "=>" << v.to_s
|
473
|
+
end
|
474
|
+
|
358
475
|
end
|
359
476
|
end
|
360
477
|
|
361
|
-
if
|
478
|
+
if str.empty?
|
362
479
|
""
|
363
480
|
else
|
364
|
-
Digest::MD5.hexdigest(
|
481
|
+
Digest::MD5.hexdigest(str)
|
365
482
|
end
|
366
483
|
end
|
367
484
|
|
@@ -455,7 +572,7 @@ Subject: #{subject}
|
|
455
572
|
raise FieldNotFoundError, "Field information missing" if fields.nil? && ! quiet
|
456
573
|
fields.each_with_index{|f,i| return i if f == field}
|
457
574
|
field_re = Regexp.new /#{field}/i
|
458
|
-
|
575
|
+
fields.each_with_index{|f,i| return i if f =~ field_re}
|
459
576
|
raise FieldNotFoundError, "Field #{ field.inspect } was not found" unless quiet
|
460
577
|
end
|
461
578
|
|
@@ -477,134 +594,6 @@ Subject: #{subject}
|
|
477
594
|
|
478
595
|
end
|
479
596
|
|
480
|
-
module NamedArray
|
481
|
-
extend ChainMethods
|
482
|
-
|
483
|
-
self.chain_prefix = :named_array
|
484
|
-
attr_accessor :fields
|
485
|
-
attr_accessor :key
|
486
|
-
|
487
|
-
def self.setup(array, fields, key = nil)
|
488
|
-
array.extend NamedArray
|
489
|
-
array.fields = fields
|
490
|
-
array.key = key
|
491
|
-
array
|
492
|
-
end
|
493
|
-
|
494
|
-
def merge(array)
|
495
|
-
double = Array === array.first
|
496
|
-
new = self.dup
|
497
|
-
(0..length - 1).each do |i|
|
498
|
-
if double
|
499
|
-
new[i] = new[i] + array[i]
|
500
|
-
else
|
501
|
-
new[i] << array[i]
|
502
|
-
end
|
503
|
-
end
|
504
|
-
new
|
505
|
-
end
|
506
|
-
|
507
|
-
def positions(fields)
|
508
|
-
if Array == fields
|
509
|
-
fields.collect{|field|
|
510
|
-
Misc.field_position(@fields, field)
|
511
|
-
}
|
512
|
-
else
|
513
|
-
Misc.field_position(@fields, fields)
|
514
|
-
end
|
515
|
-
end
|
516
|
-
|
517
|
-
def named_array_get_brackets(key)
|
518
|
-
if defined? Entity
|
519
|
-
entity = (defined?(Entity) and Entity.respond_to?(:formats)) ? Entity.formats[key] : nil
|
520
|
-
if entity
|
521
|
-
elem = if entity.annotations.first == :format
|
522
|
-
entity.setup(named_array_clean_get_brackets(Misc.field_position(fields, key)), key)
|
523
|
-
else
|
524
|
-
entity.setup(named_array_clean_get_brackets(Misc.field_position(fields, key)))
|
525
|
-
end
|
526
|
-
elem.context = self
|
527
|
-
elem
|
528
|
-
else
|
529
|
-
named_array_clean_get_brackets(Misc.field_position(fields, key))
|
530
|
-
end
|
531
|
-
else
|
532
|
-
named_array_clean_get_brackets(Misc.field_position(fields, key))
|
533
|
-
end
|
534
|
-
end
|
535
|
-
|
536
|
-
def named_array_each(&block)
|
537
|
-
if defined?(Entity) and not @fields.nil? and not @fields.empty?
|
538
|
-
@fields.zip(self).each do |field,elem|
|
539
|
-
entity = (defined?(Entity) and Entity.respond_to?(:formats)) ? Entity.formats[field] : nil
|
540
|
-
|
541
|
-
if entity
|
542
|
-
elem = elem.dup if elem.frozen?
|
543
|
-
if entity.annotations.first == :format
|
544
|
-
entity.setup(elem, field)
|
545
|
-
else
|
546
|
-
entity.setup(elem)
|
547
|
-
end
|
548
|
-
elem.context = self
|
549
|
-
elem
|
550
|
-
end
|
551
|
-
|
552
|
-
yield(elem)
|
553
|
-
elem
|
554
|
-
end
|
555
|
-
else
|
556
|
-
named_array_clean_each &block
|
557
|
-
end
|
558
|
-
end
|
559
|
-
|
560
|
-
def named_array_collect
|
561
|
-
res = []
|
562
|
-
|
563
|
-
named_array_each do |elem|
|
564
|
-
if block_given?
|
565
|
-
res << yield(elem)
|
566
|
-
else
|
567
|
-
res << elem
|
568
|
-
end
|
569
|
-
end
|
570
|
-
|
571
|
-
res
|
572
|
-
end
|
573
|
-
|
574
|
-
def named_array_set_brackets(key,value)
|
575
|
-
named_array_clean_set_brackets(Misc.field_position(fields, key), value)
|
576
|
-
end
|
577
|
-
|
578
|
-
def named_array_values_at(*keys)
|
579
|
-
keys = keys.collect{|k| Misc.field_position(fields, k) }
|
580
|
-
named_array_clean_values_at(*keys)
|
581
|
-
end
|
582
|
-
|
583
|
-
def zip_fields
|
584
|
-
return [] if self.empty?
|
585
|
-
zipped = Misc.zip_fields(self)
|
586
|
-
zipped = zipped.collect{|v| NamedArray.setup(v, fields)}
|
587
|
-
zipped
|
588
|
-
end
|
589
|
-
|
590
|
-
def detach(file)
|
591
|
-
file_fields = file.fields.collect{|field| field.fullname}
|
592
|
-
detached_fields = []
|
593
|
-
self.fields.each_with_index{|field,i| detached_fields << i if file_fields.include? field.fullname}
|
594
|
-
fields = self.fields.values_at *detached_fields
|
595
|
-
values = self.values_at *detached_fields
|
596
|
-
values = NamedArray.name(values, fields)
|
597
|
-
values.zip_fields
|
598
|
-
end
|
599
|
-
|
600
|
-
def report
|
601
|
-
fields.zip(self).collect do |field,value|
|
602
|
-
"#{ field }: #{ Array === value ? value * "|" : value }"
|
603
|
-
end * "\n"
|
604
|
-
end
|
605
|
-
|
606
|
-
end
|
607
|
-
|
608
597
|
class RBBTError < StandardError
|
609
598
|
attr_accessor :info
|
610
599
|
|
@@ -664,7 +653,7 @@ module IndiferentHash
|
|
664
653
|
|
665
654
|
def self.setup(hash)
|
666
655
|
return hash if IndiferentHash === hash
|
667
|
-
hash.extend IndiferentHash
|
656
|
+
hash.extend IndiferentHash unless IndiferentHash === hash
|
668
657
|
hash
|
669
658
|
end
|
670
659
|
end
|