rbbt-util 4.1.0 → 4.2.0
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.
- 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
|