changeset 6:626d5cfd01aa draft

Uploaded v0.0.1 preview 6, support for fragment length (using mira4_validator.py)
author peterjc
date Mon, 21 Oct 2013 12:01:47 -0400
parents ffefb87bd414
children 902f01c1084b
files tools/mira4/README.rst tools/mira4/mira4_de_novo.xml tools/mira4/mira4_mapping.xml tools/mira4/mira4_validator.py
diffstat 4 files changed, 189 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/tools/mira4/README.rst	Tue Oct 15 12:07:34 2013 -0400
+++ b/tools/mira4/README.rst	Mon Oct 21 12:01:47 2013 -0400
@@ -40,9 +40,10 @@
 
 * http://toolshed.g2.bx.psu.edu/view/peterjc/mira_datatypes 
 
-There are just three Galaxy files to install:
+There are four Galaxy files to install:
 
-* mira4.py (the Python script)
+* mira4.py (the Python wrapper script)
+* mira4_validator.py (the Python parameter validation script)
 * mira4_de_novo.xml (the Galaxy tool definition for de novo usage)
 * mira4_mapping.xml (the Galaxy tool definition for mapping usage)
 
@@ -81,7 +82,7 @@
 For making the "Galaxy Tool Shed" http://toolshed.g2.bx.psu.edu/ tarball use
 the following command from the Galaxy root folder::
 
-    $ tar -czf mira4_wrapper.tar.gz tools/mira4/README.rst tools/mira4/mira4_de_novo.xml tools/mira4/mira4_mapping.xml tools/mira4/mira4.py tools/mira4/tool_dependencies.xml test-data/tvc_mini.fastq test-data/tvc_contigs.fasta test-data/tvc_map_ref_strain.fasta test-data/tvc_map_same_strain.fasta
+    $ tar -czf mira4_wrapper.tar.gz tools/mira4/README.rst tools/mira4/mira4_de_novo.xml tools/mira4/mira4_mapping.xml tools/mira4/mira4.py tools/mira4/mira4_validator.py tools/mira4/tool_dependencies.xml test-data/tvc_mini.fastq test-data/tvc_contigs.fasta test-data/tvc_map_ref_strain.fasta test-data/tvc_map_same_strain.fasta
 
 Check this worked::
 
@@ -90,6 +91,7 @@
     tools/mira4/mira4_de_novo.xml
     tools/mira4/mira4_mapping.xml
     tools/mira4/mira4.py
+    tools/mira4/mira4_validator.py
     tools/mira4/tool_dependencies.xml
     test-data/tvc_mini.fastq
     test-data/tvc_contigs.fasta
--- a/tools/mira4/mira4_de_novo.xml	Tue Oct 15 12:07:34 2013 -0400
+++ b/tools/mira4/mira4_de_novo.xml	Mon Oct 21 12:01:47 2013 -0400
@@ -1,7 +1,6 @@
 <tool id="mira_4_0_de_novo" name="MIRA v4.0 de novo assember" version="0.0.1">
     <description>Takes Sanger, Roche 454, Solexa/Illumina, Ion Torrent and PacBio reads</description>
     <requirements>
-        <requirement type="python-module">Bio</requirement>
         <requirement type="binary">mira</requirement>
         <requirement type="package" version="4.0">MIRA</requirement>
     </requirements>
@@ -29,17 +28,39 @@
                 <option value="text">Synthetic reads (database entries, consensus sequences, artifical reads, etc)</option>
 		<!-- TODO reference/backbone as an entry here? -->
             </param>
