bio-gemma-wrapper 0.98.1 → 0.99.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +37 -15
  3. data/VERSION +1 -1
  4. data/bin/gemma-wrapper +172 -56
  5. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: b7a8bfe787236f397dba6e05aef202486ba53389
4
- data.tar.gz: 9fe2398ed3fcd053e8258f73a64b1610bfddf9e2
2
+ SHA256:
3
+ metadata.gz: 9ddfd904e74beebe0de1b97732d872fce171732965a835b101b9cc9be815bb05
4
+ data.tar.gz: 2dae1c019da23f2f87216694d641fc1eb852aa7800557bd10cfb08cb3425e844
5
5
  SHA512:
6
- metadata.gz: 0a691906f13da3469597517d160874315f5962822b0273757d33c37283c2a9a98da9a41d08c51e4ed7854b3d3593f9d96ac81d59212690edd628a2677499d501
7
- data.tar.gz: 5d4b898ff3566f52652cbb7db6597dc245e9a5da6b0d9da107de81deec0d51c02c822762e0ab921a2309c1dbc3455b55c1adc5fe94c891e31a9c32cb6d343f2e
6
+ metadata.gz: 38454a3f12dab85bef711051e73e20a015fe6b6d9c71bafada2197b9aef1aa0eabe3f3709cb0dc9d0c39f4cc454c15bc4d3aea5d06140ccde72fa13aa6285f51
7
+ data.tar.gz: 28e77a6995893245c501e602d488b5e0c504549fa91d8c94f902591b87b4454fe9b7923667dfacae2ab1dac7f6f7d814df1ec036b2b4f616dfd4b84c549d35d1
data/README.md CHANGED
@@ -1,12 +1,19 @@
1
1
  [![gemma-wrapper gem version](https://badge.fury.io/rb/bio-gemma-wrapper.svg)](https://badge.fury.io/rb/bio-gemma-wrapper)
2
2
 
3
- # GEMMA wrapper caches K between runs with LOCO support
3
+ # GEMMA with LOCO, permutations and slurm support (and caching)
4
4
 
5
5
  ![Genetic associations identified in CFW mice using GEMMA (Parker et al,
6
6
  Nat. Genet., 2016)](cfw.gif)
7
7
 
8
8
  ## Introduction
9
9
 
10
+ Gemma-wrapper allows running GEMMA with LOCO, GEMMA with caching,
11
+ GEMMA in parallel (now the default), and GEMMA on PBS. Gemma-wrapper
12
+ is used to run GEMMA as part of the https://genenetwork.org/
13
+ environment.
14
+
15
+ Note that gemma-wrapper is projected to be integrated into gemma2/lib.
16
+
10
17
  GEMMA is a software toolkit for fast application of linear mixed
11
18
  models (LMMs) and related models to genome-wide association studies
12
19
  (GWAS) and other large-scale data sets.
@@ -14,16 +21,14 @@ models (LMMs) and related models to genome-wide association studies
14
21
  This repository contains gemma-wrapper, essentially a wrapper of
15
22
  GEMMA that provides support for caching the kinship or relatedness
16
23
  matrix (K) and caching LM and LMM computations with the option of full
17
- leave-one-chromosome-out genome scans (LOCO).
24
+ leave-one-chromosome-out genome scans (LOCO). Jobs can also be
25
+ submitted to HPC PBS, i.e., slurm.
18
26
 
19
27
  gemma-wrapper requires a recent version of GEMMA and essentially
20
28
  does a pass-through of all standard GEMMA invocation switches. On
21
29
  return gemma-wrapper can return a JSON object (--json) which is
22
30
  useful for web-services.
23
31
 
24
- Note that this a work in progress (WIP). What is described below
25
- should work.
26
-
27
32
  ## Installation
28
33
 
29
34
  Prerequisites are
@@ -32,8 +37,9 @@ Prerequisites are
32
37
  * Standard [Ruby >2.0 ](https://www.ruby-lang.org/en/) which comes on
33
38
  almost all Linux systems
34
39
 
35
- gemma-wrapper comes as a Ruby [gem](https://rubygems.org/gems/bio-gemma-wrapper) and
36
- can be installed with
40
+ gemma-wrapper comes as a Ruby
41
+ [gem](https://rubygems.org/gems/bio-gemma-wrapper) and can be
42
+ installed with
37
43
 
38
44
  gem install bio-gemma-wrapper
39
45
 
@@ -52,6 +58,7 @@ Usage: gemma-wrapper [options] -- [gemma-options]
52
58
  --cache-dir path Use a cache directory
53
59
  --json Create output file in JSON format
54
60
  --force Force computation
61
+ --slurm [options] Submit to slurm PBS
55
62
  --q, --quiet Run quietly
56
63
  -v, --verbose Run verbosely
57
64
  --debug Show debug messages and keep intermediate output
@@ -69,6 +76,8 @@ Unpack it and run the tool as
69
76
 
70
77
  ./bin/gemma-wrapper --help
71
78
 
79
+ See below for using a GNU Guix environment.
80
+
72
81
  ## Usage
73
82
 
74
83
  gemma-wrapper picks up GEMMA from the PATH. To override that behaviour
@@ -95,7 +104,7 @@ the data files are found):
95
104
 
96
105
  Run it twice to see
97
106
 
98
- /tmp/3079151e14b219c3b243b673d88001c1675168b4.log.txt gemma-wrapper CACHE HIT!
107
+ /tmp/0bdd7add5e8f7d9af36b283d0341c115124273e0.log.txt CACHE HIT!
99
108
 
100
109
  gemma-wrapper computes the unique HASH value over the command
101
110
  line switches passed into GEMMA as well as the contents of the files
@@ -108,9 +117,10 @@ You can also get JSON output on STDOUT by providing the --json switch
108
117
  -g test/data/input/BXD_geno.txt.gz \
109
118
  -p test/data/input/BXD_pheno.txt \
110
119
  -gk \
111
- -debug
120
+ -debug > K.json
112
121
 
113
- prints out something that can be parsed with a calling program
122
+ K.json is something that can be parsed with a calling program, and is
123
+ also below as input for the GWA step. Example:
114
124
 
115
125
  ```json
116
126
  {"warnings":[],"errno":0,"debug":[],"type":"K","files":[["/tmp/18ce786ab92064a7ee38a7422e7838abf91f5eb0.log.txt","/tmp/18ce786ab92064a7ee38a7422e7838abf91f5eb0.cXX.txt"]],"cache_hit":true,"gemma_command":"../gemma/bin/gemma -g test/data/input/BXD_geno.txt.gz -p test/data/input/BXD_pheno.txt -gk -debug -outdir /tmp -o 18ce786ab92064a7ee38a7422e7838abf91f5eb0"}
@@ -130,7 +140,7 @@ will store K in ~/.gemma-cache.
130
140
 
131
141
  ### GWA
132
142
 
133
- Run the LMM using the K's captured in K.json using the --input
143
+ Run the LMM using the K's captured earlier in K.json using the --input
134
144
  switch
135
145
 
136
146
  gemma-wrapper --json --loco --input K.json -- \
@@ -201,12 +211,24 @@ Next, using K.json, permute the phenotypes with something like
201
211
  -lmm 2 -maf 0.1 \
202
212
  -debug > GWA.json
203
213
 
204
- This should get the 95% significant and 67% suggestive thresholds:
214
+ This should get the estimated 95% (significant) and 67% (suggestive) thresholds:
205
215
 
206
- ["95 percentile (significant) ", 2.015475e-05, 4.7]
207
- ["67 percentile (suggestive) ", 2.015475e-05, 4.7]
216
+ ["95 percentile (significant) ", 1.92081e-05, 4.7]
217
+ ["67 percentile (suggestive) ", 5.227785e-05, 4.3]
208
218
 
219
+ ### Slurm PBS
220
+
221
+ To run gemma-wrapper on HPC use the '--slurm' switch.
222
+
223
+ ## Development
224
+
225
+ We use GNU Guix for development and deployment. Use the [.guix-deploy](.guix-deploy) script in the checked out git repo:
226
+
227
+ ```
228
+ source .guix-deploy
229
+ ruby bin/gemma-wrapper --help
230
+ ```
209
231
 
210
232
  ## Copyright
211
233
 
212
- Copyright (c) 2017,2018 Pjotr Prins. See [LICENSE.txt](LICENSE.txt) for further details.
234
+ Copyright (c) 2017-2021 Pjotr Prins. See [LICENSE.txt](LICENSE.txt) for further details.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.98.1
1
+ 0.99.1
data/bin/gemma-wrapper CHANGED
@@ -4,7 +4,7 @@
4
4
  # Author:: Pjotr Prins
5
5
  # License:: GPL3
6
6
  #
7
- # Copyright (C) 2017,2018 Pjotr Prins <pjotr.prins@thebird.nl>
7
+ # Copyright (C) 2017-2021 Pjotr Prins <pjotr.prins@thebird.nl>
8
8
 
9
9
  USAGE = "
10
10
  GEMMA wrapper example:
@@ -38,11 +38,10 @@ GEMMA wrapper example:
38
38
  Gemma gets used from the path. You can override by setting
39
39
 
40
40
  env GEMMA_COMMAND=path/bin/gemma gemma-wrapper ...
41
-
42
41
  "
43
42
  # These are used for testing compatibility with the gemma tool
44
43
  GEMMA_V_MAJOR = 98
45
- GEMMA_V_MINOR = 0
44
+ GEMMA_V_MINOR = 1
46
45
 
47
46
  basepath = File.dirname(File.dirname(__FILE__))
48
47
  $: << File.join(basepath,'lib')
@@ -66,17 +65,18 @@ if not gemma_command
66
65
  end
67
66
 
68
67
 
68
+ require 'digest/sha1'
69
69
  require 'fileutils'
70
70
  require 'optparse'
71
- require 'tmpdir'
72
71
  require 'tempfile'
72
+ require 'tmpdir'
73
73
 
74
74
  split_at = ARGV.index('--')
75
75
  if split_at
76
76
  gemma_args = ARGV[split_at+1..-1]
77
77
  end
78
78
 
79
- options = { show_help: false, source: 'https://github.com/genetics-statistics/gemma-wrapper', version: version+' (Pjotr Prins)', date: Time.now.to_s, gemma_command: gemma_command, cache_dir: Dir.tmpdir() }
79
+ options = { show_help: false, source: 'https://github.com/genetics-statistics/gemma-wrapper', version: version+' (Pjotr Prins)', date: Time.now.to_s, gemma_command: gemma_command, cache_dir: Dir.tmpdir(), quiet: false, parallel: true }
80
80
 
81
81
  opts = OptionParser.new do |o|
82
82
  o.banner = "\nUsage: #{File.basename($0)} [options] -- [gemma-options]"
@@ -91,7 +91,7 @@ opts = OptionParser.new do |o|
91
91
  raise "Phenotype input file #{phenotypes} does not exist" if !File.exist?(phenotypes)
92
92
  end
93
93
 
94
- o.on('--loco [x,y,1,2,3...]', Array, 'Run full LOCO') do |lst|
94
+ o.on('--loco [x,y,1,2,3...]', Array, 'Run full leave-one-chromosome-out (LOCO)') do |lst|
95
95
  options[:loco] = lst
96
96
  end
97
97
 
@@ -112,6 +112,18 @@ opts = OptionParser.new do |o|
112
112
  options[:force] = true
113
113
  end
114
114
 
115
+ o.on("--no-parallel", "Do not run jobs in parallel") do |b|
116
+ options[:parallel] = false
117
+ end
118
+
119
+ o.on("--slurm[=opts]",String,"Use slurm PBS for submitting jobs") do |slurm|
120
+ options[:slurm_opts] = ""
121
+ options[:slurm] = true
122
+ if slurm
123
+ options[:slurm_opts] = slurm
124
+ end
125
+ end
126
+
115
127
  o.on("--q", "--quiet", "Run quietly") do |q|
116
128
  options[:quiet] = true
117
129
  end
@@ -120,15 +132,20 @@ opts = OptionParser.new do |o|
120
132
  options[:verbose] = true
121
133
  end
122
134
 
123
- o.on("--debug", "Show debug messages and keep intermediate output") do |v|
135
+ o.on("-d", "--debug", "Show debug messages and keep intermediate output") do |v|
124
136
  options[:debug] = true
125
137
  end
126
138
 
139
+ o.on("--dry-run", "Show commands, but don't execute") do |b|
140
+ options[:dry_run] = b
141
+ end
142
+
127
143
  o.on('--','Anything after gets passed to GEMMA') do
128
144
  o.terminate()
129
145
  end
130
146
 
131
147
  o.separator ""
148
+
132
149
  o.on_tail('-h', '--help', 'display this help and exit') do
133
150
  options[:show_help] = true
134
151
  end
@@ -176,18 +193,28 @@ end
176
193
  # ---- Start banner
177
194
 
178
195
  GEMMA_K_VERSION=version
179
- GEMMA_K_BANNER = "gemma-wrapper #{version} (Ruby #{RUBY_VERSION}) by Pjotr Prins 2017,2018\n"
196
+ GEMMA_K_BANNER = "gemma-wrapper #{version} (Ruby #{RUBY_VERSION}) by Pjotr Prins 2017-2021\n"
180
197
  info.call GEMMA_K_BANNER
181
198
 
182
199
  # Check gemma version
183
200
  GEMMA_COMMAND=options[:gemma_command]
201
+ info.call "NOTE: gemma-wrapper is soon to be replaced by gemma2/lib"
184
202
 
185
- gemma_version_header = `#{GEMMA_COMMAND}`.split("\n").grep(/GEMMA|Version/)[0].strip
203
+ begin
204
+ GEMMA_INFO = `#{GEMMA_COMMAND}`
205
+ rescue Errno::ENOENT
206
+ GEMMA_COMMAND = "gemma" if not GEMMA_COMMAND
207
+ error.call "<#{GEMMA_COMMAND}> command not found"
208
+ end
209
+
210
+ gemma_version_header = GEMMA_INFO.split("\n").grep(/GEMMA|Version/)[0].strip
186
211
  info.call "Using ",gemma_version_header,"\n"
187
212
  gemma_version = gemma_version_header.split(/[,\s]+/)[1]
188
213
  v_version, v_major, v_minor = gemma_version.split(".")
189
214
  info.call "Found #{gemma_version}, comparing against expected v0.#{GEMMA_V_MAJOR}.#{GEMMA_V_MINOR}"
190
215
 
216
+ info.call gemma_version_header
217
+
191
218
  warning.call "GEMMA version is out of date. Update GEMMA to 0.#{GEMMA_V_MAJOR}.#{GEMMA_V_MINOR}!" if v_major.to_i < GEMMA_V_MAJOR or (v_major.to_i == GEMMA_V_MAJOR and (v_minor != nil and v_minor.to_i < GEMMA_V_MINOR))
192
219
 
193
220
  options[:gemma_version_header] = gemma_version_header
@@ -203,40 +230,82 @@ if RUBY_VERSION =~ /^1/
203
230
  warning "runs on Ruby 2.x only\n"
204
231
  end
205
232
 
233
+ debug.call(options) # some debug output
234
+ debug.call(record)
235
+
206
236
  DO_COMPUTE_KINSHIP = gemma_args.include?("-gk")
207
237
  DO_COMPUTE_GWA = !DO_COMPUTE_KINSHIP
208
238
 
239
+ # ---- Set up parallel
240
+ if options[:parallel]
241
+ begin
242
+ PARALLEL_INFO = `parallel --help`
243
+ rescue Errno::ENOENT
244
+ error.call "<parallel> command not found"
245
+ end
246
+ parallel_cmds = []
247
+ end
248
+
209
249
  # ---- Compute HASH on inputs
210
250
  hashme = []
211
251
  geno_idx = gemma_args.index '-g'
212
252
  raise "Expected GEMMA -g genotype file switch" if geno_idx == nil
213
253
  pheno_idx = gemma_args.index '-p'
254
+
255
+ if DO_COMPUTE_GWA and options[:permute_phenotypes]
256
+ raise "Did not expect GEMMA -p phenotype whith permutations (only use --permutate-phenotypes)" if pheno_idx
257
+ end
258
+
259
+
260
+ execute = lambda { |cmd|
261
+ info.call("Executing: #{cmd}")
262
+ err = 0
263
+ if not options[:debug]
264
+ # send output to stderr line by line
265
+ IO.popen("#{cmd}") do |io|
266
+ while s = io.gets
267
+ $stderr.print s
268
+ end
269
+ io.close
270
+ err = $?.to_i
271
+ end
272
+ else
273
+ $stderr.print `#{cmd}`
274
+ err = $?.to_i
275
+ end
276
+ err
277
+ }
278
+
214
279
  hashme =
215
280
  if DO_COMPUTE_KINSHIP and pheno_idx != nil
216
- # Remove the phenotype file from the hash
281
+ # Remove the phenotype file from the hash for GRM computation
217
282
  gemma_args[0..pheno_idx-1] + gemma_args[pheno_idx+2..-1]
218
283
  else
219
284
  gemma_args
220
285
  end
221
286
 
222
- if DO_COMPUTE_GWA and options[:permute_phenotypes]
223
- raise "Did not expect GEMMA -p phenotype whith permutations (only use --permutate-phenotypes)" if pheno_idx
224
- hashme += ['-p', options[:permute_phenotypes]]
225
- end
226
-
227
- require 'digest/sha1'
228
- debug.call "Hashing on ",hashme,"\n"
229
- hashes = []
230
- hashme.each do | item |
231
- if File.exist?(item)
232
- hashes << Digest::SHA1.hexdigest(File.read(item))
233
- debug.call [item,hashes.last]
234
- else
235
- hashes << item
287
+ compute_hash = lambda do | phenofn = nil |
288
+ # Compute a HASH on the inputs
289
+ debug.call "Hashing on ",hashme,"\n"
290
+ hashes = []
291
+ hm = if phenofn
292
+ hashme + ["-p", phenofn]
293
+ else
294
+ hashme
295
+ end
296
+ debug.call(hm)
297
+ hm.each do | item |
298
+ if File.file?(item)
299
+ hashes << Digest::SHA1.hexdigest(File.read(item))
300
+ debug.call [item,hashes.last]
301
+ else
302
+ hashes << item
303
+ end
236
304
  end
305
+ Digest::SHA1.hexdigest hashes.join(' ')
237
306
  end
238
- HASH = Digest::SHA1.hexdigest hashes.join(' ')
239
307
 
308
+ HASH = compute_hash.call()
240
309
  options[:hash] = HASH
241
310
 
242
311
  # Create cache dir
@@ -250,27 +319,49 @@ GEMMA_ARGS = gemma_args
250
319
 
251
320
  debug.call "Options: ",options,"\n" if !options[:quiet]
252
321
 
253
- invoke_gemma = lambda do |extra_args, cache_hit = false|
254
- cmd="#{GEMMA_COMMAND} #{GEMMA_ARGS.join(' ')} #{extra_args.join(' ')}"
322
+ invoke_gemma = lambda do |extra_args, cache_hit = false, chr = "full", permutation = 1|
323
+ cmd = "#{GEMMA_COMMAND} #{GEMMA_ARGS.join(' ')} #{extra_args.join(' ')}"
255
324
  record[:gemma_command] = cmd
256
325
  return if cache_hit
257
- debug.call cmd
326
+ if options[:slurm]
327
+ info.call cmd
328
+ hashi = HASH
329
+ prefix = options[:cache_dir]+'/'+hashi
330
+ scriptfn = prefix+".#{chr}.#{permutation}-pbs.sh"
331
+ script = "#!/bin/bash
332
+ #SBATCH --job-name=gemma-#{scriptfn}
333
+ #SBATCH --ntasks=1
334
+ #SBATCH --time=20:00
335
+ srun #{cmd}
336
+ "
337
+ debug.call(script)
338
+ File.open(scriptfn,"w") { |f|
339
+ f.write(script)
340
+ }
341
+ cmd = "sbatch "+options[:slurm_opts] + scriptfn
342
+ end
258
343
  errno =
259
344
  if options[:json]
260
345
  # capture output
261
346
  err = 0
262
- IO.popen(cmd) do |io|
263
- while s = io.gets
264
- $stderr.print s
265
- end
266
- io.close
267
- err = $?.to_i
347
+ if options[:dry_run]
348
+ info.call("Would have invoked: ",cmd)
349
+ elsif options[:parallel]
350
+ info.call("Add parallel job: ",cmd)
351
+ parallel_cmds << cmd
352
+ else
353
+ err = execute.call(cmd)
268
354
  end
269
355
  err
270
356
  else
271
- debug.call("Invoking ",cmd) if options[:debug]
272
- system(cmd)
273
- $?.exitstatus
357
+ if options[:dry_run]
358
+ info.call("Would have invoked ",cmd)
359
+ 0
360
+ else
361
+ debug.call("Invoking ",cmd) if options[:debug]
362
+ system(cmd)
363
+ $?.exitstatus
364
+ end
274
365
  end
275
366
  if errno != 0
276
367
  debug.call "Gemma exit ",errno
@@ -281,10 +372,12 @@ invoke_gemma = lambda do |extra_args, cache_hit = false|
281
372
  end
282
373
 
283
374
  # returns datafn, logfn, cache_hit
284
- cache = lambda do | chr, ext |
375
+ cache = lambda do | chr, ext, h=HASH, permutation=0 |
285
376
  inject = (chr==nil ? "" : ".#{chr}" )+ext
286
- hashi = (chr==nil ? HASH : HASH+inject)
287
- prefix = options[:cache_dir]+'/'+hashi
377
+ hashi = (chr==nil ? h : h+inject)
378
+ prefix = options[:cache_dir]+'/'+hashi+(permutation!=0 ? "."+permutation.to_s : "")
379
+ # for chr 3 and permutation 1 forms something like
380
+ # /tmp/1b700-a996f.3.cXX.txt.1.log.txt
288
381
  logfn = prefix+".log.txt"
289
382
  datafn = prefix+ext
290
383
  record[:files] ||= []
@@ -320,20 +413,21 @@ kinship = lambda do | chr = nil |
320
413
  end
321
414
 
322
415
  # ---- Run GWA
323
- gwas = lambda do | chr, kfn, pfn |
416
+ gwas = lambda do | chr, kfn, pfn, permutation=0 |
324
417
  record[:type] = "GWA"
325
418
  error.call "Do not use the GEMMA -k switch with gemma-wrapper - it is automatic!" if GEMMA_ARGS.include? '-k' # K is automatic
326
- hashi, cache_hit = cache.call chr,".assoc.txt"
419
+ # Update hash for each permutation
420
+ hash = compute_hash.call(pfn)
421
+ hashi, cache_hit = cache.call(chr,".assoc.txt",hash,permutation)
327
422
  if not cache_hit
328
423
  args = [ '-k', kfn, '-o', hashi ]
329
424
  args << [ '-loco', chr ] if chr != nil
330
425
  args << [ '-p', pfn ] if pfn
331
- invoke_gemma.call args
426
+ invoke_gemma.call args,false,chr,permutation
332
427
  end
333
428
  end
334
429
 
335
430
  LOCO = options[:loco]
336
- # if GEMMA_ARGS.include? '-gk'
337
431
  if DO_COMPUTE_KINSHIP
338
432
  # compute K
339
433
  info.call LOCO
@@ -364,10 +458,10 @@ else
364
458
  end
365
459
  score_list = []
366
460
  debug.call(options[:permutate],"x permutations")
367
- (1..options[:permutate]).each do |i|
368
- $stderr.print "Iteration ",i,"\n"
461
+ (1..options[:permutate]).each do |permutation|
462
+ $stderr.print "Iteration ",permutation,"\n"
369
463
  # Create a shuffled phenotype file
370
- file = File.open("phenotypes-#{i}","w")
464
+ file = File.open("phenotypes-#{permutation}","w")
371
465
  tmp_pfn = file.path
372
466
  p tmp_pfn
373
467
  ps.shuffle.each do | l |
@@ -375,20 +469,23 @@ else
375
469
  end
376
470
  file.close
377
471
  k_files.each do | chr, kfn | # call a GWA for each chromosome
378
- gwas.call(chr,kfn,tmp_pfn)
472
+ gwas.call(chr,kfn,tmp_pfn,permutation)
379
473
  end
380
- # p [:HEY,record[:files].last]
381
- assocfn = record[:files].last[2]
382
- debug.call("Reading ",assocfn)
383
474
  score_min = 1000.0
384
- File.foreach(assocfn).with_index do |assoc, assoc_line_num|
385
- if assoc_line_num > 0
386
- value = assoc.strip.split(/\t/).last.to_f
387
- score_min = value if value < score_min
475
+ if false and not options[:slurm]
476
+ # p [:HEY,record[:files].last]
477
+ assocfn = record[:files].last[2]
478
+ debug.call("Reading ",assocfn)
479
+ File.foreach(assocfn).with_index do |assoc, assoc_line_num|
480
+ if assoc_line_num > 0
481
+ value = assoc.strip.split(/\t/).last.to_f
482
+ score_min = value if value < score_min
483
+ end
388
484
  end
389
485
  end
390
486
  score_list << score_min
391
487
  end
488
+ exit 0 if options[:slurm]
392
489
  ls = score_list.sort
393
490
  p ls
394
491
  significant = ls[(ls.size - ls.size*0.95).floor]
@@ -399,5 +496,24 @@ else
399
496
  end
400
497
  end
401
498
 
499
+ # ---- Invoke parallel
500
+ if options[:parallel]
501
+ # parallel_cmds = ["echo 1","sleep 1 && echo 2", "false", "echo 3"]
502
+ cmd = parallel_cmds.join("\\n")
503
+
504
+ cmd = "echo -e \"#{cmd}\""
505
+ err = execute.call(cmd+"|parallel") # all jobs in parallel
506
+ if err != 0
507
+ [16,8,4,1].each do |jobs|
508
+ info.call("Failed to complete parallel run -- retrying with smaller RAM footprint!")
509
+ err = execute.call(cmd+"|parallel -j #{jobs}")
510
+ break if err == 0
511
+ end
512
+ if err != 0
513
+ info.call("Run failed!")
514
+ exit err
515
+ end
516
+ end
517
+ info.call("Run successful!")
518
+ end
402
519
  json_out.call
403
- exit 0
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bio-gemma-wrapper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.98.1
4
+ version: 0.99.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pjotr Prins
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-11-20 00:00:00.000000000 Z
11
+ date: 2021-07-11 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: GEMMA wrapper adds LOCO and permutation support. Also caches K between
14
14
  runs with LOCO support
@@ -44,7 +44,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
44
44
  version: '0'
45
45
  requirements: []
46
46
  rubyforge_project:
47
- rubygems_version: 2.6.8
47
+ rubygems_version: 2.7.6.2
48
48
  signing_key:
49
49
  specification_version: 4
50
50
  summary: GEMMA with LOCO and permutations