Repository 'in_sillico_pcr'
hg clone https://toolshed.g2.bx.psu.edu/repos/bvalot/in_sillico_pcr

Changeset 0:1f4836da4a14 (2022-06-14)
Commit message:
planemo upload for repository https://github.com/bvalot/galaxy commit d57c24d4b2c0c741d572af9ca0d09f8b82689640
added:
primer_search.py
primer_search.xml
qpcr_search.py
qpcr_search.xml
test-data/input.fasta
test-data/pcr.fasta
test-data/qpcr.txt
b
diff -r 000000000000 -r 1f4836da4a14 primer_search.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/primer_search.py Tue Jun 14 08:52:22 2022 +0000
[
b'@@ -0,0 +1,319 @@\n+#!/usr/bin/env python3\n+# -*- coding: utf-8 -*-\n+\n+"""Search primers on database and return result"""\n+\n+import argparse\n+import os\n+import subprocess\n+import sys\n+import tempfile\n+\n+from Bio import SeqIO\n+\n+gasst_exe = "Gassst"\n+nucleo = {\n+    "R": ("A", "G"),\n+    "Y": ("C", "T"),\n+    "S": ("G", "C"),\n+    "W": ("A", "T"),\n+    "K": ("G", "T"),\n+    "M": ("A", "C"),\n+    "B": ("C", "G", "T"),\n+    "D": ("A", "G", "T"),\n+    "H": ("A", "C", "T"),\n+    "V": ("A", "C", "G"),\n+    "N": ("A", "T", "C", "G"),\n+}\n+\n+desc = "Search primer on database and return amplicons."\n+command = argparse.ArgumentParser(\n+    prog="primer_search.py",\n+    description=desc,\n+    usage="%(prog)s [options] forward reverse database",\n+)\n+command.add_argument(\n+    "-o",\n+    "--out",\n+    nargs="?",\n+    type=argparse.FileType("w"),\n+    default=sys.stdout,\n+    help="Return amplicon on fasta file, default=stdout",\n+)\n+command.add_argument(\n+    "-d",\n+    "--debug",\n+    nargs="?",\n+    type=argparse.FileType("w+"),\n+    default=None,\n+    help="Conserve a copy of primer search, default No",\n+)\n+command.add_argument(\n+    "-e",\n+    "--error",\n+    nargs="?",\n+    type=int,\n+    default=1,\n+    help="Maximun error allowed on match, default=1",\n+)\n+command.add_argument(\n+    "-m",\n+    "--min",\n+    nargs="?",\n+    type=int,\n+    default=100,\n+    help="Min len amplicon size, default=100",\n+)\n+command.add_argument(\n+    "-M",\n+    "--max",\n+    nargs="?",\n+    type=int,\n+    default=1500,\n+    help="Max len amplicon size, default=1500",\n+)\n+command.add_argument(\n+    "-k",\n+    "--keep",\n+    action="store_true",\n+    help="Keep description instead of report PCR position",\n+)\n+command.add_argument(\n+    "-r", "--remove", action="store_true", help="Remove primer from reported amplicons"\n+)\n+command.add_argument("forward", type=str, help="Forward primer sequence")\n+command.add_argument("reverse", type=str, help="Reverse primer sequence")\n+command.add_argument(\n+    "database", type=argparse.FileType("r"), help="Database to search on fasta"\n+)\n+command.add_argument("-v", "--version", action="version", version="%(prog)s 0.3.0")\n+\n+\n+class GassstResult:\n+    """A simple Gassst class containing result\n+    rev : True indicate if reverse primers, else forward\n+    """\n+\n+    def __init__(self, line):\n+        h = line.strip().split("\\t")\n+        if len(h) != 9:\n+            raise Exception("Line seems not correspond to gassst result\\n" + line)\n+        self.primer = h[0]\n+        self.rev = h[0] != "Forward"\n+        self.match = h[1]\n+        self.strand = int(h[2])\n+        self.start = int(h[3])\n+        self.error = int(h[5])\n+        self.stop = self.start + len(h[7])\n+\n+    def __repr__(self):\n+        return (\n+            self.match\n+            + " : "\n+            + str(self.start)\n+            + " in strand:"\n+            + str(self.strand)\n+            + " in primer: "\n+            + self.primer\n+            + " with error: "\n+            + str(self.error)\n+        )\n+\n+    def __eq__(self, other):\n+        return (\n+            isinstance(other, GassstResult)\n+            and self.primer == other.primer\n+            and self.rev == other.rev\n+            and self.match == other.match\n+            and self.strand == other.strand\n+            and self.start == other.start\n+        )\n+\n+    def __ne__(self, other):\n+        return not self == other\n+\n+    def __lt__(self, other):\n+        if self != other:\n+            raise Exception("Only compare equal GassstResult")\n+        return self.error < other.error\n+\n+\n+class Amplicon:\n+    """A simple Amplicon class containing forward and reverse gassst result"""\n+\n+    def __init__(self, forw, reve):\n+        if forw.strand == reve.strand:\n+            raise Exception(\n+                "Amplicon could be in inverse strand for reverse/forwar primer\\n"\n+                + forw\n+                + reve\n+            )\n+        self.forw = forw\n+        self.reve = reve\n+        self.'..b'de):\n+        primer_fasta.write(">Forward\\n" + forward + "\\n")\n+    for reverse in degenerate_primer(reverse_de):\n+        primer_fasta.write(">Reverse\\n" + reverse + "\\n")\n+    primer_fasta.close()\n+    return primer_fasta.name\n+\n+\n+def performed_gassst(command):\n+    proc = subprocess.Popen(command, stderr=subprocess.PIPE, stdout=sys.stderr)\n+    error = ""\n+    for line in iter(proc.stderr.readline, b""):\n+        error += line.decode()\n+    if error != "":\n+        sys.stdout.write("Error during processing Gassst\\n")\n+        raise Exception(error)\n+\n+\n+def read_result(f_res, f_debug):\n+    result = {}\n+    for line in iter(f_res.readline, ""):\n+        if line[0] == "F" or line[0] == "R":\n+            if f_debug is not None:\n+                f_debug.write(line)\n+            res = GassstResult(line)\n+            other_res = result.setdefault(res.match, {}).setdefault(res.primer, [])\n+            notfound = True\n+            for i, res2 in enumerate(other_res):\n+                if res == res2:\n+                    notfound = False\n+                    if res < res2:\n+                        other_res[i] = res\n+                        # print res\n+                        break\n+            if notfound:\n+                other_res.append(res)\n+    return result\n+\n+\n+def get_amplicons(result):\n+    """Function to get amplicon on a sequence from forward / reverse result"""\n+    for forw in result["Forward"]:\n+        for reve in result["Reverse"]:\n+            if forw.strand != reve.strand:\n+                amp = Amplicon(forw, reve)\n+                if amp.get_start() < amp.get_stop():  # must be side by side\n+                    yield amp\n+                else:\n+                    del amp\n+\n+\n+if __name__ == "__main__":\n+    """Performed job on execution script"""\n+    args = command.parse_args()\n+    primer_fasta = write_primer_fasta(args.forward, args.reverse)\n+    output_result = tempfile.NamedTemporaryFile(delete=False, mode="w+")\n+    identity = int(\n+        100 - args.error / float(max(len(args.forward), len(args.reverse))) * 100\n+    )\n+\n+    command = [\n+        gasst_exe,\n+        "-p",\n+        str(identity),\n+        "-g",\n+        "0",\n+        "-w",\n+        "6",\n+        "-h",\n+        "0",\n+        "-i",\n+        primer_fasta,\n+        "-d",\n+        args.database.name,\n+        "-o",\n+        output_result.name,\n+    ]\n+    performed_gassst(command)\n+    result = read_result(output_result, args.debug)\n+\n+    # load amplicons\n+    sys.stderr.write("Search amplicons : ")\n+    amplicons = {}\n+    for seq in result.keys():\n+        if len(result[seq]) == 2:\n+            # print "Search amplicon on seq: " + seq\n+            for amplicon in get_amplicons(result[seq]):\n+                if len(amplicon) > args.min and len(amplicon) < args.max:\n+                    amplicons.setdefault(seq, []).append(amplicon)\n+                else:\n+                    del amplicon\n+            # print "Find amplicons : "  + str(len(amplicons[seq]))\n+    sys.stderr.write(str(sum(map(len, amplicons.values()))) + "\\n\\n")\n+\n+    # print amplicons\n+\n+    sys.stderr.write("Write result : ")\n+    for record in SeqIO.parse(args.database, "fasta"):\n+        if record.id not in amplicons:\n+            continue\n+        for i, amplicon in enumerate(amplicons.get(record.id)):\n+            sub = record[amplicon.get_start() - 1: amplicon.get_stop() - 1]\n+            if amplicon.strand == 1:\n+                sub = sub.reverse_complement()\n+            if args.remove:\n+                sub = sub[len(args.forward): len(sub) - len(args.reverse)]\n+            if args.keep:\n+                sub.id = record.id\n+                sub.description = record.description\n+            else:\n+                sub.id = record.id + "_ampli_" + str(i)\n+                sub.description = str(amplicon)\n+            SeqIO.write(sub, args.out, "fasta")\n+\n+    sys.stderr.write("OK\\n")\n+    # delete tempfile\n+    os.unlink(primer_fasta)\n+    os.unlink(output_result.name)\n'
b
diff -r 000000000000 -r 1f4836da4a14 primer_search.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/primer_search.xml Tue Jun 14 08:52:22 2022 +0000
b
@@ -0,0 +1,78 @@
+<tool id="primer_search_wrapper" name="Primer Search" version="0.1">
+  <description></description>
+  <requirements>
+    <requirement type="package" version="1.28">gassst</requirement>
+ <requirement type="package" version="1.78">biopython</requirement>
+  </requirements>
+    <stdio>
+    <exit_code range="1:" level="fatal" />
+  </stdio>
+  <version_command>$__tool_directory__/primer_search.py -v</version_command>
+  <command>
+    $__tool_directory__/primer_search.py -o $output 
+    #if str($error)
+      -e $error
+    #end if
+    #if str($min)
+      -m $min
+    #end if
+    #if str($max)
+      -M $max
+    #end if
+    #if $keep
+      -k
+    #end if
+    #if $remove
+      -r 
+    #end if
+    $forward $reverse $database 2> $logfile
+  </command>
+  <inputs>
+    <param name="database" type="data" format="fasta" label="Database to search on fasta" help="FASTA format" />
+ <param name="forward" type="text" value="" optional="false" size="50"
+    label="Forward primer sequence"
+    help="DNA sequence, letters corresponding to multiple nucleotide allowed" />
+ <param name="reverse" type="text" value="" optional="false" size="50"
+    label="Reverse primer sequence"
+    help="DNA sequence, letters corresponding to multiple nucleotide allowed" />
+    <param name="error" type="integer" value="1" optional="true"
+    label="Maximun error allowed on match" help="Number of mismatch allowed for each primer" />
+    <param name="min" type="integer" value="100" optional="true"
+    label="Min len amplicon size" help="Only amplicon with this minimun length were reported" />
+    <param name="max" type="integer" value="1500" optional="true"
+    label="Max len amplicon size" help="Only amplicon with this maximun length were reported" />
+    <param name="keep" type="boolean" checked="false"
+    label="If set, Keep description instead of report PCR position" />
+    <param name="remove" type="boolean" checked="false"
+    label="If set, remove primer sequance from reported amplicons" />
+  </inputs>
+  <outputs>
+    <data name="logfile" format="txt" label="${tool.name} on ${on_string}: log" />
+    <data name="output" format="fasta" label="${tool.name} on ${on_string}: fasta" />
+  </outputs>
+  <tests>
+ <test expect_num_outputs="2">
+      <param name="database" value="input.fasta" />
+      <param name="forward" value="ACCTGGTGTACGCCTCGCTGAC" />
+      <param name="reverse" value="GACATAGATGCCCTGCCCCTTGAT" />
+      <param name="error" value="2" />
+      <output name="output" file="pcr.fasta" ftype="fasta" />
+    </test>
+  </tests>
+  <help>
+**What it does**
+
+Search primer on database and return amplicons on fasta format.
+
+**License and citation**
+
+This Galaxy tool is Copyright © 2018 `B. Valot` and is released under the `GPL3 license`.
+
+This tool uses Gassst, which is licensed separately.
+Please cite: Rizk G. and Dominique Lavenier D. (2010) GASSST: global alignment short sequence search tool. *Bioinformatics* 26(20), 2534-2540.
+http://www.irisa.fr/symbiose/projects/gassst/
+  </help>
+  <citations>
+ <citation type="doi">10.1093/bioinformatics/btq485</citation>
+  </citations>
+</tool>
b
diff -r 000000000000 -r 1f4836da4a14 qpcr_search.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/qpcr_search.py Tue Jun 14 08:52:22 2022 +0000
[
b'@@ -0,0 +1,361 @@\n+#!/usr/bin/env python3\n+# -*- coding: utf-8 -*-\n+\n+"""Search primers/probe on database and return result"""\n+\n+import argparse\n+import os\n+import subprocess\n+import sys\n+import tempfile\n+\n+from Bio import SeqIO\n+\n+gasst_exe = "Gassst"\n+nucleo = {\n+    "R": ("A", "G"),\n+    "Y": ("C", "T"),\n+    "S": ("G", "C"),\n+    "W": ("A", "T"),\n+    "K": ("G", "T"),\n+    "M": ("A", "C"),\n+    "B": ("C", "G", "T"),\n+    "D": ("A", "G", "T"),\n+    "H": ("A", "C", "T"),\n+    "V": ("A", "C", "G"),\n+    "N": ("A", "T", "C", "G"),\n+}\n+\n+desc = "Search primer/probe on database and return position and errors."\n+command = argparse.ArgumentParser(\n+    prog="primer_search.py",\n+    description=desc,\n+    usage="%(prog)s [options] forward probe reverse database",\n+)\n+command.add_argument(\n+    "-o",\n+    "--out",\n+    nargs="?",\n+    type=argparse.FileType("w"),\n+    default=sys.stdout,\n+    help="Return amplicon position on file, default=stdout",\n+)\n+command.add_argument(\n+    "-d",\n+    "--debug",\n+    nargs="?",\n+    type=argparse.FileType("w"),\n+    default=None,\n+    help="Conserve a copy of primer search, default No",\n+)\n+command.add_argument(\n+    "-e",\n+    "--error",\n+    nargs="?",\n+    type=int,\n+    default=1,\n+    help="Maximun error allowed on match, default=1",\n+)\n+command.add_argument(\n+    "-m",\n+    "--min",\n+    nargs="?",\n+    type=int,\n+    default=50,\n+    help="Min len amplicon size, default=50",\n+)\n+command.add_argument(\n+    "-M",\n+    "--max",\n+    nargs="?",\n+    type=int,\n+    default=200,\n+    help="Max len amplicon size, default=200",\n+)\n+command.add_argument(\n+    "-t", "--taxo", action="store_true", help="Parse description to report species only"\n+)\n+command.add_argument("forward", type=str, help="Forward primer sequence")\n+command.add_argument("probe", type=str, help="Probe sequence")\n+command.add_argument("reverse", type=str, help="Reverse primer sequence")\n+command.add_argument(\n+    "database", type=argparse.FileType("r"), help="Database to search on fasta"\n+)\n+command.add_argument("-v", "--version", action="version", version="%(prog)s 0.3.0")\n+\n+\n+class GassstResult:\n+    """A simple Gassst class containing result\n+    rev : True indicate if reverse primers, else forward\n+    """\n+\n+    def __init__(self, line):\n+        h = line.strip().split()\n+        if len(h) != 9:\n+            raise Exception("Line seems not correspond to gassst result\\n" + line)\n+        self.primer = h[0]\n+        # self.rev = h[0] != "Forward"\n+        self.match = h[1]\n+        self.strand = int(h[2])\n+        self.start = int(h[3])\n+        self.error = int(h[5])\n+        self.stop = self.start + len(h[7])\n+\n+    def __repr__(self):\n+        return (\n+            self.match\n+            + " : "\n+            + str(self.start)\n+            + " in strand:"\n+            + str(self.strand)\n+            + " in primer: "\n+            + self.primer\n+            + " with error: "\n+            + str(self.error)\n+        )\n+\n+    def __eq__(self, other):\n+        return (\n+            isinstance(other, GassstResult)\n+            and self.primer == other.primer\n+            and self.match == other.match\n+            and self.strand == other.strand\n+            and self.start == other.start\n+        )\n+\n+    def __ne__(self, other):\n+        return not self == other\n+\n+    def __lt__(self, other):\n+        if self != other:\n+            raise Exception("Only compare equal GassstResult")\n+        return self.error < other.error\n+\n+\n+class Amplicon:\n+    """A simple Amplicon class containing forward and reverse gassst result\n+    Add probe including\n+    """\n+\n+    def __init__(self, forw, reve):\n+        if forw.strand == reve.strand:\n+            raise Exception(\n+                "Amplicon could be in inverse strand for reverse/forward primer\\n"\n+                + forw\n+                + reve\n+            )\n+        self.forw = forw\n+        self.prob = None\n+        self.reve = reve\n+        self.strand = forw.strand\n+\n+    def'..b'n primer_fasta.name\n+\n+\n+def performed_gassst(command):\n+    proc = subprocess.Popen(command, stderr=subprocess.PIPE, stdout=sys.stderr)\n+    error = ""\n+    for line in iter(proc.stderr.readline, b""):\n+        error += line.decode()\n+    if error != "":\n+        sys.stdout.write("Error during processing Gassst\\n")\n+        raise Exception(error)\n+\n+\n+def read_result(f_res, f_debug):\n+    result = {}\n+    for line in iter(f_res.readline, ""):\n+        if line[0] == "F" or line[0] == "R" or line[0] == "P":\n+            if f_debug is not None:\n+                f_debug.write(line)\n+            res = GassstResult(line)\n+            other_res = result.setdefault(res.match, {}).setdefault(res.primer, [])\n+            notfound = True\n+            for i, res2 in enumerate(other_res):\n+                if res == res2:\n+                    notfound = False\n+                    if res < res2:\n+                        other_res[i] = res\n+                        # print res\n+                        break\n+            if notfound:\n+                other_res.append(res)\n+    return result\n+\n+\n+def get_amplicons(result):\n+    """Function to get amplicon on a sequence from forward / reverse result"""\n+    for forw in result["Forward"]:\n+        for reve in result["Reverse"]:\n+            if forw.strand != reve.strand:\n+                amp = Amplicon(forw, reve)\n+                if amp.get_start() < amp.get_stop():  # must be side by side\n+                    for probe in result["Probe"]:\n+                        if amp.contain_probe(probe):\n+                            yield amp\n+                            break\n+                    del amp\n+                else:\n+                    del amp\n+\n+\n+if __name__ == "__main__":\n+    """Performed job on execution script"""\n+    args = command.parse_args()\n+    primer_fasta = write_primer_fasta(args.forward, args.probe, args.reverse)\n+    output_result = tempfile.NamedTemporaryFile(delete=False, mode="w+")\n+    identity = int(\n+        100 - args.error / float(max(len(args.forward), len(args.reverse))) * 100\n+    )\n+\n+    command = [\n+        gasst_exe,\n+        "-p",\n+        str(identity),\n+        "-g",\n+        "0",\n+        "-w",\n+        "6",\n+        "-h",\n+        "0",\n+        "-i",\n+        primer_fasta,\n+        "-d",\n+        args.database.name,\n+        "-o",\n+        output_result.name,\n+    ]\n+    performed_gassst(command)\n+    result = read_result(output_result, args.debug)\n+\n+    # load amplicons\n+    sys.stderr.write("Search amplicons : ")\n+    amplicons = {}\n+    for seq in result.keys():\n+        if len(result[seq]) == 3:\n+            # print "Search amplicon on seq: " + seq\n+            for amplicon in get_amplicons(result[seq]):\n+                if len(amplicon) > args.min and len(amplicon) < args.max:\n+                    amplicons.setdefault(seq, []).append(amplicon)\n+                else:\n+                    del amplicon\n+            # print "Find amplicons : "  + str(len(amplicons[seq]))\n+    sys.stderr.write(str(sum(map(len, amplicons.values()))) + "\\n\\n")\n+\n+    # print amplicons\n+\n+    sys.stderr.write("Write result : ")\n+    sep = "\\t"\n+    args.out.write(\n+        "Id\\tAmpli number\\tDescription\\tStart\\tStop\\tError forward\\tError probe\\tError reverse\\n"\n+    )\n+    for record in SeqIO.parse(args.database, "fasta"):\n+        if record.id not in amplicons:\n+            continue\n+        for i, amplicon in enumerate(amplicons.get(record.id)):\n+            desc = record.description.lstrip(record.id)\n+            if args.taxo:\n+                desc = record.description.split(";")[-1].strip()\n+            args.out.write(\n+                record.id\n+                + sep\n+                + str(i + 1)\n+                + sep\n+                + desc\n+                + sep\n+                + sep.join(amplicon.get_tab_data())\n+                + "\\n"\n+            )\n+    sys.stderr.write("OK\\n")\n+    # delete tempfile\n+    os.unlink(primer_fasta)\n+    os.unlink(output_result.name)\n'
b
diff -r 000000000000 -r 1f4836da4a14 qpcr_search.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/qpcr_search.xml Tue Jun 14 08:52:22 2022 +0000
b
@@ -0,0 +1,79 @@
+<tool id="qpcr_search_wrapper" name="qPCR Search" version="0.1">
+  <description></description>
+  <requirements>
+    <requirement type="package" version="1.28">gassst</requirement>
+ <requirement type="package" version="1.78">biopython</requirement>
+  </requirements>
+  <stdio>
+    <exit_code range="1:" level="fatal" />
+  </stdio>
+  <version_command>$__tool_directory__/qpcr_search.py -v</version_command>
+  <command>
+    $__tool_directory__/qpcr_search.py -o $output 
+    #if str($error)
+      -e $error
+    #end if
+    #if str($min)
+      -m $min
+    #end if
+    #if str($max)
+      -M $max
+    #end if
+    #if $taxo
+      -t
+    #end if
+    $forward $probe $reverse $database 2> $logfile
+  </command>
+
+  <inputs>
+    <param name="database" type="data" format="fasta" label="Database to search on fasta" help="FASTA format" />
+ <param name="forward" type="text" value="" optional="false" size="50"
+    label="Forward primer sequence"
+    help="DNA sequence, letters corresponding to multiple nucleotide allowed" />
+ <param name="probe" type="text" value="" optional="false" size="50"
+    label="Probe sequence"
+    help="DNA sequence, letters corresponding to multiple nucleotide allowed" />
+ <param name="reverse" type="text" value="" optional="false" size="50"
+    label="Reverse primer sequence"
+    help="DNA sequence, letters corresponding to multiple nucleotide allowed" />
+    <param name="error" type="integer" value="1" optional="true"
+    label="Maximun error allowed on match" help="Number of mismatch allowed for each primer" />
+    <param name="min" type="integer" value="50" optional="true"
+    label="Min len amplicon size" help="Only amplicon with this minimun length were reported" />
+    <param name="max" type="integer" value="200" optional="true"
+    label="Max len amplicon size" help="Only amplicon with this maximun length were reported" />
+    <param name="taxo" type="boolean" checked="false"
+    label="If set, parse description to report species only" />
+  </inputs>
+
+  <outputs>
+    <data name="logfile" format="txt" label="${tool.name} on ${on_string}: log" />
+    <data name="output" format="txt" label="${tool.name} on ${on_string}: search" />
+  </outputs>
+  <tests>
+ <test expect_num_outputs="2">
+      <param name="database" value="input.fasta" />
+      <param name="forward" value="TTCAACTTCGGCGACTTCC" />
+      <param name="probe" value="CGGTGCGCCCGATCGCCGGTACCCG" />
+      <param name="reverse" value="TCTTCGTTGATCCCGCGC" />
+      <param name="error" value="2" />
+      <output name="output" file="qpcr.txt" ftype="txt" />
+    </test>
+  </tests>
+  <help>
+**What it does**
+
+Search qPCR primer/probe on database and return position and errors.
+
+**License and citation**
+
+This Galaxy tool is Copyright © 2018 `B. Valot` and is released under the `GPL3 license`.
+
+This tool uses Gassst, which is licensed separately.
+Please cite: Rizk G. and Dominique Lavenier D. (2010) GASSST: global alignment short sequence search tool. *Bioinformatics* 26(20), 2534-2540.
+http://www.irisa.fr/symbiose/projects/gassst/
+  </help>
+  <citations>
+ <citation type="doi">10.1093/bioinformatics/btq485</citation>
+  </citations>
+</tool>
b
diff -r 000000000000 -r 1f4836da4a14 test-data/input.fasta
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/input.fasta Tue Jun 14 08:52:22 2022 +0000
b
b'@@ -0,0 +1,121324 @@\n+>NODE_1_length_344587_cov_27.773165\n+ATGGTGTCCACCAAAAACAGGTGGACACCATGCCGCTAGCTGGAAGAACCGGGGAGGTGT\n+GTTGGCCAGACGCTTACACTGTTTCGCCCATATGTCTGTCGATGCGGATCAGCACAAACC\n+GAATTGGACTTGGGTATAGATGGCCTTCGGGCCGCCTTTTTTGCCAATGGAGGCATCCCG\n+GGGGGTGGGCCGACAACGCACCCCCGGTGGGAGCTACTGTTAAGAGTCAGCGCCGAAGGT\n+ATTACGCAGAAAGGCTTGCACGGTCGACAGGATTTCCTGAGATAGCTCATCGTCCGCGAC\n+CGCACGCGAAAGCCCCAAGGCACCGACCATAGTGCTGAAAGCCACAATCGCTTCAGCGCG\n+CTTTTCACTATTGCCGCCCCCCACCAAAGCCGAAATGCCCTTGATGTTGGCCTTGAGCTT\n+ACGCGTATACAGCTCCCGCGCCTCACCCTCTACGCGACCAATATCACTTACCAGCGCGCC\n+CACTGCGCATCCTGTGCCTACGGAGTCACGGTGCTCTTGGCTCAGATACTCGCTCACGAG\n+CTTATCGAAGGTCGCCTTATAGGTGCGGTCAGGATTTTCCGAGCGCTGAAAAGCGACATC\n+CAAAGCCTCAACAACCAACTGGTCACGGGACTCGAAGTGCTTGTAGAAGCCACCATGGGT\n+AAGGCCAGCTTCTTTCATGAGGTCGGCGATGCTTAAGCCATCAATTCCCAGCTCGCAAAA\n+TCGTTCAGCCGCGATGCTGACAATGCGGTCATGAGTTGCCTGCTTGCTAGCTTGTGAGTG\n+CCCCATCTCTGATGACCTTGATCTCTGATCCGTAGCGGATGATATCACCCGCTACGGATG\n+CGCTTTTAGCTCACCATTTTTCGCCAAAGGGGCGGATTTCCGTCAGGAAGGACCAAGCAC\n+TTCTGGGCTGTTGAATGAGGTGACCCACTTCGGCGGCGATGTCTGCCGGCTGGATGAAAA\n+ACTCATCAGGTGCAGTCGGGTGCATCTTGCGCGTCCATTCCACATCGATCACAGCATCGA\n+TGACCACGTAGGCGACATGGATGCCTTTCGGCCCCAACTCTCGGGCAATCGACTCGCTCA\n+AGATGCGCTGTGCTGCCTTGGTAGGGGCGAAACCGGCAAAGTGGCTTTTTCCGCGTAGCG\n+CGGAGGTATTGCCGGTGACGATGATCGCGCCTTCGCCTTTATCGATCATTGCAGGTGAGA\n+GATGGCGGGCTAGGTGCAGTAGCGAAACGACATTCGTTTCGAAGTTGTTGGTGAGCGCCT\n+TGGGATCGATCTCTAGGAAGCTGCCAAATGTCCCACCCACCGCATTGTGAACCAGTACCG\n+CAGCGTCCCCGAGCTGGGACTTGATGCGATCCAAAGCCAGCTCAAGCTGCTCAATATCGG\n+CAACGTCAGTGGGGAATATGTAGGTGTCCGGTAGCTCTGTCGCCAGCGCTGTCAGGCGCT\n+CCTCATTGCGAGCAATCATTGCTACCCGGAAGCCGTCCTCGACGAGCCGACGAACGATTG\n+CCGCGCCGGTGCCTGGCCCAACGCCAGTGACGATTGCGAGTTTCTTGGTATTCATTTCGA\n+GGCTCCTTTGGCTTTTTGCAGAGCGGCACGCACGAAGTCGAGTCGGTCATTGCCGAAGAA\n+CATTTCGTCGCCGCAGAAGAGGGTCGGCACACCAAATACGCCGCGTCGAGCGGCTTCTTC\n+ATTGTTGGCGGCCAGTTGGTCACGAACGGCAGGTCGATCCGCTAACTGCCAGATGTCTTC\n+GTCTACGCCGAGATTTTTCAGAAAGGTAGATCGTCCTTCTGCGGTGATGAGGTCGTCAGT\n+ACCCGCCCATACGGCTTGAAATAAGGCCGGATGGACGACTTCAAACGAGCCGGTCTGCTG\n+AGCCGCAAGAGCGGCGCGGGCCAAGATCGCGCCTTCAACTTGCCCTGCGCGCATTGCTTG\n+GAAGAACGCGCCATTTGGTGCAAGCGGGACGCCGTAGACGGCTGCCCAACGCGCGGCGTC\n+GATGCCCGAGTACTTCGCTTTGGCAGGGCAAGCAGGAGAGGGTTGGTTATTCACCTTCTT\n+CATCACCTCCAAAATGTCGATGGCGAAGTAGCTGATGGGCGTATCGAACTCTGGCAGGCG\n+GGTGTTGGCCAGGTAAGCGTAAGGGCTTCGGTAATCAAAAACGGACTGGAGATTCATTGA\n+TCTCTCCCGTGGGGGAATGGATTGGTCGGAGCGCGCTCAACTGGATGTTATTCATCATCC\n+ATTCTGGATGTCAAATAACATCCAGAGTGTCGGCCAGCCGACCATGGAGTTGCTGACGCT\n+GCCCTAGGATTGAGGCCCCAAATCCGTTCCACCCAGGGACGCTAGGAGATCCGCTTTATG\n+TCCGGCTTTCAGCACAAGTACGCATTCACCAATGGCATTCGCATGCACTATGTCGACGAG\n+GGCGTGGGGCCGGTCGTTGTTCTTCTCCACGGCTGGCCGGAGTCCTGGTATTCCTGGCGG\n+CACCAGATTTCGTTCTTGGCTGAAGCGGGCTATCGGGTTATCGCGCCCGATCAGCGAGGG\n+TATGGGGATACCGAGATTCCATCGGAGGTAGGCAGCTACCACATCCTCAATTTGGTCGGG\n+GACGTGGTGGGGCTGTTGAACGCGTTGGAAATTAAGTCGGCGGCCCTTGTCGGCCATGAC\n+TGGGGATCGATGGTTGCAGCGGCAGCGGCGCTCCTGCGGCCTGACCTGTTTCATCGTGTC\n+TGTCTGCTGAGCGTTCCCTACATGCCTCGTCGGAGCCTACGACCTAGCACTCGCTTCCAG\n+CTCGCAACCCAGGGAAAGCACTTCTATCAGGACTATTTCCAGCGTGTCGGCATCGTCGAG\n+AAAGAGCTGGGTGAGGATACGCATCGAAGCATTTTGGGTGCCCTTTACGCCCGCTCGGGC\n+GAGGCGAAAAAGCACCCAGAGCACAGCCGCTCAGGCTTCATCGCCTTCGACAAAAGCACT\n+CGCTTTGTAGACAACTTGGCTGTTCCGGACCAGCTGCCGGCTTGGCTTACGGAAGAGGAC\n+CTTGATGTCTTCGTGAAGCAGTTCGAGCGTTCTGGCTTCTTCGGCGGCATCAACTGGTAC\n+AGGAACATGGACCGAAACTGGGAGCTGACGCCCTTTTGGAATGGTGCCGTGTTGATTCAG\n+CCGTTGCTGTTCATCGCAGGCGAGCTCGACGGTGTTCTCACGATGGCCGGTGAAGAGTAC\n+GAAGCGCTGGATATCAATGCTAGGCAGCTGATTGGGAAGGAGTTGATTCCTGGGGCAGGC\n+CATTGGATTCAGCAGGAGCGTCCAGACCACGTTAACCAACTACTGCTGAACTTCGTAGAG\n+CCTGACAGCCCGAGGGATATCTGCCCCTGACCGATTTTCTAACGTTCTGTCCAGGTCACC\n+AATAAAGGGCGTCTGAACAAGCGATATAACGATCGATAGCTTCGTCGGTAATTTGCATCG\n+GAATTGGTAGGTCGTATGGGTGCTAAAGCACTAGCAGTGCATTGATTGGTTCTCTACTGC\n+CAGCGACATACCAAGGAGAACATGTACATGGAGTTTCGGCATCTTCGTTGCTTCCTCGCA\n+GTTGCCGAGGAGCTGCATTTTGCGCGGGCAGCTGAGCGACTGCACATTGAGCAGTCTCCG\n+TTATCTCGTGCGATTAAGGAGCTTGAGGAAGAGTTGGGCACACAGCTTTTCGTGCGAACC\n+ACCCGGAGTACGAGACTTACGCATGCCGGACGACTATTTCTAGATCATGTGCCTCGTGTA\n+TTCACTGCTTTGCAACAGGCGCGCGACAGCGTGAGGGCCGTCGCGAATGGGTACTGTGGC\n+CAACTGCGATTGGCTCTCTCGGACGGGATCTCTC'..b'CC\n+GGCGCCGAGGACCTGATTGTCGAGGACGGAGTGGACCACGTCGTTTTCCAAACCGCTTGG\n+CGTAGCGGTAACCCTTGGCTCTACGCGATCAGGAAGGACTGACATGGCTTATTTCACAGG\n+AACAGCGAACAACCCGGCCGACTTGCTCGCCAAGGTGCGCGTCCACGCCGAGTCGCTCGG\n+CTGGGT\n+>NODE_226_length_359_cov_20.244681\n+TGGTTGTAGTCCCGCAGCCAGCCGCAAGTGACAACGAAGCGAGGAGCAGGCACAGGGGAA\n+GCACCTGGTGCCGGCCGATATTGGGTCGAGACATGGGCGATACGCTCCGATAGCTGTTGC\n+TGGAGGGCAGTGAACTGATCCTGGGCTGACAGGAATCGCGCTTCCGCCTGATTCGCGCGA\n+GTGACCTGCTGTTGGAACTGCAGGAGGTTGTCCTCAGCGATCTTGGCCAGCTCGTTGGAA\n+TGCTGCAGTTGCAGGTTGAGCAGCGCTGCGTCACCTTCAGCACGAGCGGTGGCGTACCCA\n+CGGTCGTAGCTTGCGGAGCCGTGGATCACTACAGCTACGCTGTACAGCACCGCAATCAG\n+>NODE_227_length_356_cov_22.627240\n+AGCGCTCCATCGGGATGACGACCAAGGCGCCGGACTGGGTGATAGCGGCTTGGCCACCGG\n+TGGCCTCCGCCAGTTGCCGGTGGAGATGCTGGGCCTCGTTGCACCACCCTTCGGCACATT\n+CCTCCATGCGGGTCAGCTCGGTGCGCAGGTGCTCGTTCTCTTCGGCAAGGCGCGCAGCTT\n+CGATGCAGAGCTGCTCATAGGCTTTCTCGTCCAGGCGCCGCAGCAGCGCCTGCAGGTTGA\n+TGGACTCACTCATCGTCAGCCACTCCAAAGTCCAGTTGAGGGGTTTCTGCCTGGGCGACG\n+TTGCCGTGGTGCCAAGCGAGGGATTCGAGGCCGGCGCGGATGGCGTCCAGGGTCTG\n+>NODE_228_length_350_cov_31.344322\n+ACAGCGAACAACCCGGCCGACTTGCTCGCCAAGGTGCGCGTCCACGCCGAGTCGCTCGGC\n+TGGGTCACCGACCGCGCGTCGGCATCGGAATGGATCTGTCACAACGCTGATGGGTACTGG\n+TCATTCAATGCCGGAGCCAATCAGTTTCAGATCGCGGGCAATACGGGGTTCGACAACGGG\n+CTGGCGTGGAACGCGCAGCCCGGTAACTCGGTGCAGAACAACCCGTATTCGTCGAAAGAA\n+GCAACCATAGCGCAGCTCAGCGCCGGGCCATTCACGCGCTATCACCTGTTCGCCACCGCT\n+GCCTATCTGCACCTGCACGTCGAAATCGCTGCCGGTCAGTTTCGTCCAGT\n+>NODE_229_length_339_cov_28.759542\n+CCGTGCTGTCGGGCTTACCCTTTTCCCCGGGCGACCACTTTCAGCGACTCGATGTCGAGG\n+TGGGCCTCGGCGAGCAATTTCTTCAATCGGCTGTTTTCCAGTTCAAGATCCTTCAACCGT\n+TTGGCGTCCGCCACGGTCATACCGCCAAACTTGGCCCGCCAGGTGTAGAACGAGGCATCA\n+CTGAAGCCGTGTCGGCGACACAGTTCCTTCACCGGCACACCGGCCTCCGCCTGCTTGAGG\n+AAGTCGAGAATCTGCTCTTCGATAAAACGCTTTTTCACTGCCGTCTCCTGCTCGGAAAAC\n+GGACTCTACTAAGTTCGGCGTGGTACTGAAATCGGGGAG\n+>NODE_230_length_337_cov_22.915385\n+GTAAATCGCGACCGTAGGCTGGCCTCGGCATCCGGCGCCGACCAGCTGGCCTGGTTCGAT\n+TCCGTCGAGCGCTTCAATTCCGGGCGCTCGGCCGCCAACTTCCGCGAGAACCGCAACTAC\n+CCGCGCCTCATCCTGCTGCGCTACGAGCGGATCTATCTGCAGTGGGGCGACGGTGTGTGC\n+GGCGAGAGGTACACCCTGTGAGACTGTCCCCCAGCATCACCCTGGCTCTGAACATTACCT\n+ACCTCGACCTAGCGCTGATCCAGCGGCTGTTCGCAGGCAGTCGCGACTTCCTACCGGCAC\n+CTGAGCTGTATTGCTCGCCAGTGCCGCGCGAGCGGCA\n+>NODE_231_length_335_cov_57.887597\n+TCTCCTCCATATCTTCGAACAGCTCATATTGGGCGACGATGTCACCTTGCTCGGCGGAGT\n+CGAGGAGCGAGGCAAGCTTTGAAGGCGTGAGTCCACGGGATGGGTGACCAGCGACTTCCT\n+GGTGAAGGCTGGTCAGGTGGGCGGTCTGGGCTTCTTTCAGGTCAGCATCGGCCATGCTCT\n+GCTGCCCGAAAATGCGCGCGACAGTGGCGCGTAGCGTCTGCATCACCATGCGGAAGGCTC\n+CGGTAGTTCAATGTCATCGTTGTGGTCCTGGACGTTGTCGAAGCCGCGGCTATGGCGTGG\n+CAGCGCCGTGAAGGCGATCTCGCCACCCTCCATGT\n+>NODE_233_length_321_cov_145.581967\n+CTCAATAACGTGATCGAGGCCGATCACGGAAAGCTCAAGATACTGATCAAGCCGGTGCGC\n+GGTTTCAAATCGATCCCCACGGCCTATGCCACGATCAAGGGATTCGAAGTCATGCGAGCC\n+CTGCGCAAAGGACAGGCTCGCCCCTGGTGCCTGCAGCCCGGCATCAGGGGCGAGGTGCGC\n+CTTGTGGAGAGAGCTTTTGGCATTGGGCCCTCGGCGCTGACGGAGGCCATGGGCATGCTC\n+AACCACCATTTCGCAGCAGCCGCCTGATCGGCGCAGAGCGACAGCCTACCTCTGACTGCC\n+GCCAATCTTTGCAACAGAGCC\n+>NODE_234_length_313_cov_43.343220\n+GGCATACTGGGTGCCGCGATGGACCACCCGCACCGGCCGCCACCAGGCGTTGAAGTCGGC\n+ACGCGGATGACCTTCCAAGGCAAAGGCGTGGCCCGGGATCAGCCGCGGGTCGTCGCCGCT\n+GACCGATGCCTCCCGCGCATCGCGCCGGTGCCCTCTGAGGCGGCTTTCGGTGAAAGGCCG\n+GCCGGCGCCGCTCCGCTTGTAGCGACCGGGGTAGTCGTAGCGCTCGTAGGACGAGCCCTG\n+ATGCTCGAGCGCCTCGCCAGCGAGATGATGCTCCTGGTCGTAGGTCGGGCGCTTGAAGCT\n+GTAGTCCCGCTGG\n+>NODE_235_length_306_cov_24.820961\n+AGGATCGAACGGCGGGGCATGCGGTTTCCTTCTTCTTGAAAACGTAGGTTTGTGACAAGC\n+CCGCCAAGGCAACCGGCTGTCATTTTCAGAAGACGACTGCACCAGTTGATTGGGCGTAAT\n+GGCTGTTGTGCAGCCAGCTCCTGACAGTTCAATATCAGAAGTGATCTGCACCAATCTCGA\n+CTATGCTCAATACTCGTGTGCACCAAAGCGAGGTGAGCATGGCGACGGAGGCTCTGTTGC\n+AAAGATTGGCGGCAGTCAGAGGTAGGCTGTCGCTCTGCGCCGATCAGGCGGCTGCTGCGA\n+AATGGT\n+>NODE_236_length_305_cov_44.745614\n+GGCTGGGCGCTGAACAGTACCGGGCCGCCGGCGATACGCTCCTGGACGTAGAGCCGGTCG\n+CTGCAGACCAGGGTGTGACGGTGTTCGTCGAAGCGGAAGTAGTAGACCAGGCCTTCCTCG\n+AAGGCCAGCCGGTCGTGCAGGTAGTGATCGCTGTCGCCGGCCTGCACGCAGTATTCGCGT\n+GGCAGGTGCTCGTGGTAGATGCGCTGTTCGTAGTCGAGCACCCGGTGCTCCTTGAGCAGC\n+GCCTGGAGAATCTCCGGAACACTCTTCTCCTGGAAGATCCGCCAGTTGCAGCACAGCTCC\n+AGGCG\n'
b
diff -r 000000000000 -r 1f4836da4a14 test-data/pcr.fasta
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/pcr.fasta Tue Jun 14 08:52:22 2022 +0000
b
@@ -0,0 +1,16 @@
+>NODE_33_length_85799_cov_26.696344_ampli_0 20191 : 21033 in strand:1; error F:0,R:0
+ACCTGGTGTACGCCTCGCTGACCCACGAGCGGGTCTTCGACTACCGTCCGGGCGAAGTCT
+ACTGGTGCACCGCCGACATCGGCTGGGTCACCGGCCACACCTACATCGTCTATGGCCCGC
+TGGCCAACGGCGCCACCACCATTCTGTTCGAGGGCGTGCCGAACTACCCCGACGTGACCC
+GCGTGGCGAAAATCATCGACAAGCACAAGGTCAACATCCTCTACACCGCGCCGACCGCGA
+TCCGCGCGATGATGGCCGAAGGCAAGGCGGCGGTGGCCGGTGCCGACGGTTCCAGCCTGC
+GTCTGCTCGGTTCGGTGGGCGAGCCGATCAACCCGGAAGCCTGGCAGTGGTACTACGAGA
+CCGTCGGCCAGTCGCGCTGCCCGATCGTCGACACCTGGTGGCAGACCGAGACCGGCGCCT
+GCCTGATGACCCCGCTGCCGGGCGCCCACGCGATGAAGCCGGGCTCTGCAGCCAAGCCGT
+TCTTCGGCGTGGTACCGGCACTGGTGGACAACCTCGGCAACCTGATCGAGGGCGCCGCCG
+AGGGCAACCTGGTGATCCTCGACTCCTGGCCGGGCCAGGCGCGGACCCTGTTCGGCGACC
+ATGACCGCTTCGTCGACACCTACTTCAAGACCTTCAAGGGCATGTACTTCACCGGCGACG
+GCGCGCGCCGCGACGAGGACGGCTACTACTGGATCACCGGGCGGGTCGACGACGTGCTCA
+ACGTCTCCGGCCACCGCATGGGCACCGCCGAGGTGGAAAGCGCGATGGTCGCCCACCCGA
+AGGTCGCCGAGGCGGCGGTGGTCGGCATGCAGCACGACATCAAGGGGCAGGGCATCTATG
+TC
b
diff -r 000000000000 -r 1f4836da4a14 test-data/qpcr.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test-data/qpcr.txt Tue Jun 14 08:52:22 2022 +0000
b
@@ -0,0 +1,2 @@
+Id Ampli number Description Start Stop Error forward Error probe Error reverse
+NODE_2_length_251595_cov_31.920467 1 215345 215464 0 0 0