-            <param name="segment_placement" type="select" label="Pairing type (segment placing)">
-                <option value="">None (e.g. single end sequencing)</option>
-                <option value="FR">---&gt; &lt;--- (e.g. Sanger capillary or Solexa/Illumina paired-end library)</option>
-                <option value="RF">&lt;--- ---&gt; (e.g. Solexa/Illumina mate-pair library)</option>
-                <option value="SB">2---&gt; 1---&gt; (e.g. Roche 454 paired-end libraries or IonTorrent long-mate; see note)</option>
-                <option value="?">Unknown or not relevant (e.g. primer walking with Sanger capillary sequencing)</option>
-            </param>
+            <conditional name="segments">
+                <param name="type" type="select" label="Are these paired reads?">
+                    <option value="paired">Paired reads</option>
+                    <option value="none">Single reads or not relevant (e.g. primer walking with Sanger capillary sequencing)</option>
+                </param>
+                <when value="paired">
+                    <param name="placement" type="select" label="Pairing type (segment placing)">
+                        <option value="FR">---&gt; &lt;--- (e.g. Sanger capillary or Solexa/Illumina paired-end library)</option>
+                        <option value="RF">&lt;--- ---&gt; (e.g. Solexa/Illumina mate-pair library)</option>
+                        <option value="SB">2---&gt; 1---&gt; (e.g. Roche 454 paired-end libraries or IonTorrent long-mate; see note)</option>
+                    </param>
+                    <!-- min/max validation is done via the <code> tag -->
+                    <param name="min_size" type="integer" optional="true" min="0" value=""
+                           label="Minimum size of 'good' DNA templates in the library preparation"
+                           help="Optional, but if used you must also supply a maximum value." /> 
+                    <param name="max_size" type="integer" optional="true" min="0" value=""
+                           label="Maximum size of 'good' DNA templates in the library preparation"
+                           help="Optional, but if used you must also supply a minimum value." />
+                    <param name="naming" type="select" label="Pair naming convention">
+                        <option value="solexa">Solexa/Illumina (using '/1' and '/2' suffixes)</option>
+                        <option value="FR">Forward/Reverse scheme (using '.f*' and '.r*' suffixes)</option>
+                        <option value="tigr">TIGR scheme (using 'TF*' and 'TR*' suffixes)</option>
+                        <option value="sanger">Sanger scheme (see notes)</option>
+                        <option value="stlouis">St. Louis scheme (see notes)</option>
+                    </param>
+                </when>
+                <when value="none" /><!-- no further questions -->
+            </conditional>
 	    <param name="filenames" type="data" format="fastq,mira" multiple="true" required="true" label="Read file(s)"
 		   help="Multiple files allowed, for example paired reads can be given as two files (MIRA looks at read names to identify pairs)." />
         </repeat>
     </inputs>
+    <code file="mira4_validator.py" />
     <outputs>
         <data name="out_fasta" format="fasta" label="MIRA de novo contigs (FASTA)" />
         <data name="out_maf" format="mira" label="MIRA de novo assembly" />
@@ -67,12 +88,20 @@
 
 readgroup
 technology = ${rg.technology}
+##Record the segment placement (if any)
+#if str($rg.segments.type) == "paired"
+segmentplacement = ${rg.segments.placement}
+segmentnaming = ${rg.segments.naming}
+#if str($rg.segments.min_size) != "" or str($rg.segments.max_size) != ""
+##If our min/max validation failed I trust MIRA to give an error message...
+templatesize = $rg.segments.min_size $rg.segments.max_size
+#end if
+#end if
+#if str($rg.segments.type) == "none"
+segmentplacement = ?
+#end if
 ##MIRA will accept multiple filenames on one data line, or multiple data lines
 #for $f in $rg.filenames
-#if str($rg.segment_placement) != ""
-##Record the segment placement (if any)
-segmentplacement = ${rg.segment_placement}
-#end if
 ##Must now map Galaxy datatypes to MIRA file types...
 #if $f.ext.startswith("fastq")
 ##MIRA doesn't like fastqsanger etc, just plain old fastq:
@@ -120,18 +149,35 @@
 
 It is particularly suited to small genomes such as bacteria.
 
-**Notes**
+
+**Notes on paired reads**
 
 .. class:: warningmark
 
-Note that the raw data for Roche 454 and Ion Torrent paired-end libraries
-sequences a circularised fragment such that the raw data starts with the
-end of the fragment, a linker, then the start of the fragment. This means
-both the start and end are sequenced from the same strand, and thus should
-be given to MIRA as orientation "2---&gt; 1---&gt;". However, in order to
-use this data with traditional tools expecting Sanger capillary style
-libraries which expect "---&gt; &lt;---" your FASTQ files may have been
-pre-processed to mimic this by reverse complementing one of the pair.
+MIRA uses read naming conventions to identify paired read partners
+(and does not care about their order in the input files). In most cases,
+the Solexa/Illumina setting is fine. For Sanger capillary sequencing,
+you may need to rename your reads to match one of the standard conventions
+supported by MIRA. For Roche 454 or Ion Torrent the appropriate settings
+depend on how the FASTQ file was produced:
+
+* If using Roche's ``sffinfo`` or older versions of ``sff_extract``
+  to convert SFF files to FASTQ, your reads will probably have the
+  ``---&gt; &lt;---`` orientation and use the ``.f`` and ``.r``
+  suffixes (FR naming).
+
+* If using a recent version of ``sff_extract``, then the ``/1`` and ``/2``
+  suffixes are used (Solexa/Illumina style naming) and the original
+  ``2---&gt; 1---&gt;`` orientation is preserved.
+
+The reason for this is the raw data for Roche 454 and Ion Torrent paired-end
+libraries sequences a circularised fragment such that the raw data begins
+with the end of the fragment, a linker, then the start of the fragment.
+This means both the start and end are sequenced from the same strand, and
+have the orientation ``2---&gt; 1---&gt;``. However, in order to use the data
+with traditional tools expecting Sanger capillary style ``---&gt; &lt;---``
+orientation it was common to reverse complement one of the pair to mimic this.
+
 
 **Citation**
 
