Changes to be committed:

modified:   go.mod
	modified:   go.sum
	modified:   pkg/obilua/obilib.go
	modified:   pkg/obilua/obiseq.go
	modified:   pkg/obilua/obiseqslice.go
	new file:   pkg/obilua/obitaxon.go
	new file:   pkg/obilua/obitaxonomy.go
	modified:   pkg/obioptions/version.go
This commit is contained in:
Eric Coissac
2025-02-02 16:52:52 +01:00
parent c10df073a7
commit b9bee5f426
8 changed files with 446 additions and 1 deletions

1
go.mod
View File

@ -26,6 +26,7 @@ require (
require (
github.com/Clever/csvlint v0.3.0 // indirect
github.com/buger/jsonparser v1.1.1 // indirect
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/goombaio/orderedmap v0.0.0-20180924084748-ba921b7e2419 // indirect
github.com/kr/pretty v0.3.0 // indirect

2
go.sum
View File

@ -12,6 +12,8 @@ github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMU
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
github.com/chen3feng/stl4go v0.1.1 h1:0L1+mDw7pomftKDruM23f1mA7miavOj6C6MZeadzN2Q=
github.com/chen3feng/stl4go v0.1.1/go.mod h1:5ml3psLgETJjRJnMbPE+JiHLrCpt+Ajc2weeTECXzWU=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=

View File

@ -4,4 +4,5 @@ import lua "github.com/yuin/gopher-lua"
func RegisterObilib(luaState *lua.LState) {
RegisterObiSeq(luaState)
RegisterObiTaxonomy(luaState)
}

View File

@ -1,7 +1,9 @@
package obilua
import (
"git.metabarcoding.org/obitools/obitools4/obitools4/pkg/obiformats"
"git.metabarcoding.org/obitools/obitools4/obitools4/pkg/obiseq"
"git.metabarcoding.org/obitools/obitools4/obitools4/pkg/obitax"
lua "github.com/yuin/gopher-lua"
)
@ -16,6 +18,7 @@ func registerBioSequenceType(luaState *lua.LState) {
bioSequenceType := luaState.NewTypeMetatable(luaBioSequenceTypeName)
luaState.SetGlobal(luaBioSequenceTypeName, bioSequenceType)
luaState.SetField(bioSequenceType, "new", luaState.NewFunction(newObiSeq))
luaState.SetField(bioSequenceType, "nil", obiseq2Lua(luaState, nil))
luaState.SetField(bioSequenceType, "__index",
luaState.SetFuncs(luaState.NewTable(),
@ -53,6 +56,7 @@ var bioSequenceMethods = map[string]lua.LGFunction{
"definition": bioSequenceGetSetDefinition,
"count": bioSequenceGetSetCount,
"taxid": bioSequenceGetSetTaxid,
"taxon": bioSequenceGetSetTaxon,
"attribute": bioSequenceGetSetAttribute,
"len": bioSequenceGetLength,
"has_sequence": bioSequenceHasSequence,
@ -62,6 +66,9 @@ var bioSequenceMethods = map[string]lua.LGFunction{
"md5_string": bioSequenceGetMD5String,
"subsequence": bioSequenceGetSubsequence,
"reverse_complement": bioSequenceGetRevcomp,
"fasta": bioSequenceGetFasta,
"fastq": bioSequenceGetFastq,
"string": bioSequenceAsString,
}
// checkBioSequence checks if the first argument in the Lua stack is a *obiseq.BioSequence.
@ -254,3 +261,88 @@ func bioSequenceGetRevcomp(luaState *lua.LState) int {
luaState.Push(obiseq2Lua(luaState, revcomp))
return 1
}
func bioSequenceGetSetTaxon(luaState *lua.LState) int {
s := checkBioSequence(luaState)
if luaState.GetTop() > 1 {
taxon := checkTaxon(luaState, 2)
s.SetTaxon(taxon)
return 0
}
taxon := s.Taxon(obitax.DefaultTaxonomy())
luaState.Push(taxon2Lua(luaState, taxon))
return 1
}
func bioSequenceGetFasta(luaState *lua.LState) int {
s := checkBioSequence(luaState)
formater := obiformats.FormatFastSeqJsonHeader
if luaState.GetTop() > 1 {
format := luaState.CheckString(2)
switch format {
case "json":
formater = obiformats.FormatFastSeqJsonHeader
case "obi":
formater = obiformats.FormatFastSeqOBIHeader
}
}
txt := obiformats.FormatFasta(s, formater)
luaState.Push(lua.LString(txt))
return 1
}
func bioSequenceGetFastq(luaState *lua.LState) int {
s := checkBioSequence(luaState)
formater := obiformats.FormatFastSeqJsonHeader
if luaState.GetTop() > 1 {
format := luaState.CheckString(2)
switch format {
case "json":
formater = obiformats.FormatFastSeqJsonHeader
case "obi":
formater = obiformats.FormatFastSeqOBIHeader
}
}
txt := obiformats.FormatFastq(s, formater)
luaState.Push(lua.LString(txt))
return 1
}
func bioSequenceAsString(luaState *lua.LState) int {
s := checkBioSequence(luaState)
formater := obiformats.FormatFastSeqJsonHeader
format := obiformats.FormatFasta
if s.HasQualities() {
format = obiformats.FormatFastq
}
if luaState.GetTop() > 1 {
format := luaState.CheckString(2)
switch format {
case "json":
formater = obiformats.FormatFastSeqJsonHeader
case "obi":
formater = obiformats.FormatFastSeqOBIHeader
}
}
txt := format(s, formater)
luaState.Push(lua.LString(txt))
return 1
}

View File

@ -1,6 +1,9 @@
package obilua
import (
"strings"
"git.metabarcoding.org/obitools/obitools4/obitools4/pkg/obiformats"
"git.metabarcoding.org/obitools/obitools4/obitools4/pkg/obiseq"
lua "github.com/yuin/gopher-lua"
)
@ -11,6 +14,7 @@ func registerBioSequenceSliceType(luaState *lua.LState) {
bioSequenceSliceType := luaState.NewTypeMetatable(luaBioSequenceSliceTypeName)
luaState.SetGlobal(luaBioSequenceSliceTypeName, bioSequenceSliceType)
luaState.SetField(bioSequenceSliceType, "new", luaState.NewFunction(newObiSeqSlice))
luaState.SetField(bioSequenceSliceType, "nil", obiseqslice2Lua(luaState, nil))
luaState.SetField(bioSequenceSliceType, "__index",
luaState.SetFuncs(luaState.NewTable(),
@ -37,6 +41,9 @@ var bioSequenceSliceMethods = map[string]lua.LGFunction{
"pop": bioSequenceSlicePop,
"sequence": bioSequenceSliceGetSetSequence,
"len": bioSequenceSliceGetLength,
"fasta": bioSequenceSliceGetFasta,
"fastq": bioSequenceSliceGetFastq,
"string": bioSequenceSliceAsString,
}
func checkBioSequenceSlice(L *lua.LState) *obiseq.BioSequenceSlice {
@ -105,3 +112,96 @@ func bioSequenceSlicePop(luaState *lua.LState) int {
return 1
}
func bioSequenceSliceGetFasta(luaState *lua.LState) int {
s := checkBioSequenceSlice(luaState)
formater := obiformats.FormatFastSeqJsonHeader
if luaState.GetTop() > 1 {
format := luaState.CheckString(2)
switch format {
case "json":
formater = obiformats.FormatFastSeqJsonHeader
case "obi":
formater = obiformats.FormatFastSeqOBIHeader
}
}
txts := make([]string, len(*s))
for i, seq := range *s {
txts[i] = obiformats.FormatFasta(seq, formater)
}
txt := strings.Join(txts, "\n")
luaState.Push(lua.LString(txt))
return 1
}
func bioSequenceSliceGetFastq(luaState *lua.LState) int {
s := checkBioSequenceSlice(luaState)
formater := obiformats.FormatFastSeqJsonHeader
if luaState.GetTop() > 1 {
format := luaState.CheckString(2)
switch format {
case "json":
formater = obiformats.FormatFastSeqJsonHeader
case "obi":
formater = obiformats.FormatFastSeqOBIHeader
}
}
txts := make([]string, len(*s))
for i, seq := range *s {
txts[i] = obiformats.FormatFastq(seq, formater)
}
txt := strings.Join(txts, "\n")
luaState.Push(lua.LString(txt))
return 1
}
func bioSequenceSliceAsString(luaState *lua.LState) int {
s := checkBioSequenceSlice(luaState)
formater := obiformats.FormatFastSeqJsonHeader
if luaState.GetTop() > 1 {
format := luaState.CheckString(2)
switch format {
case "json":
formater = obiformats.FormatFastSeqJsonHeader
case "obi":
formater = obiformats.FormatFastSeqOBIHeader
}
}
txts := make([]string, len(*s))
format := obiformats.FormatFasta
allQual := true
for _, s := range *s {
allQual = allQual && s.HasQualities()
}
if allQual {
format = obiformats.FormatFastq
}
for i, seq := range *s {
txts[i] = format(seq, formater)
}
txt := strings.Join(txts, "\n")
luaState.Push(lua.LString(txt))
return 1
}

139
pkg/obilua/obitaxon.go Normal file
View File

@ -0,0 +1,139 @@
package obilua
import (
"git.metabarcoding.org/obitools/obitools4/obitools4/pkg/obitax"
lua "github.com/yuin/gopher-lua"
)
const luaTaxonTypeName = "Taxon"
func registerTaxonType(luaState *lua.LState) {
taxonType := luaState.NewTypeMetatable(luaTaxonTypeName)
luaState.SetGlobal(luaTaxonTypeName, taxonType)
luaState.SetField(taxonType, "new", luaState.NewFunction(newTaxon))
luaState.SetField(taxonType, "nil", taxonomy2Lua(luaState, nil))
luaState.SetField(taxonType, "__index",
luaState.SetFuncs(luaState.NewTable(),
taxonMethods))
}
func taxon2Lua(interpreter *lua.LState,
taxon *obitax.Taxon) lua.LValue {
ud := interpreter.NewUserData()
ud.Value = taxon
interpreter.SetMetatable(ud, interpreter.GetTypeMetatable(luaTaxonTypeName))
return ud
}
func newTaxon(luaState *lua.LState) int {
taxonomy := checkTaxonomy(luaState)
taxid := luaState.CheckString(2)
parent := luaState.CheckString(3)
sname := luaState.CheckString(4)
rank := luaState.CheckString(5)
isroot := false
if luaState.GetTop() > 5 {
isroot = luaState.CheckBool(6)
}
taxon, err := taxonomy.AddTaxon(taxid, parent, rank, isroot, false)
if err != nil {
luaState.RaiseError("(%v,%v,%v) : Error on taxon creation: %v", taxid, parent, sname, err)
return 0
}
taxon.SetName(sname, "scientific name")
luaState.Push(taxon2Lua(luaState, taxon))
return 1
}
var taxonMethods = map[string]lua.LGFunction{
"string": taxonAsString,
"scientific_name": taxonGetSetScientificName,
"parent": taxonGetParent,
"taxon_at_rank": taxGetTaxonAtRank,
"species": taxonGetSpecies,
"genus": taxonGetGenus,
"family": taxonGetFamily,
}
func checkTaxon(L *lua.LState, i int) *obitax.Taxon {
ud := L.CheckUserData(i)
if v, ok := ud.Value.(*obitax.Taxon); ok {
return v
}
L.ArgError(i, "obitax.Taxon expected")
return nil
}
func taxonAsString(luaState *lua.LState) int {
taxon := checkTaxon(luaState, 1)
luaState.Push(lua.LString(taxon.String()))
return 1
}
func taxonGetSetScientificName(luaState *lua.LState) int {
taxon := checkTaxon(luaState, 1)
if luaState.GetTop() > 1 {
sname := luaState.CheckString(2)
taxon.SetName(sname, "scientific name")
return 0
}
luaState.Push(lua.LString(taxon.ScientificName()))
return 1
}
func taxonGetParent(luaState *lua.LState) int {
taxon := checkTaxon(luaState, 1)
parent := taxon.Parent()
luaState.Push(taxon2Lua(luaState, parent))
return 1
}
func taxonGetSpecies(luaState *lua.LState) int {
taxon := checkTaxon(luaState, 1)
species := taxon.Species()
luaState.Push(taxon2Lua(luaState, species))
return 1
}
func taxonGetGenus(luaState *lua.LState) int {
taxon := checkTaxon(luaState, 1)
genus := taxon.Genus()
luaState.Push(taxon2Lua(luaState, genus))
return 1
}
func taxonGetFamily(luaState *lua.LState) int {
taxon := checkTaxon(luaState, 1)
family := taxon.Family()
luaState.Push(taxon2Lua(luaState, family))
return 1
}
func taxGetTaxonAtRank(luaState *lua.LState) int {
taxon := checkTaxon(luaState, 1)
rank := luaState.CheckString(2)
taxonAt := taxon.TaxonAtRank(rank)
luaState.Push(taxon2Lua(luaState, taxonAt))
return 1
}

110
pkg/obilua/obitaxonomy.go Normal file
View File

@ -0,0 +1,110 @@
package obilua
import (
"git.metabarcoding.org/obitools/obitools4/obitools4/pkg/obitax"
"git.metabarcoding.org/obitools/obitools4/obitools4/pkg/obiutils"
lua "github.com/yuin/gopher-lua"
)
func RegisterObiTaxonomy(luaState *lua.LState) {
registerTaxonomyType(luaState)
registerTaxonType(luaState)
}
const luaTaxonomyTypeName = "Taxonomy"
func registerTaxonomyType(luaState *lua.LState) {
taxonomyType := luaState.NewTypeMetatable(luaTaxonomyTypeName)
luaState.SetGlobal(luaTaxonomyTypeName, taxonomyType)
luaState.SetField(taxonomyType, "new", luaState.NewFunction(newTaxonomy))
luaState.SetField(taxonomyType, "default", luaState.NewFunction(defaultTaxonomy))
luaState.SetField(taxonomyType, "has_default", luaState.NewFunction(hasDefaultTaxonomy))
luaState.SetField(taxonomyType, "nil", taxon2Lua(luaState, nil))
luaState.SetField(taxonomyType, "__index",
luaState.SetFuncs(luaState.NewTable(),
taxonomyMethods))
}
func taxonomy2Lua(interpreter *lua.LState,
taxonomy *obitax.Taxonomy) lua.LValue {
ud := interpreter.NewUserData()
ud.Value = taxonomy
interpreter.SetMetatable(ud, interpreter.GetTypeMetatable(luaTaxonomyTypeName))
return ud
}
func newTaxonomy(luaState *lua.LState) int {
name := luaState.CheckString(1)
code := luaState.CheckString(2)
charset := obiutils.AsciiAlphaNumSet
if luaState.GetTop() > 2 {
charset = obiutils.AsciiSetFromString(luaState.CheckString(3))
}
taxonomy := obitax.NewTaxonomy(name, code, charset)
luaState.Push(taxonomy2Lua(luaState, taxonomy))
return 1
}
func defaultTaxonomy(luaState *lua.LState) int {
taxonomy := obitax.DefaultTaxonomy()
if taxonomy == nil {
luaState.RaiseError("No default taxonomy")
return 0
}
luaState.Push(taxonomy2Lua(luaState, taxonomy))
return 1
}
func hasDefaultTaxonomy(luaState *lua.LState) int {
taxonomy := obitax.DefaultTaxonomy()
luaState.Push(lua.LBool(taxonomy != nil))
return 1
}
var taxonomyMethods = map[string]lua.LGFunction{
"name": taxonomyGetName,
"code": taxonomyGetCode,
"taxon": taxonomyGetTaxon,
}
func checkTaxonomy(L *lua.LState) *obitax.Taxonomy {
ud := L.CheckUserData(1)
if v, ok := ud.Value.(*obitax.Taxonomy); ok {
return v
}
L.ArgError(1, "obitax.Taxonomy expected")
return nil
}
func taxonomyGetName(luaState *lua.LState) int {
taxo := checkTaxonomy(luaState)
luaState.Push(lua.LString(taxo.Name()))
return 1
}
func taxonomyGetCode(luaState *lua.LState) int {
taxo := checkTaxonomy(luaState)
luaState.Push(lua.LString(taxo.Code()))
return 1
}
func taxonomyGetTaxon(luaState *lua.LState) int {
taxo := checkTaxonomy(luaState)
taxid := luaState.CheckString(2)
taxon, err := taxo.Taxon(taxid)
if err != nil {
luaState.RaiseError("%s : Error on taxon taxon: %v", taxid, err)
return 0
}
luaState.Push(taxon2Lua(luaState, taxon))
return 1
}

View File

@ -8,7 +8,7 @@ import (
// corresponds to the last commit, and not the one when the file will be
// commited
var _Commit = "d3dac1b"
var _Commit = "c10df07"
var _Version = "Release 4.2.0"
// Version returns the version of the obitools package.