bio-gemma-wrapper 0.97 → 0.97.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 +4 -4
- data/VERSION +1 -1
- data/bin/gemma-wrapper +78 -14
- data/gemma-wrapper.gemspec +2 -2
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 740af7561d0fb801b810713cd623f3d25e78971a
|
4
|
+
data.tar.gz: ce3aaae3418073dc1365bc8755ac73745ef4b01a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 30043473cf8b09ecf8a6fdcfa97468ba5d169bc7a0b6b6ab2102f7f978b8cb2c63fb5c5cefd7267cfe526e4748b6481aa9b6dbe7309dceff62f0351f79b16b0e
|
7
|
+
data.tar.gz: 07e50ab7b2b2d87bed1ce21b5b2d123693898163ff9a175841db190fcc22b43ee37ecc1df7cbc697e89b3dcaa193c489c299d3c50c1aa557d9512c4d494adec6
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.97
|
1
|
+
0.97.1
|
data/bin/gemma-wrapper
CHANGED
@@ -6,7 +6,8 @@
|
|
6
6
|
#
|
7
7
|
# Copyright (C) 2017,2018 Pjotr Prins <pjotr.prins@thebird.nl>
|
8
8
|
|
9
|
-
USAGE = "
|
9
|
+
USAGE = "
|
10
|
+
GEMMA wrapper example:
|
10
11
|
|
11
12
|
Simple caching of K computation with
|
12
13
|
|
@@ -63,6 +64,7 @@ end
|
|
63
64
|
require 'fileutils'
|
64
65
|
require 'optparse'
|
65
66
|
require 'tmpdir'
|
67
|
+
require 'tempfile'
|
66
68
|
|
67
69
|
split_at = ARGV.index('--')
|
68
70
|
if split_at
|
@@ -72,7 +74,17 @@ end
|
|
72
74
|
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() }
|
73
75
|
|
74
76
|
opts = OptionParser.new do |o|
|
75
|
-
o.banner = "
|
77
|
+
o.banner = "\nUsage: #{File.basename($0)} [options] -- [gemma-options]"
|
78
|
+
|
79
|
+
o.on('--permutate n', Integer, 'Permutate by shuffling phenotypes') do |lst|
|
80
|
+
options[:permutate] = lst
|
81
|
+
options[:force] = true
|
82
|
+
end
|
83
|
+
|
84
|
+
o.on('--phenotypes filen',String, 'Phenotypes to be shuffled in permutations') do |phenotypes|
|
85
|
+
options[:phenotypes] = phenotypes
|
86
|
+
raise "Phenotype input file #{phenotypes} does not exist" if !File.exist?(phenotypes)
|
87
|
+
end
|
76
88
|
|
77
89
|
o.on('--loco [x,y,1,2,3...]', Array, 'Run full LOCO') do |lst|
|
78
90
|
options[:loco] = lst
|
@@ -91,7 +103,7 @@ opts = OptionParser.new do |o|
|
|
91
103
|
options[:json] = b
|
92
104
|
end
|
93
105
|
|
94
|
-
o.on("--force", "Force computation") do |q|
|
106
|
+
o.on("--force", "Force computation (override cache)") do |q|
|
95
107
|
options[:force] = true
|
96
108
|
end
|
97
109
|
|
@@ -130,6 +142,7 @@ json_out = lambda do
|
|
130
142
|
print record.to_json if options[:json]
|
131
143
|
end
|
132
144
|
|
145
|
+
# ---- Some error handlers
|
133
146
|
error = lambda do |*msg|
|
134
147
|
if options[:json]
|
135
148
|
record[:error] = *msg.join(" ")
|
@@ -138,12 +151,14 @@ error = lambda do |*msg|
|
|
138
151
|
end
|
139
152
|
raise *msg
|
140
153
|
end
|
154
|
+
|
141
155
|
debug = lambda do |*msg|
|
142
156
|
if options[:debug]
|
143
157
|
record[:debug].push *msg.join("") if options[:json]
|
144
158
|
OUTPUT.print "DEBUG: ",*msg,"\n"
|
145
159
|
end
|
146
160
|
end
|
161
|
+
|
147
162
|
warning = lambda do |*msg|
|
148
163
|
record[:warnings].push *msg.join("")
|
149
164
|
OUTPUT.print "WARNING: ",*msg,"\n"
|
@@ -153,6 +168,8 @@ info = lambda do |*msg|
|
|
153
168
|
OUTPUT.print *msg,"\n" if !options[:quiet]
|
154
169
|
end
|
155
170
|
|
171
|
+
# ---- Start banner
|
172
|
+
|
156
173
|
GEMMA_K_VERSION=version
|
157
174
|
GEMMA_K_BANNER = "gemma-wrapper #{version} (Ruby #{RUBY_VERSION}) by Pjotr Prins 2017,2018\n"
|
158
175
|
info.call GEMMA_K_BANNER
|
@@ -160,7 +177,7 @@ info.call GEMMA_K_BANNER
|
|
160
177
|
# Check gemma version
|
161
178
|
GEMMA_COMMAND=options[:gemma_command]
|
162
179
|
gemma_version_header = `#{GEMMA_COMMAND}`.split("\n").grep(/GEMMA|Version/)[0].strip
|
163
|
-
info.call "Using
|
180
|
+
info.call "Using ",gemma_version_header,"\n"
|
164
181
|
gemma_version = gemma_version_header.split(/[,\s]+/)[1]
|
165
182
|
v_version, v_major, v_minor = gemma_version.split(".")
|
166
183
|
info.call "Found #{gemma_version}, comparing against expected v0.#{GEMMA_V_MAJOR}.#{GEMMA_V_MINOR}"
|
@@ -185,6 +202,7 @@ hashme = []
|
|
185
202
|
geno_idx = gemma_args.index '-g'
|
186
203
|
raise "Expected GEMMA -g switch" if geno_idx == nil
|
187
204
|
hashme = gemma_args
|
205
|
+
hashme += ['-p', options[:phenotypes]] if options[:phenotypes]
|
188
206
|
|
189
207
|
require 'digest/sha1'
|
190
208
|
debug.call "Hashing on ",hashme,"\n"
|
@@ -230,6 +248,7 @@ invoke_gemma = lambda do |extra_args, cache_hit = false|
|
|
230
248
|
end
|
231
249
|
err
|
232
250
|
else
|
251
|
+
debug.call("Invoking ",cmd) if options[:debug]
|
233
252
|
system(cmd)
|
234
253
|
$?.exitstatus
|
235
254
|
end
|
@@ -244,7 +263,7 @@ end
|
|
244
263
|
# returns datafn, logfn, cache_hit
|
245
264
|
cache = lambda do | chr, ext |
|
246
265
|
inject = (chr==nil ? "" : ".#{chr}" )+ext
|
247
|
-
hashi = HASH+inject
|
266
|
+
hashi = (chr==nil ? HASH : HASH+inject)
|
248
267
|
prefix = options[:cache_dir]+'/'+hashi
|
249
268
|
logfn = prefix+".log.txt"
|
250
269
|
datafn = prefix+ext
|
@@ -262,6 +281,7 @@ cache = lambda do | chr, ext |
|
|
262
281
|
return hashi,false
|
263
282
|
end
|
264
283
|
|
284
|
+
# ---- Compute K
|
265
285
|
kinship = lambda do | chr = nil |
|
266
286
|
record[:type] = "K"
|
267
287
|
ext = case (GEMMA_ARGS[GEMMA_ARGS.index('-gk')+1]).to_i
|
@@ -279,16 +299,16 @@ kinship = lambda do | chr = nil |
|
|
279
299
|
end
|
280
300
|
end
|
281
301
|
|
282
|
-
|
302
|
+
# ---- Run GWA
|
303
|
+
gwas = lambda do | chr, kfn, pfn |
|
283
304
|
record[:type] = "GWA"
|
284
|
-
error.call "Do not use the GEMMA -k switch!" if GEMMA_ARGS.include? '-k'
|
305
|
+
error.call "Do not use the GEMMA -k switch with gemma-wrapper!" if GEMMA_ARGS.include? '-k' # K is automatic
|
285
306
|
hashi, cache_hit = cache.call chr,".assoc.txt"
|
286
307
|
if not cache_hit
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
end
|
308
|
+
args = [ '-k', kfn, '-o', hashi ]
|
309
|
+
args << [ '-loco', chr ] if chr != nil
|
310
|
+
args << [ '-p', pfn ] if pfn
|
311
|
+
invoke_gemma.call args
|
292
312
|
end
|
293
313
|
end
|
294
314
|
|
@@ -308,9 +328,53 @@ else
|
|
308
328
|
# GWAS
|
309
329
|
json_in = JSON.parse(File.read(options[:input]))
|
310
330
|
raise "JSON problem, file #{options[:input]} is not -gk derived" if json_in["type"] != "K"
|
331
|
+
|
332
|
+
pfn = options[:phenotypes] # can be nil
|
311
333
|
k_files = json_in["files"].map { |rec| [rec[0],rec[2]] }
|
312
|
-
k_files.each do | chr, kfn |
|
313
|
-
gwas.call(chr,kfn)
|
334
|
+
k_files.each do | chr, kfn | # call a GWA for each chromosome
|
335
|
+
gwas.call(chr,kfn,pfn)
|
336
|
+
end
|
337
|
+
# Permute
|
338
|
+
if options[:permutate]
|
339
|
+
ps = []
|
340
|
+
raise "You should supply --phenotype with gemma-wrapper --permutate" if not pfn
|
341
|
+
File.foreach(pfn).with_index do |line, line_num|
|
342
|
+
ps << line
|
343
|
+
end
|
344
|
+
score_list = []
|
345
|
+
debug.call(options[:permutate],"x permutations")
|
346
|
+
(1..options[:permutate]).each do |i|
|
347
|
+
$stderr.print "Iteration ",i,"\n"
|
348
|
+
# Create a shuffled phenotype file
|
349
|
+
file = File.open("phenotypes-#{i}","w")
|
350
|
+
tmp_pfn = file.path
|
351
|
+
p tmp_pfn
|
352
|
+
ps.shuffle.each do | l |
|
353
|
+
file.print(l)
|
354
|
+
end
|
355
|
+
file.close
|
356
|
+
k_files.each do | chr, kfn | # call a GWA for each chromosome
|
357
|
+
gwas.call(chr,kfn,tmp_pfn)
|
358
|
+
end
|
359
|
+
# p [:HEY,record[:files].last]
|
360
|
+
assocfn = record[:files].last[2]
|
361
|
+
debug.call("Reading ",assocfn)
|
362
|
+
score_min = 1000.0
|
363
|
+
File.foreach(assocfn).with_index do |assoc, assoc_line_num|
|
364
|
+
if assoc_line_num > 0
|
365
|
+
value = assoc.strip.split(/\t/).last.to_f
|
366
|
+
score_min = value if value < score_min
|
367
|
+
end
|
368
|
+
end
|
369
|
+
score_list << score_min
|
370
|
+
end
|
371
|
+
ls = score_list.sort
|
372
|
+
p ls
|
373
|
+
significant = ls[(ls.size - ls.size*0.95).floor]
|
374
|
+
suggestive = ls[(ls.size - ls.size*0.67).floor]
|
375
|
+
p ["95 percentile (significant) ",significant,(-Math.log10(significant)).round(1)]
|
376
|
+
p ["67 percentile (suggestive) ",suggestive,(-Math.log10(suggestive)).round(1)]
|
377
|
+
exit 0
|
314
378
|
end
|
315
379
|
end
|
316
380
|
|
data/gemma-wrapper.gemspec
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'bio-gemma-wrapper'
|
3
3
|
s.version = File.read('VERSION')
|
4
|
-
s.summary = "
|
5
|
-
s.description = "GEMMA wrapper caches K between runs with LOCO support"
|
4
|
+
s.summary = "GEMMA with LOCO and permutations"
|
5
|
+
s.description = "GEMMA wrapper adds LOCO and permutation support. Also caches K between runs with LOCO support"
|
6
6
|
s.authors = ["Pjotr Prins"]
|
7
7
|
s.email = 'pjotr.public01@thebird.nl'
|
8
8
|
s.files = ["bin/gemma-wrapper",
|
metadata
CHANGED
@@ -1,16 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bio-gemma-wrapper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 0.97.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
|
+
date: 2018-07-19 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
|
-
description: GEMMA wrapper
|
13
|
+
description: GEMMA wrapper adds LOCO and permutation support. Also caches K between
|
14
|
+
runs with LOCO support
|
14
15
|
email: pjotr.public01@thebird.nl
|
15
16
|
executables:
|
16
17
|
- gemma-wrapper
|
@@ -46,5 +47,5 @@ rubyforge_project:
|
|
46
47
|
rubygems_version: 2.6.8
|
47
48
|
signing_key:
|
48
49
|
specification_version: 4
|
49
|
-
summary:
|
50
|
+
summary: GEMMA with LOCO and permutations
|
50
51
|
test_files: []
|