datafarming 2.2.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/exe/generate_design.rb +103 -81
- data/lib/datafarming/version.rb +1 -1
- metadata +3 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8d7589dc50c37a95f61fcd663202a51b54f5dcab18b40f06fd82a7ca6335a0ae
|
|
4
|
+
data.tar.gz: be600740132b28b59ee3b0b11b45dffaa630023b2babc884bb732efdb0757d49
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7d734fadf28fdef038fbb3f4cc9ee0b0d836d0c388345a005ecd3d9609396b411e527e7f408832a69dade7414ae01c1d016fc16a475be9b6a91045390c88fa44
|
|
7
|
+
data.tar.gz: 51122d843649187c2e335244b532d1df783fb100c5f0588f9965e604d1570a4cd036b44694590d1368087e13f2eff4649261803d23943512ca9c8032a1afae7b
|
data/exe/generate_design.rb
CHANGED
|
@@ -62,15 +62,15 @@ EXAMPLES = [
|
|
|
62
62
|
" by whitespace.",
|
|
63
63
|
'',
|
|
64
64
|
'EXAMPLE 3:',
|
|
65
|
-
"\n #{File.basename($PROGRAM_NAME)} -d nolh -k 5 --output_yaml > my_template.
|
|
65
|
+
"\n #{File.basename($PROGRAM_NAME)} -d nolh -k 5 --output_yaml > my_template.yml",
|
|
66
66
|
"\n Generate a YAML template for a 5-factor NOLH design, and redirect it",
|
|
67
|
-
" to the file 'my_template.
|
|
67
|
+
" to the file 'my_template.yml'. (The output file can be given any name",
|
|
68
68
|
' of your choosing.) The resulting YAML file has an intuitive human',
|
|
69
69
|
" readable format. It can be edited using your favorite programmer's",
|
|
70
70
|
' text editor (NOTE: word processors will not work!). After saving your',
|
|
71
71
|
' revisions, you can read it back in to generate the actual design using',
|
|
72
72
|
" the '--input_yaml' option:\n",
|
|
73
|
-
" #{File.basename($PROGRAM_NAME)} --input_yaml
|
|
73
|
+
" #{File.basename($PROGRAM_NAME)} --input_yaml my_template.yml",
|
|
74
74
|
' '
|
|
75
75
|
].freeze
|
|
76
76
|
|
|
@@ -91,34 +91,40 @@ def examples(opts)
|
|
|
91
91
|
exit
|
|
92
92
|
end
|
|
93
93
|
|
|
94
|
+
def fatal_err(msg)
|
|
95
|
+
STDERR.puts msg
|
|
96
|
+
exit 1
|
|
97
|
+
end
|
|
98
|
+
|
|
94
99
|
def resv(options)
|
|
95
100
|
require 'datafarming/res_v_seqs'
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
RESV.make_design
|
|
101
|
+
num_factors = options[:specs].size
|
|
102
|
+
fatal_err("Too many factors for ResV designs") if num_factors > RESV::INDEX.size
|
|
103
|
+
RESV.make_design num_factors
|
|
99
104
|
end
|
|
100
105
|
|
|
101
106
|
def ccd(options)
|
|
102
107
|
require 'datafarming/res_v_seqs'
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
RESV.make_design(
|
|
108
|
+
num_factors = options[:specs].size
|
|
109
|
+
fatal_err("Too many factors for CCD designs") if num_factors > RESV::INDEX.size
|
|
110
|
+
RESV.make_design(num_factors) + RESV.star_pts(num_factors)
|
|
106
111
|
end
|
|
107
112
|
|
|
108
113
|
def rotatable(options)
|
|
109
114
|
require 'datafarming/res_v_seqs'
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
inv_len = 1.0 / Math.sqrt(
|
|
113
|
-
RESV.make_design(
|
|
115
|
+
num_factors = options[:specs].size
|
|
116
|
+
fatal_err("Too many factors for Rotatable designs") if num_factors > RESV::INDEX.size
|
|
117
|
+
inv_len = 1.0 / Math.sqrt(num_factors)
|
|
118
|
+
RESV.make_design(num_factors).each do |line|
|
|
114
119
|
line.map! { |value| value * inv_len }
|
|
115
|
-
end + RESV.star_pts(
|
|
120
|
+
end + RESV.star_pts(num_factors)
|
|
116
121
|
end
|
|
117
122
|
|
|
118
123
|
def nolh(options)
|
|
119
124
|
require 'datafarming/nolh_designs'
|
|
125
|
+
num_factors = options[:specs].size
|
|
120
126
|
minimal_size =
|
|
121
|
-
case
|
|
127
|
+
case num_factors
|
|
122
128
|
when 1..7
|
|
123
129
|
17
|
|
124
130
|
when 8..11
|
|
@@ -132,25 +138,19 @@ def nolh(options)
|
|
|
132
138
|
when 30..100
|
|
133
139
|
512
|
|
134
140
|
else
|
|
135
|
-
|
|
141
|
+
fatal_err "invalid number of factors: #{num_factors}"
|
|
136
142
|
end
|
|
137
|
-
|
|
138
143
|
options[:levels] ||= minimal_size
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
"too small for #{options[:num_factors]} factors."
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
+
fatal_err("Latin hypercube with #{options[:levels]} levels is " \
|
|
145
|
+
"too small for #{num_factors} factors.") if options[:levels] < minimal_size
|
|
144
146
|
NOLH::DESIGN_TABLE[options[:levels]]
|
|
145
147
|
end
|
|
146
148
|
|
|
147
149
|
def freqs2cols(options, design_set)
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
150
|
+
num_factors = options[:specs].size
|
|
151
|
+
fatal_err("No design (yet) for #{num_factors} factors") unless design_set.key? num_factors
|
|
151
152
|
design_num = 0 # most have only one design after removing isomorphisms
|
|
152
|
-
|
|
153
|
-
ds = design_set[options[:num_factors]]
|
|
153
|
+
ds = design_set[num_factors]
|
|
154
154
|
freqs = ds.freqs[design_num]
|
|
155
155
|
Array.new(freqs.size) do |row|
|
|
156
156
|
omega = freqs[row]
|
|
@@ -176,17 +176,15 @@ end
|
|
|
176
176
|
def validate_opts(options)
|
|
177
177
|
required_options = [:design]
|
|
178
178
|
missing = required_options - options.keys
|
|
179
|
-
|
|
180
|
-
|
|
179
|
+
fatal_err("Missing required options: --#{missing.join(', --')}") unless missing.empty?
|
|
181
180
|
options[:design] = options[:design].to_sym
|
|
182
181
|
end
|
|
183
182
|
|
|
184
183
|
def validate(spec)
|
|
185
184
|
unknown = spec.keys - REQUIRED_SPECS - ELECTIVE_SPECS
|
|
186
|
-
|
|
187
|
-
|
|
185
|
+
fatal_err("Unknown factor spec(s): #{unknown}") unless unknown.empty?
|
|
188
186
|
missing = REQUIRED_SPECS - spec.keys
|
|
189
|
-
|
|
187
|
+
fatal_err("Factor spec #{spec} missing #{missing}") unless missing.empty?
|
|
190
188
|
end
|
|
191
189
|
|
|
192
190
|
def optional_specs(factor_spec, i)
|
|
@@ -201,64 +199,89 @@ end
|
|
|
201
199
|
|
|
202
200
|
def parse_specs(options, remainder)
|
|
203
201
|
if remainder.size.positive?
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
elsif options.key? :num_factors
|
|
207
|
-
Array.new(options[:num_factors]) do |i|
|
|
208
|
-
{ "id": "X_#{format('%03d', (i + 1))}", "min": -1, "max": 1, "decimals": nil }
|
|
202
|
+
remainder.each.with_index do |factor_spec, i|
|
|
203
|
+
options[:specs] << optional_specs(factor_spec, i)
|
|
209
204
|
end
|
|
210
|
-
else
|
|
211
|
-
y_options, factor_specs = YAML.safe_load($stdin, permitted_classes: [Symbol])
|
|
212
|
-
y_options.each_key { |key| options[key] ||= y_options[key] }
|
|
213
|
-
factor_specs.each { |spec| validate(spec) }
|
|
214
205
|
end
|
|
215
206
|
end
|
|
216
207
|
|
|
217
208
|
def parse_args
|
|
218
|
-
|
|
209
|
+
default_options = {
|
|
219
210
|
headers: true,
|
|
220
211
|
replicate: 1,
|
|
221
212
|
stack: 1,
|
|
222
|
-
center: false
|
|
213
|
+
center: false,
|
|
214
|
+
specs: []
|
|
223
215
|
}
|
|
224
216
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
217
|
+
yaml_input = false
|
|
218
|
+
if ARGV.size > 2 && ARGV.any? { |elt| elt.eql?("-i") || elt.eql?("--input_yaml") }
|
|
219
|
+
STDERR.puts 'NOTE: All other arguments ignored when using YAML input'
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
options = default_options
|
|
223
|
+
|
|
224
|
+
begin
|
|
225
|
+
remainder = OptionParser.new do |opts|
|
|
226
|
+
opts.banner = HELP_MSG.join("\n")
|
|
227
|
+
opts.on('-h', '--help', 'Prints help') { prog_help(opts) }
|
|
228
|
+
opts.on('-v', '--verbose-help', 'Print more verbose help') { verbose(opts) }
|
|
229
|
+
opts.on('-x', '--examples', 'Show some examples') { examples(opts) }
|
|
230
|
+
opts.on('-d', '--design TYPE', DESIGN_TYPES,
|
|
231
|
+
'REQUIRED: Type of design, one of:',
|
|
232
|
+
" #{DESIGN_TYPES.join ' '}")
|
|
233
|
+
opts.on('-k', '--num_factors QTY', /[1-9][0-9]*/, Integer,
|
|
234
|
+
'Number of factors',
|
|
235
|
+
'Ignored if optional factor specs provided') do |k|
|
|
236
|
+
options[:specs] = Array.new(k) do |i|
|
|
237
|
+
{id: "X_#{format('%03d', (i + 1))}", :min => -1, :max => 1 }
|
|
238
|
+
end
|
|
239
|
+
k
|
|
240
|
+
end
|
|
241
|
+
opts.on('-r', '--replicate QTY', /[1-9][0-9]*/, Integer,
|
|
242
|
+
'Replicate QTY times', '(default: 1)')
|
|
243
|
+
opts.on('-s', '--stack QTY', /[1-9][0-9]*/, Integer,
|
|
244
|
+
'Stack QTY times', '(default: 1)')
|
|
245
|
+
opts.on('--[no-]center', 'NOTE: Applies only to stacked designs',
|
|
246
|
+
'Stacking includes center pt','(default: no-center)')
|
|
247
|
+
opts.on('--[no-]headers', 'Output has column headers', '(default: headers)')
|
|
248
|
+
opts.on('-l', '--levels QTY', Regexp.new("(#{LEVELS.join(')|(')})"),
|
|
249
|
+
Integer, 'NOTE: Applies only to NOLH designs',
|
|
250
|
+
'Number of levels in the base NOLH:',
|
|
251
|
+
" #{LEVELS.join ' '}")
|
|
252
|
+
opts.on('-o', '--output_yaml', 'Write design YAML to STDOUT')
|
|
253
|
+
opts.on("-i PATH", "--input_yaml", 'Read design YAML from PATH',
|
|
254
|
+
'Mutually exclusive with all other options, prints',
|
|
255
|
+
'warning to STDERR if other options are passed') do |path|
|
|
256
|
+
ARGV.clear
|
|
257
|
+
options = {specs: []}
|
|
258
|
+
yaml_input = true
|
|
259
|
+
YAML::safe_load_file(path, permitted_classes: [Symbol]).each do |k, v|
|
|
260
|
+
options.merge!({k.to_sym => v})
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
end.parse!(into: options)
|
|
264
|
+
rescue OptionParser::ParseError => error
|
|
265
|
+
fatal_err("#{error}\n(-h or --help will show valid options)")
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
fatal_err("Levels option only valid for NOLH designs") if options[:levels] && options[:design] != :nolh
|
|
269
|
+
|
|
270
|
+
remainder = [] if yaml_input
|
|
271
|
+
if remainder.size.positive? && options[:specs].size.positive?
|
|
272
|
+
STDERR.puts 'NOTE: Num_factors ignored when using optional factor specs'
|
|
273
|
+
options[:specs] = []
|
|
274
|
+
end
|
|
275
|
+
options.delete(:num_factors) if options.include?(:num_factors)
|
|
276
|
+
|
|
277
|
+
parse_specs(options, remainder)
|
|
254
278
|
validate_opts options
|
|
255
|
-
|
|
279
|
+
options
|
|
256
280
|
end
|
|
257
281
|
|
|
258
282
|
def stack(design, num_stacks, centered)
|
|
259
283
|
return design if num_stacks < 2
|
|
260
|
-
|
|
261
|
-
|
|
284
|
+
fatal_err("Stacking #{num_stacks} times exceeds number of design columns") if num_stacks > design[0].length
|
|
262
285
|
num_stacks -= 1
|
|
263
286
|
result = design.transpose
|
|
264
287
|
if num_stacks > 0
|
|
@@ -275,25 +298,24 @@ def stack(design, num_stacks, centered)
|
|
|
275
298
|
result.transpose
|
|
276
299
|
end
|
|
277
300
|
|
|
278
|
-
|
|
279
301
|
ARGV << '--help' if ARGV.empty?
|
|
280
302
|
|
|
281
|
-
options
|
|
303
|
+
options = parse_args
|
|
282
304
|
|
|
283
305
|
if options[:output_yaml]
|
|
284
306
|
options.delete :output_yaml
|
|
285
|
-
puts
|
|
307
|
+
puts options.to_yaml
|
|
286
308
|
else
|
|
287
309
|
base_design = method(options[:design]).call(options)
|
|
288
310
|
separator = ','
|
|
289
|
-
puts Array.new(options[:
|
|
311
|
+
puts Array.new(options[:specs].size) { |i| options[:specs][i][:id] }.join(separator) if options[:headers]
|
|
290
312
|
|
|
291
313
|
# stack
|
|
292
314
|
design = stack(base_design, options[:stack], options[:center])
|
|
293
|
-
.transpose.first(options[:
|
|
315
|
+
.transpose.first(options[:specs].size).transpose
|
|
294
316
|
|
|
295
317
|
# scale
|
|
296
|
-
scaler = specs.map do |spec|
|
|
318
|
+
scaler = options[:specs].map do |spec|
|
|
297
319
|
Scaler.new(min: spec[:min], max: spec[:max], decimals: spec[:decimals])
|
|
298
320
|
end
|
|
299
321
|
|
data/lib/datafarming/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: datafarming
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Paul J Sanchez
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 2025-01-26 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: fwt
|
|
@@ -136,7 +135,6 @@ homepage: https://bitbucket.org/paul_j_sanchez/datafarmingrubyscripts
|
|
|
136
135
|
licenses:
|
|
137
136
|
- MIT
|
|
138
137
|
metadata: {}
|
|
139
|
-
post_install_message:
|
|
140
138
|
rdoc_options: []
|
|
141
139
|
require_paths:
|
|
142
140
|
- lib
|
|
@@ -151,8 +149,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
151
149
|
- !ruby/object:Gem::Version
|
|
152
150
|
version: '0'
|
|
153
151
|
requirements: []
|
|
154
|
-
rubygems_version: 3.
|
|
155
|
-
signing_key:
|
|
152
|
+
rubygems_version: 3.6.2
|
|
156
153
|
specification_version: 4
|
|
157
154
|
summary: Useful scripts for data farming.
|
|
158
155
|
test_files: []
|