Reduce memomry inprint of obipcr

Former-commit-id: bd25be2d454f083c729346a828e27f07ad1a216e
This commit is contained in:
2023-03-31 10:53:53 +02:00
parent 2c9bca5c8a
commit 84b3e4d097
5 changed files with 149 additions and 40 deletions

View File

@@ -1,3 +1,5 @@
// It adds to a CLI every options proposed to the user to tune the parametters of the PCR simulation
// algorithm
package obipcr
import (
@@ -14,13 +16,14 @@ var _ReversePrimer string
var _AllowedMismatch = 0
var _MinimumLength = 0
var _MaximumLength = -1
var _Fragmented = false
// PCROptionSet defines every options related to a simulated PCR.
//
// The function adds to a CLI every options proposed to the user
// to tune the parametters of the PCR simulation algorithm.
//
// Parameters
// # Parameters
//
// - option : is a pointer to a getoptions.GetOpt instance normaly
// produced by the
@@ -29,6 +32,9 @@ func PCROptionSet(options *getoptions.GetOpt) {
options.Alias("c"),
options.Description("Considers that sequences are [c]ircular."))
options.BoolVar(&_Fragmented, "fragmented", false,
options.Description("Fragaments long sequences in overlaping fragments to speedup computations"))
options.StringVar(&_ForwardPrimer, "forward", "",
options.Required("You must provide a forward primer"),
options.Description("The forward primer used for the electronic PCR."))
@@ -46,6 +52,7 @@ func PCROptionSet(options *getoptions.GetOpt) {
options.Description("Minimum length of the barcode (primers excluded)."))
options.IntVar(&_MaximumLength, "max-length", -1,
options.Alias("L"),
options.Required("You must indicate the maximum size of the amplicon (excluded primer length)"),
options.Description("Maximum length of the barcode (primers excluded)."))
}
@@ -56,11 +63,11 @@ func OptionSet(options *getoptions.GetOpt) {
PCROptionSet(options)
}
// ForwardPrimer returns the sequence of the forward primer as indicated by the
// CLIForwardPrimer returns the sequence of the forward primer as indicated by the
// --forward command line option
func ForwardPrimer() string {
func CLIForwardPrimer() string {
pattern, err := obiapat.MakeApatPattern(_ForwardPrimer, _AllowedMismatch, false)
if err != nil {
log.Fatalf("%+v", err)
}
@@ -70,10 +77,10 @@ func ForwardPrimer() string {
return _ForwardPrimer
}
// ReversePrimer returns the sequence of the reverse primer as indicated by the
// CLIReversePrimer returns the sequence of the reverse primer as indicated by the
// --reverse command line option
func ReversePrimer() string {
pattern, err := obiapat.MakeApatPattern(_ReversePrimer, _AllowedMismatch,false)
func CLIReversePrimer() string {
pattern, err := obiapat.MakeApatPattern(_ReversePrimer, _AllowedMismatch, false)
if err != nil {
log.Fatalf("%+v", err)
@@ -84,27 +91,31 @@ func ReversePrimer() string {
return _ReversePrimer
}
// AllowedMismatch returns the allowed mistmatch count between each
// CLIAllowedMismatch returns the allowed mistmatch count between each
// primer and the sequences as indicated by the
// --allowed-mismatches|-e command line option
func AllowedMismatch() int {
func CLIAllowedMismatch() int {
return _AllowedMismatch
}
// Circular returns the considered sequence topology as indicated by the
// CLICircular returns the considered sequence topology as indicated by the
// --circular|-c command line option
func Circular() bool {
func CLICircular() bool {
return _Circular
}
// MinLength returns the amplicon minimum length as indicated by the
// CLIMinLength returns the amplicon minimum length as indicated by the
// --min-length|-l command line option
func MinLength() int {
func CLIMinLength() int {
return _MinimumLength
}
// MaxLength returns the amplicon maximum length as indicated by the
// CLIMaxLength returns the amplicon maximum length as indicated by the
// --max-length|-L command line option
func MaxLength() int {
func CLIMaxLength() int {
return _MaximumLength
}
func CLIFragmented() bool {
return _Fragmented
}

View File

@@ -4,39 +4,56 @@ import (
"git.metabarcoding.org/lecasofts/go/obitools/pkg/obiapat"
"git.metabarcoding.org/lecasofts/go/obitools/pkg/obiiter"
"git.metabarcoding.org/lecasofts/go/obitools/pkg/obioptions"
"git.metabarcoding.org/lecasofts/go/obitools/pkg/obiutils"
log "github.com/sirupsen/logrus"
)
// PCR iterates over sequences provided by a obiseq.IBioSequenceBatch
// CLIPCR iterates over sequences provided by a obiseq.IBioSequenceBatch
// and returns an other obiseq.IBioSequenceBatch distributing
// obiseq.BioSequenceBatch containing the selected amplicon sequences.
func PCR(iterator obiiter.IBioSequence) (obiiter.IBioSequence, error) {
func CLIPCR(iterator obiiter.IBioSequence) (obiiter.IBioSequence, error) {
opts := make([]obiapat.WithOption, 0, 10)
opts = append(opts,
obiapat.OptionForwardPrimer(
ForwardPrimer(),
AllowedMismatch(),
CLIForwardPrimer(),
CLIAllowedMismatch(),
),
obiapat.OptionReversePrimer(
ReversePrimer(),
AllowedMismatch(),
CLIReversePrimer(),
CLIAllowedMismatch(),
),
)
if MinLength() > 0 {
opts = append(opts, obiapat.OptionMinLength(MinLength()))
if CLIMinLength() > 0 {
opts = append(opts, obiapat.OptionMinLength(CLIMinLength()))
}
if MaxLength() > 0 {
opts = append(opts, obiapat.OptionMaxLength(MaxLength()))
}
opts = append(opts, obiapat.OptionMaxLength(CLIMaxLength()))
if Circular() {
opts = append(opts, obiapat.OptionCircular(Circular()))
if CLICircular() {
opts = append(opts, obiapat.OptionCircular(CLICircular()))
}
worker := obiapat.PCRSliceWorker(opts...)
if CLIFragmented() {
frags := obiiter.IFragments(
CLIMaxLength()*1000,
CLIMaxLength()*100,
CLIMaxLength()+obiutils.MaxInt(len(CLIForwardPrimer()),
len(CLIReversePrimer()))+obiutils.MinInt(len(CLIForwardPrimer()),
len(CLIReversePrimer()))/2,
100,
obioptions.CLIParallelWorkers(),
)
log.Infof("Fragmenting sequence longer than %dbp into chuncks of %dbp",
CLIMaxLength()*100000000,
CLIMaxLength()*100,
)
iterator = iterator.Pipe(frags)
}
return iterator.MakeISliceWorker(worker, obioptions.CLIParallelWorkers(), 0), nil
}