rbbt-util 5.44.0 → 6.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (169) hide show
  1. checksums.yaml +4 -4
  2. data/bin/rbbt +67 -90
  3. data/etc/app.d/base.rb +3 -3
  4. data/etc/app.d/semaphores.rb +3 -3
  5. data/lib/rbbt/annotations/annotated_array.rb +207 -207
  6. data/lib/rbbt/annotations/refactor.rb +27 -0
  7. data/lib/rbbt/annotations/util.rb +282 -282
  8. data/lib/rbbt/annotations.rb +343 -320
  9. data/lib/rbbt/association/database.rb +200 -225
  10. data/lib/rbbt/association/index.rb +294 -291
  11. data/lib/rbbt/association/item.rb +227 -227
  12. data/lib/rbbt/association/open.rb +35 -34
  13. data/lib/rbbt/association/util.rb +0 -169
  14. data/lib/rbbt/association.rb +2 -4
  15. data/lib/rbbt/entity/identifiers.rb +119 -118
  16. data/lib/rbbt/entity/refactor.rb +12 -0
  17. data/lib/rbbt/entity.rb +319 -315
  18. data/lib/rbbt/hpc/batch.rb +72 -53
  19. data/lib/rbbt/hpc/lsf.rb +2 -2
  20. data/lib/rbbt/hpc/orchestrate/batches.rb +2 -2
  21. data/lib/rbbt/hpc/orchestrate/chains.rb +25 -5
  22. data/lib/rbbt/hpc/orchestrate/rules.rb +2 -2
  23. data/lib/rbbt/hpc/orchestrate.rb +19 -13
  24. data/lib/rbbt/hpc/slurm.rb +18 -18
  25. data/lib/rbbt/knowledge_base/entity.rb +13 -5
  26. data/lib/rbbt/knowledge_base/query.rb +2 -2
  27. data/lib/rbbt/knowledge_base/registry.rb +32 -31
  28. data/lib/rbbt/knowledge_base/traverse.rb +1 -1
  29. data/lib/rbbt/knowledge_base.rb +1 -1
  30. data/lib/rbbt/monitor.rb +36 -25
  31. data/lib/rbbt/persist/refactor.rb +166 -0
  32. data/lib/rbbt/persist/tsv/sharder.rb +1 -1
  33. data/lib/rbbt/persist/tsv/tokyocabinet.rb +105 -105
  34. data/lib/rbbt/persist/tsv.rb +187 -185
  35. data/lib/rbbt/persist.rb +556 -551
  36. data/lib/rbbt/refactor.rb +20 -0
  37. data/lib/rbbt/resource/path/refactor.rb +178 -0
  38. data/lib/rbbt/resource/path.rb +317 -497
  39. data/lib/rbbt/resource/util.rb +0 -48
  40. data/lib/rbbt/resource.rb +3 -390
  41. data/lib/rbbt/tsv/accessor.rb +2 -838
  42. data/lib/rbbt/tsv/attach.rb +303 -299
  43. data/lib/rbbt/tsv/change_id.rb +244 -245
  44. data/lib/rbbt/tsv/csv.rb +87 -85
  45. data/lib/rbbt/tsv/dumper.rb +2 -100
  46. data/lib/rbbt/tsv/excel.rb +26 -24
  47. data/lib/rbbt/tsv/field_index.rb +4 -1
  48. data/lib/rbbt/tsv/filter.rb +3 -2
  49. data/lib/rbbt/tsv/index.rb +2 -284
  50. data/lib/rbbt/tsv/manipulate.rb +750 -747
  51. data/lib/rbbt/tsv/marshal.rb +3 -3
  52. data/lib/rbbt/tsv/matrix.rb +2 -2
  53. data/lib/rbbt/tsv/parallel/through.rb +2 -1
  54. data/lib/rbbt/tsv/parallel/traverse.rb +783 -781
  55. data/lib/rbbt/tsv/parser.rb +678 -678
  56. data/lib/rbbt/tsv/refactor.rb +195 -0
  57. data/lib/rbbt/tsv/stream.rb +253 -251
  58. data/lib/rbbt/tsv/util.rb +420 -420
  59. data/lib/rbbt/tsv.rb +210 -208
  60. data/lib/rbbt/util/R/eval.rb +4 -4
  61. data/lib/rbbt/util/R/plot.rb +62 -166
  62. data/lib/rbbt/util/R.rb +21 -18
  63. data/lib/rbbt/util/cmd.rb +2 -318
  64. data/lib/rbbt/util/color.rb +269 -269
  65. data/lib/rbbt/util/colorize.rb +89 -89
  66. data/lib/rbbt/util/concurrency/processes/refactor.rb +22 -0
  67. data/lib/rbbt/util/concurrency/processes/worker.rb +2 -2
  68. data/lib/rbbt/util/concurrency/processes.rb +389 -386
  69. data/lib/rbbt/util/config.rb +169 -167
  70. data/lib/rbbt/util/iruby.rb +20 -0
  71. data/lib/rbbt/util/log/progress/report.rb +241 -241
  72. data/lib/rbbt/util/log/progress/util.rb +99 -99
  73. data/lib/rbbt/util/log/progress.rb +102 -102
  74. data/lib/rbbt/util/log/refactor.rb +49 -0
  75. data/lib/rbbt/util/log.rb +486 -532
  76. data/lib/rbbt/util/migrate.rb +1 -1
  77. data/lib/rbbt/util/misc/concurrent_stream.rb +248 -246
  78. data/lib/rbbt/util/misc/development.rb +12 -11
  79. data/lib/rbbt/util/misc/exceptions.rb +117 -112
  80. data/lib/rbbt/util/misc/format.rb +2 -230
  81. data/lib/rbbt/util/misc/indiferent_hash.rb +2 -107
  82. data/lib/rbbt/util/misc/inspect.rb +2 -476
  83. data/lib/rbbt/util/misc/lock.rb +109 -106
  84. data/lib/rbbt/util/misc/omics.rb +10 -1
  85. data/lib/rbbt/util/misc/pipes.rb +765 -793
  86. data/lib/rbbt/util/misc/refactor.rb +20 -0
  87. data/lib/rbbt/util/misc/ssw.rb +308 -0
  88. data/lib/rbbt/util/misc/system.rb +0 -15
  89. data/lib/rbbt/util/misc.rb +39 -20
  90. data/lib/rbbt/util/named_array/refactor.rb +4 -0
  91. data/lib/rbbt/util/named_array.rb +3 -220
  92. data/lib/rbbt/util/open/refactor.rb +7 -0
  93. data/lib/rbbt/util/open.rb +3 -857
  94. data/lib/rbbt/util/procpath.rb +6 -6
  95. data/lib/rbbt/util/python/paths.rb +27 -0
  96. data/lib/rbbt/util/python/run.rb +115 -0
  97. data/lib/rbbt/util/python/script.rb +110 -0
  98. data/lib/rbbt/util/python/util.rb +3 -3
  99. data/lib/rbbt/util/python.rb +22 -81
  100. data/lib/rbbt/util/semaphore.rb +152 -148
  101. data/lib/rbbt/util/simpleopt.rb +9 -8
  102. data/lib/rbbt/util/ssh/refactor.rb +19 -0
  103. data/lib/rbbt/util/ssh.rb +122 -118
  104. data/lib/rbbt/util/tar.rb +117 -115
  105. data/lib/rbbt/util/tmpfile.rb +69 -67
  106. data/lib/rbbt/util/version.rb +2 -0
  107. data/lib/rbbt/workflow/refactor/entity.rb +11 -0
  108. data/lib/rbbt/workflow/refactor/export.rb +66 -0
  109. data/lib/rbbt/workflow/refactor/inputs.rb +24 -0
  110. data/lib/rbbt/workflow/refactor/recursive.rb +64 -0
  111. data/lib/rbbt/workflow/refactor/task_info.rb +65 -0
  112. data/lib/rbbt/workflow/refactor.rb +153 -0
  113. data/lib/rbbt/workflow/remote_workflow/driver/ssh.rb +55 -32
  114. data/lib/rbbt/workflow/remote_workflow/remote_step/rest.rb +3 -1
  115. data/lib/rbbt/workflow/remote_workflow/remote_step/ssh.rb +14 -5
  116. data/lib/rbbt/workflow/remote_workflow/remote_step.rb +19 -7
  117. data/lib/rbbt/workflow/remote_workflow.rb +6 -1
  118. data/lib/rbbt/workflow/step/info.rb +2 -2
  119. data/lib/rbbt/workflow/step/run.rb +766 -766
  120. data/lib/rbbt/workflow/step/save_load_inputs.rb +254 -254
  121. data/lib/rbbt/workflow/step.rb +2 -362
  122. data/lib/rbbt/workflow/task.rb +118 -118
  123. data/lib/rbbt/workflow/usage.rb +289 -287
  124. data/lib/rbbt/workflow/util/archive.rb +6 -5
  125. data/lib/rbbt/workflow/util/data.rb +1 -1
  126. data/lib/rbbt/workflow/util/orchestrator.rb +249 -246
  127. data/lib/rbbt/workflow/util/trace.rb +79 -44
  128. data/lib/rbbt/workflow.rb +4 -882
  129. data/lib/rbbt-util.rb +21 -13
  130. data/lib/rbbt.rb +16 -3
  131. data/python/rbbt/__init__.py +19 -1
  132. data/share/Rlib/plot.R +37 -37
  133. data/share/Rlib/svg.R +22 -5
  134. data/share/install/software/lib/install_helpers +1 -1
  135. data/share/rbbt_commands/hpc/list +2 -3
  136. data/share/rbbt_commands/hpc/orchestrate +4 -4
  137. data/share/rbbt_commands/hpc/tail +2 -0
  138. data/share/rbbt_commands/hpc/task +10 -7
  139. data/share/rbbt_commands/lsf/list +2 -3
  140. data/share/rbbt_commands/lsf/orchestrate +4 -4
  141. data/share/rbbt_commands/lsf/tail +2 -0
  142. data/share/rbbt_commands/lsf/task +10 -7
  143. data/share/rbbt_commands/migrate +1 -1
  144. data/share/rbbt_commands/pbs/list +2 -3
  145. data/share/rbbt_commands/pbs/orchestrate +4 -4
  146. data/share/rbbt_commands/pbs/tail +2 -0
  147. data/share/rbbt_commands/pbs/task +10 -7
  148. data/share/rbbt_commands/resource/produce +8 -1
  149. data/share/rbbt_commands/slurm/list +2 -3
  150. data/share/rbbt_commands/slurm/orchestrate +4 -4
  151. data/share/rbbt_commands/slurm/tail +2 -0
  152. data/share/rbbt_commands/slurm/task +10 -7
  153. data/share/rbbt_commands/system/clean +5 -5
  154. data/share/rbbt_commands/system/status +5 -5
  155. data/share/rbbt_commands/tsv/get +2 -3
  156. data/share/rbbt_commands/tsv/info +10 -13
  157. data/share/rbbt_commands/tsv/keys +18 -14
  158. data/share/rbbt_commands/tsv/slice +2 -2
  159. data/share/rbbt_commands/tsv/transpose +6 -2
  160. data/share/rbbt_commands/workflow/info +20 -24
  161. data/share/rbbt_commands/workflow/list +1 -1
  162. data/share/rbbt_commands/workflow/prov +20 -13
  163. data/share/rbbt_commands/workflow/server +16 -1
  164. data/share/rbbt_commands/workflow/task +76 -71
  165. data/share/rbbt_commands/workflow/write_info +26 -9
  166. data/share/software/opt/ssw/ssw.c +861 -0
  167. data/share/software/opt/ssw/ssw.h +130 -0
  168. data/share/workflow_config.ru +3 -3
  169. metadata +42 -3