--- a/tools/mira4/mira4_mapping.xml	Tue Oct 15 12:07:34 2013 -0400
+++ b/tools/mira4/mira4_mapping.xml	Mon Oct 21 12:01:47 2013 -0400
@@ -1,7 +1,6 @@
 <tool id="mira_4_0_mapping" name="MIRA v4.0 mapping" version="0.0.1">
     <description>Maps Sanger, Roche 454, Solexa/Illumina, Ion Torrent and PacBio reads</description>
     <requirements>
-        <requirement type="python-module">Bio</requirement>
         <requirement type="binary">mira</requirement>
         <requirement type="package" version="4.0">MIRA</requirement>
     </requirements>
@@ -38,13 +37,27 @@
                 <option value="pcbiohq">PacBio high quality (corrected)</option>
                 <option value="text">Synthetic reads (database entries, consensus sequences, artifical reads, etc)</option>
             </param>
-            <param name="segment_placement" type="select" label="Pairing type (segment placing)">
-                <option value="">None (e.g. single end sequencing)</option>
-                <option value="FR">---&gt; &lt;--- (e.g. Sanger capillary or Solexa/Illumina paired-end library)</option>
-                <option value="RF">&lt;--- ---&gt; (e.g. Solexa/Illumina mate-pair library)</option>
-                <option value="SB">2---&gt; 1---&gt; (e.g. Roche 454 paired-end libraries or IonTorrent long-mate; see note)</option>
-                <option value="?">Unknown or not relevant (e.g. primer walking with Sanger capillary sequencing)</option>
-            </param>
+            <conditional name="segments">
+                <param name="type" type="select" label="Are these paired reads?">
+                    <option value="paired">Paired reads</option>
+                    <option value="none">Single reads or not relevant (e.g. primer walking with Sanger capillary sequencing)</option>
+                </param>
+                <when value="paired">
+                    <param name="placement" type="select" label="Pairing type (segment placing)">
+                        <option value="FR">---&gt; &lt;--- (e.g. Sanger capillary or Solexa/Illumina paired-end library)</option>
+                        <option value="RF">&lt;--- ---&gt; (e.g. Solexa/Illumina mate-pair library)</option>
+                        <option value="SB">2---&gt; 1---&gt; (e.g. Roche 454 paired-end libraries or IonTorrent long-mate; see note)</option>
+                    </param>
+                    <param name="naming" type="select" label="Pair naming convention">
+                        <option value="solexa">Solexa/Illumina (using '/1' and '/2' suffixes)</option>
+                        <option value="FR">Forward/Reverse scheme (using '.f*' and '.r*' suffixes)</option>
+                        <option value="tigr">TIGR scheme (using 'TF*' and 'TR*' suffixes)</option>
+                        <option value="sanger">Sanger scheme (see notes)</option>
+                        <option value="stlouis">St. Louis scheme (see notes)</option>
+                    </param>
+                </when>
+                <when value="none" /><!-- no further questions -->
+            </conditional>
             <param name="filenames" type="data" format="fastq,mira" multiple="true" required="true" label="Read file(s)"
                    help="Multiple files allowed, for example paired reads can be given as two files (MIRA looks at read names to identify pairs)." />
         </repeat>
@@ -104,9 +117,13 @@
 ##This is perhaps redundant as MIRA defaults to StrainX for the reads:
 strain = StrainX
 #end if
-#if str($rg.segment_placement) != ""
 ##Record the segment placement (if any)
-segmentplacement = ${rg.segment_placement}
+#if str($rg.segments.type) == "paired"
+segmentplacement = ${rg.segments.placement}
+segmentnaming = ${rg.segments.naming}
+#end if
+#if str($rg.segments.type) == "none"
+segmentplacement = ?
 #end if
 ##MIRA will accept multiple filenames on one data line, or multiple data lines
 #for $f in $rg.filenames
