From 87a7219ab48e99a2b4925443d60d2e50d92d8cae Mon Sep 17 00:00:00 2001 From: Eric Coissac Date: Tue, 4 Jun 2024 22:57:07 +0200 Subject: [PATCH] Adds the reading of the options through the csv formated ngsfilter configuration file Former-commit-id: 0e9a13689da2ba45293c7de1f728d3d0d34d3238 --- pkg/obiformats/ngsfilter_read.go | 132 ++++++++++++++++++++++++++++--- pkg/obingslibrary/ngslibrary.go | 56 +++++++++++-- pkg/obioptions/version.go | 2 +- 3 files changed, 171 insertions(+), 19 deletions(-) diff --git a/pkg/obiformats/ngsfilter_read.go b/pkg/obiformats/ngsfilter_read.go index 5f53f40..ea1264d 100644 --- a/pkg/obiformats/ngsfilter_read.go +++ b/pkg/obiformats/ngsfilter_read.go @@ -226,7 +226,7 @@ func ReadOldNGSFilter(reader io.Reader) (*obingslibrary.NGSLibrary, error) { } var library_parameter = map[string]func(library *obingslibrary.NGSLibrary, values ...string){ - "@spacer": func(library *obingslibrary.NGSLibrary, values ...string) { + "spacer": func(library *obingslibrary.NGSLibrary, values ...string) { switch len(values) { case 0: log.Fatalln("Missing value for @spacer parameter") @@ -251,6 +251,108 @@ var library_parameter = map[string]func(library *obingslibrary.NGSLibrary, value log.Fatalln("Invalid value for @spacer parameter") } }, + "forward_spacer": func(library *obingslibrary.NGSLibrary, values ...string) { + switch len(values) { + case 0: + log.Fatalln("Missing value for @forward_spacer parameter") + case 1: + spacer, err := strconv.Atoi(values[0]) + + if err != nil { + log.Fatalln("Invalid value for @forward_spacer parameter") + } + + library.SetForwardTagSpacer(spacer) + default: + log.Fatalln("Invalid value for @forward_spacer parameter") + } + }, + "reverse_spacer": func(library *obingslibrary.NGSLibrary, values ...string) { + switch len(values) { + case 0: + log.Fatalln("Missing value for @reverse_spacer parameter") + case 1: + spacer, err := strconv.Atoi(values[0]) + + if err != nil { + log.Fatalln("Invalid value for @reverse_spacer parameter") + } + + library.SetReverseTagSpacer(spacer) + default: + log.Fatalln("Invalid value for @reverse_spacer parameter") + } + }, + "tag_delimiter": func(library *obingslibrary.NGSLibrary, values ...string) { + switch len(values) { + case 0: + log.Fatalln("Missing value for @tag_delimiter parameter") + case 1: + library.SetTagDelimiter([]byte(values[0])[0]) + case 2: + library.SetTagDelimiterFor(values[0], []byte(values[1])[0]) + default: + log.Fatalln("Invalid value for @tag_delimiter parameter") + } + }, + "forward_tag_delimiter": func(library *obingslibrary.NGSLibrary, values ...string) { + switch len(values) { + case 0: + log.Fatalln("Missing value for @forward_tag_delimiter parameter") + case 1: + library.SetForwardTagDelimiter([]byte(values[0])[0]) + default: + log.Fatalln("Invalid value for @forward_tag_delimiter parameter") + } + }, + "reverse_tag_delimiter": func(library *obingslibrary.NGSLibrary, values ...string) { + switch len(values) { + case 0: + log.Fatalln("Missing value for @reverse_tag_delimiter parameter") + case 1: + library.SetReverseTagDelimiter([]byte(values[0])[0]) + default: + log.Fatalln("Invalid value for @reverse_tag_delimiter parameter") + } + }, + "matching": func(library *obingslibrary.NGSLibrary, values ...string) { + switch len(values) { + case 0: + log.Fatalln("Missing value for @matching parameter") + case 1: + if err := library.SetMatching(values[0]); err != nil { + log.Fatalf("Invalid value %s for @matching parameter", values[0]) + } + default: + log.Fatalln("Invalid value for @matching parameter") + } + }, + "primer_mismatches": func(library *obingslibrary.NGSLibrary, values ...string) { + switch len(values) { + case 0: + log.Fatalln("Missing value for @primer_error parameter") + case 1: + dist, err := strconv.Atoi(values[0]) + + if err != nil { + log.Fatalf("Invalid value %s for @primer_error parameter", values[0]) + } + + library.SetAllowedMismatch(dist) + default: + log.Fatalln("Invalid value for @primer_error parameter") + } + }, + "indels": func(library *obingslibrary.NGSLibrary, values ...string) { + switch len(values) { + case 0: + log.Fatalln("Missing value for @indels parameter") + case 1: + library.SetAllowsIndels(values[0] == "true") + default: + log.Fatalln("Invalid value for @indels parameter") + } + }, } func ReadCSVNGSFilter(reader io.Reader) (*obingslibrary.NGSLibrary, error) { @@ -272,20 +374,9 @@ func ReadCSVNGSFilter(reader io.Reader) (*obingslibrary.NGSLibrary, error) { i := 0 for i = 0; i < len(records) && records[i][0] == "@param"; i++ { - param := records[i][1] - if len(records[i]) < 3 { - log.Fatalf("At line %d: Missing value for parameter %s", i, param) - } - data := records[i][2:] - setparam, ok := library_parameter[param] - - if ok { - setparam(&ngsfilter, data...) - } else { - log.Warnf("At line %d: Skipping unknown parameter %s: %v", i, param, data) - } } + params := records[0:i] records = records[i:] header := records[0] @@ -371,5 +462,20 @@ func ReadCSVNGSFilter(reader io.Reader) (*obingslibrary.NGSLibrary, error) { } + for i := 0; i < len(params); i++ { + param := params[i][1] + if len(params[i]) < 3 { + log.Fatalf("At line %d: Missing value for parameter %s", i, param) + } + data := params[i][2:] + setparam, ok := library_parameter[param] + + if ok { + setparam(&ngsfilter, data...) + } else { + log.Warnf("At line %d: Skipping unknown parameter %s: %v", i, param, data) + } + } + return &ngsfilter, nil } diff --git a/pkg/obingslibrary/ngslibrary.go b/pkg/obingslibrary/ngslibrary.go index 8b8c7ae..a84d25a 100644 --- a/pkg/obingslibrary/ngslibrary.go +++ b/pkg/obingslibrary/ngslibrary.go @@ -24,15 +24,20 @@ type PCR struct { } type NGSLibrary struct { - Matching string - Primers map[string]PrimerPair - Markers map[PrimerPair]*Marker + Matching string + Allowed_mismatches int + Allows_indels bool + Primers map[string]PrimerPair + Markers map[PrimerPair]*Marker } func MakeNGSLibrary() NGSLibrary { return NGSLibrary{ - Primers: make(map[string]PrimerPair, 10), - Markers: make(map[PrimerPair]*Marker, 10), + Matching: "strict", + Allowed_mismatches: 2, + Allows_indels: false, + Primers: make(map[string]PrimerPair, 10), + Markers: make(map[PrimerPair]*Marker, 10), } } @@ -109,6 +114,22 @@ func (library *NGSLibrary) SetTagDelimiter(delim byte) { library.SetReverseTagDelimiter(delim) } +func (library *NGSLibrary) SetTagDelimiterFor(primer string, delim byte) { + primers, ok := library.Primers[primer] + + if ok { + marker, ok := library.Markers[primers] + + if ok { + if primer == primers.Forward { + marker.SetForwardTagDelimiter(delim) + } else { + marker.SetReverseTagDelimiter(delim) + } + } + } +} + func (library *NGSLibrary) CheckTagLength() { for _, marker := range library.Markers { @@ -132,3 +153,28 @@ func (library *NGSLibrary) CheckPrimerUnicity() error { } return nil } + +// SetMatching sets the matching strategy for the library. +// Returns an error if the matching strategy is invalid. +func (library *NGSLibrary) SetMatching(matching string) error { + switch matching { + case "strict", "hamming", "indel": // Valid matching strategies + library.Matching = matching + default: + return fmt.Errorf("invalid matching : %s", matching) + } + return nil +} + +func (library *NGSLibrary) SetAllowedMismatch(allowed_mismatches int) { + if allowed_mismatches < 0 { + allowed_mismatches = 0 + } + library.Allowed_mismatches = allowed_mismatches +} + +// SetAllowsIndels sets whether the library allows indels. +// The value of the argument allows_indels is directly assigned to the library's Allows_indels field. +func (library *NGSLibrary) SetAllowsIndels(allows_indels bool) { + library.Allows_indels = allows_indels +} diff --git a/pkg/obioptions/version.go b/pkg/obioptions/version.go index 8ea226b..0917d0f 100644 --- a/pkg/obioptions/version.go +++ b/pkg/obioptions/version.go @@ -7,7 +7,7 @@ import ( // TODO: The version number is extracted from git. This induces that the version // corresponds to the last commit, and not the one when the file will be // commited -var _Commit = "d00f335" +var _Commit = "5affee2" var _Version = "Release 4.2.0" // Version returns the version of the obitools package.