mirror of
https://github.com/metabarcoding/obitools4.git
synced 2025-06-29 16:20:46 +00:00
Add some options to obiannotate
This commit is contained in:
@ -1,13 +1,16 @@
|
|||||||
package obieval
|
package obieval
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
"git.metabarcoding.org/lecasofts/go/obitools/pkg/goutils"
|
"git.metabarcoding.org/lecasofts/go/obitools/pkg/goutils"
|
||||||
"github.com/PaesslerAG/gval"
|
"github.com/PaesslerAG/gval"
|
||||||
)
|
)
|
||||||
|
|
||||||
func maxIntVector(values []int) float64 {
|
func maxIntVector(values []int) float64 {
|
||||||
m := values[0]
|
m := values[0]
|
||||||
for _,v := range values {
|
for _, v := range values {
|
||||||
if v > m {
|
if v > m {
|
||||||
m = v
|
m = v
|
||||||
}
|
}
|
||||||
@ -19,7 +22,7 @@ func maxIntVector(values []int) float64 {
|
|||||||
func maxIntMap(values map[string]int) float64 {
|
func maxIntMap(values map[string]int) float64 {
|
||||||
var m int
|
var m int
|
||||||
first := true
|
first := true
|
||||||
for _,v := range values {
|
for _, v := range values {
|
||||||
if first {
|
if first {
|
||||||
first = false
|
first = false
|
||||||
m = v
|
m = v
|
||||||
@ -35,7 +38,7 @@ func maxIntMap(values map[string]int) float64 {
|
|||||||
|
|
||||||
func minIntVector(values []int) float64 {
|
func minIntVector(values []int) float64 {
|
||||||
m := values[0]
|
m := values[0]
|
||||||
for _,v := range values {
|
for _, v := range values {
|
||||||
if v < m {
|
if v < m {
|
||||||
m = v
|
m = v
|
||||||
}
|
}
|
||||||
@ -47,7 +50,7 @@ func minIntVector(values []int) float64 {
|
|||||||
func minIntMap(values map[string]int) float64 {
|
func minIntMap(values map[string]int) float64 {
|
||||||
var m int
|
var m int
|
||||||
first := true
|
first := true
|
||||||
for _,v := range values {
|
for _, v := range values {
|
||||||
if first {
|
if first {
|
||||||
first = false
|
first = false
|
||||||
m = v
|
m = v
|
||||||
@ -61,10 +64,9 @@ func minIntMap(values map[string]int) float64 {
|
|||||||
return float64(m)
|
return float64(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func maxFloatVector(values []float64) float64 {
|
func maxFloatVector(values []float64) float64 {
|
||||||
m := values[0]
|
m := values[0]
|
||||||
for _,v := range values {
|
for _, v := range values {
|
||||||
if v > m {
|
if v > m {
|
||||||
m = v
|
m = v
|
||||||
}
|
}
|
||||||
@ -76,7 +78,7 @@ func maxFloatVector(values []float64) float64 {
|
|||||||
func maxFloatMap(values map[string]float64) float64 {
|
func maxFloatMap(values map[string]float64) float64 {
|
||||||
var m float64
|
var m float64
|
||||||
first := true
|
first := true
|
||||||
for _,v := range values {
|
for _, v := range values {
|
||||||
if first {
|
if first {
|
||||||
first = false
|
first = false
|
||||||
m = v
|
m = v
|
||||||
@ -92,7 +94,7 @@ func maxFloatMap(values map[string]float64) float64 {
|
|||||||
|
|
||||||
func minFloatVector(values []float64) float64 {
|
func minFloatVector(values []float64) float64 {
|
||||||
m := values[0]
|
m := values[0]
|
||||||
for _,v := range values {
|
for _, v := range values {
|
||||||
if v < m {
|
if v < m {
|
||||||
m = v
|
m = v
|
||||||
}
|
}
|
||||||
@ -104,7 +106,7 @@ func minFloatVector(values []float64) float64 {
|
|||||||
func minFloatMap(values map[string]float64) float64 {
|
func minFloatMap(values map[string]float64) float64 {
|
||||||
var m float64
|
var m float64
|
||||||
first := true
|
first := true
|
||||||
for _,v := range values {
|
for _, v := range values {
|
||||||
if first {
|
if first {
|
||||||
first = false
|
first = false
|
||||||
m = v
|
m = v
|
||||||
@ -139,6 +141,34 @@ var OBILang = gval.NewLanguage(
|
|||||||
gval.Function("ismap", func(args ...interface{}) (interface{}, error) {
|
gval.Function("ismap", func(args ...interface{}) (interface{}, error) {
|
||||||
ismap := goutils.IsAMap(args[0])
|
ismap := goutils.IsAMap(args[0])
|
||||||
return ismap, nil
|
return ismap, nil
|
||||||
|
}),
|
||||||
|
gval.Function("printf", func(args ...interface{}) (interface{}, error) {
|
||||||
|
text := fmt.Sprintf(args[0].(string), args[1:]...)
|
||||||
|
return text, nil
|
||||||
|
}),
|
||||||
|
gval.Function("int", func(args ...interface{}) (interface{}, error) {
|
||||||
|
val, err := goutils.InterfaceToInt(args[0])
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("%v cannot be converted to an integer value", args[0])
|
||||||
|
}
|
||||||
|
return val, nil
|
||||||
|
}),
|
||||||
|
gval.Function("numeric", func(args ...interface{}) (interface{}, error) {
|
||||||
|
val, err := goutils.InterfaceToFloat64(args[0])
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("%v cannot be converted to a numeric value", args[0])
|
||||||
|
}
|
||||||
|
return val, nil
|
||||||
|
}),
|
||||||
|
gval.Function("bool", func(args ...interface{}) (interface{}, error) {
|
||||||
|
val, err := goutils.InterfaceToBool(args[0])
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("%v cannot be converted to a boolan value", args[0])
|
||||||
|
}
|
||||||
|
return val, nil
|
||||||
}))
|
}))
|
||||||
|
|
||||||
func Expression(expression string) (gval.Evaluable, error) {
|
func Expression(expression string) (gval.Evaluable, error) {
|
||||||
|
@ -1,12 +1,21 @@
|
|||||||
package obiiter
|
package obiiter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/schollz/progressbar/v3"
|
"github.com/schollz/progressbar/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (iterator IBioSequence) Speed(message ...string) IBioSequence {
|
func (iterator IBioSequence) Speed(message ...string) IBioSequence {
|
||||||
|
|
||||||
|
// If the STDERR is redicted and doesn't end up to a terminal
|
||||||
|
// No progress bar is printed.
|
||||||
|
o, _ := os.Stderr.Stat()
|
||||||
|
if (o.Mode() & os.ModeCharDevice) != os.ModeCharDevice {
|
||||||
|
return iterator
|
||||||
|
}
|
||||||
|
|
||||||
newIter := MakeIBioSequence()
|
newIter := MakeIBioSequence()
|
||||||
|
|
||||||
newIter.Add(1)
|
newIter.Add(1)
|
||||||
@ -44,6 +53,7 @@ func (iterator IBioSequence) Speed(message ...string) IBioSequence {
|
|||||||
bar.Add(l)
|
bar.Add(l)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fmt.Fprintln(os.Stderr)
|
||||||
newIter.Done()
|
newIter.Done()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
62
pkg/obiseq/eval.go
Normal file
62
pkg/obiseq/eval.go
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
package obiseq
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.metabarcoding.org/lecasofts/go/obitools/pkg/obieval"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Expression(expression string) func(*BioSequence) (interface{},error) {
|
||||||
|
|
||||||
|
exp, err := obieval.OBILang.NewEvaluable(expression)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error in the expression : %s", expression)
|
||||||
|
}
|
||||||
|
|
||||||
|
f := func(sequence *BioSequence) (interface{},error) {
|
||||||
|
return exp(context.Background(),
|
||||||
|
map[string]interface{}{
|
||||||
|
"annotations": sequence.Annotations(),
|
||||||
|
"sequence": sequence,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
func EditIdWorker(expression string) SeqWorker {
|
||||||
|
e := Expression(expression)
|
||||||
|
f := func(sequence *BioSequence) *BioSequence {
|
||||||
|
v,err := e(sequence)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Expression '%s' cannot be evaluated on sequence %s",
|
||||||
|
expression,
|
||||||
|
sequence.Id())
|
||||||
|
}
|
||||||
|
sequence.SetId(fmt.Sprintf("%v",v))
|
||||||
|
return sequence
|
||||||
|
}
|
||||||
|
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
func EditAttributeWorker(key string, expression string) SeqWorker {
|
||||||
|
e := Expression(expression)
|
||||||
|
f := func(sequence *BioSequence) *BioSequence {
|
||||||
|
v,err := e(sequence)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Expression '%s' cannot be evaluated on sequence %s",
|
||||||
|
expression,
|
||||||
|
sequence.Id())
|
||||||
|
}
|
||||||
|
sequence.SetAttribute(key,v)
|
||||||
|
return sequence
|
||||||
|
}
|
||||||
|
|
||||||
|
return f
|
||||||
|
}
|
@ -225,3 +225,4 @@ func ExpressionPredicat(expression string) SequencePredicate {
|
|||||||
|
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
|
|
||||||
"git.metabarcoding.org/lecasofts/go/obitools/pkg/obicorazick"
|
"git.metabarcoding.org/lecasofts/go/obitools/pkg/obicorazick"
|
||||||
"git.metabarcoding.org/lecasofts/go/obitools/pkg/obiiter"
|
"git.metabarcoding.org/lecasofts/go/obitools/pkg/obiiter"
|
||||||
|
"git.metabarcoding.org/lecasofts/go/obitools/pkg/obioptions"
|
||||||
"git.metabarcoding.org/lecasofts/go/obitools/pkg/obiseq"
|
"git.metabarcoding.org/lecasofts/go/obitools/pkg/obiseq"
|
||||||
"git.metabarcoding.org/lecasofts/go/obitools/pkg/obitax"
|
"git.metabarcoding.org/lecasofts/go/obitools/pkg/obitax"
|
||||||
"git.metabarcoding.org/lecasofts/go/obitools/pkg/obitools/obigrep"
|
"git.metabarcoding.org/lecasofts/go/obitools/pkg/obitools/obigrep"
|
||||||
@ -65,6 +66,21 @@ func RenameAttributeWorker(toBeRenamed map[string]string) obiseq.SeqWorker {
|
|||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func EvalAttributeWorker(expression map[string]string) obiseq.SeqWorker {
|
||||||
|
var w obiseq.SeqWorker
|
||||||
|
w = nil
|
||||||
|
|
||||||
|
for a,e := range expression {
|
||||||
|
if w == nil {
|
||||||
|
w = obiseq.EditAttributeWorker(a,e)
|
||||||
|
} else {
|
||||||
|
w.ChainWorkers(obiseq.EditAttributeWorker(a,e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
func AddTaxonAtRankWorker(taxonomy *obitax.Taxonomy, ranks ...string) obiseq.SeqWorker {
|
func AddTaxonAtRankWorker(taxonomy *obitax.Taxonomy, ranks ...string) obiseq.SeqWorker {
|
||||||
f := func(s *obiseq.BioSequence) *obiseq.BioSequence {
|
f := func(s *obiseq.BioSequence) *obiseq.BioSequence {
|
||||||
for _, r := range ranks {
|
for _, r := range ranks {
|
||||||
@ -121,6 +137,11 @@ func CLIAnnotationWorker() obiseq.SeqWorker {
|
|||||||
annotator = annotator.ChainWorkers(w)
|
annotator = annotator.ChainWorkers(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if CLIHasSetAttributeExpression() {
|
||||||
|
w := EvalAttributeWorker(CLISetAttributeExpression())
|
||||||
|
annotator = annotator.ChainWorkers(w)
|
||||||
|
}
|
||||||
|
|
||||||
if CLIHasAhoCorasick() {
|
if CLIHasAhoCorasick() {
|
||||||
patterns := CLIAhoCorazick()
|
patterns := CLIAhoCorazick()
|
||||||
log.Println("Matching : ", len(patterns), " patterns on sequences")
|
log.Println("Matching : ", len(patterns), " patterns on sequences")
|
||||||
@ -138,7 +159,7 @@ func CLIAnnotationPipeline() obiiter.Pipeable {
|
|||||||
worker := CLIAnnotationWorker()
|
worker := CLIAnnotationWorker()
|
||||||
|
|
||||||
annotator := obiseq.SeqToSliceConditionalWorker(worker, predicate, true)
|
annotator := obiseq.SeqToSliceConditionalWorker(worker, predicate, true)
|
||||||
f := obiiter.SliceWorkerPipe(annotator)
|
f := obiiter.SliceWorkerPipe(annotator, obioptions.CLIParallelWorkers())
|
||||||
|
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ var _toBeRenamed = make(map[string]string, 0)
|
|||||||
var _toBeDeleted = make([]string, 0)
|
var _toBeDeleted = make([]string, 0)
|
||||||
var _keepOnly = make([]string, 0)
|
var _keepOnly = make([]string, 0)
|
||||||
var _taxonAtRank = make([]string, 0)
|
var _taxonAtRank = make([]string, 0)
|
||||||
|
var _evalAttribute = make(map[string]string, 0)
|
||||||
var _tagList = ""
|
var _tagList = ""
|
||||||
var _clearAll = false
|
var _clearAll = false
|
||||||
var _setSeqLength = false
|
var _setSeqLength = false
|
||||||
@ -41,6 +42,12 @@ func SequenceAnnotationOptionSet(options *getoptions.GetOpt) {
|
|||||||
// options.Description("Forces sequence record ids to be unique."),
|
// options.Description("Forces sequence record ids to be unique."),
|
||||||
// )
|
// )
|
||||||
|
|
||||||
|
options.StringMapVar(&_evalAttribute, "set-tag", 1, 1,
|
||||||
|
options.Alias("S"),
|
||||||
|
options.ArgName("KEY=EXPRESSION"),
|
||||||
|
options.Description("Creates a new attribute named with a key <KEY> "+
|
||||||
|
"sets with a value computed from <EXPRESSION>."))
|
||||||
|
|
||||||
options.StringMapVar(&_toBeRenamed, "rename-tag", 1, 1,
|
options.StringMapVar(&_toBeRenamed, "rename-tag", 1, 1,
|
||||||
options.Alias("R"),
|
options.Alias("R"),
|
||||||
options.ArgName("NEW_NAME=OLD_NAME"),
|
options.ArgName("NEW_NAME=OLD_NAME"),
|
||||||
@ -140,6 +147,17 @@ func CLIHasClearAllFlag() bool {
|
|||||||
return _clearAll
|
return _clearAll
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CLIHasSetAttributeExpression() bool {
|
||||||
|
return len(_evalAttribute) > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func CLISetAttributeExpression() map[string]string {
|
||||||
|
return _evalAttribute
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func CLIHasAhoCorasick() bool {
|
func CLIHasAhoCorasick() bool {
|
||||||
_, err := os.Stat(_ahoCorazick)
|
_, err := os.Stat(_ahoCorazick)
|
||||||
return err == nil
|
return err == nil
|
||||||
|
Reference in New Issue
Block a user