@@ -160,18 +177,35 @@
 
 It is particularly suited to small genomes such as bacteria.
 
-**Notes**
+
+**Notes on paired reads**
 
 .. class:: warningmark
 
-Note that the raw data for Roche 454 and Ion Torrent paired-end libraries
-sequences a circularised fragment such that the raw data starts with the
-end of the fragment, a linker, then the start of the fragment. This means
-both the start and end are sequenced from the same strand, and thus should
-be given to MIRA as orientation "2---&gt; 1---&gt;". However, in order to
-use this data with traditional tools expecting Sanger capillary style
-libraries which expect "---&gt; &lt;---" your FASTQ files may have been
-pre-processed to mimic this by reverse complementing one of the pair.
+MIRA uses read naming conventions to identify paired read partners
+(and does not care about their order in the input files). In most cases,
+the Solexa/Illumina setting is fine. For Sanger capillary sequencing,
+you may need to rename your reads to match one of the standard conventions
+supported by MIRA. For Roche 454 or Ion Torrent the appropriate settings
+depend on how the FASTQ file was produced:
+
+* If using Roche's ``sffinfo`` or older versions of ``sff_extract``
+  to convert SFF files to FASTQ, your reads will probably have the
+  ``---&gt; &lt;---`` orientation and use the ``.f`` and ``.r``
+  suffixes (FR naming).
+
+* If using a recent version of ``sff_extract``, then the ``/1`` and ``/2``
+  suffixes are used (Solexa/Illumina style naming) and the original
+  ``2---&gt; 1---&gt;`` orientation is preserved.
+
+The reason for this is the raw data for Roche 454 and Ion Torrent paired-end
+libraries sequences a circularised fragment such that the raw data begins
+with the end of the fragment, a linker, then the start of the fragment.
+This means both the start and end are sequenced from the same strand, and
+have the orientation ``2---&gt; 1---&gt;``. However, in order to use the data
+with traditional tools expecting Sanger capillary style ``---&gt; &lt;---``
+orientation it was common to reverse complement one of the pair to mimic this.
+
 
 **Citation**
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/mira4/mira4_validator.py	Mon Oct 21 12:01:47 2013 -0400
@@ -0,0 +1,64 @@
+#Called from the Galaxy Tool XML file
+#import sys
+
+def validate_input(trans, error_map, param_values, page_param_map):
+    """Validates the min_size/max_size user input, before execution."""
+    err_list = []
+    for read_group in param_values["read_group"]:
+        err = dict()
+        segments = read_group["segments"]
+        if str(segments["type"]) != "paired":
+            err_list.append(dict())
+            continue
+
+        min_size = str(segments["min_size"]).strip()
+        max_size = str(segments["max_size"]).strip()
+        #sys.stderr.write("DEBUG min_size=%r, max_size=%r\n" % (min_size, max_size))
+
+        #Somehow Galaxy seems to turn an empty field into string "None"...
+        if min_size=="None":
+            min_size = ""
+        if max_size=="None":
+            max_size = ""
+
+        if min_size=="" and max_size=="":
+            #Both missing is good
+            pass
+        elif min_size=="":
+            err["min_size"] = "Minimum size required if maximum size given"
+        elif max_size=="":
+            err["max_size"] = "Maximum size required if minimum size given"
+            
+        if min_size:
+            try:
+                min_size_int = int(min_size)
+                if min_size_int < 0:
+                    err["min_size"] = "Minumum size must not be negative (%i)" % min_size_int
+                    min_size = None # Avoid doing comparison below
+            except ValueError:
+                err["min_size"] = "Minimum size is not an integer (%s)" % min_size
+                min_size = None # Avoid doing comparison below
+
+        if max_size:
+            try:
+                max_size_int = int(max_size)
+                if max_size_int< 0:
+                    err["max_size"] = "Maximum size must not be negative (%i)" % max_size_int
+                    max_size = None # Avoid doing comparison below
+            except ValueError:
+                err["max_size"] = "Maximum size is not an integer (%s)" % max_size
+                max_size = None # Avoid doing comparison below
+
+        if min_size and max_size and min_size_int > max_size_int:
+            msg = "Minimum size must be less than maximum size (%i vs %i)" % (min_size_int, max_size_int)
+            err["min_size"] = msg
+            err["max_size"] = msg
+
+        if err:
+            err_list.append({"segments":err})
+        else:
+            err_list.append(dict())
+
+    if any(err_list):
+        #Return an error map only if any readgroup gave errors
+        error_map["read_group"] = err_list