rbbt-util 5.44.1 → 6.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/bin/rbbt +67 -90
  4. data/bin/rbbt_exec.rb +2 -2
  5. data/etc/app.d/base.rb +2 -2
  6. data/etc/app.d/semaphores.rb +3 -3
  7. data/lib/rbbt/annotations/annotated_array.rb +207 -207
  8. data/lib/rbbt/annotations/refactor.rb +27 -0
  9. data/lib/rbbt/annotations/util.rb +282 -282
  10. data/lib/rbbt/annotations.rb +343 -320
  11. data/lib/rbbt/association/database.rb +200 -225
  12. data/lib/rbbt/association/index.rb +294 -291
  13. data/lib/rbbt/association/item.rb +227 -227
  14. data/lib/rbbt/association/open.rb +35 -34
  15. data/lib/rbbt/association/util.rb +0 -169
  16. data/lib/rbbt/association.rb +2 -4
  17. data/lib/rbbt/entity/identifiers.rb +119 -118
  18. data/lib/rbbt/entity/refactor.rb +12 -0
  19. data/lib/rbbt/entity.rb +319 -315
  20. data/lib/rbbt/hpc/batch.rb +72 -53
  21. data/lib/rbbt/hpc/lsf.rb +2 -2
  22. data/lib/rbbt/hpc/orchestrate/batches.rb +2 -2
  23. data/lib/rbbt/hpc/orchestrate/chains.rb +25 -5
  24. data/lib/rbbt/hpc/orchestrate/rules.rb +2 -2
  25. data/lib/rbbt/hpc/orchestrate.rb +19 -13
  26. data/lib/rbbt/hpc/slurm.rb +18 -18
  27. data/lib/rbbt/knowledge_base/entity.rb +13 -5
  28. data/lib/rbbt/knowledge_base/query.rb +2 -2
  29. data/lib/rbbt/knowledge_base/registry.rb +32 -31
  30. data/lib/rbbt/knowledge_base/traverse.rb +1 -1
  31. data/lib/rbbt/knowledge_base.rb +1 -1
  32. data/lib/rbbt/monitor.rb +36 -25
  33. data/lib/rbbt/persist/refactor.rb +166 -0
  34. data/lib/rbbt/persist/tsv/tokyocabinet.rb +105 -105
  35. data/lib/rbbt/persist/tsv.rb +187 -185
  36. data/lib/rbbt/persist.rb +556 -551
  37. data/lib/rbbt/refactor.rb +20 -0
  38. data/lib/rbbt/resource/path/refactor.rb +178 -0
  39. data/lib/rbbt/resource/path.rb +317 -497
  40. data/lib/rbbt/resource/util.rb +0 -48
  41. data/lib/rbbt/resource.rb +3 -390
  42. data/lib/rbbt/tsv/accessor.rb +2 -838
  43. data/lib/rbbt/tsv/attach.rb +303 -299
  44. data/lib/rbbt/tsv/change_id.rb +244 -245
  45. data/lib/rbbt/tsv/csv.rb +87 -85
  46. data/lib/rbbt/tsv/dumper.rb +2 -100
  47. data/lib/rbbt/tsv/excel.rb +26 -24
  48. data/lib/rbbt/tsv/field_index.rb +4 -1
  49. data/lib/rbbt/tsv/filter.rb +3 -2
  50. data/lib/rbbt/tsv/index.rb +2 -284
  51. data/lib/rbbt/tsv/manipulate.rb +750 -747
  52. data/lib/rbbt/tsv/marshal.rb +3 -3
  53. data/lib/rbbt/tsv/matrix.rb +2 -2
  54. data/lib/rbbt/tsv/parallel/through.rb +2 -1
  55. data/lib/rbbt/tsv/parallel/traverse.rb +783 -781
  56. data/lib/rbbt/tsv/parser.rb +678 -678
  57. data/lib/rbbt/tsv/refactor.rb +195 -0
  58. data/lib/rbbt/tsv/stream.rb +253 -251
  59. data/lib/rbbt/tsv/util.rb +420 -420
  60. data/lib/rbbt/tsv.rb +210 -208
  61. data/lib/rbbt/util/R/eval.rb +4 -4
  62. data/lib/rbbt/util/R/plot.rb +62 -166
  63. data/lib/rbbt/util/R.rb +21 -18
  64. data/lib/rbbt/util/cmd.rb +2 -318
  65. data/lib/rbbt/util/color.rb +269 -269
  66. data/lib/rbbt/util/colorize.rb +89 -89
  67. data/lib/rbbt/util/concurrency/processes/refactor.rb +22 -0
  68. data/lib/rbbt/util/concurrency/processes/worker.rb +2 -2
  69. data/lib/rbbt/util/concurrency/processes.rb +389 -386
  70. data/lib/rbbt/util/config.rb +169 -167
  71. data/lib/rbbt/util/filecache.rb +1 -1
  72. data/lib/rbbt/util/iruby.rb +20 -0
  73. data/lib/rbbt/util/log/progress/report.rb +241 -241
  74. data/lib/rbbt/util/log/progress/util.rb +99 -99
  75. data/lib/rbbt/util/log/progress.rb +102 -102
  76. data/lib/rbbt/util/log/refactor.rb +49 -0
  77. data/lib/rbbt/util/log.rb +486 -532
  78. data/lib/rbbt/util/migrate.rb +2 -2
  79. data/lib/rbbt/util/misc/concurrent_stream.rb +248 -246
  80. data/lib/rbbt/util/misc/development.rb +12 -11
  81. data/lib/rbbt/util/misc/exceptions.rb +117 -112
  82. data/lib/rbbt/util/misc/format.rb +2 -230
  83. data/lib/rbbt/util/misc/indiferent_hash.rb +2 -107
  84. data/lib/rbbt/util/misc/inspect.rb +2 -476
  85. data/lib/rbbt/util/misc/lock.rb +109 -106
  86. data/lib/rbbt/util/misc/omics.rb +9 -1
  87. data/lib/rbbt/util/misc/pipes.rb +765 -793
  88. data/lib/rbbt/util/misc/refactor.rb +20 -0
  89. data/lib/rbbt/util/misc/ssw.rb +27 -17
  90. data/lib/rbbt/util/misc/system.rb +92 -105
  91. data/lib/rbbt/util/misc.rb +39 -20
  92. data/lib/rbbt/util/named_array/refactor.rb +4 -0
  93. data/lib/rbbt/util/named_array.rb +3 -220
  94. data/lib/rbbt/util/open/refactor.rb +7 -0
  95. data/lib/rbbt/util/open.rb +3 -857
  96. data/lib/rbbt/util/procpath.rb +6 -6
  97. data/lib/rbbt/util/python/paths.rb +27 -0
  98. data/lib/rbbt/util/python/run.rb +115 -0
  99. data/lib/rbbt/util/python/script.rb +110 -0
  100. data/lib/rbbt/util/python/util.rb +3 -3
  101. data/lib/rbbt/util/python.rb +22 -81
  102. data/lib/rbbt/util/semaphore.rb +152 -148
  103. data/lib/rbbt/util/simpleopt.rb +9 -8
  104. data/lib/rbbt/util/ssh/refactor.rb +19 -0
  105. data/lib/rbbt/util/ssh.rb +122 -118
  106. data/lib/rbbt/util/tar.rb +117 -115
  107. data/lib/rbbt/util/tmpfile.rb +69 -67
  108. data/lib/rbbt/util/version.rb +2 -0
  109. data/lib/rbbt/workflow/refactor/entity.rb +11 -0
  110. data/lib/rbbt/workflow/refactor/export.rb +66 -0
  111. data/lib/rbbt/workflow/refactor/inputs.rb +24 -0
  112. data/lib/rbbt/workflow/refactor/recursive.rb +64 -0
  113. data/lib/rbbt/workflow/refactor/task_info.rb +66 -0
  114. data/lib/rbbt/workflow/refactor.rb +150 -0
  115. data/lib/rbbt/workflow/remote_workflow/driver/rest.rb +1 -2
  116. data/lib/rbbt/workflow/remote_workflow/driver/ssh.rb +55 -32
  117. data/lib/rbbt/workflow/remote_workflow/remote_step/rest.rb +3 -1
  118. data/lib/rbbt/workflow/remote_workflow/remote_step/ssh.rb +14 -5
  119. data/lib/rbbt/workflow/remote_workflow/remote_step.rb +19 -7
  120. data/lib/rbbt/workflow/remote_workflow.rb +6 -1
  121. data/lib/rbbt/workflow/step/run.rb +766 -766
  122. data/lib/rbbt/workflow/step/save_load_inputs.rb +254 -254
  123. data/lib/rbbt/workflow/step.rb +2 -362
  124. data/lib/rbbt/workflow/task.rb +118 -118
  125. data/lib/rbbt/workflow/usage.rb +289 -287
  126. data/lib/rbbt/workflow/util/archive.rb +6 -5
  127. data/lib/rbbt/workflow/util/data.rb +1 -1
  128. data/lib/rbbt/workflow/util/orchestrator.rb +249 -246
  129. data/lib/rbbt/workflow/util/trace.rb +79 -44
  130. data/lib/rbbt/workflow.rb +4 -882
  131. data/lib/rbbt-util.rb +21 -13
  132. data/lib/rbbt.rb +16 -3
  133. data/python/rbbt/__init__.py +96 -4
  134. data/python/rbbt/workflow/remote.py +104 -0
  135. data/python/rbbt/workflow.py +64 -0
  136. data/python/test.py +10 -0
  137. data/share/Rlib/plot.R +37 -37
  138. data/share/Rlib/svg.R +22 -5
  139. data/share/install/software/lib/install_helpers +1 -1
  140. data/share/rbbt_commands/hpc/list +2 -3
  141. data/share/rbbt_commands/hpc/orchestrate +4 -4
  142. data/share/rbbt_commands/hpc/tail +2 -0
  143. data/share/rbbt_commands/hpc/task +10 -7
  144. data/share/rbbt_commands/lsf/list +2 -3
  145. data/share/rbbt_commands/lsf/orchestrate +4 -4
  146. data/share/rbbt_commands/lsf/tail +2 -0
  147. data/share/rbbt_commands/lsf/task +10 -7
  148. data/share/rbbt_commands/migrate +1 -1
  149. data/share/rbbt_commands/pbs/list +2 -3
  150. data/share/rbbt_commands/pbs/orchestrate +4 -4
  151. data/share/rbbt_commands/pbs/tail +2 -0
  152. data/share/rbbt_commands/pbs/task +10 -7
  153. data/share/rbbt_commands/resource/produce +8 -1
  154. data/share/rbbt_commands/slurm/list +2 -3
  155. data/share/rbbt_commands/slurm/orchestrate +4 -4
  156. data/share/rbbt_commands/slurm/tail +2 -0
  157. data/share/rbbt_commands/slurm/task +10 -7
  158. data/share/rbbt_commands/system/clean +5 -5
  159. data/share/rbbt_commands/system/status +5 -5
  160. data/share/rbbt_commands/tsv/get +2 -3
  161. data/share/rbbt_commands/tsv/info +10 -13
  162. data/share/rbbt_commands/tsv/keys +18 -14
  163. data/share/rbbt_commands/tsv/slice +2 -2
  164. data/share/rbbt_commands/tsv/transpose +6 -2
  165. data/share/rbbt_commands/workflow/info +20 -24
  166. data/share/rbbt_commands/workflow/list +1 -1
  167. data/share/rbbt_commands/workflow/prov +20 -13
  168. data/share/rbbt_commands/workflow/retry +43 -0
  169. data/share/rbbt_commands/workflow/server +12 -2
  170. data/share/rbbt_commands/workflow/task +80 -73
  171. data/share/rbbt_commands/workflow/write_info +26 -9
  172. data/share/software/opt/ssw/ssw.c +861 -0
  173. data/share/software/opt/ssw/ssw.h +130 -0
  174. data/share/workflow_config.ru +3 -3
  175. metadata +45 -6
@@ -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