From 10b8f398c4272700dd27a177af244d6b531d2582 Mon Sep 17 00:00:00 2001 From: Willow Carretero Chavez Date: Tue, 12 Sep 2023 16:12:42 -0400 Subject: [PATCH] Re-enable golangci-lint.yml, turn on linters, and lint. (#343) --- .github/workflows/golangci-lint.yml | 38 ++++++++++++++++++++++++ .golangci.yml | 34 +++++++++------------ align/align.go | 3 -- align/align_test.go | 3 -- align/example_test.go | 1 + align/matrix/matrices.go | 2 +- align/matrix/matrix_test.go | 2 +- alphabet/alphabet_test.go | 1 - clone/clone_test.go | 1 - fold/fold.go | 2 -- fold/seqfold.go | 3 +- io/example_test.go | 1 - io/fasta/fasta.go | 1 - io/genbank/example_test.go | 7 ++--- io/genbank/genbank.go | 35 ++-------------------- io/genbank/genbank_test.go | 7 +---- io/gff/example_test.go | 4 --- io/gff/gff.go | 4 +-- io/gff/gff_test.go | 1 - io/pileup/pileup.go | 46 ++++++++++++++--------------- io/pileup/pileup_test.go | 5 ++-- io/polyjson/example_test.go | 7 ++--- io/polyjson/polyjson_test.go | 3 +- io/rebase/rebase_test.go | 2 -- io/slow5/slow5.go | 4 +-- io/uniprot/example_test.go | 1 + primers/pcr/example_test.go | 1 + primers/pcr/pcr.go | 8 ++--- primers/primers.go | 2 +- primers/primers_test.go | 2 -- random/random.go | 2 -- seqhash/seqhash.go | 4 --- seqhash/seqhash_test.go | 2 -- synthesis/codon/codon.go | 13 ++------ synthesis/codon/codon_test.go | 6 ---- synthesis/codon/example_test.go | 2 -- synthesis/fix/synthesis.go | 2 -- synthesis/fix/synthesis_test.go | 1 - synthesis/fragment/fragment_test.go | 5 +--- transform/transform_test.go | 2 +- transform/variants/variants.go | 33 ++++++++++----------- 41 files changed, 122 insertions(+), 181 deletions(-) create mode 100644 .github/workflows/golangci-lint.yml diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml new file mode 100644 index 00000000..b4f66a9e --- /dev/null +++ b/.github/workflows/golangci-lint.yml @@ -0,0 +1,38 @@ +name: golangci-lint + +on: + push: + tags: + - v* + branches: + - main + pull_request: +jobs: + golangci: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Run golangci-lint + uses: golangci/golangci-lint-action@v2.5.2 + with: + # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version + version: latest + + # Optional: working directory, useful for monorepos + # working-directory: somedir + + # Optional: golangci-lint command line arguments. + # args: --issues-exit-code=0 + + # Optional: show only new issues if it's a pull request. The default value is `false`. + # only-new-issues: true + + # Optional: if set to true then the action will use pre-installed Go. + # skip-go-installation: true + + # Optional: if set to true then the action don't cache or restore ~/go/pkg. + # skip-pkg-cache: true + + # Optional: if set to true then the action don't cache or restore ~/.cache/go-build. + # skip-build-cache: true diff --git a/.golangci.yml b/.golangci.yml index ee5feb70..53d8d62f 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -5,31 +5,25 @@ run: linters: enable: - bodyclose - ##- dogsled - dupl - #- exhaustivestruct - exportloopref - #- funlen - gochecknoinits - ##- goconst - ##- gocritic - ##- gocyclo - ##- gofmt - ##- goimports - #- gomnd + # - goconst # TODO: Enable this and fix the errors. + - gofmt + - goimports - goprintffuncname - ##- gosec - #- lll - ##- misspell + - misspell - nakedret - nilnil - noctx - nolintlint - ##- stylecheck - ##- unconvert - ##- unparam - ##- whitespace -#linters-settings: -# stylecheck: -# # https://staticcheck.io/docs/options#checks -# checks: ["all", "-ST1005"] \ No newline at end of file + - stylecheck + - unconvert + - unparam + - whitespace +linters-settings: + stylecheck: + # https://staticcheck.io/docs/options#checks + checks: + - "all" + - "-ST1005" # Disable "Incorrectly formatted error string" errors. TODO: Enable this and fix the errors. \ No newline at end of file diff --git a/align/align.go b/align/align.go index 1401f90a..fc4edef9 100644 --- a/align/align.go +++ b/align/align.go @@ -77,7 +77,6 @@ type Scoring struct { // NewScoring returns a new Scoring struct with default values for DNA. func NewScoring(substitutionMatrix *matrix.SubstitutionMatrix, gapPenalty int) (Scoring, error) { - if substitutionMatrix == nil { substitutionMatrix = matrix.Default } @@ -99,7 +98,6 @@ func (s Scoring) Score(a, b byte) (int, error) { // It returns the final score and the optimal alignments of the two strings in O(nm) time and O(nm) space. // https://en.wikipedia.org/wiki/Needleman-Wunsch_algorithm func NeedlemanWunsch(stringA string, stringB string, scoring Scoring) (int, string, string, error) { - // Get the M and N dimensions of the matrix. The M x N matrix is standard linear algebra notation. // But I added columns and rows to the variable name to make it more clear what the dimensions are. columnLengthM, rowLengthN := len(stringA), len(stringB) @@ -171,7 +169,6 @@ func NeedlemanWunsch(stringA string, stringB string, scoring Scoring) (int, stri // It returns the max score and optimal local alignments between two strings alignments of the two strings in O(nm) time and O(nm) space. // https://en.wikipedia.org/wiki/Smith-Waterman_algorithm func SmithWaterman(stringA string, stringB string, scoring Scoring) (int, string, string, error) { - columnLengthM, rowLengthN := len(stringA), len(stringB) // Initialize the alignment matrix diff --git a/align/align_test.go b/align/align_test.go index 58a774d8..aca3a7de 100644 --- a/align/align_test.go +++ b/align/align_test.go @@ -9,7 +9,6 @@ import ( ) func TestNeedlemanWunsch(t *testing.T) { - mat := [][]int{ /* A C G T U */ /* A */ {1, -1, -1, -1, -1}, @@ -138,7 +137,6 @@ func TestNeedlemanWunsch(t *testing.T) { } func TestSmithWaterman(t *testing.T) { - mat := [][]int{ /* - A C G T */ /* - */ {0, 0, 0, 0, 0}, @@ -291,5 +289,4 @@ func TestSmithWaterman(t *testing.T) { if alignN != "G" { t.Errorf("Alignment is %s, expected G", alignN) } - } diff --git a/align/example_test.go b/align/example_test.go index d1eeed12..1cab08e8 100644 --- a/align/example_test.go +++ b/align/example_test.go @@ -1,3 +1,4 @@ +//nolint:dupl package align_test import ( diff --git a/align/matrix/matrices.go b/align/matrix/matrices.go index 49f5a790..41fc032c 100644 --- a/align/matrix/matrices.go +++ b/align/matrix/matrices.go @@ -5,7 +5,7 @@ // license that can be found in the LICENSE file. /* -Package matrix provides a variety of alignment scoring matrices for sequence alignment. +Package matrix provides a variety of alignment scoring matrices for sequence alignment. These matrices have been lovingly borrowed from biogo/align. https://github.com/biogo/biogo/blob/master/align/matrix/matrices.go diff --git a/align/matrix/matrix_test.go b/align/matrix/matrix_test.go index 5e6d05a3..f05c63f8 100644 --- a/align/matrix/matrix_test.go +++ b/align/matrix/matrix_test.go @@ -11,7 +11,7 @@ import ( func TestSubstitutionMatrix(t *testing.T) { alpha1 := alphabet.NewAlphabet([]string{"-", "A", "C", "G", "T"}) alpha2 := alphabet.NewAlphabet([]string{"-", "A", "C", "G", "T"}) - NUC_4 := [][]int{ + NUC_4 := [][]int{ //nolint:stylecheck /* - A C G T */ /* - */ {0, 0, 0, 0, 0}, /* A */ {0, 5, -4, -4, -4}, diff --git a/alphabet/alphabet_test.go b/alphabet/alphabet_test.go index eacb15d8..81dd70ad 100644 --- a/alphabet/alphabet_test.go +++ b/alphabet/alphabet_test.go @@ -64,7 +64,6 @@ func TestAlphabet(t *testing.T) { } func TestAlphabet_Symbols(t *testing.T) { - // Test Symbols symbols := []string{"A", "C", "G", "T"} a := alphabet.NewAlphabet(symbols) diff --git a/clone/clone_test.go b/clone/clone_test.go index d96e94f4..2cfb5761 100644 --- a/clone/clone_test.go +++ b/clone/clone_test.go @@ -141,7 +141,6 @@ func ExampleGoldenGate() { fmt.Println(seqhash.RotateSequence(Clones[0])) // Output: AAAAAAAGGATCTCAAGAAGGCCTACTATTAGCAACAACGATCCTTTGATCTTTTCTACGGGGTCTGACGCTCAGTGGAACGAAAACTCACGTTAAGGGATTTTGGTCATGAGATTATCAAAAAGGATCTTCACCTAGATCCTTTTAAATTAAAAATGAAGTTTTAAATCAATCTAAAGTATATATGAGTAAACTTGGTCTGACAGTTACCAATGCTTAATCAGTGAGGCACCTATCTCAGCGATCTGTCTATTTCGTTCATCCATAGTTGCCTGACTCCCCGTCGTGTAGATAACTACGATACGGGAGGGCTTACCATCTGGCCCCAGTGCTGCAATGATACCGCGAGAACCACGCTCACCGGCTCCAGATTTATCAGCAATAAACCAGCCAGCCGGAAGGGCCGAGCGCAGAAGTGGTCCTGCAACTTTATCCGCCTCCATCCAGTCTATTAATTGTTGCCGGGAAGCTAGAGTAAGTAGTTCGCCAGTTAATAGTTTGCGCAACGTTGTTGCCATTGCTACAGGCATCGTGGTGTCACGCTCGTCGTTTGGTATGGCTTCATTCAGCTCCGGTTCCCAACGATCAAGGCGAGTTACATGATCCCCCATGTTGTGCAAAAAAGCGGTTAGCTCCTTCGGTCCTCCGATCGTTGTCAGAAGTAAGTTGGCCGCAGTGTTATCACTCATGGTTATGGCAGCACTGCATAATTCTCTTACTGTCATGCCATCCGTAAGATGCTTTTCTGTGACTGGTGAGTACTCAACCAAGTCATTCTGAGAATAGTGTATGCGGCGACCGAGTTGCTCTTGCCCGGCGTCAATACGGGATAATACCGCGCCACATAGCAGAACTTTAAAAGTGCTCATCATTGGAAAACGTTCTTCGGGGCGAAAACTCTCAAGGATCTTACCGCTGTTGAGATCCAGTTCGATGTAACCCACTCGTGCACCCAACTGATCTTCAGCATCTTTTACTTTCACCAGCGTTTCTGGGTGAGCAAAAACAGGAAGGCAAAATGCCGCAAAAAAGGGAATAAGGGCGACACGGAAATGTTGAATACTCATACTCTTCCTTTTTCAATATTATTGAAGCATTTATCAGGGTTATTGTCTCATGAGCGGATACATATTTGAATGTATTTAGAAAAATAAACAAATAGGGGTTCCGCGCACCTGCACCAGTCAGTAAAACGACGGCCAGTAGTCAAAAGCCTCCGACCGGAGGCTTTTGACTTGGTTCAGGTGGAGTGGGAGAAACACGTGGCAAACATTCCGGTCTCAAATGGAAAAGAGCAACGAAACCAACGGCTACCTTGACAGCGCTCAAGCCGGCCCTGCAGCTGGCCCGGGCGCTCCGGGTACCGCCGCGGGTCGTGCACGTCGTTGCGCGGGCTTCCTGCGGCGCCAAGCGCTGGTGCTGCTCACGGTGTCTGGTGTTCTGGCAGGCGCCGGTTTGGGCGCGGCACTGCGTGGGCTCAGCCTGAGCCGCACCCAGGTCACCTACCTGGCCTTCCCCGGCGAGATGCTGCTCCGCATGCTGCGCATGATCATCCTGCCGCTGGTGGTCTGCAGCCTGGTGTCGGGCGCCGCCTCCCTCGATGCCAGCTGCCTCGGGCGTCTGGGCGGTATCGCTGTCGCCTACTTTGGCCTCACCACACTGAGTGCCTCGGCGCTCGCCGTGGCCTTGGCGTTCATCATCAAGCCAGGATCCGGTGCGCAGACCCTTCAGTCCAGCGACCTGGGGCTGGAGGACTCGGGGCCTCCTCCTGTCCCCAAAGAAACGGTGGACTCTTTCCTCGACCTGGCCAGAAACCTGTTTCCCTCCAATCTTGTGGTTGCAGCTTTCCGTACGTATGCAACCGATTATAAAGTCGTGACCCAGAACAGCAGCTCTGGAAATGTAACCCATGAAAAGATCCCCATAGGCACTGAGATAGAAGGGATGAACATTTTAGGATTGGTCCTGTTTGCTCTGGTGTTAGGAGTGGCCTTAAAGAAACTAGGCTCCGAAGGAGAGGACCTCATCCGTTTCTTCAATTCCCTCAACGAGGCGACGATGGTGCTGGTGTCCTGGATTATGTGGTACGTACCTGTGGGCATCATGTTCCTTGTTGGAAGCAAGATCGTGGAAATGAAAGACATCATCGTGCTGGTGACCAGCCTGGGGAAATACATCTTCGCATCTATATTGGGCCACGTCATTCATGGTGGTATCGTCCTGCCGCTGATTTATTTTGTTTTCACACGAAAAAACCCATTCAGATTCCTCCTGGGCCTCCTCGCCCCATTTGCGACAGCATTTGCTACGTGCTCCAGCTCAGCGACCCTTCCCTCTATGATGAAGTGCATTGAAGAGAACAATGGTGTGGACAAGAGGATCTCCAGGTTTATTCTCCCCATCGGGGCCACCGTGAACATGGACGGAGCAGCCATCTTCCAGTGTGTGGCCGCGGTGTTCATTGCGCAACTCAACAACGTAGAGCTCAACGCAGGACAGATTTTCACCATTCTAGTGACTGCCACAGCGTCCAGTGTTGGAGCAGCAGGCGTGCCAGCTGGAGGGGTCCTCACCATTGCCATTATCCTGGAGGCCATTGGGCTGCCTACTCATGATCTGCCTCTGATCCTGGCTGTGGACTGGATTGTGGACCGGACCACCACGGTGGTGAATGTGGAAGGGGATGCCCTGGGTGCAGGCATTCTCCACCACCTGAATCAGAAGGCAACAAAGAAAGGCGAGCAGGAACTTGCTGAGGTGAAAGTGGAAGCCATCCCCAACTGCAAGTCTGAGGAGGAAACCTCGCCCCTGGTGACACACCAGAACCCCGCTGGCCCCGTGGCCAGTGCCCCAGAACTGGAATCCAAGGAGTCGGTTCTGTGAAGAGCTTAGAGACCGACGACTGCCTAAGGACATTCGCTGAGGTGTCAATCGTCGGAGCCGCTGAGCAATAACTAGCATAACCCCTTGGGGCCTCTAAACGGGTCTTGAGGGGTTTTTTGCATGGTCATAGCTGTTTCCTGAGAGCTTGGCAGGTGATGACACACATTAACAAATTTCGTGAGGAGTCTCCAGAAGAATGCCATTAATTTCCATAGGCTCCGCCCCCCTGACGAGCATCACAAAAATCGACGCTCAAGTCAGAGGTGGCGAAACCCGACAGGACTATAAAGATACCAGGCGTTTCCCCCTGGAAGCTCCCTCGTGCGCTCTCCTGTTCCGACCCTGCCGCTTACCGGATACCTGTCCGCCTTTCTCCCTTCGGGAAGCGTGGCGCTTTCTCATAGCTCACGCTGTAGGTATCTCAGTTCGGTGTAGGTCGTTCGCTCCAAGCTGGGCTGTGTGCACGAACCCCCCGTTCAGCCCGACCGCTGCGCCTTATCCGGTAACTATCGTCTTGAGTCCAACCCGGTAAGACACGACTTATCGCCACTGGCAGCAGCCACTGGTAACAGGATTAGCAGAGCGAGGTATGTAGGCGGTGCTACAGAGTTCTTGAAGTGGTGGCCTAACTACGGCTACACTAGAAGAACAGTATTTGGTATCTGCGCTCTGCTGAAGCCAGTTACCTTCGGAAAAAGAGTTGGTAGCTCTTGATCCGGCAAACAAACCACCGCTGGTAGCGGTGGTTTTTTTGTTTGCAAGCAGCAGATTACGCGCAG - } func TestSignalKilledGoldenGate(t *testing.T) { diff --git a/fold/fold.go b/fold/fold.go index 17f3a379..34ca7998 100644 --- a/fold/fold.go +++ b/fold/fold.go @@ -480,7 +480,6 @@ func multibranch(start, mid, end int, foldContext context, helix bool) (nucleicA } summedEnergy += w.energy } - } if unpaired < 0 { @@ -539,7 +538,6 @@ func internalLoop(start, rightOfStart, end, leftOfEnd int, foldContext context) if loopLeftIndex < 1 { return 0, fmt.Errorf("internal loop: subsequence (%d, %d, %d, %d): missing left part of the loop", start, rightOfStart, end, leftOfEnd) - } if loopRightIndex < 1 { return 0, fmt.Errorf("internal loop: subsequence (%d, %d, %d, %d): missing right part of the loop", start, rightOfStart, end, leftOfEnd) diff --git a/fold/seqfold.go b/fold/seqfold.go index 35cb6724..f5a39fb3 100644 --- a/fold/seqfold.go +++ b/fold/seqfold.go @@ -41,7 +41,7 @@ A - number of helices in the loop B - number of unpaired nucleotides in the loop C - coxial stacking in the loop D - terminal mismatch contributions -E - base composition of the unpaired nucleotides (probably neglible?) +E - base composition of the unpaired nucleotides (probably negligible?) Inferred from: Supplemental Material: Annu.Rev.Biophs.Biomol.Struct.33:415-40 doi: 10.1146/annurev.biophys.32.110601.141800 @@ -189,7 +189,6 @@ func newFoldingContext(seq string, temp float64) (context, error) { return context{}, fmt.Errorf("error filling the caches for the FoldingContext: %w", err) } return ret, nil - } // Result holds the resulting structures of the folded s diff --git a/io/example_test.go b/io/example_test.go index 6a29e39f..08fd21f4 100644 --- a/io/example_test.go +++ b/io/example_test.go @@ -10,7 +10,6 @@ import ( // This is where the integration tests that make effed up cyclic dependencies go. func Example() { - // Poly can take in basic gff, gbk, fasta, and JSON. // We call the json package "pson" (poly JSON) to prevent namespace collision with Go's standard json package. diff --git a/io/fasta/fasta.go b/io/fasta/fasta.go index 56bcd294..ab2d14d9 100644 --- a/io/fasta/fasta.go +++ b/io/fasta/fasta.go @@ -363,7 +363,6 @@ func Build(fastas []Fasta) ([]byte, error) { lineCount := 0 // write the fasta sequence 80 characters at a time for _, character := range fasta.Sequence { - fastaString.WriteRune(character) lineCount++ if lineCount == 80 { diff --git a/io/genbank/example_test.go b/io/genbank/example_test.go index 8fd52d0b..0bc8433e 100644 --- a/io/genbank/example_test.go +++ b/io/genbank/example_test.go @@ -111,7 +111,6 @@ func ExampleParseMulti() { } func ExampleGenbank_AddFeature() { - // Sequence for greenflourescent protein (GFP) that we're using as test data for this example. gfpSequence := "ATGGCTAGCAAAGGAGAAGAACTTTTCACTGGAGTTGTCCCAATTCTTGTTGAATTAGATGGTGATGTTAATGGGCACAAATTTTCTGTCAGTGGAGAGGGTGAAGGTGATGCTACATACGGAAAGCTTACCCTTAAATTTATTTGCACTACTGGAAAACTACCTGTTCCATGGCCAACACTTGTCACTACTTTCTCTTATGGTGTTCAATGCTTTTCCCGTTATCCGGATCATATGAAACGGCATGACTTTTTCAAGAGTGCCATGCCCGAAGGTTATGTACAGGAACGCACTATATCTTTCAAAGATGACGGGAACTACAAGACGCGTGCTGAAGTCAAGTTTGAAGGTGATACCCTTGTTAATCGTATCGAGTTAAAAGGTATTGATTTTAAAGAAGATGGAAACATTCTCGGACACAAACTCGAGTACAACTATAACTCACACAATGTATACATCACGGCAGACAAACAAAAGAATGGAATCAAAGCTAACTTCAAAATTCGCCACAACATTGAAGATGGATCCGTTCAACTAGCAGACCATTATCAACAAAATACTCCAATTGGCGATGGCCCTGTCCTTTTACCAGACAACCATTACCTGTCGACACAATCTGCCCTTTCGAAAGATCCCAACGAAAAGCGTGACCACATGGTCCTTCTTGAGTTTGTAACTGCTGCTGGGATTACACATGGCATGGATGAGCTCTACAAATAA" @@ -123,7 +122,7 @@ func ExampleGenbank_AddFeature() { sequence.Sequence = gfpSequence // Set the initialized feature name and sequence location. - feature.Description = "Green Flourescent Protein" + feature.Description = "Green Fluorescent Protein" feature.Location = genbank.Location{} feature.Location.Start = 0 feature.Location.End = len(sequence.Sequence) @@ -141,7 +140,6 @@ func ExampleGenbank_AddFeature() { } func ExampleFeature_GetSequence() { - // Sequence for greenflourescent protein (GFP) that we're using as test data for this example. gfpSequence := "ATGGCTAGCAAAGGAGAAGAACTTTTCACTGGAGTTGTCCCAATTCTTGTTGAATTAGATGGTGATGTTAATGGGCACAAATTTTCTGTCAGTGGAGAGGGTGAAGGTGATGCTACATACGGAAAGCTTACCCTTAAATTTATTTGCACTACTGGAAAACTACCTGTTCCATGGCCAACACTTGTCACTACTTTCTCTTATGGTGTTCAATGCTTTTCCCGTTATCCGGATCATATGAAACGGCATGACTTTTTCAAGAGTGCCATGCCCGAAGGTTATGTACAGGAACGCACTATATCTTTCAAAGATGACGGGAACTACAAGACGCGTGCTGAAGTCAAGTTTGAAGGTGATACCCTTGTTAATCGTATCGAGTTAAAAGGTATTGATTTTAAAGAAGATGGAAACATTCTCGGACACAAACTCGAGTACAACTATAACTCACACAATGTATACATCACGGCAGACAAACAAAAGAATGGAATCAAAGCTAACTTCAAAATTCGCCACAACATTGAAGATGGATCCGTTCAACTAGCAGACCATTATCAACAAAATACTCCAATTGGCGATGGCCCTGTCCTTTTACCAGACAACCATTACCTGTCGACACAATCTGCCCTTTCGAAAGATCCCAACGAAAAGCGTGACCACATGGTCCTTCTTGAGTTTGTAACTGCTGCTGGGATTACACATGGCATGGATGAGCTCTACAAATAA" @@ -153,7 +151,7 @@ func ExampleFeature_GetSequence() { sequence.Sequence = gfpSequence // Set the initialized feature name and sequence location. - feature.Description = "Green Flourescent Protein" + feature.Description = "Green Fluorescent Protein" feature.Location.Start = 0 feature.Location.End = len(sequence.Sequence) @@ -167,5 +165,4 @@ func ExampleFeature_GetSequence() { fmt.Println(gfpSequence == featureSequence) // Output: true - } diff --git a/io/genbank/genbank.go b/io/genbank/genbank.go index 1225de45..34062b36 100644 --- a/io/genbank/genbank.go +++ b/io/genbank/genbank.go @@ -138,9 +138,7 @@ func getFeatureSequence(feature Feature, location Location) (string, error) { if len(location.SubLocations) == 0 { sequenceBuffer.WriteString(parentSequence[location.Start:location.End]) - } else { - for _, subLocation := range location.SubLocations { sequence, _ := getFeatureSequence(feature, subLocation) @@ -213,19 +211,12 @@ func WriteMulti(sequences []Genbank, path string) error { // Build builds a GBK byte slice to be written out to db or file. func Build(gbk Genbank) ([]byte, error) { gbkSlice := []Genbank{gbk} - multiGBK, err := buildMultiNth(gbkSlice, -1) + multiGBK, err := BuildMulti(gbkSlice) return multiGBK, err - } // BuildMulti builds a MultiGBK byte slice to be written out to db or file. -func BuildMulti(sequence []Genbank) ([]byte, error) { - multiGBK, err := buildMultiNth(sequence, -1) - return multiGBK, err -} - -// buildMultiNth builds a MultiGBK byte slice to be written out to db or file. -func buildMultiNth(sequences []Genbank, count int) ([]byte, error) { +func BuildMulti(sequences []Genbank) ([]byte, error) { var gbkString bytes.Buffer for _, sequence := range sequences { locus := sequence.Meta.Locus @@ -264,7 +255,6 @@ func buildMultiNth(sequences []Genbank, count int) ([]byte, error) { gbkString.WriteString(organismString) if len(sequence.Meta.Taxonomy) > 0 { - var taxonomyString strings.Builder for i, taxonomyData := range sequence.Meta.Taxonomy { taxonomyString.WriteString(taxonomyData) @@ -306,7 +296,6 @@ func buildMultiNth(sequences []Genbank, count int) ([]byte, error) { consrtmString := buildMetaString(" CONSRTM", reference.Consortium) gbkString.WriteString(consrtmString) } - } // building other meta fields that are catch all @@ -372,7 +361,6 @@ func Parse(r io.Reader) (Genbank, error) { // ParseMulti takes in a reader representing a multi gbk/gb/genbank file and parses it into a slice of Genbank structs. func ParseMulti(r io.Reader) ([]Genbank, error) { - genbankSlice, err := parseMultiNthFn(r, -1) if err != nil { @@ -422,7 +410,6 @@ func ParseMultiNth(r io.Reader, count int) ([]Genbank, error) { // Loop through each line of the file for lineNum := 0; scanner.Scan(); lineNum++ { - // get line from scanner and split it line := scanner.Text() splitLine := strings.Split(strings.TrimSpace(line), " ") @@ -433,7 +420,6 @@ func ParseMultiNth(r io.Reader, count int) ([]Genbank, error) { // keep scanning until we find the start of the first record if !parameters.genbankStarted { - // We detect the beginning of a new genbank file with "LOCUS" locusFlag := strings.Contains(line, "LOCUS") @@ -444,11 +430,9 @@ func ParseMultiNth(r io.Reader, count int) ([]Genbank, error) { parameters.genbankStarted = true } continue - } switch parameters.parseStep { - case "metadata": // Handle empty lines if len(line) == 0 { @@ -457,7 +441,6 @@ func ParseMultiNth(r io.Reader, count int) ([]Genbank, error) { // If we are currently reading a line, we need to figure out if it is a new meta line. if string(line[0]) != " " || parameters.metadataTag == "FEATURES" { - // If this is true, it means we are beginning a new meta tag. In that case, let's save // the older data, and then continue along. switch parameters.metadataTag { @@ -541,7 +524,6 @@ func ParseMultiNth(r io.Reader, count int) ([]Genbank, error) { // determine if current line is a new top level feature if countLeadingSpaces(parameters.currentLine) < countLeadingSpaces(parameters.prevline) || parameters.prevline == "FEATURES" { - // save our completed attribute / qualifier string to the current feature if parameters.attributeValue != "" { parameters.feature.Attributes[parameters.attribute] = parameters.attributeValue @@ -568,20 +550,16 @@ func ParseMultiNth(r io.Reader, count int) ([]Genbank, error) { parameters.feature.Type = strings.TrimSpace(splitLine[0]) parameters.feature.Location.GbkLocationString = strings.TrimSpace(splitLine[len(splitLine)-1]) parameters.multiLineFeature = false // without this we can't tell if something is a multiline feature or multiline qualifier - } else if !strings.Contains(parameters.currentLine, "/") { // current line is continuation of a feature or qualifier (sub-constituent of a feature) - // if it's a continuation of the current feature, add it to the location if !strings.Contains(parameters.currentLine, "\"") && (countLeadingSpaces(parameters.currentLine) > countLeadingSpaces(parameters.prevline) || parameters.multiLineFeature) { parameters.feature.Location.GbkLocationString += strings.TrimSpace(line) parameters.multiLineFeature = true // without this we can't tell if something is a multiline feature or multiline qualifier } else { // it's a continued line of a qualifier - removeAttributeValueQuotes := strings.Replace(trimmedLine, "\"", "", -1) parameters.attributeValue = parameters.attributeValue + removeAttributeValueQuotes } - } else if strings.Contains(parameters.currentLine, "/") { // current line is a new qualifier trimmedCurrentLine := strings.TrimSpace(parameters.currentLine) if trimmedCurrentLine[0] != '/' { // if we have an exception case, like (adenine(1518)-N(6)/adenine(1519)-N(6))- @@ -615,13 +593,11 @@ func ParseMultiNth(r io.Reader, count int) ([]Genbank, error) { if len(line) < 2 { // throw error if line is malformed return genbanks, fmt.Errorf("Too short line found while parsing genbank sequence on line %d. Got line: %s", lineNum, line) } else if line[0:2] == "//" { // end of sequence - parameters.genbank.Sequence = parameters.sequenceBuilder.String() genbanks = append(genbanks, parameters.genbank) parameters.genbankStarted = false parameters.sequenceBuilder.Reset() - } else { // add line to total sequence parameters.sequenceBuilder.WriteString(sequenceRegex.ReplaceAllString(line, "")) } @@ -802,7 +778,7 @@ func parseLocus(locusString string) Locus { return locus } -// indeces for random points of interests on a gbk line. +// indices for random points of interests on a gbk line. const subMetaIndex = 5 const qualifierIndex = 21 @@ -855,7 +831,6 @@ func parseLocation(locationString string) (Location, error) { } location = Location{Start: start - 1, End: end} } - } else { firstOuterParentheses := strings.Index(locationString, "(") expression := locationString[firstOuterParentheses+1 : strings.LastIndex(locationString, ")")] @@ -948,13 +923,11 @@ func buildMetaString(name string, data string) string { // BuildLocationString is a recursive function that takes a location object and creates a gbk location string for Build() func BuildLocationString(location Location) string { - var locationString string if location.Complement { location.Complement = false locationString = "complement(" + BuildLocationString(location) + ")" - } else if location.Join { locationString = "join(" for _, sublocation := range location.SubLocations { @@ -962,7 +935,6 @@ func BuildLocationString(location Location) string { } locationString = strings.TrimSuffix(locationString, ",") + ")" } else { - locationString = strconv.Itoa(location.Start+1) + ".." + strconv.Itoa(location.End) if location.FivePrimePartial { locationString = "<" + locationString @@ -996,7 +968,6 @@ func BuildFeatureString(feature Feature) string { for _, qualifier := range qualifierKeys { returnString += generateWhiteSpace(qualifierIndex) + "/" + qualifier + "=\"" + feature.Attributes[qualifier] + "\"\n" - } return returnString } diff --git a/io/genbank/genbank_test.go b/io/genbank/genbank_test.go index cb88a819..17090386 100644 --- a/io/genbank/genbank_test.go +++ b/io/genbank/genbank_test.go @@ -51,7 +51,6 @@ func TestGbkIO(t *testing.T) { t.Errorf("Parsing the output of Build() does not produce the same output as parsing the original file, \"%s\", read with Read(). Got this diff:\n%s", filepath.Base(gbkPath), diff) } } // end test single gbk read, write, build, parse - } func TestMultiLineFeatureParse(t *testing.T) { @@ -84,7 +83,6 @@ func TestMultiGenbankIO(t *testing.T) { if diff := cmp.Diff(multiGbk, writeTestGbk, []cmp.Option{cmpopts.IgnoreFields(Feature{}, "ParentSequence")}...); diff != "" { t.Errorf("Parsing the output of Build() does not produce the same output as parsing the original file, \"%s\", read with Read(). Got this diff:\n%s", filepath.Base(gbkPath), diff) } - } func TestGbkLocationStringBuilder(t *testing.T) { @@ -171,7 +169,6 @@ func TestSnapgeneGenbankRegression(t *testing.T) { } func TestGetSequenceMethod(t *testing.T) { - gbk, _ := Read("../../data/t4_intron.gb") // Check to see if GetSequence method works on Features struct @@ -180,7 +177,6 @@ func TestGetSequenceMethod(t *testing.T) { if feature != seq { t.Errorf("Feature GetSequence method has failed. Got this:\n%s instead of \n%s", feature, seq) } - } func TestLocationParser(t *testing.T) { @@ -360,7 +356,7 @@ func TestFeature_GetSequence_Legacy(t *testing.T) { subLocationReverseComplemented.End = sequenceLength subLocationReverseComplemented.Complement = true // According to genbank complement means reverse complement. What a country. - feature.Description = "Green Flourescent Protein" + feature.Description = "Green Fluorescent Protein" feature.Location.SubLocations = []Location{subLocation, subLocationReverseComplemented} // Add the GFP feature to the sequence struct. @@ -373,7 +369,6 @@ func TestFeature_GetSequence_Legacy(t *testing.T) { if gfpSequence != featureSequence { t.Error("Feature sequence was not properly retrieved.") } - } func Test_parseLoopParameters_init(t *testing.T) { diff --git a/io/gff/example_test.go b/io/gff/example_test.go index e5361434..040e9403 100644 --- a/io/gff/example_test.go +++ b/io/gff/example_test.go @@ -66,7 +66,6 @@ func ExampleWrite() { } func ExampleGff_AddFeature() { - // Sequence for greenflourescent protein (GFP) that we're using as test data for this example. gfpSequence := "ATGGCTAGCAAAGGAGAAGAACTTTTCACTGGAGTTGTCCCAATTCTTGTTGAATTAGATGGTGATGTTAATGGGCACAAATTTTCTGTCAGTGGAGAGGGTGAAGGTGATGCTACATACGGAAAGCTTACCCTTAAATTTATTTGCACTACTGGAAAACTACCTGTTCCATGGCCAACACTTGTCACTACTTTCTCTTATGGTGTTCAATGCTTTTCCCGTTATCCGGATCATATGAAACGGCATGACTTTTTCAAGAGTGCCATGCCCGAAGGTTATGTACAGGAACGCACTATATCTTTCAAAGATGACGGGAACTACAAGACGCGTGCTGAAGTCAAGTTTGAAGGTGATACCCTTGTTAATCGTATCGAGTTAAAAGGTATTGATTTTAAAGAAGATGGAAACATTCTCGGACACAAACTCGAGTACAACTATAACTCACACAATGTATACATCACGGCAGACAAACAAAAGAATGGAATCAAAGCTAACTTCAAAATTCGCCACAACATTGAAGATGGATCCGTTCAACTAGCAGACCATTATCAACAAAATACTCCAATTGGCGATGGCCCTGTCCTTTTACCAGACAACCATTACCTGTCGACACAATCTGCCCTTTCGAAAGATCCCAACGAAAAGCGTGACCACATGGTCCTTCTTGAGTTTGTAACTGCTGCTGGGATTACACATGGCATGGATGAGCTCTACAAATAA" @@ -95,7 +94,6 @@ func ExampleGff_AddFeature() { } func ExampleFeature_GetSequence() { - // Sequence for greenflourescent protein (GFP) that we're using as test data for this example. gfpSequence := "ATGGCTAGCAAAGGAGAAGAACTTTTCACTGGAGTTGTCCCAATTCTTGTTGAATTAGATGGTGATGTTAATGGGCACAAATTTTCTGTCAGTGGAGAGGGTGAAGGTGATGCTACATACGGAAAGCTTACCCTTAAATTTATTTGCACTACTGGAAAACTACCTGTTCCATGGCCAACACTTGTCACTACTTTCTCTTATGGTGTTCAATGCTTTTCCCGTTATCCGGATCATATGAAACGGCATGACTTTTTCAAGAGTGCCATGCCCGAAGGTTATGTACAGGAACGCACTATATCTTTCAAAGATGACGGGAACTACAAGACGCGTGCTGAAGTCAAGTTTGAAGGTGATACCCTTGTTAATCGTATCGAGTTAAAAGGTATTGATTTTAAAGAAGATGGAAACATTCTCGGACACAAACTCGAGTACAACTATAACTCACACAATGTATACATCACGGCAGACAAACAAAAGAATGGAATCAAAGCTAACTTCAAAATTCGCCACAACATTGAAGATGGATCCGTTCAACTAGCAGACCATTATCAACAAAATACTCCAATTGGCGATGGCCCTGTCCTTTTACCAGACAACCATTACCTGTCGACACAATCTGCCCTTTCGAAAGATCCCAACGAAAAGCGTGACCACATGGTCCTTCTTGAGTTTGTAACTGCTGCTGGGATTACACATGGCATGGATGAGCTCTACAAATAA" @@ -120,7 +118,6 @@ func ExampleFeature_GetSequence() { fmt.Println(gfpSequence == featureSequence) // Output: true - } func TestFeature_GetSequence(t *testing.T) { @@ -170,5 +167,4 @@ func TestFeature_GetSequence(t *testing.T) { if gfpSequence != featureSequence { t.Error("Feature sequence was not properly retrieved.") } - } diff --git a/io/gff/gff.go b/io/gff/gff.go index b8779ff6..afc688df 100644 --- a/io/gff/gff.go +++ b/io/gff/gff.go @@ -78,7 +78,7 @@ type Location struct { // AddFeature takes a feature and adds it to the Gff struct. func (sequence *Gff) AddFeature(feature *Feature) error { feature.ParentSequence = sequence - var featureCopy Feature = *feature + featureCopy := *feature sequence.Features = append(sequence.Features, featureCopy) return nil } @@ -97,7 +97,6 @@ func getFeatureSequence(feature Feature, location Location) (string, error) { if len(location.SubLocations) == 0 { sequenceBuffer.WriteString(parentSequence[location.Start:location.End]) } else { - for _, subLocation := range location.SubLocations { sequence, _ := getFeatureSequence(feature, subLocation) sequenceBuffer.WriteString(sequence) @@ -224,7 +223,6 @@ func extractInfoFromField(lines []string, fieldName string) ([]string, int, erro } endOfMetaInfo = lineIndex break - } if index == 0 && fieldName != "gff-version" { return nil, 0, errors.New("the given file does not have any meta information") diff --git a/io/gff/gff_test.go b/io/gff/gff_test.go index 42b79966..7a6e029d 100644 --- a/io/gff/gff_test.go +++ b/io/gff/gff_test.go @@ -56,7 +56,6 @@ func TestGffIO(t *testing.T) { if gffDiffText != "" { t.Errorf("Build() does not output the same file as was input through ReadGff(). Got this diff:\n%s", gffDiffText) } - } // testing that readAllFn() returns an error. diff --git a/io/pileup/pileup.go b/io/pileup/pileup.go index 0f714169..f8a6bb02 100644 --- a/io/pileup/pileup.go +++ b/io/pileup/pileup.go @@ -36,7 +36,6 @@ package pileup import ( "bufio" "bytes" - "compress/gzip" "errors" "fmt" "io" @@ -49,11 +48,6 @@ import ( // https://en.wikipedia.org/wiki/Pileup_format -var ( - gzipReaderFn = gzip.NewReader - openFn = os.Open -) - // Pileup struct is a single position in a pileup file. Pileup files "pile" // a bunch of separate bam/sam alignments into something more readable at a per // base pair level, so are only useful as a grouping. @@ -119,6 +113,9 @@ func (parser *Parser) ParseNext() (Pileup, error) { } // Parse out a single line lineBytes, err := parser.reader.ReadSlice('\n') + if err != nil { + return Pileup{}, err + } parser.line++ line := string(lineBytes) line = line[:len(line)-1] // Exclude newline delimiter. @@ -210,7 +207,7 @@ Start of Read functions // Read reads a file into an array of Pileup structs func Read(path string) ([]Pileup, error) { - file, err := openFn(path) + file, err := os.Open(path) if err != nil { return nil, err } @@ -224,29 +221,32 @@ Start of Write functions ******************************************************************************/ -// WritePileup writes a pileup array to an io.Writer -func WritePileup(pileups []Pileup, w io.Writer) { +// WritePileups writes a pileup array to an io.Writer +func WritePileups(pileups []Pileup, w io.Writer) error { for _, pileup := range pileups { - w.Write([]byte(pileup.Sequence)) - w.Write([]byte("\t")) - w.Write([]byte(strconv.FormatUint(uint64(pileup.Position), 10))) - w.Write([]byte("\t")) - w.Write([]byte(pileup.ReferenceBase)) - w.Write([]byte("\t")) - w.Write([]byte(strconv.FormatUint(uint64(pileup.ReadCount), 10))) - w.Write([]byte("\t")) - for _, readResult := range pileup.ReadResults { - w.Write([]byte(readResult)) + _, err := w.Write([]byte( + strings.Join( + []string{ + pileup.Sequence, + strconv.FormatUint(uint64(pileup.Position), 10), + pileup.ReferenceBase, + strconv.FormatUint(uint64(pileup.ReadCount), 10), + strings.Join(pileup.ReadResults, ""), + pileup.Quality, + }, + "\t") + "\n")) + if err != nil { + return err } - w.Write([]byte("\t")) - w.Write([]byte(pileup.Quality)) - w.Write([]byte("\n")) } + return nil } // Write writes a pileup array to a file func Write(pileups []Pileup, path string) error { var b bytes.Buffer - WritePileup(pileups, &b) + if err := WritePileups(pileups, &b); err != nil { + return err + } return os.WriteFile(path, b.Bytes(), 0644) } diff --git a/io/pileup/pileup_test.go b/io/pileup/pileup_test.go index 38c95f47..a38aa2ba 100644 --- a/io/pileup/pileup_test.go +++ b/io/pileup/pileup_test.go @@ -144,7 +144,9 @@ func TestBuild(t *testing.T) { } parser.Reset(file) var b bytes.Buffer - WritePileup(pileups, &b) + if err := WritePileups(pileups, &b); err != nil { + t.Errorf("Failed to write pileups: %v", err) + } newBody := b.Bytes() file.Close() @@ -160,7 +162,6 @@ func TestBuild(t *testing.T) { if string(body) != string(newBody) { t.Errorf("input bytes do not equal output bytes of build") } - } func TestRead(t *testing.T) { diff --git a/io/polyjson/example_test.go b/io/polyjson/example_test.go index 37989fb3..eb65a190 100644 --- a/io/polyjson/example_test.go +++ b/io/polyjson/example_test.go @@ -11,7 +11,6 @@ import ( ) func Example() { - // this example also is run by the poly's test suite so this just sets up a temporary directory for writing files tmpDataDir, err := os.MkdirTemp("", "data-*") if err != nil { @@ -97,7 +96,6 @@ JSON related tests end here. ******************************************************************************/ func ExamplePoly_AddFeature() { - // Sequence for greenflourescent protein (GFP) that we're using as test data for this example. gfpSequence := "ATGGCTAGCAAAGGAGAAGAACTTTTCACTGGAGTTGTCCCAATTCTTGTTGAATTAGATGGTGATGTTAATGGGCACAAATTTTCTGTCAGTGGAGAGGGTGAAGGTGATGCTACATACGGAAAGCTTACCCTTAAATTTATTTGCACTACTGGAAAACTACCTGTTCCATGGCCAACACTTGTCACTACTTTCTCTTATGGTGTTCAATGCTTTTCCCGTTATCCGGATCATATGAAACGGCATGACTTTTTCAAGAGTGCCATGCCCGAAGGTTATGTACAGGAACGCACTATATCTTTCAAAGATGACGGGAACTACAAGACGCGTGCTGAAGTCAAGTTTGAAGGTGATACCCTTGTTAATCGTATCGAGTTAAAAGGTATTGATTTTAAAGAAGATGGAAACATTCTCGGACACAAACTCGAGTACAACTATAACTCACACAATGTATACATCACGGCAGACAAACAAAAGAATGGAATCAAAGCTAACTTCAAAATTCGCCACAACATTGAAGATGGATCCGTTCAACTAGCAGACCATTATCAACAAAATACTCCAATTGGCGATGGCCCTGTCCTTTTACCAGACAACCATTACCTGTCGACACAATCTGCCCTTTCGAAAGATCCCAACGAAAAGCGTGACCACATGGTCCTTCTTGAGTTTGTAACTGCTGCTGGGATTACACATGGCATGGATGAGCTCTACAAATAA" @@ -109,7 +107,7 @@ func ExamplePoly_AddFeature() { sequence.Sequence = gfpSequence // Set the initialized feature name and sequence location. - feature.Description = "Green Flourescent Protein" + feature.Description = "Green Fluorescent Protein" feature.Location = polyjson.Location{} feature.Location.Start = 0 feature.Location.End = len(sequence.Sequence) @@ -127,7 +125,6 @@ func ExamplePoly_AddFeature() { } func ExampleFeature_GetSequence() { - // Sequence for greenflourescent protein (GFP) that we're using as test data for this example. gfpSequence := "ATGGCTAGCAAAGGAGAAGAACTTTTCACTGGAGTTGTCCCAATTCTTGTTGAATTAGATGGTGATGTTAATGGGCACAAATTTTCTGTCAGTGGAGAGGGTGAAGGTGATGCTACATACGGAAAGCTTACCCTTAAATTTATTTGCACTACTGGAAAACTACCTGTTCCATGGCCAACACTTGTCACTACTTTCTCTTATGGTGTTCAATGCTTTTCCCGTTATCCGGATCATATGAAACGGCATGACTTTTTCAAGAGTGCCATGCCCGAAGGTTATGTACAGGAACGCACTATATCTTTCAAAGATGACGGGAACTACAAGACGCGTGCTGAAGTCAAGTTTGAAGGTGATACCCTTGTTAATCGTATCGAGTTAAAAGGTATTGATTTTAAAGAAGATGGAAACATTCTCGGACACAAACTCGAGTACAACTATAACTCACACAATGTATACATCACGGCAGACAAACAAAAGAATGGAATCAAAGCTAACTTCAAAATTCGCCACAACATTGAAGATGGATCCGTTCAACTAGCAGACCATTATCAACAAAATACTCCAATTGGCGATGGCCCTGTCCTTTTACCAGACAACCATTACCTGTCGACACAATCTGCCCTTTCGAAAGATCCCAACGAAAAGCGTGACCACATGGTCCTTCTTGAGTTTGTAACTGCTGCTGGGATTACACATGGCATGGATGAGCTCTACAAATAA" @@ -139,7 +136,7 @@ func ExampleFeature_GetSequence() { sequence.Sequence = gfpSequence // Set the initialized feature name and sequence location. - feature.Description = "Green Flourescent Protein" + feature.Description = "Green Fluorescent Protein" feature.Location.Start = 0 feature.Location.End = len(sequence.Sequence) diff --git a/io/polyjson/polyjson_test.go b/io/polyjson/polyjson_test.go index 701ab821..eaee25b1 100644 --- a/io/polyjson/polyjson_test.go +++ b/io/polyjson/polyjson_test.go @@ -51,7 +51,7 @@ func TestFeature_GetSequence(t *testing.T) { subLocationReverseComplemented.End = sequenceLength subLocationReverseComplemented.Complement = true // According to genbank complement means reverse complement. What a country. - feature.Description = "Green Flourescent Protein" + feature.Description = "Green Fluorescent Protein" feature.Location.SubLocations = []Location{subLocation, subLocationReverseComplemented} // Add the GFP feature to the sequence struct. @@ -64,7 +64,6 @@ func TestFeature_GetSequence(t *testing.T) { if gfpSequence != featureSequence { t.Error("Feature sequence was not properly retrieved.") } - } func TestParse_error(t *testing.T) { diff --git a/io/rebase/rebase_test.go b/io/rebase/rebase_test.go index 977c0d87..a7d961f5 100644 --- a/io/rebase/rebase_test.go +++ b/io/rebase/rebase_test.go @@ -40,7 +40,6 @@ func TestRead_error(t *testing.T) { }() _, err := Read("data/rebase_test.txt") assert.EqualError(t, err, readErr.Error()) - } func TestRead_multipleRefs(t *testing.T) { @@ -52,7 +51,6 @@ func TestRead_multipleRefs(t *testing.T) { assert.Equal(t, "Calleja, F., de Waard, A., Unpublished observations.\nHughes, S.G., Bruce, T., Murray, K., Unpublished observations.", enzymeMap["AcaI"].References) - } func TestExport_error(t *testing.T) { diff --git a/io/slow5/slow5.go b/io/slow5/slow5.go index 58cbd7b1..3d43f0cd 100644 --- a/io/slow5/slow5.go +++ b/io/slow5/slow5.go @@ -46,7 +46,7 @@ most of these attributes in a map for future proofing. Even the binary file format, blow5, does not have types for these attributes, and just stores them as a long string. -Reads have 8 required columns, and a few auxillary. These are typed, since they +Reads have 8 required columns, and a few auxiliary. These are typed, since they are what will probably be used in real software. Cheers mate, @@ -205,7 +205,7 @@ func (parser *Parser) ParseNext() (Read, error) { parser.line++ line := strings.TrimSpace(string(lineBytes)) - values := strings.Split(string(line), "\t") + values := strings.Split(line, "\t") // Reads have started. // Once we have the read headers, start to parse the actual reads var newRead Read diff --git a/io/uniprot/example_test.go b/io/uniprot/example_test.go index 003ed0d7..5b1af139 100644 --- a/io/uniprot/example_test.go +++ b/io/uniprot/example_test.go @@ -2,6 +2,7 @@ package uniprot_test import ( "fmt" + "github.com/TimothyStiles/poly/io/uniprot" ) diff --git a/primers/pcr/example_test.go b/primers/pcr/example_test.go index 63b0765d..aefa8147 100644 --- a/primers/pcr/example_test.go +++ b/primers/pcr/example_test.go @@ -2,6 +2,7 @@ package pcr_test import ( "fmt" + "github.com/TimothyStiles/poly/primers/pcr" ) diff --git a/primers/pcr/pcr.go b/primers/pcr/pcr.go index 972d4b45..523f78e4 100644 --- a/primers/pcr/pcr.go +++ b/primers/pcr/pcr.go @@ -23,11 +23,12 @@ package pcr import ( "errors" - "github.com/TimothyStiles/poly/primers" - "github.com/TimothyStiles/poly/transform" "index/suffixarray" "sort" "strings" + + "github.com/TimothyStiles/poly/primers" + "github.com/TimothyStiles/poly/transform" ) // https://doi.org/10.1089/dna.1994.13.75 @@ -151,7 +152,6 @@ func SimulateSimple(sequences []string, targetTm float64, circular bool, primerL rotatedForwardLocation := 0 rotatedReverseLocation := len(sequence[forwardLocation:]) + reverseLocation pcrFragments = append(pcrFragments, generatePcrFragments(rotatedSequence, rotatedForwardLocation, rotatedReverseLocation, forwardLocations[forwardLocation], reverseLocations[reverseLocation], minimalPrimers, primerList)...) - } } } @@ -164,7 +164,7 @@ func SimulateSimple(sequences []string, targetTm float64, circular bool, primerL // Simulate simulates a PCR reaction, including concatemerization analysis. It // takes in a list of sequences and list of primers, produces all possible PCR // fragments in a given reaction, and then attempts to see if the output -// fragments can amplify themselves. If they can, concatemerization is occuring +// fragments can amplify themselves. If they can, concatemerization is occurring // in your reaction, which can lead to confusing results. The variable // `circular` is for if the target template is circular, like a plasmid. func Simulate(sequences []string, targetTm float64, circular bool, primerList []string) ([]string, error) { diff --git a/primers/primers.go b/primers/primers.go index d53c0d10..b10d8988 100644 --- a/primers/primers.go +++ b/primers/primers.go @@ -146,7 +146,7 @@ If we pooled these two samples together into a single tube, and sequenced them, we would not be able to tell if ATGC came from DNA-1 or DNA-2. In order to tell the difference, we would have to go through the process of DNA barcoding. Let's attach(2) two small barcodes to each DNA fragment separately -in their own tubes and then pool them togehter: +in their own tubes and then pool them together: Barcode-1 + DNA-1 = GC + ATGC = GCATGC Barcode-2 + DNA-2 = AT + AGGC = ATAGGC diff --git a/primers/primers_test.go b/primers/primers_test.go index 3d6d9367..f6c498f0 100644 --- a/primers/primers_test.go +++ b/primers/primers_test.go @@ -27,7 +27,6 @@ func TestMarmurDoty(t *testing.T) { } func ExampleSantaLucia() { - sequenceString := "ACGATGGCAGTAGCATGC" //"GTAAAACGACGGCCAGT" // M13 fwd testCPrimer := 0.1e-6 // primer concentration testCNa := 350e-3 // salt concentration @@ -64,7 +63,6 @@ func TestSantaLuciaReverseComplement(t *testing.T) { if calcTM, _, _ := primers.SantaLucia(testSeq, testCPrimer, testCNa, testCMg); math.Abs(expectedTM-calcTM)/expectedTM >= 0.02 { t.Errorf("SantaLucia has changed on test. Got %f instead of %f", calcTM, expectedTM) } - } func ExampleMeltingTemp() { diff --git a/random/random.go b/random/random.go index b0509b6c..7b933a9b 100644 --- a/random/random.go +++ b/random/random.go @@ -41,13 +41,11 @@ func ProteinSequence(length int, seed int64) (string, error) { // DNASequence returns a random DNA sequence string of a given length and seed. func DNASequence(length int, seed int64) (string, error) { - return randomNucelotideSequence(length, seed, []rune("ACTG")), nil } // RNASequence returns a random DNA sequence string of a given length and seed. func RNASequence(length int, seed int64) (string, error) { - return randomNucelotideSequence(length, seed, []rune("ACUG")), nil } diff --git a/seqhash/seqhash.go b/seqhash/seqhash.go index 7e02e27e..335a9254 100644 --- a/seqhash/seqhash.go +++ b/seqhash/seqhash.go @@ -76,7 +76,6 @@ const ( // boothLeastRotation gets the least rotation of a circular string. func boothLeastRotation(sequence string) int { - // https://en.wikipedia.org/wiki/Lexicographically_minimal_string_rotation // this is generally over commented but I'm keeping it this way for now. - Tim @@ -97,7 +96,6 @@ func boothLeastRotation(sequence string) int { failure := failureSlice[characterIndex-leastRotationIndex-1] // while failure does not equal -1 and character does not equal the character found at the least rotation + failure + 1 <- why this? for failure != -1 && character != sequence[leastRotationIndex+failure+1] { - // if character is lexically less than whatever is at the leastRotationIndex index update leastRotation index if character < sequence[leastRotationIndex+failure+1] { leastRotationIndex = characterIndex - failure - 1 @@ -108,7 +106,6 @@ func boothLeastRotation(sequence string) int { // if character does not equal whatever character is at leastRotationIndex plus failure. if character != sequence[leastRotationIndex+failure+1] { - // if character is lexically less then what is rotated least leastRotationIndex gets value of character index. if character < sequence[leastRotationIndex] { leastRotationIndex = characterIndex @@ -224,5 +221,4 @@ func Hash(sequence string, sequenceType SequenceType, circular bool, doubleStran newhash := blake3.Sum256([]byte(deterministicSequence)) seqhash := "v1" + "_" + sequenceTypeLetter + circularLetter + doubleStrandedLetter + "_" + hex.EncodeToString(newhash[:]) return seqhash, nil - } diff --git a/seqhash/seqhash_test.go b/seqhash/seqhash_test.go index a980b98b..5787cc36 100644 --- a/seqhash/seqhash_test.go +++ b/seqhash/seqhash_test.go @@ -63,7 +63,6 @@ func TestHash(t *testing.T) { if seqhash != "v1_PLS_922ec11f5227ce77a42f07f565a7a1a479772b5cf3f1f6e93afc5ecbc0fd5955" { t.Errorf("Linear single stranded hashing failed. Expected v1_PLS_922ec11f5227ce77a42f07f565a7a1a479772b5cf3f1f6e93afc5ecbc0fd5955, got: " + seqhash) } - } func TestLeastRotation(t *testing.T) { @@ -89,5 +88,4 @@ func TestLeastRotation(t *testing.T) { } } } - } diff --git a/synthesis/codon/codon.go b/synthesis/codon/codon.go index 59ae7440..9a44b69f 100644 --- a/synthesis/codon/codon.go +++ b/synthesis/codon/codon.go @@ -118,7 +118,6 @@ func Translate(sequence string, codonTable Table) (string, error) { startCodonReached := false for _, letter := range sequence { - // add current nucleotide to currentCodon currentCodon.WriteRune(letter) @@ -182,7 +181,6 @@ func Optimize(aminoAcids string, codonTable Table, randomState ...int) (string, // OptimizeTable weights each codon in a codon table according to input string codon frequency. // This function actually mutates the codonTable struct itself. func (table codonTable) OptimizeTable(sequence string) Table { - sequence = strings.ToUpper(sequence) codonFrequencyMap := getCodonFrequency(sequence) @@ -191,7 +189,6 @@ func (table codonTable) OptimizeTable(sequence string) Table { for codonIndex, codon := range aminoAcid.Codons { table.AminoAcids[aminoAcidIndex].Codons[codonIndex].Weight = codonFrequencyMap[codon.Triplet] } - } return table } @@ -209,22 +206,20 @@ func (table codonTable) GenerateStartCodonTable() map[string]string { // getCodonFrequency takes a DNA sequence and returns a hashmap of its codons and their frequencies. func getCodonFrequency(sequence string) map[string]int { - codonFrequencyHashMap := map[string]int{} var currentCodon strings.Builder for _, letter := range sequence { - // add current nucleotide to currentCodon currentCodon.WriteRune(letter) // if current nucleotide is the third in a codon add to hashmap if currentCodon.Len() == 3 { - // if codon is already initalized in map increment + // if codon is already initialized in map increment if _, ok := codonFrequencyHashMap[currentCodon.String()]; ok { codonString := currentCodon.String() codonFrequencyHashMap[codonString]++ - // if codon is not already initalized in map initialize with value at 1 + // if codon is not already initialized in map initialize with value at 1 } else { codonString := currentCodon.String() codonFrequencyHashMap[codonString] = 1 @@ -242,13 +237,11 @@ func (table codonTable) IsEmpty() bool { // Chooser is a codonTable method to convert a codon table to a chooser func (table codonTable) Chooser() (map[string]weightedRand.Chooser, error) { - // This maps codon tables structure to weightRand.NewChooser structure codonChooser := make(map[string]weightedRand.Chooser) // iterate over every amino acid in the codonTable for _, aminoAcid := range table.AminoAcids { - // create a list of codon choices for this specific amino acid codonChoices := make([]weightedRand.Choice, len(aminoAcid.Codons)) @@ -364,7 +357,7 @@ func GetCodonTable(index int) Table { return defaultCodonTablesByNumber[index] } -// defaultCodonTablesByNumber stores all codon tables published by NCBI https://www.ncbi.nlm.nih.gov/Taxonomy/Utils/wprintgc.cgi using numbered indeces. +// defaultCodonTablesByNumber stores all codon tables published by NCBI https://www.ncbi.nlm.nih.gov/Taxonomy/Utils/wprintgc.cgi using numbered indices. var defaultCodonTablesByNumber = map[int]codonTable{ 1: generateCodonTable("FFLLSSSSYY**CC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG", "---M------**--*----M---------------M----------------------------"), 2: generateCodonTable("FFLLSSSSYY**CCWWLLLLPPPPHHQQRRRRIIMMTTTTNNKKSS**VVVVAAAADDEEGGGG", "----------**--------------------MMMM----------**---M------------"), diff --git a/synthesis/codon/codon_test.go b/synthesis/codon/codon_test.go index 6c49c618..c5b84625 100644 --- a/synthesis/codon/codon_test.go +++ b/synthesis/codon/codon_test.go @@ -19,7 +19,6 @@ func TestTranslation(t *testing.T) { if got, _ := Translate(gfpDnaSequence, GetCodonTable(11)); got != gfpTranslation { t.Errorf("TestTranslation has failed. Translate has returned %q, want %q", got, gfpTranslation) } - } // Non-Met start codons should still map to Met for our standard codon tables. @@ -65,7 +64,6 @@ func TestTranslationMixedCase(t *testing.T) { if got, _ := Translate(gfpDnaSequence, GetCodonTable(11)); got != gfpTranslation { t.Errorf("TestTranslationMixedCase has failed. Translate has returned %q, want %q", got, gfpTranslation) } - } func TestTranslationLowerCase(t *testing.T) { @@ -74,7 +72,6 @@ func TestTranslationLowerCase(t *testing.T) { if got, _ := Translate(gfpDnaSequence, GetCodonTable(11)); got != gfpTranslation { t.Errorf("TestTranslationLowerCase has failed. Translate has returned %q, want %q", got, gfpTranslation) } - } func TestOptimize(t *testing.T) { @@ -211,7 +208,6 @@ func TestOptimizeErrorsOnBrokenChooser(t *testing.T) { } func TestGetCodonFrequency(t *testing.T) { - translationTable := GetCodonTable(11).GenerateTranslationTable() var codons strings.Builder @@ -253,7 +249,6 @@ func TestGetCodonFrequency(t *testing.T) { t.Errorf("TestGetCodonFrequency has failed. The codon \"%q\" appears %q times when it should only appear twice.", codon, frequency) } } - } func TestChooserError(t *testing.T) { @@ -288,7 +283,6 @@ func TestWriteCodonJSON(t *testing.T) { if diff := cmp.Diff(testCodonTable, readTestCodonTable); diff != "" { t.Errorf(" mismatch (-want +got):\n%s", diff) } - } /* diff --git a/synthesis/codon/example_test.go b/synthesis/codon/example_test.go index 448d5e3c..ce5f9061 100644 --- a/synthesis/codon/example_test.go +++ b/synthesis/codon/example_test.go @@ -10,7 +10,6 @@ import ( ) func ExampleTranslate() { - gfpTranslation := "MASKGEELFTGVVPILVELDGDVNGHKFSVSGEGEGDATYGKLTLKFICTTGKLPVPWPTLVTTFSYGVQCFSRYPDHMKRHDFFKSAMPEGYVQERTISFKDDGNYKTRAEVKFEGDTLVNRIELKGIDFKEDGNILGHKLEYNYNSHNVYITADKQKNGIKANFKIRHNIEDGSVQLADHYQQNTPIGDGPVLLPDNHYLSTQSALSKDPNEKRDHMVLLEFVTAAGITHGMDELYK*" gfpDnaSequence := "ATGGCTAGCAAAGGAGAAGAACTTTTCACTGGAGTTGTCCCAATTCTTGTTGAATTAGATGGTGATGTTAATGGGCACAAATTTTCTGTCAGTGGAGAGGGTGAAGGTGATGCTACATACGGAAAGCTTACCCTTAAATTTATTTGCACTACTGGAAAACTACCTGTTCCATGGCCAACACTTGTCACTACTTTCTCTTATGGTGTTCAATGCTTTTCCCGTTATCCGGATCATATGAAACGGCATGACTTTTTCAAGAGTGCCATGCCCGAAGGTTATGTACAGGAACGCACTATATCTTTCAAAGATGACGGGAACTACAAGACGCGTGCTGAAGTCAAGTTTGAAGGTGATACCCTTGTTAATCGTATCGAGTTAAAAGGTATTGATTTTAAAGAAGATGGAAACATTCTCGGACACAAACTCGAGTACAACTATAACTCACACAATGTATACATCACGGCAGACAAACAAAAGAATGGAATCAAAGCTAACTTCAAAATTCGCCACAACATTGAAGATGGATCCGTTCAACTAGCAGACCATTATCAACAAAATACTCCAATTGGCGATGGCCCTGTCCTTTTACCAGACAACCATTACCTGTCGACACAATCTGCCCTTTCGAAAGATCCCAACGAAAAGCGTGACCACATGGTCCTTCTTGAGTTTGTAACTGCTGCTGGGATTACACATGGCATGGATGAGCTCTACAAATAA" testTranslation, _ := codon.Translate(gfpDnaSequence, codon.GetCodonTable(11)) // need to specify which codons map to which amino acids per NCBI table @@ -20,7 +19,6 @@ func ExampleTranslate() { } func ExampleOptimize() { - gfpTranslation := "MASKGEELFTGVVPILVELDGDVNGHKFSVSGEGEGDATYGKLTLKFICTTGKLPVPWPTLVTTFSYGVQCFSRYPDHMKRHDFFKSAMPEGYVQERTISFKDDGNYKTRAEVKFEGDTLVNRIELKGIDFKEDGNILGHKLEYNYNSHNVYITADKQKNGIKANFKIRHNIEDGSVQLADHYQQNTPIGDGPVLLPDNHYLSTQSALSKDPNEKRDHMVLLEFVTAAGITHGMDELYK*" sequence, _ := genbank.Read("../../data/puc19.gbk") diff --git a/synthesis/fix/synthesis.go b/synthesis/fix/synthesis.go index 5effa5db..4aa50767 100644 --- a/synthesis/fix/synthesis.go +++ b/synthesis/fix/synthesis.go @@ -129,7 +129,6 @@ func GcContentFixer(upperBound, lowerBound float64) func(string, chan DnaSuggest } waitgroup.Done() } - } // getSuggestions gets suggestions from the suggestions channel. This removes @@ -218,7 +217,6 @@ changes that were done to the sequence. // functions to solve for, and a number of iterations to attempt fixing. // Unless you are an advanced user, you should use CdsSimple. func Cds(sequence string, codontable codon.Table, problematicSequenceFuncs []func(string, chan DnaSuggestion, *sync.WaitGroup)) (string, []Change, error) { - codonLength := 3 if len(sequence)%codonLength != 0 { return "", []Change{}, errors.New("this sequence isn't a complete CDS, please try to use a CDS without interrupted codons") diff --git a/synthesis/fix/synthesis_test.go b/synthesis/fix/synthesis_test.go index 8a8d7049..9e274d95 100644 --- a/synthesis/fix/synthesis_test.go +++ b/synthesis/fix/synthesis_test.go @@ -214,7 +214,6 @@ func TestPanicIndex(t *testing.T) { codonTable := codon.ReadCodonJSON(dataDir + "freqB.json") gene := "ATGTCCGAAAAGAATCTGGAGCACAACCACGGTATCATCAAGGGTATCGATATTGCAGCGGAGGTGCGTAAAGACTTCCTGGAGTACAGCATGAGCGTCATCGTGAGCCGCGCACTGCCGGACCTGAAAGACGGTCTGAAACCGGTTCACCGTCGTATTATCTATGCGATGAACGACCTGGGTATCACCGCGGATAAGCCGCACAAGAAGAGCGCGCGTATCGTCGGTGAAGTTATTGGCAAGTATCACCCGCATGGTGACACCGCAGTTTATGATAGCATGGTTCGTATGGCGCAAGATTTTAGCTACCGCTATCCGCTGGTTGACGGCCACGGTAACTTTGGTAGCATCGACGGTGATGGCGCGGCGGCCATGCGTTACACCGAGGCGCGTTTGGCAAAAGTGTCCAATTTTATTATCAAGGACATCGATATGAATACCGTGCCGTTCGTGGACAACTACGACGCAAGCGAGCGTGAACCGGCTTACCTGACGGGCTATTTCCCGAATCTGCTGGCAAATGGTGCAATGGGTATCGCGGTCGGTATGGCTACCAGCATCCCGCCGCATAATCTGCGTGAGGTGATCTCCGCGATTCATGCATTTATCGATAACAAAGATATCACCATCGATGAGATCCTGGACAATCATATTATGGGTCCGGATTTCCCGACCGGTGCTCTGATGACCAACGGTATTCGTATGCGTGAGGGTTACAAAACGGGTCGCGGTGCGGTGACCATCCGCGCTAAAGTCGCACTGGAAGAGAATGATCGCCATGCGCGCTTCATCATTACGGAGATTCCGTATCAGACCAACAAGGCGAAACTGATTGAGCGCATCGCAGAGCTGGTCAAGACGAAGCAGCTGGAAGGTATCAGCGACATTCGTGACGAGAGCAATTATGAAGGTATTCGCATCGTTATCGAGCTGCGTCGCGACAGCAATCCGGACGTGGTCCTGAGCAAGCTGTACAAATTTACCAACTTGCAAACCACGTATAGCTTGAACCTGCTGAGCCTGCACAATAATATTCCGGTTCTGCTGGACCTGAAAAGCATCATCAAACACTACGTCGACTTTCAGATCAACGTTATTATCAAGCGCAGCATTTTTGAGAAGGATAAGATCGAAAAACGCTTCCACATCCTGGAAGCGCTGGATACCGCGCTGGACAATATCGACGCGATTGTCAACATTCTGCGTAACAGCCCGGAGAGCAACGAGGCTAAAATGAAGCTGACCGAAGCGTTCGGCTTCGATGAAGAACAAAATAAAGCGATCCTGGATATGCGTCTGCAACGTTTGGTCGGTCTGGAACGTGGCAAAATCCAGCAGGAGATGGCGCAGATCAAAGAGCGTATTGACTACCTGACCCTGCTGATTAGCGATGAAACCGAACAGAACAATGTTCTGAAGAACCAGCTGAGCGAAATTGCTGAGAAATTCGGTGACAACCGTCGCACGGAGACGATTGACGAGGGTCTGATGGATATCGAGGATGAGGAACTGATTCCGGACGTGAAGACGATGATTCTGCTGAGCGACGAAGGCTATATTCGTCGTGTGGATCCGGAGGAATTTCGCGTCCAAAAGCGCGGTGGTCGCGGTGTGAGCGTGAACTCCAGCAATGAGGACCCGATTGTTATCGCGACGATGGGTAAGATGCGTGACTGGGTCCTGTTTTTCACGAATAGCGGTAAGGTCTTCCGCACCAAAGCCTACAACATTCGCCAATACAGCCGTACCGCGCGCGGCCTGCCGATCGTGAATTTTCTGAACGGTCTGACCGCGGGCGACAAGATTACCGCGATTCTGCCGCTGCGTAATGTGAAAGAGAAAATGAATTATTTGACCTTTATTACCGAGAAGGGTATGATTAAGAAAACCGATATTAGCCTGTTTGACAATATCAACAAAAACGGTAAAATCGCGATTAACTTGAAAGAGGACGACCAACTGGTGACCGTTTTCGCGACCACGGGCGAGGATACCATCTTTGTGGCAAACAAGAGCGGTAAAGTTATCCGTATTCAGGAAAACATCGTCCGCCCGTTGTCTCGTACGGCATCTGGTGTGAAAGCGATTAAGTTGGACGAGAACGATGTGGTGGTGGGTGCAGTTACGAGCTTCGGTATTGAGAACATTACGACCATTTCCTCCAAGGGTAGCTTCAAAAAGACGAACATCGATGAGTATCGTATCAGCGGCCGTAATGGTAAAGGCATCAAAGTCATGAATCTGAACGAAAAGACCGGTGATTTCAAAAGCATCATTGCGGCACGCGAAACCGATCTGGTTTGTATTATTAGCACGGACGGCAATCTGATTAAGACCAAAGCGAGCGATATCCCGGTGCTGGGCCGTGCGGCTGCCGGCGTGCGTGGTATTCGCCTGTCCGAGGGTAATAAGATTCAGGCCGTTATGCTGGAGTACCGTAAACACGGTGAAGAGAACCAGGAATTCGAGGAAGAC" _, _, _ = CdsSimple(gene, codonTable, []string{"GAAGAC", "GGTCTC", "GCGATG", "CGTCTC", "GCTCTTC", "CACCTGC", "CGTCTC"}) - } func TestNdeIFix(t *testing.T) { diff --git a/synthesis/fragment/fragment_test.go b/synthesis/fragment/fragment_test.go index 1f59a047..0a71bfde 100644 --- a/synthesis/fragment/fragment_test.go +++ b/synthesis/fragment/fragment_test.go @@ -34,13 +34,12 @@ func TestFragmentSizes(t *testing.T) { if err == nil { t.Errorf("Fragment should fail when minFragmentSize < 8") } - } func TestSmallFragmentSize(t *testing.T) { // The following should succeed, but will require setting minFragmentSize = 12 lacZ := "ATGACCATGATTACGCCAAGCTTGCATGCCTGCAGGTCGACTCTAGAGGATCCCCGGGTACCGAGCTCGAATTCACTGGCCGTCGTTTTACAACGTCGTGACTGGGAAAACCCTGGCGTTACCCAACTTAATCGCCTTGCAGCACATCCCCCTTTCGCCAGCTGGCGTAATAGCGAAGAGGCCCGCACCGATCGCCCTTCCCAACAGTTGCGCAGCCTGAATGGCGAATGGCGCCTGATGCGGTATTTTCTCCTTACGCATCTGTGCGGTATTTCACACCGCATATGGTGCACTCTCAGTACAATCTGCTCTGATGCCGCATAG" - _, _, err := Fragment(lacZ, 12, 30, []string{}) + _, _, err := Fragment(lacZ, 12, 30, []string{}) if err != nil { t.Errorf("Got error in small fragmentation: %s", err) } @@ -75,7 +74,6 @@ func TestCheckLongRegresssion(t *testing.T) { if foundGTCT { t.Errorf("Should not have found GTCT since it is the reverse complement of AGAC") } - } func TestRegressionTestMatching12(t *testing.T) { @@ -84,7 +82,6 @@ func TestRegressionTestMatching12(t *testing.T) { overhangs := []string{"CGAG", "GTCT", "TACT", "AATG", "ATCC", "CGCT", "AAAA", "AAGT", "ATAG", "ATTA", "ACAA", "ACGC", "TATC", "TAGA", "TTAC", "TTCA", "TGTG", "TCGG", "TCCC", "GAAG", "GTGC", "GCCG", "CAGG", "TACG"} efficiency := SetEfficiency(overhangs) if (efficiency > 1) || (efficiency < 0.965) { - t.Errorf("Expected efficiency of .99 - approximately matches NEB ligase fidelity viewer of .97. Got: %g", efficiency) } } diff --git a/transform/transform_test.go b/transform/transform_test.go index 9f877f69..fdcf51e6 100644 --- a/transform/transform_test.go +++ b/transform/transform_test.go @@ -112,7 +112,7 @@ func TestComplementBaseRNA(t *testing.T) { got := ComplementBaseRNA(c) gotI := ComplementBaseRNA(got) gotII := ComplementBaseRNA(gotI) - if rune(c) != gotI || gotII != got { + if c != gotI || gotII != got { t.Errorf("complement transform mismatch: %q->%q->%q->%q", c, got, gotI, gotII) } } diff --git a/transform/variants/variants.go b/transform/variants/variants.go index cb682e1b..8ea276a4 100644 --- a/transform/variants/variants.go +++ b/transform/variants/variants.go @@ -20,21 +20,21 @@ func AllVariantsIUPAC(seq string) ([]string, error) { seqVariants := []string{} iupac := map[rune][]rune{ // rune map of all iupac nucleotide variants - 'G': []rune{'G'}, - 'A': []rune{'A'}, - 'T': []rune{'T'}, - 'C': []rune{'C'}, - 'R': []rune{'G', 'A'}, - 'Y': []rune{'T', 'C'}, - 'M': []rune{'A', 'C'}, - 'K': []rune{'G', 'T'}, - 'S': []rune{'G', 'C'}, - 'W': []rune{'A', 'T'}, - 'H': []rune{'A', 'C', 'T'}, - 'B': []rune{'G', 'T', 'C'}, - 'V': []rune{'G', 'C', 'A'}, - 'D': []rune{'G', 'A', 'T'}, - 'N': []rune{'G', 'A', 'T', 'C'}, + 'G': {'G'}, + 'A': {'A'}, + 'T': {'T'}, + 'C': {'C'}, + 'R': {'G', 'A'}, + 'Y': {'T', 'C'}, + 'M': {'A', 'C'}, + 'K': {'G', 'T'}, + 'S': {'G', 'C'}, + 'W': {'A', 'T'}, + 'H': {'A', 'C', 'T'}, + 'B': {'G', 'T', 'C'}, + 'V': {'G', 'C', 'A'}, + 'D': {'G', 'A', 'T'}, + 'N': {'G', 'A', 'T', 'C'}, } for _, s := range strings.ToUpper(seq) { @@ -44,7 +44,6 @@ func AllVariantsIUPAC(seq string) ([]string, error) { } else { return seqVariants, errors.New("Error:" + string(s) + " is not a supported IUPAC character") } - } cartesianProducts := cartRune(seqVariantList...) @@ -59,7 +58,7 @@ func cartRune(inLists ...[]rune) [][]rune { // Adapted from https://rosettacode.org/wiki/Cartesian_product_of_two_or_more_lists // supposedly "minimizes allocations and computes and fills the result sequentially" - var possibleVariants int = 1 // a counter used to determine the possible number of variants + possibleVariants := 1 // a counter used to determine the possible number of variants for _, inList := range inLists { possibleVariants *= len(inList) }