Skip to content

Commit

Permalink
more work on converting to lua
Browse files Browse the repository at this point in the history
  • Loading branch information
brentp committed Dec 24, 2015
1 parent 097b0fa commit 9fa02fd
Show file tree
Hide file tree
Showing 11 changed files with 128 additions and 203 deletions.
2 changes: 1 addition & 1 deletion api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func (s *Source) LuaOp(v interfaces.IVariant, code string, vals []interface{}) s
value, err := s.Vm.Run(code, map[string]interface{}{
"chrom": v.Chrom(),
"start": v.Start(),
"end": v.End(),
"stop": v.End(),
"vals": vals})
if err != nil {
return fmt.Sprintf("lua-error: %s", err)
Expand Down
8 changes: 4 additions & 4 deletions bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ func benchmarkAnno(b *testing.B) {
}

out := bufio.NewWriter(ioutil.Discard)
Js, _ := xopen.Ropen("example/custom.js")
jbytes, _ := ioutil.ReadAll(Js)
js_string := string(jbytes)
Lua, _ := xopen.Ropen("example/custom.lua")
lbytes, _ := ioutil.ReadAll(Lua)
l_string := string(lbytes)

srcs, err := configs.Sources()
if err != nil {
Expand All @@ -36,7 +36,7 @@ func benchmarkAnno(b *testing.B) {
if err != nil {
log.Fatal(err)
}
a := api.NewAnnotator(srcs, js_string, false, true, empty)
a := api.NewAnnotator(srcs, l_string, false, true, empty)
qrdr, err := xopen.Ropen("example/query.vcf.gz")
if err != nil {
log.Fatal(err)
Expand Down
1 change: 1 addition & 0 deletions docs/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ v0.0.9
+ new [documentation site](http://brentp.github.io/vcfanno/)
+ [[postannotation]] allows modifying stuff in the query VCF after annotation (or instead).
See examples on the documentation site.
+ convert scripting engine to lua from javascript


v0.0.8
Expand Down
65 changes: 28 additions & 37 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Usage
After downloading the [binary for your system](https://github.com/brentp/vcfanno/releases/) (see section below) usage looks like:

```Shell
./vcfanno -js example/custom.js example/conf.toml example/query.vcf.gz
./vcfanno -lua example/custom.lua example/conf.toml example/query.vcf.gz
```

Where conf.toml looks like:
Expand All @@ -44,9 +44,9 @@ ops=["first", "first", "min"]
[[annotation]]
file="fitcons.bed"
columns = [4, 4]
names=["fitcons_mean", "js_sum"]
# note the 2nd op here is javascript that has access to `vals`
ops=["mean", "js:sum=0;for(i=0;i<vals.length;i++){sum+=vals[i]}; vals"]
names=["fitcons_mean", "lua_sum"]
# note the 2nd op here is lua that has access to `vals`
ops=["mean", "lua:function sum(t) local sum = 0; for i=1,#t do sum = sum + t[i] end return sum / #t end"]
[[annotation]]
file="example/ex.bam"
Expand Down Expand Up @@ -77,7 +77,7 @@ from this directory.
Then, you can annotate with:

```Shell
GOMAXPROCS=4 ./vcfanno -js example/custom.js example/conf.toml example/query.vcf.gz > annotated.vcf
GOMAXPROCS=4 ./vcfanno -lua example/custom.lua example/conf.toml example/query.vcf.gz > annotated.vcf
```

An example INFO field row before annotation (pos 98683):
Expand All @@ -87,7 +87,7 @@ AB=0.282443;ABP=56.8661;AC=11;AF=0.34375;AN=32;AO=45;CIGAR=1X;TYPE=snp

and after:
```
AB=0.2824;ABP=56.8661;AC=11;AF=0.3438;AN=32;AO=45;CIGAR=1X;TYPE=snp;AC_AFR=0;AC_AMR=0;AC_EAS=0;fitcons_mean=0.061;js_sum=0.061
AB=0.2824;ABP=56.8661;AC=11;AF=0.3438;AN=32;AO=45;CIGAR=1X;TYPE=snp;AC_AFR=0;AC_AMR=0;AC_EAS=0;fitcons_mean=0.061;lua_sum=0.061
```

Operations
Expand All @@ -98,7 +98,7 @@ in the query VCF. However, it is possible that there will be multiple annotation
from a single annotation file--in this case, the op determines how the many values
are `reduced`. Valid operations are:

+ js:$javascript // see section below for more details
+ lua:$lua // see section below for more details
+ mean
+ max
+ min
Expand Down Expand Up @@ -129,17 +129,8 @@ Development
===========

This, and the associated go libraries ([vcfgo](https://github.com/brentp/vcfgo),
[irelate](https://github.com/brentp/irelate), [xopen](https://github.com/brentp/xopen)) are
under active development. The following are on our radar (most have been completed):

- [x] allow annotating with bam fields, e.g. QUAL and SEQ.
- [ ] decompose, normalize, and get allelic primitives for variants on the fly
(we have code to do this, it just needs to be integrated)
- [ ] allow custom golang ops when using api.
- [x] improve test coverage for vcfanno (still need more tests for bam)
- [x] embed otto js engine to allow custom ops.
- [x] support for annotating BED files.

[irelate](https://github.com/brentp/irelate), [xopen](https://github.com/brentp/xopen),
[goluaez](https://github.com/brentp/goluaez) are under active development.

Additional Usage
================
Expand Down Expand Up @@ -172,38 +163,38 @@ REF/ALT are not required.
Set to the number of processes that `vcfanno` can use during annotation. `vcfanno` parallelizes well
up to 15 or so cores.

-js
---
-lua
----

custom in ops (javascript). For use when the built-in `ops` don't supply the needed reduction.
custom in ops (lua). For use when the built-in `ops` don't supply the needed reduction.

we embed the javascript engine [otto](https://github.com/robertkrimen/otto) so that it's
we embed the lua engine [go-lua](https://github.com/yuin/gopher-lua) so that it's
possible to create a custom op if it is not provided. For example if the users wants to

"js:sum=0;for(i=0;i<vals.length;i++){sum+=vals[i]};sum"
"lua:function sum(t) local sum = 0; for i=1,#t do sum = sum + t[i] end return sum end"

where the last value (in this case sum) is returned as the annotation value. It is encouraged
to instead define javascript functions in separate `.js` file and point to it when calling
`vcfanno` using the `-js` flag. So, in an external file, "some.js", instead put:

```javascript
function sum(vals) {
s = 0;
for(i=0; i<vals.length; i++){
s+=vals[i]
}
return s
}
to instead define lua functions in separate `.lua` file and point to it when calling
`vcfanno` using the `-lua` flag. So, in an external file, "some.lua", instead put:

```lua
function sum(t)
local sum = 0
for i=1,#t do
sum = sum + t[i]
end
return sum
end
```

And then the above custom op would be: "js:sum(vals)". (note that there's a sum op provided
And then the above custom op would be: "lua:sum(vals)". (note that there's a sum op provided
by `vcfanno` which will be faster).

The variables `vals`, `chrom`, `start`, `end` from the current variant will all be available
in the javascript code.
in the lua code.


See [example/conf.toml](https://github.com/brentp/vcfanno/blob/master/example/conf.toml)
and [example/custom.js](https://github.com/brentp/vcfanno/blob/master/example/custom.js)
and [example/custom.lua](https://github.com/brentp/vcfanno/blob/master/example/custom.lua)
for more examples.

19 changes: 9 additions & 10 deletions example/conf.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,22 @@ ops=["first", "first", "first", "first"]

[[annotation]]
file="example/fitcons.bed.gz"
names=["otto_start", "otto_end", "otto_len", "otto_sum", "otto_mean", "otto_loc"]
columns=[4, 4, 4, 4, 4, 4]
# when a custom value is needed, specify arbitrary javascript after "js:"
names=["lua_start", "lua_end", "lua_len", "lua_mean", "lua_loc"]
columns=[4, 4, 4, 4, 4]
# when a custom value is needed, specify arbitrary javascript after "lua:"
# the variable available will be:
# + vals: the list of values from this annotation
# + chrom: the chrom of the variant being annotated
# + start: the (0-based) start of the variant being annotated
# + end: the end of the variant being annotated
# + stop: the end of the variant being annotated
# the result of the expression can be anything. it will be converted to a string.
# loc() and mean() are defined in examples/custom.js
ops=["js:start", "js:end", "js:vals.length", "js:sum=0;for(i=0;i<vals.length;i++){sum+=vals[i]};vals", "js:mean(vals)", "js:loc(chrom, start, end)"]
# note the last 2 use functions declared in js above.
# loc() and mean() are defined in examples/custom.lua
ops=["lua:start", "lua:stop", "lua:#vals", "lua:mean(vals)", "lua:loc(chrom, start, stop)"]
# note the last 2 use functions declared in lua above.

# it is also possible to define some javascript functions that will be
# available. This is specified as a .js file to the vcfanno executable as
# ./vcfanno -js some.js ... see example/custom.js for an example.

# available. This is specified as a .lua file to the vcfanno executable as
# ./vcfanno -lua some.lua ... see example/custom.lua for an example.

[[annotation]]
file="example/cadd.sub.txt.gz"
Expand Down
119 changes: 0 additions & 119 deletions example/custom.js

This file was deleted.

67 changes: 67 additions & 0 deletions example/custom.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
function mean(vals)
local sum=0
for i=1,#vals do
sum = sum + vals[i]
end
return sum / #vals
end

function loc(chrom, start, stop)
return chrom .. ":" .. start .. "-" .. stop
end

CLINVAR_LOOKUP = {}
CLINVAR_LOOKUP['0'] = 'unknown'
CLINVAR_LOOKUP['1'] = 'germline'
CLINVAR_LOOKUP['2'] = 'somatic'
CLINVAR_LOOKUP['4'] = 'inherited'
CLINVAR_LOOKUP['8'] = 'paternal'
CLINVAR_LOOKUP['16'] = 'maternal'
CLINVAR_LOOKUP['32'] = 'de-novo'
CLINVAR_LOOKUP['64'] = 'biparental'
CLINVAR_LOOKUP['128'] = 'uniparental'
CLINVAR_LOOKUP['256'] = 'not-tested'
CLINVAR_LOOKUP['512'] = 'tested-inconclusive'
CLINVAR_LOOKUP['1073741824'] = 'other'

CLINVAR_SIG = {}
CLINVAR_SIG['0'] = 'uncertain'
CLINVAR_SIG['1'] = 'not-provided'
CLINVAR_SIG['2'] = 'benign'
CLINVAR_SIG['3'] = 'likely-benign'
CLINVAR_SIG['4'] = 'likely-pathogenic'
CLINVAR_SIG['5'] = 'pathogenic'
CLINVAR_SIG['6'] = 'drug-response'
CLINVAR_SIG['7'] = 'histocompatibility'
CLINVAR_SIG['255'] = 'other'
CLINVAR_SIG['.'] = '.'

function clinvar_sig(vals)
local t = type(vals)
-- just a single-value
if(t == "string" or t == "number") then
return CLINVAR_SIG[vals]
else
vals = {vals}
end
local ret = {}
for i=1,#vals do
if(index(vals[i], "|") == -1) then
ret[#ret+1] = CLINVAR_SIG[vals[i]]
else
local invals = split(vals[i], "|")
local inret = {}
for j=1,#invals do
inret[#inret+1] = CLINVAR_SIG[invals[j]]
end
ret[#ret+1] = table.concat(inret, "|")
end
end
return table.concat(ret, ",")
end


function div(a, b)
if(a == 0) then return 0.0 end
return (a / b).toFixed(9)
end
Loading

0 comments on commit 9fa02fd

Please sign in to comment.