@@ -1,747 +1,750 @@
1
- module TSV
2
-
3
- attr_accessor :monitor
4
-
5
- class Traverser
6
- attr_accessor :new_key_field, :new_fields, :new_key_field_name, :new_field_names, :type, :uniq
7
-
8
- def process_null(key, values)
9
- [[key], values]
10
- end
11
-
12
- def process_subset_list(key, values)
13
- [key, @new_fields.collect{|field| field == :key ? key : values[field] }]
14
- end
15
-
16
- def process_subset_all_but_list(key, values)
17
- new = values.dup
18
- new.delete_at(0 - @new_fields)
19
- [key, new]
20
- end
21
-
22
- def process_reorder_single(key, values)
23
- new_key = @new_key_field == :key ? key : values
24
- new_value = @new_fields.collect{|field| field == :key ? key : values }.first
25
- return [new_key, new_value]
26
- [ [values[@new_key_field]],
27
- @new_fields.collect{|field| field == :key ? key : values[field] }]
28
- end
29
-
30
- def process_reorder_list(key, values)
31
- [ [values[@new_key_field]],
32
- @new_fields.collect{|field| field == :key ? key : values[field] }]
33
- end
34
-
35
- def process_reorder_double_uniq(key, values)
36
- [ values[@new_key_field].uniq,
37
- @new_fields.collect{|field| field == :key ?
38
- [key] : values[field] }
39
- ]
40
- end
41
-
42
- def process_subset_double(key, values)
43
- [[key], @new_fields.collect{|field| field == :key ? [key] : values[field] }]
44
- end
45
-
46
- def process_subset_all_but_double(key, values)
47
- new = values.dup
48
- new.delete_at(0 - @new_fields)
49
- [[key], new]
50
- end
51
-
52
- def process_reorder_double(key, values)
53
- [ values[@new_key_field],
54
- @new_fields.collect{|field| field == :key ?
55
- [key] : values[field] }
56
- ]
57
- end
58
-
59
- def process_reorder_flat(key, values)
60
- [ values,
61
- @new_fields.collect{|field| field == :key ?
62
- [key] : values[field] }.flatten
63
- ]
64
- end
65
-
66
- def initialize(key_field, fields, new_key_field, new_fields, type, uniq)
67
- @new_key_field = TSV.identify_field(key_field, fields, new_key_field)
68
-
69
- raise "Key field #{ new_key_field } not found" if @new_key_field.nil?
70
- @new_fields = case new_fields
71
- when nil
72
- case
73
- when @new_key_field == :key
74
- :all
75
- when fields.nil?
76
- - @new_key_field
77
- else
78
- new = (0..fields.length - 1).to_a
79
- new.delete_at(@new_key_field)
80
- new.unshift :key
81
- new
82
- end
83
- when Array
84
- new_fields.collect do |field|
85
- TSV.identify_field(key_field, fields, field)
86
- end
87
- when String, Symbol
88
- [TSV.identify_field(key_field, fields, new_fields)]
89
- else
90
- raise "Unknown format for new_fields (should be nil, Array or String): #{new_fields.inspect}"
91
- end
92
-
93
- @new_key_field_name = case
94
- when @new_key_field == :key
95
- key_field
96
- else
97
- fields[@new_key_field] if Array === fields
98
- end
99
-
100
- if Array === fields
101
- @new_field_names = case
102
- when fields.nil?
103
- nil
104
- when Array === @new_fields
105
- @new_field_names = @new_fields.collect do |field|
106
- case
107
- when field == :key
108
- key_field
109
- else
110
- fields[field]
111
- end
112
- end
113
- when @new_fields == :all
114
- fields
115
- when (Numeric === @new_fields and @new_fields <= 0)
116
- new = fields.dup
117
- new.delete_at(- @new_fields)
118
- new.unshift key_field
119
- new
120
- end
121
- end
122
-
123
- case
124
- when (@new_key_field == :key and (@new_fields == :all or fields.nil? or @new_fields == (0..fields.length - 1).to_a))
125
- self.instance_eval do alias process process_null end
126
- when @new_key_field == :key
127
- if type == :double
128
- if Numeric === @new_fields and @new_fields <= 0
129
- self.instance_eval do alias process process_subset_all_but_double end
130
- else
131
- self.instance_eval do alias process process_subset_double end
132
- end
133
- else
134
- if Numeric === @new_fields and @new_fields <= 0
135
- self.instance_eval do alias process process_subset_all_but_list end
136
- else
137
- self.instance_eval do alias process process_subset_list end
138
- end
139
- end
140
- else
141
- case type
142
- when :double
143
- if uniq
144
- self.instance_eval do alias process process_reorder_double_uniq end
145
- else
146
- self.instance_eval do alias process process_reorder_double end
147
- end
148
- when :flat
149
- self.instance_eval do alias process process_reorder_flat end
150
- when :single
151
- self.instance_eval do alias process process_reorder_single end
152
- else
153
- self.instance_eval do alias process process_reorder_list end
154
- end
155
- end
156
- end
157
- end
158
-
159
- #{{{ Methods
160
-
161
- def through(new_key_field = nil, new_fields = nil, uniq = false, zipped = false)
162
-
163
- traverser = Traverser.new key_field, fields, new_key_field, new_fields, type, uniq
164
-
165
- if @monitor
166
- if Log::ProgressBar === @monitor
167
- @monitor.max = size
168
- progress_monitor = @monitor
169
- else
170
- desc = "Iterating TSV"
171
- step = 100
172
- if Hash === @monitor
173
- desc = @monitor[:desc] if @monitor.include? :desc
174
- step = @monitor[:step] if @monitor.include? :step
175
- elsif String === @monitor
176
- desc = @monitor
177
- end
178
- progress_monitor = Log::ProgressBar.new_bar(size, :desc => desc)
179
- end
180
- else
181
- progress_monitor = nil
182
- end
183
-
184
- each do |key, value|
185
- progress_monitor.tick if progress_monitor
186
-
187
- keys, value = traverser.process(key, value)
188
-
189
- next if keys.nil?
190
-
191
- keys = [keys].compact unless Array === keys
192
-
193
- # Annotated with Entity and NamedArray
194
- if not @unnamed and not traverser.new_field_names.nil?
195
-
196
- case type
197
- when :double, :list
198
- #Log.warn "Value frozen: #{ value }" if value.frozen?
199
-
200
- value.nil? ?
201
- nil :
202
- NamedArray.setup(value, traverser.new_field_names, key, entity_options, entity_templates)
203
-
204
- when :flat, :single
205
- prepare_entity(value, traverser.new_field_names.first, entity_options)
206
- end
207
- end
208
-
209
-
210
-
211
- if zipped
212
-
213
- keys.each_with_index do |k,i|
214
- v = value.collect{|v|
215
- r = v[i]
216
- r = v[0] if r.nil?
217
- r
218
- }
219
-
220
- if not @unnamed
221
- k = Misc.prepare_entity(k, traverser.new_key_field_name, entity_options)
222
- end
223
-
224
- v.key = k if NamedArray === v
225
-
226
- yield k, v
227
-
228
- end
229
-
230
- else
231
-
232
- keys.each do |key|
233
- if not @unnamed
234
- k = Misc.prepare_entity(k, traverser.new_key_field_name, entity_options)
235
- end
236
- value.key = key if NamedArray === value
237
- yield key, value
238
- end
239
-
240
- end
241
-
242
- end
243
-
244
- Log::ProgressBar.remove_bar progress_monitor if progress_monitor
245
-
246
- [traverser.new_key_field_name, traverser.new_field_names]
247
- end
248
-
249
- def reorder(new_key_field = nil, new_fields = nil, options = {})
250
- zipped, uniq, merge = Misc.process_options options, :zipped, :uniq, :merge
251
-
252
- persist_options = Misc.pull_keys options, :persist
253
- persist_options[:prefix] = "Reorder"
254
-
255
- Persist.persist_tsv self, self.filename, self.options.merge({:key_field => new_key_field, :fields => new_fields}), persist_options do |data|
256
- data.serializer = type if data.respond_to? :serializer and data.serializer == :type
257
-
258
- new_key_field_name, new_field_names = nil, nil
259
- with_unnamed do
260
- if zipped or (type != :double and type != :flat)
261
- new_key_field_name, new_field_names = through new_key_field, new_fields, uniq, zipped do |key, value|
262
- if merge
263
- if data[key]
264
- new_values = data[key].dup
265
- value.each_with_index do |v,i|
266
- new_values[i] += [v]
267
- end
268
- data[key] = new_values if Array === value
269
- else
270
- data[key] = value.collect{|v| [v]} if Array === value
271
- end
272
- else
273
- data[key] = value.clone if Array === value
274
- end
275
- end
276
- else
277
- case type
278
- when :double
279
- new_key_field_name, new_field_names = through new_key_field, new_fields, uniq, zipped do |keys, value|
280
- keys = [keys] unless Array === keys
281
- keys.each do |key|
282
- if data[key]
283
- current = data[key].dup
284
- value.each_with_index do |v, i|
285
- if current[i]
286
- current[i] += v if v
287
- else
288
- current[i] = v || []
289
- end
290
- end
291
- data[key] = current
292
- else
293
- data[key] = value.collect{|v| v.nil? ? nil : v.dup}
294
- end
295
- end
296
- end
297
- when :flat
298
- new_key_field_name, new_field_names = through new_key_field, new_fields, uniq, zipped do |key, value|
299
- data[key] ||= []
300
- data[key] += value
301
- end
302
- else
303
- raise "Unkown type #{type}"
304
- end
305
- end
306
- end
307
-
308
- #if real_data and real_data.respond_to? :persistence_path
309
- # real_data.serializer = type if real_data.respond_to? :serializer
310
- # real_data.merge!(data)
311
- # data = real_data
312
- #end
313
-
314
- data.extend TSV unless TSV === data
315
- self.annotate(data)
316
- data.entity_options = self.entity_options
317
- data.entity_templates = self.entity_templates
318
-
319
- data.key_field = new_key_field_name
320
- data.fields = new_field_names
321
- data.fields.each do |field|
322
- data.entity_templates[field] = entity_templates[field] if entity_templates.include? field
323
- end
324
- data.type = zipped ? (merge ? :double : :list) : type
325
-
326
- data
327
- end
328
- end
329
-
330
- def slice(fields)
331
- reorder :key, fields
332
- end
333
-
334
- def sort(*fields)
335
- fields = nil if fields.empty?
336
-
337
- elems = []
338
- through :key, fields do |key, value|
339
- elems << case
340
- when block_given?
341
- [key, yield(*value)]
342
- else
343
- case
344
- when type == :single
345
- [key, value]
346
- when type == :double
347
- [key, value.first.first]
348
- else
349
- [key, value.first]
350
- end
351
- end
352
- end
353
-
354
- elems.sort_by{|k,v| v}.collect{|k,v| k}
355
- end
356
-
357
- def subset(keys)
358
- new = TSV.setup({}, :key_field => key_field, :fields => fields, :type => type, :filename => filename, :identifiers => identifiers)
359
- self.with_unnamed do
360
- keys.each do |k|
361
- new[k] = self[k] if self.include?(k)
362
- end
363
- end
364
- new
365
- end
366
-
367
- def select(method = nil, invert = false, &block)
368
- new = TSV.setup({}, :key_field => key_field, :fields => fields, :type => type, :filename => filename, :identifiers => identifiers)
369
-
370
- self.annotate(new)
371
- #new.key_field = key_field
372
- #new.fields = fields.dup unless fields.nil?
373
- #new.type = type
374
- #new.filename = filename
375
- #new.namespace = namespace
376
- #new.entity_options = entity_options
377
- #new.entity_templates = entity_templates
378
-
379
- case
380
- when (method.nil? and block_given?)
381
- through do |key, values|
382
- new[key] = values if invert ^ (yield key, values)
383
- end
384
- when Array === method
385
- method = Set.new method
386
- with_unnamed do
387
- case type
388
- when :single
389
- through do |key, value|
390
- new[key] = value if invert ^ (method.include? key or method.include? value)
391
- end
392
- when :list, :flat
393
- through do |key, values|
394
- new[key] = values if invert ^ (method.include? key or (method & values).length > 0)
395
- end
396
- else
397
- through do |key, values|
398
- new[key] = values if invert ^ (method.include? key or (method & values.flatten).length > 0)
399
- end
400
- end
401
- end
402
- when Regexp === method
403
- with_unnamed do
404
- through do |key, values|
405
- new[key] = values if invert ^ ([key,values].flatten.select{|v| v =~ method}.any?)
406
- end
407
- end
408
- when (String === method || Symbol === method)
409
- if block_given?
410
- case
411
- when block.arity == 1
412
- with_unnamed do
413
- case
414
- when (method == key_field or method == :key)
415
- through do |key, values|
416
- new[key] = values if invert ^ (yield(key))
417
- end
418
- when (type == :single or type == :flat)
419
- through do |key, value|
420
- new[key] = value if invert ^ (yield(value))
421
- end
422
- else
423
- pos = identify_field method
424
- raise "Field #{ method } not identified. Available: #{ fields * ", " }" if pos.nil?
425
-
426
- through do |key, values|
427
- new[key] = values if invert ^ (yield(values[pos]))
428
- end
429
- end
430
- end
431
- when block.arity == 2
432
- with_unnamed do
433
- case
434
- when (method == key_field or method == :key)
435
- through do |key, values|
436
- new[key] = values if invert ^ (yield(key, key))
437
- end
438
- when (type == :single or type == :flat)
439
- through do |key, value|
440
- new[key] = value if invert ^ (yield(key, value))
441
- end
442
- else
443
- pos = identify_field method
444
- through do |key, values|
445
- new[key] = values if invert ^ (yield(key, values[pos]))
446
- end
447
- end
448
-
449
- end
450
- end
451
-
452
- else
453
- with_unnamed do
454
- through do |key, values|
455
- new[key] = values if invert ^ ([key,values].flatten.select{|v| v == method}.any?)
456
- end
457
- end
458
- end
459
- when Hash === method
460
- key = method.keys.first
461
- method = method.values.first
462
- case
463
- when (Array === method and (key == :key or key_field == key))
464
- with_unnamed do
465
- Annotated.purge(method).each{|key|
466
- new[key] = self[key] if invert ^ (self.include? key)
467
- }
468
- end
469
- when Array === method
470
- with_unnamed do
471
- method = Set.new method unless Set === method
472
- case type
473
- when :single
474
- through :key, key do |key, value|
475
- new[key] = self[key] if invert ^ (method.include? value)
476
- end
477
- when :list
478
- through :key, key do |key, values|
479
- new[key] = self[key] if invert ^ (method.include? values.first)
480
- end
481
- when :flat #untested
482
- through :key, key do |key, values|
483
- new[key] = self[key] if invert ^ ((method & values.flatten).any?)
484
- end
485
- else
486
- through :key, key do |key, values|
487
- new[key] = self[key] if invert ^ ((method & values.flatten).any?)
488
- end
489
- end
490
- end
491
-
492
- when Regexp === method
493
- with_unnamed do
494
- through :key, key do |key, values|
495
- values = [values] if type == :single
496
- new[key] = self[key] if invert ^ (values.flatten.select{|v| v =~ method}.any?)
497
- end
498
- end
499
-
500
- when (String === method and method =~ /name:(.*)/)
501
- name = $1
502
- old_unnamed = self.unnamed
503
- self.unnamed = false
504
- if name.strip =~ /^\/(.*)\/$/
505
- regexp = Regexp.new $1
506
- through :key, key do |key, values|
507
- case type
508
- when :single
509
- values = values.annotate([values])
510
- when :double
511
- values = values[0]
512
- end
513
- new[key] = self[key] if invert ^ (values.select{|v| v.name =~ regexp}.any?)
514
- end
515
- else
516
- through :key, key do |key, values|
517
- case type
518
- when :single
519
- values = values.annotate([values])
520
- when :double
521
- values = values[0]
522
- end
523
- new[key] = self[key] if invert ^ (values.select{|v| v.name == name}.any?)
524
- end
525
- end
526
- self.unnamed = old_unnamed
527
-
528
- when String === method
529
- if method =~ /^([<>]=?)(.*)/
530
- with_unnamed do
531
- through :key, key do |key, values|
532
- value = Array === values ? values.flatten.first : values
533
- new[key] = self[key] if value.to_f.send($1, $2.to_f)
534
- end
535
- end
536
- else
537
- with_unnamed do
538
- through :key, key do |key, values|
539
- values = [values] if type == :single
540
- new[key] = self[key] if invert ^ (values.flatten.select{|v| v == method}.length > 0)
541
- end
542
- end
543
- end
544
- when Numeric === method
545
- with_unnamed do
546
- through :key, key do |key, values|
547
- new[key] = self[key] if invert ^ (values.flatten.length >= method)
548
- end
549
- end
550
- when Proc === method
551
- with_unnamed do
552
- through :key, key do |key, values|
553
- values = [values] if type == :single
554
- new[key] = self[key] if invert ^ (values.flatten.select{|v| method.call(v)}.length > 0)
555
- end
556
- end
557
- end
558
- end
559
-
560
- new
561
- end
562
-
563
- def column(field, cast = nil)
564
- new = slice(field)
565
-
566
- new.with_unnamed do
567
- new.each do |k,v|
568
- nv = v.first
569
- nv = nv.send(cast) unless cast.nil?
570
- new[k] = nv
571
- end
572
- end
573
-
574
- case type
575
- when :double, :flat
576
- new.type = :flat
577
- else
578
- new.type = :single
579
- end
580
-
581
- new
582
- end
583
-
584
- def column_values(field, options = {})
585
- all = []
586
- through :key, field do |k,values|
587
- values = Array === values ? values.flatten : [values]
588
- all.concat values
589
- end
590
- prepare_entity(all, field, options = {})
591
- end
592
-
593
-
594
- def process_key(&block)
595
- new = annotate({})
596
- through do |key, values|
597
- key = case
598
- when block.arity == 1
599
- yield(key)
600
- when block.arity == 2
601
- yield(key, values)
602
- else
603
- raise "Unexpected arity in block, must be 1, 2 or 3: #{block.arity}"
604
- end
605
- new[key] = values
606
- end
607
- new
608
- end
609
-
610
- def process(field, &block)
611
- field_pos = identify_field field
612
-
613
- through do |key, values|
614
- case
615
- when type == :single
616
- field_values = values
617
- when type == :flat
618
- field_values = values
619
- else
620
- next if values.nil?
621
- field_values = values[field_pos]
622
- end
623
-
624
- new_values = case
625
- when block.arity == 1
626
- yield(field_values)
627
- when block.arity == 2
628
- yield(field_values, key)
629
- when block.arity == 3
630
- yield(field_values, key, values)
631
- else
632
- raise "Unexpected arity in block, must be 1, 2 or 3: #{block.arity}"
633
- end
634
-
635
- case
636
- when type == :single
637
- self[key] = new_values
638
- when type == :flat
639
- self[key] = new_values
640
- else
641
- if ! values[field_pos].frozen? && ((String === values[field_pos] && String === new_values) ||
642
- (Array === values[field_pos] && Array === new_values))
643
- values[field_pos].replace new_values
644
- else
645
- values[field_pos] = new_values
646
- end
647
- self[key] = values
648
- end
649
- end
650
-
651
- self
652
- end
653
-
654
- def add_field(name = nil)
655
- old_monitor = @monitor
656
- @monitor = {:desc => "Adding field #{ name }"} if TrueClass === monitor
657
-
658
- through do |key, values|
659
- new_values = yield(key, values)
660
- new_values = [new_values] if type == :double and not Array === new_values
661
-
662
- case
663
- when (values.nil? and (fields.nil? or fields.empty?))
664
- values = [new_values]
665
- when values.nil?
666
- values = [nil] * fields.length + [new_values]
667
- when Array === values
668
- values += [new_values]
669
- else
670
- values << new_values
671
- end
672
-
673
- self[key] = values
674
- end
675
- @monitor = old_monitor
676
-
677
- if not fields.nil? and not name.nil?
678
- new_fields = self.fields + [name]
679
- self.fields = new_fields
680
- end
681
-
682
- self
683
- end
684
-
685
- def add_fields(names = [])
686
- old_monitor = @monitor
687
- @monitor = {:desc => "Adding field #{ names * ", " }"} if TrueClass === monitor
688
-
689
- through do |key, values|
690
- values ||= fields ? [nil] * fields : []
691
- new_values = yield(key, values)
692
-
693
- case type
694
- when :double
695
- new_values = new_values.collect{|v| [v] } if Array === new_values and new_values.first and not Array === new_values.first
696
- values += new_values || [nil] * names.length
697
- when :list
698
- values += new_values || [nil] * names.length
699
- end
700
-
701
- self[key] = values
702
- end
703
- @monitor = old_monitor
704
-
705
- if not fields.nil? and not (names.nil? or names.empty?)
706
- new_fields = self.fields + names
707
- self.fields = new_fields
708
- end
709
-
710
- self
711
- end
712
-
713
- def transpose_list(key_field="Unkown ID")
714
- new_fields = keys.dup
715
- new = self.annotate({})
716
- TSV.setup(new, :key_field => key_field, :fields => new_fields, :type => type, :filename => filename, :identifiers => identifiers)
717
-
718
- require 'matrix'
719
- m = Matrix.rows values
720
- new_rows = m.transpose.to_a
721
-
722
- fields.zip(new_rows) do |key,row|
723
- new[key] = row
724
- end
725
-
726
- new
727
- end
728
-
729
- def transpose_double(key_field = "Unkown ID")
730
- sep = "-!SEP--#{rand 10000}!-"
731
- tmp = self.to_list{|v| v * sep}
732
- new = tmp.transpose_list(key_field)
733
- new.to_double{|v| v.split(sep)}
734
- end
735
-
736
- def transpose(key_field = "Unkown ID")
737
- case type
738
- when :single, :flat
739
- self.to_list.transpose_list key_field
740
- when :list
741
- transpose_list key_field
742
- when :double
743
- transpose_double key_field
744
- end
745
- end
746
-
747
- end
1
+ #module TSV
2
+ #
3
+ # def self.identify_field(key_field, fields, name)
4
+ # return 0 if name == :key || key_field.start_with?(name.to_s)
5
+ # pos = NamedArray.identify_name(fields, name)
6
+ # pos.nil? ? nil : pos + 1
7
+ # end
8
+ #
9
+ # def identify_field(name)
10
+ # TSV.identify_field(@key_field, @fields, name)
11
+ # end
12
+ #
13
+ # attr_accessor :monitor
14
+ #
15
+ # class Traverser
16
+ # attr_accessor :new_key_field, :new_fields, :new_key_field_name, :new_field_names, :type, :uniq
17
+ #
18
+ # def process_null(key, values)
19
+ # [[key], values]
20
+ # end
21
+ #
22
+ # def process_subset_list(key, values)
23
+ # [key, @new_fields.collect{|field| field == :key ? key : values[field] }]
24
+ # end
25
+ #
26
+ # def process_subset_all_but_list(key, values)
27
+ # new = values.dup
28
+ # new.delete_at(0 - @new_fields)
29
+ # [key, new]
30
+ # end
31
+ #
32
+ # def process_reorder_single(key, values)
33
+ # new_key = @new_key_field == :key ? key : values
34
+ # new_value = @new_fields.collect{|field| field == :key ? key : values }.first
35
+ # return [new_key, new_value]
36
+ # [ [values[@new_key_field]],
37
+ # @new_fields.collect{|field| field == :key ? key : values[field] }]
38
+ # end
39
+ #
40
+ # def process_reorder_list(key, values)
41
+ # [ [values[@new_key_field]],
42
+ # @new_fields.collect{|field| field == :key ? key : values[field] }]
43
+ # end
44
+ #
45
+ # def process_reorder_double_uniq(key, values)
46
+ # [ values[@new_key_field].uniq,
47
+ # @new_fields.collect{|field| field == :key ?
48
+ # [key] : values[field] }
49
+ # ]
50
+ # end
51
+ #
52
+ # def process_subset_double(key, values)
53
+ # [[key], @new_fields.collect{|field| field == :key ? [key] : values[field] }]
54
+ # end
55
+ #
56
+ # def process_subset_all_but_double(key, values)
57
+ # new = values.dup
58
+ # new.delete_at(0 - @new_fields)
59
+ # [[key], new]
60
+ # end
61
+ #
62
+ # def process_reorder_double(key, values)
63
+ # [ values[@new_key_field],
64
+ # @new_fields.collect{|field| field == :key ?
65
+ # [key] : values[field] }
66
+ # ]
67
+ # end
68
+ #
69
+ # def process_reorder_flat(key, values)
70
+ # [ values,
71
+ # @new_fields.collect{|field| field == :key ?
72
+ # [key] : values[field] }.flatten
73
+ # ]
74
+ # end
75
+ #
76
+ # def initialize(key_field, fields, new_key_field, new_fields, type, uniq)
77
+ # @new_key_field = TSV.identify_field(key_field, fields, new_key_field)
78
+ #
79
+ # raise "Key field #{ new_key_field } not found" if @new_key_field.nil?
80
+ # @new_fields = case new_fields
81
+ # when nil
82
+ # case
83
+ # when @new_key_field == :key
84
+ # :all
85
+ # when fields.nil?
86
+ # - @new_key_field
87
+ # else
88
+ # new = (0..fields.length - 1).to_a
89
+ # new.delete_at(@new_key_field)
90
+ # new.unshift :key
91
+ # new
92
+ # end
93
+ # when Array
94
+ # new_fields.collect do |field|
95
+ # TSV.identify_field(key_field, fields, field)
96
+ # end
97
+ # when String, Symbol
98
+ # [TSV.identify_field(key_field, fields, new_fields)]
99
+ # else
100
+ # raise "Unknown format for new_fields (should be nil, Array or String): #{new_fields.inspect}"
101
+ # end
102
+ #
103
+ # @new_key_field_name = case
104
+ # when @new_key_field == :key
105
+ # key_field
106
+ # else
107
+ # fields[@new_key_field] if Array === fields
108
+ # end
109
+ #
110
+ # if Array === fields
111
+ # @new_field_names = case
112
+ # when fields.nil?
113
+ # nil
114
+ # when Array === @new_fields
115
+ # @new_field_names = @new_fields.collect do |field|
116
+ # case
117
+ # when field == :key
118
+ # key_field
119
+ # else
120
+ # fields[field]
121
+ # end
122
+ # end
123
+ # when @new_fields == :all
124
+ # fields
125
+ # when (Numeric === @new_fields and @new_fields <= 0)
126
+ # new = fields.dup
127
+ # new.delete_at(- @new_fields)
128
+ # new.unshift key_field
129
+ # new
130
+ # end
131
+ # end
132
+ #
133
+ # case
134
+ # when (@new_key_field == :key and (@new_fields == :all or fields.nil? or @new_fields == (0..fields.length - 1).to_a))
135
+ # self.instance_eval do alias process process_null end
136
+ # when @new_key_field == :key
137
+ # if type == :double
138
+ # if Numeric === @new_fields and @new_fields <= 0
139
+ # self.instance_eval do alias process process_subset_all_but_double end
140
+ # else
141
+ # self.instance_eval do alias process process_subset_double end
142
+ # end
143
+ # else
144
+ # if Numeric === @new_fields and @new_fields <= 0
145
+ # self.instance_eval do alias process process_subset_all_but_list end
146
+ # else
147
+ # self.instance_eval do alias process process_subset_list end
148
+ # end
149
+ # end
150
+ # else
151
+ # case type
152
+ # when :double
153
+ # if uniq
154
+ # self.instance_eval do alias process process_reorder_double_uniq end
155
+ # else
156
+ # self.instance_eval do alias process process_reorder_double end
157
+ # end
158
+ # when :flat
159
+ # self.instance_eval do alias process process_reorder_flat end
160
+ # when :single
161
+ # self.instance_eval do alias process process_reorder_single end
162
+ # else
163
+ # self.instance_eval do alias process process_reorder_list end
164
+ # end
165
+ # end
166
+ # end
167
+ # end
168
+ #
169
+ # #{{{ Methods
170
+ #
171
+ # def through(new_key_field = nil, new_fields = nil, uniq = false, zipped = false)
172
+ #
173
+ # traverser = Traverser.new key_field, fields, new_key_field, new_fields, type, uniq
174
+ #
175
+ # if @monitor
176
+ # if Log::ProgressBar === @monitor
177
+ # @monitor.max = size
178
+ # progress_monitor = @monitor
179
+ # else
180
+ # desc = "Iterating TSV"
181
+ # step = 100
182
+ # if Hash === @monitor
183
+ # desc = @monitor[:desc] if @monitor.include? :desc
184
+ # step = @monitor[:step] if @monitor.include? :step
185
+ # elsif String === @monitor
186
+ # desc = @monitor
187
+ # end
188
+ # progress_monitor = Log::ProgressBar.new_bar(size, :desc => desc)
189
+ # end
190
+ # else
191
+ # progress_monitor = nil
192
+ # end
193
+ #
194
+ # each do |key, value|
195
+ # progress_monitor.tick if progress_monitor
196
+ #
197
+ # keys, value = traverser.process(key, value)
198
+ #
199
+ # next if keys.nil?
200
+ #
201
+ # keys = [keys].compact unless Array === keys
202
+ #
203
+ # # Annotated with Entity and NamedArray
204
+ # if not @unnamed and not traverser.new_field_names.nil?
205
+ #
206
+ # case type
207
+ # when :double, :list
208
+ # #Log.warn "Value frozen: #{ value }" if value.frozen?
209
+ #
210
+ # value.nil? ?
211
+ # nil :
212
+ # NamedArray.setup(value, traverser.new_field_names, key, entity_options, entity_templates)
213
+ #
214
+ # when :flat, :single
215
+ # prepare_entity(value, traverser.new_field_names.first, entity_options)
216
+ # end
217
+ # end
218
+ #
219
+ #
220
+ #
221
+ # if zipped
222
+ #
223
+ # keys.each_with_index do |k,i|
224
+ # v = value.collect{|v|
225
+ # r = v[i]
226
+ # r = v[0] if r.nil?
227
+ # r
228
+ # }
229
+ #
230
+ # if not @unnamed
231
+ # k = Misc.prepare_entity(k, traverser.new_key_field_name, entity_options)
232
+ # end
233
+ #
234
+ # v.key = k if NamedArray === v
235
+ #
236
+ # yield k, v
237
+ #
238
+ # end
239
+ #
240
+ # else
241
+ #
242
+ # keys.each do |key|
243
+ # if not @unnamed
244
+ # k = Misc.prepare_entity(k, traverser.new_key_field_name, entity_options)
245
+ # end
246
+ # value.key = key if NamedArray === value
247
+ # yield key, value
248
+ # end
249
+ #
250
+ # end
251
+ #
252
+ # end
253
+ #
254
+ # Log::ProgressBar.remove_bar progress_monitor if progress_monitor
255
+ #
256
+ # [traverser.new_key_field_name, traverser.new_field_names]
257
+ # end
258
+ #
259
+ # def reorder(new_key_field = nil, new_fields = nil, options = {})
260
+ # zipped, uniq, merge = Misc.process_options options, :zipped, :uniq, :merge
261
+ #
262
+ # persist_options = Misc.pull_keys options, :persist
263
+ # persist_options[:prefix] = "Reorder"
264
+ #
265
+ # Persist.persist_tsv self, self.filename, self.options.merge({:key_field => new_key_field, :fields => new_fields}), persist_options do |data|
266
+ # data.serializer = type if data.respond_to? :serializer and data.serializer == :type
267
+ #
268
+ # new_key_field_name, new_field_names = nil, nil
269
+ # with_unnamed do
270
+ # if zipped or (type != :double and type != :flat)
271
+ # new_key_field_name, new_field_names = through new_key_field, new_fields, uniq, zipped do |key, value|
272
+ # if merge
273
+ # if data[key]
274
+ # new_values = data[key].dup
275
+ # value.each_with_index do |v,i|
276
+ # new_values[i] += [v]
277
+ # end
278
+ # data[key] = new_values if Array === value
279
+ # else
280
+ # data[key] = value.collect{|v| [v]} if Array === value
281
+ # end
282
+ # else
283
+ # data[key] = value.clone if Array === value
284
+ # end
285
+ # end
286
+ # else
287
+ # case type
288
+ # when :double
289
+ # new_key_field_name, new_field_names = through new_key_field, new_fields, uniq, zipped do |keys, value|
290
+ # keys = [keys] unless Array === keys
291
+ # keys.each do |key|
292
+ # if data[key]
293
+ # current = data[key].dup
294
+ # value.each_with_index do |v, i|
295
+ # if current[i]
296
+ # current[i] += v if v
297
+ # else
298
+ # current[i] = v || []
299
+ # end
300
+ # end
301
+ # data[key] = current
302
+ # else
303
+ # data[key] = value.collect{|v| v.nil? ? nil : v.dup}
304
+ # end
305
+ # end
306
+ # end
307
+ # when :flat
308
+ # new_key_field_name, new_field_names = through new_key_field, new_fields, uniq, zipped do |key, value|
309
+ # data[key] ||= []
310
+ # data[key] += value
311
+ # end
312
+ # else
313
+ # raise "Unkown type #{type}"
314
+ # end
315
+ # end
316
+ # end
317
+ #
318
+ # #if real_data and real_data.respond_to? :persistence_path
319
+ # # real_data.serializer = type if real_data.respond_to? :serializer
320
+ # # real_data.merge!(data)
321
+ # # data = real_data
322
+ # #end
323
+ #
324
+ # data.extend TSV unless TSV === data
325
+ # self.annotate(data)
326
+ # data.entity_options = self.entity_options
327
+ # data.entity_templates = self.entity_templates
328
+ #
329
+ # data.key_field = new_key_field_name
330
+ # data.fields = new_field_names
331
+ # data.fields.each do |field|
332
+ # data.entity_templates[field] = entity_templates[field] if entity_templates.include? field
333
+ # end
334
+ # data.type = zipped ? (merge ? :double : :list) : type
335
+ #
336
+ # data
337
+ # end
338
+ # end
339
+ #
340
+ # def slice(fields)
341
+ # reorder :key, fields
342
+ # end
343
+ #
344
+ # def sort(*fields)
345
+ # fields = nil if fields.empty?
346
+ #
347
+ # elems = []
348
+ # through :key, fields do |key, value|
349
+ # elems << case
350
+ # when block_given?
351
+ # [key, yield(*value)]
352
+ # else
353
+ # case
354
+ # when type == :single
355
+ # [key, value]
356
+ # when type == :double
357
+ # [key, value.first.first]
358
+ # else
359
+ # [key, value.first]
360
+ # end
361
+ # end
362
+ # end
363
+ #
364
+ # elems.sort_by{|k,v| v}.collect{|k,v| k}
365
+ # end
366
+ #
367
+ # def subset(keys)
368
+ # new = TSV.setup({}, :key_field => key_field, :fields => fields, :type => type, :filename => filename, :identifiers => identifiers)
369
+ # self.with_unnamed do
370
+ # keys.each do |k|
371
+ # new[k] = self[k] if self.include?(k)
372
+ # end
373
+ # end
374
+ # new
375
+ # end
376
+ #
377
+ # def select(method = nil, invert = false, &block)
378
+ # new = TSV.setup({}, :key_field => key_field, :fields => fields, :type => type, :filename => filename, :identifiers => identifiers)
379
+ #
380
+ # self.annotate(new)
381
+ #
382
+ # case
383
+ # when (method.nil? and block_given?)
384
+ # through do |key, values|
385
+ # new[key] = values if invert ^ (yield key, values)
386
+ # end
387
+ # when Array === method
388
+ # method = Set.new method
389
+ # with_unnamed do
390
+ # case type
391
+ # when :single
392
+ # through do |key, value|
393
+ # new[key] = value if invert ^ (method.include? key or method.include? value)
394
+ # end
395
+ # when :list, :flat
396
+ # through do |key, values|
397
+ # new[key] = values if invert ^ (method.include? key or (method & values).length > 0)
398
+ # end
399
+ # else
400
+ # through do |key, values|
401
+ # new[key] = values if invert ^ (method.include? key or (method & values.flatten).length > 0)
402
+ # end
403
+ # end
404
+ # end
405
+ # when Regexp === method
406
+ # with_unnamed do
407
+ # through do |key, values|
408
+ # new[key] = values if invert ^ ([key,values].flatten.select{|v| v =~ method}.any?)
409
+ # end
410
+ # end
411
+ # when (String === method || Symbol === method)
412
+ # if block_given?
413
+ # case
414
+ # when block.arity == 1
415
+ # with_unnamed do
416
+ # case
417
+ # when (method == key_field or method == :key)
418
+ # through do |key, values|
419
+ # new[key] = values if invert ^ (yield(key))
420
+ # end
421
+ # when (type == :single or type == :flat)
422
+ # through do |key, value|
423
+ # new[key] = value if invert ^ (yield(value))
424
+ # end
425
+ # else
426
+ # pos = identify_field method
427
+ # raise "Field #{ method } not identified. Available: #{ fields * ", " }" if pos.nil?
428
+ #
429
+ # through do |key, values|
430
+ # new[key] = values if invert ^ (yield(values[pos]))
431
+ # end
432
+ # end
433
+ # end
434
+ # when block.arity == 2
435
+ # with_unnamed do
436
+ # case
437
+ # when (method == key_field or method == :key)
438
+ # through do |key, values|
439
+ # new[key] = values if invert ^ (yield(key, key))
440
+ # end
441
+ # when (type == :single or type == :flat)
442
+ # through do |key, value|
443
+ # new[key] = value if invert ^ (yield(key, value))
444
+ # end
445
+ # else
446
+ # pos = identify_field method
447
+ # through do |key, values|
448
+ # new[key] = values if invert ^ (yield(key, values[pos]))
449
+ # end
450
+ # end
451
+ #
452
+ # end
453
+ # end
454
+ #
455
+ # else
456
+ # with_unnamed do
457
+ # through do |key, values|
458
+ # new[key] = values if invert ^ ([key,values].flatten.select{|v| v == method}.any?)
459
+ # end
460
+ # end
461
+ # end
462
+ # when Hash === method
463
+ # key = method.keys.first
464
+ # method = method.values.first
465
+ # case
466
+ # when (Array === method and (key == :key or key_field == key))
467
+ # with_unnamed do
468
+ # Annotated.purge(method).each{|key|
469
+ # new[key] = self[key] if invert ^ (self.include? key)
470
+ # }
471
+ # end
472
+ # when Array === method
473
+ # with_unnamed do
474
+ # method = Set.new method unless Set === method
475
+ # case type
476
+ # when :single
477
+ # through :key, key do |key, value|
478
+ # new[key] = self[key] if invert ^ (method.include? value)
479
+ # end
480
+ # when :list
481
+ # through :key, key do |key, values|
482
+ # new[key] = self[key] if invert ^ (method.include? values.first)
483
+ # end
484
+ # when :flat #untested
485
+ # through :key, key do |key, values|
486
+ # new[key] = self[key] if invert ^ ((method & values.flatten).any?)
487
+ # end
488
+ # else
489
+ # through :key, key do |key, values|
490
+ # new[key] = self[key] if invert ^ ((method & values.flatten).any?)
491
+ # end
492
+ # end
493
+ # end
494
+ #
495
+ # when Regexp === method
496
+ # with_unnamed do
497
+ # through :key, key do |key, values|
498
+ # values = [values] if type == :single
499
+ # new[key] = self[key] if invert ^ (values.flatten.select{|v| v =~ method}.any?)
500
+ # end
501
+ # end
502
+ #
503
+ # when (String === method and method =~ /name:(.*)/)
504
+ # name = $1
505
+ # old_unnamed = self.unnamed
506
+ # self.unnamed = false
507
+ # if name.strip =~ /^\/(.*)\/$/
508
+ # regexp = Regexp.new $1
509
+ # through :key, key do |key, values|
510
+ # case type
511
+ # when :single
512
+ # values = values.annotate([values])
513
+ # when :double
514
+ # values = values[0]
515
+ # end
516
+ # new[key] = self[key] if invert ^ (values.select{|v| v.name =~ regexp}.any?)
517
+ # end
518
+ # else
519
+ # through :key, key do |key, values|
520
+ # case type
521
+ # when :single
522
+ # values = values.annotate([values])
523
+ # when :double
524
+ # values = values[0]
525
+ # end
526
+ # new[key] = self[key] if invert ^ (values.select{|v| v.name == name}.any?)
527
+ # end
528
+ # end
529
+ # self.unnamed = old_unnamed
530
+ #
531
+ # when String === method
532
+ # if method =~ /^([<>]=?)(.*)/
533
+ # with_unnamed do
534
+ # through :key, key do |key, values|
535
+ # value = Array === values ? values.flatten.first : values
536
+ # new[key] = self[key] if value.to_f.send($1, $2.to_f)
537
+ # end
538
+ # end
539
+ # else
540
+ # with_unnamed do
541
+ # through :key, key do |key, values|
542
+ # values = [values] if type == :single
543
+ # new[key] = self[key] if invert ^ (values.flatten.select{|v| v == method}.length > 0)
544
+ # end
545
+ # end
546
+ # end
547
+ # when Numeric === method
548
+ # with_unnamed do
549
+ # through :key, key do |key, values|
550
+ # new[key] = self[key] if invert ^ (values.flatten.length >= method)
551
+ # end
552
+ # end
553
+ # when Proc === method
554
+ # with_unnamed do
555
+ # through :key, key do |key, values|
556
+ # values = [values] if type == :single
557
+ # new[key] = self[key] if invert ^ (values.flatten.select{|v| method.call(v)}.length > 0)
558
+ # end
559
+ # end
560
+ # end
561
+ # end
562
+ #
563
+ # new
564
+ # end
565
+ #
566
+ # def column(field, cast = nil)
567
+ # new = slice(field)
568
+ #
569
+ # new.with_unnamed do
570
+ # new.each do |k,v|
571
+ # nv = v.first
572
+ # nv = nv.send(cast) unless cast.nil?
573
+ # new[k] = nv
574
+ # end
575
+ # end
576
+ #
577
+ # case type
578
+ # when :double, :flat
579
+ # new.type = :flat
580
+ # else
581
+ # new.type = :single
582
+ # end
583
+ #
584
+ # new
585
+ # end
586
+ #
587
+ # def column_values(field, options = {})
588
+ # all = []
589
+ # through :key, field do |k,values|
590
+ # values = Array === values ? values.flatten : [values]
591
+ # all.concat values
592
+ # end
593
+ # prepare_entity(all, field, options = {})
594
+ # end
595
+ #
596
+ #
597
+ # def process_key(&block)
598
+ # new = annotate({})
599
+ # through do |key, values|
600
+ # key = case
601
+ # when block.arity == 1
602
+ # yield(key)
603
+ # when block.arity == 2
604
+ # yield(key, values)
605
+ # else
606
+ # raise "Unexpected arity in block, must be 1, 2 or 3: #{block.arity}"
607
+ # end
608
+ # new[key] = values
609
+ # end
610
+ # new
611
+ # end
612
+ #
613
+ # def process(field, &block)
614
+ # field_pos = identify_field field
615
+ #
616
+ # through do |key, values|
617
+ # case
618
+ # when type == :single
619
+ # field_values = values
620
+ # when type == :flat
621
+ # field_values = values
622
+ # else
623
+ # next if values.nil?
624
+ # field_values = values[field_pos]
625
+ # end
626
+ #
627
+ # new_values = case
628
+ # when block.arity == 1
629
+ # yield(field_values)
630
+ # when block.arity == 2
631
+ # yield(field_values, key)
632
+ # when block.arity == 3
633
+ # yield(field_values, key, values)
634
+ # else
635
+ # raise "Unexpected arity in block, must be 1, 2 or 3: #{block.arity}"
636
+ # end
637
+ #
638
+ # case
639
+ # when type == :single
640
+ # self[key] = new_values
641
+ # when type == :flat
642
+ # self[key] = new_values
643
+ # else
644
+ # if ! values[field_pos].frozen? && ((String === values[field_pos] && String === new_values) ||
645
+ # (Array === values[field_pos] && Array === new_values))
646
+ # values[field_pos].replace new_values
647
+ # else
648
+ # values[field_pos] = new_values
649
+ # end
650
+ # self[key] = values
651
+ # end
652
+ # end
653
+ #
654
+ # self
655
+ # end
656
+ #
657
+ # def add_field(name = nil)
658
+ # old_monitor = @monitor
659
+ # @monitor = {:desc => "Adding field #{ name }"} if TrueClass === monitor
660
+ #
661
+ # through do |key, values|
662
+ # new_values = yield(key, values)
663
+ # new_values = [new_values] if type == :double and not Array === new_values
664
+ #
665
+ # case
666
+ # when (values.nil? and (fields.nil? or fields.empty?))
667
+ # values = [new_values]
668
+ # when values.nil?
669
+ # values = [nil] * fields.length + [new_values]
670
+ # when Array === values
671
+ # values += [new_values]
672
+ # else
673
+ # values << new_values
674
+ # end
675
+ #
676
+ # self[key] = values
677
+ # end
678
+ # @monitor = old_monitor
679
+ #
680
+ # if not fields.nil? and not name.nil?
681
+ # new_fields = self.fields + [name]
682
+ # self.fields = new_fields
683
+ # end
684
+ #
685
+ # self
686
+ # end
687
+ #
688
+ # def add_fields(names = [])
689
+ # old_monitor = @monitor
690
+ # @monitor = {:desc => "Adding field #{ names * ", " }"} if TrueClass === monitor
691
+ #
692
+ # through do |key, values|
693
+ # values ||= fields ? [nil] * fields : []
694
+ # new_values = yield(key, values)
695
+ #
696
+ # case type
697
+ # when :double
698
+ # new_values = new_values.collect{|v| [v] } if Array === new_values and new_values.first and not Array === new_values.first
699
+ # values += new_values || [nil] * names.length
700
+ # when :list
701
+ # values += new_values || [nil] * names.length
702
+ # end
703
+ #
704
+ # self[key] = values
705
+ # end
706
+ # @monitor = old_monitor
707
+ #
708
+ # if not fields.nil? and not (names.nil? or names.empty?)
709
+ # new_fields = self.fields + names
710
+ # self.fields = new_fields
711
+ # end
712
+ #
713
+ # self
714
+ # end
715
+ #
716
+ # def transpose_list(key_field="Unkown ID")
717
+ # new_fields = keys.dup
718
+ # new = self.annotate({})
719
+ # TSV.setup(new, :key_field => key_field, :fields => new_fields, :type => type, :filename => filename, :identifiers => identifiers)
720
+ #
721
+ # require 'matrix'
722
+ # m = Matrix.rows values
723
+ # new_rows = m.transpose.to_a
724
+ #
725
+ # fields.zip(new_rows) do |key,row|
726
+ # new[key] = row
727
+ # end
728
+ #
729
+ # new
730
+ # end
731
+ #
732
+ # def transpose_double(key_field = "Unkown ID")
733
+ # sep = "-!SEP--#{rand 10000}!-"
734
+ # tmp = self.to_list{|v| v * sep}
735
+ # new = tmp.transpose_list(key_field)
736
+ # new.to_double{|v| v.split(sep)}
737
+ # end
738
+ #
739
+ # def transpose(key_field = "Unkown ID")
740
+ # case type
741
+ # when :single, :flat
742
+ # self.to_list.transpose_list key_field
743
+ # when :list
744
+ # transpose_list key_field
745
+ # when :double
746
+ # transpose_double key_field
747
+ # end
748
+ # end
749
+ #
750
+ #end