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.
- checksums.yaml +5 -5
- data/README.md +37 -15
- data/VERSION +1 -1
- data/bin/gemma-wrapper +172 -56
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9ddfd904e74beebe0de1b97732d872fce171732965a835b101b9cc9be815bb05
|
4
|
+
data.tar.gz: 2dae1c019da23f2f87216694d641fc1eb852aa7800557bd10cfb08cb3425e844
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|
36
|
-
can be
|
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/
|
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
|
-
|
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) ",
|
207
|
-
["67 percentile (suggestive) ",
|
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
|
234
|
+
Copyright (c) 2017-2021 Pjotr Prins. See [LICENSE.txt](LICENSE.txt) for further details.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
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
|
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 =
|
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
|
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
|
-
|
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
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
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
|
-
|
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
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
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
|
-
|
272
|
-
|
273
|
-
|
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 ?
|
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
|
-
|
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 |
|
368
|
-
$stderr.print "Iteration ",
|
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-#{
|
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
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
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.
|
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:
|
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.
|
47
|
+
rubygems_version: 2.7.6.2
|
48
48
|
signing_key:
|
49
49
|
specification_version: 4
|
50
50
|
summary: GEMMA with LOCO and permutations
|