bio-gemma-wrapper 0.98.1 → 0.99.1
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 +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
|
[](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
|

|
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
|