Repository 'jbrowse2'
hg clone https://toolshed.g2.bx.psu.edu/repos/fubar/jbrowse2

Changeset 13:1d86925dbb4c (2024-01-22)
Previous changeset 12:247e17ce504b (2024-01-20) Next changeset 14:7c2e28e144f3 (2024-01-22)
Commit message:
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse2 commit 873a12803692b0a84814a6dc08331d772d0e5492-dirty
modified:
jbrowse2.py
macros.xml
added:
abjbrowse2.py
abjbrowse2.xml
b
diff -r 247e17ce504b -r 1d86925dbb4c abjbrowse2.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/abjbrowse2.py Mon Jan 22 11:52:19 2024 +0000
[
b'@@ -0,0 +1,1097 @@\n+#!/usr/bin/env python\n+import argparse\n+import binascii\n+import datetime\n+import hashlib\n+import json\n+import logging\n+import os\n+import re\n+import shutil\n+import struct\n+import subprocess\n+import tempfile\n+import xml.etree.ElementTree as ET\n+from collections import defaultdict\n+\n+logging.basicConfig(level=logging.INFO)\n+log = logging.getLogger(\'jbrowse\')\n+TODAY = datetime.datetime.now().strftime("%Y-%m-%d")\n+GALAXY_INFRASTRUCTURE_URL = None\n+\n+\n+class ColorScaling(object):\n+\n+    COLOR_FUNCTION_TEMPLATE = """\n+    function(feature, variableName, glyphObject, track) {{\n+        var score = {score};\n+        {opacity}\n+        return \'rgba({red}, {green}, {blue}, \' + opacity + \')\';\n+    }}\n+    """\n+\n+    COLOR_FUNCTION_TEMPLATE_QUAL = r"""\n+    function(feature, variableName, glyphObject, track) {{\n+        var search_up = function self(sf, attr){{\n+            if(sf.get(attr) !== undefined){{\n+                return sf.get(attr);\n+            }}\n+            if(sf.parent() === undefined) {{\n+                return;\n+            }}else{{\n+                return self(sf.parent(), attr);\n+            }}\n+        }};\n+\n+        var search_down = function self(sf, attr){{\n+            if(sf.get(attr) !== undefined){{\n+                return sf.get(attr);\n+            }}\n+            if(sf.children() === undefined) {{\n+                return;\n+            }}else{{\n+                var kids = sf.children();\n+                for(var child_idx in kids){{\n+                    var x = self(kids[child_idx], attr);\n+                    if(x !== undefined){{\n+                        return x;\n+                    }}\n+                }}\n+                return;\n+            }}\n+        }};\n+\n+        var color = ({user_spec_color} || search_up(feature, \'color\') || search_down(feature, \'color\') || {auto_gen_color});\n+        var score = (search_up(feature, \'score\') || search_down(feature, \'score\'));\n+        {opacity}\n+        if(score === undefined){{ opacity = 1; }}\n+        var result = /^#?([a-f\\d]{{2}})([a-f\\d]{{2}})([a-f\\d]{{2}})$/i.exec(color);\n+        var red = parseInt(result[1], 16);\n+        var green = parseInt(result[2], 16);\n+        var blue = parseInt(result[3], 16);\n+        if(isNaN(opacity) || opacity < 0){{ opacity = 0; }}\n+        return \'rgba(\' + red + \',\' + green + \',\' + blue + \',\' + opacity + \')\';\n+    }}\n+    """\n+\n+    OPACITY_MATH = {\n+        \'linear\': """\n+            var opacity = (score - ({min})) / (({max}) - ({min}));\n+        """,\n+        \'logarithmic\': """\n+            var opacity = Math.log10(score - ({min})) / Math.log10(({max}) - ({min}));\n+        """,\n+        \'blast\': """\n+            var opacity = 0;\n+            if(score == 0.0) {{\n+                opacity = 1;\n+            }} else {{\n+                opacity = (20 - Math.log10(score)) / 180;\n+            }}\n+        """\n+    }\n+\n+    BREWER_COLOUR_IDX = 0\n+    BREWER_COLOUR_SCHEMES = [\n+        (166, 206, 227),\n+        (31, 120, 180),\n+        (178, 223, 138),\n+        (51, 160, 44),\n+        (251, 154, 153),\n+        (227, 26, 28),\n+        (253, 191, 111),\n+        (255, 127, 0),\n+        (202, 178, 214),\n+        (106, 61, 154),\n+        (255, 255, 153),\n+        (177, 89, 40),\n+        (228, 26, 28),\n+        (55, 126, 184),\n+        (77, 175, 74),\n+        (152, 78, 163),\n+        (255, 127, 0),\n+    ]\n+\n+    BREWER_DIVERGING_PALLETES = {\n+        \'BrBg\': ("#543005", "#003c30"),\n+        \'PiYg\': ("#8e0152", "#276419"),\n+        \'PRGn\': ("#40004b", "#00441b"),\n+        \'PuOr\': ("#7f3b08", "#2d004b"),\n+        \'RdBu\': ("#67001f", "#053061"),\n+        \'RdGy\': ("#67001f", "#1a1a1a"),\n+        \'RdYlBu\': ("#a50026", "#313695"),\n+        \'RdYlGn\': ("#a50026", "#006837"),\n+        \'Spectral\': ("#9e0142", "#5e4fa2"),\n+    }\n+\n+    def __init__(self):\n+        self.brewer_colour_idx = 0\n+\n+    def rgb_from_hex(self, hexstr):\n+        # http://stackoverflow.com/questions/4296249/how-do-i-convert-a-hex-triplet-to-an-rgb-tuple-and-b'..b'ation\')\n+\n+    parser.add_argument(\'--jbrowse\', help=\'Folder containing a jbrowse release\')\n+    parser.add_argument(\'--outdir\', help=\'Output directory\', default=\'out\')\n+    parser.add_argument(\'--version\', \'-V\', action=\'version\', version="%(prog)s 0.8.0")\n+    args = parser.parse_args()\n+\n+    tree = ET.parse(args.xml.name)\n+    root = tree.getroot()\n+\n+    # This should be done ASAP\n+    GALAXY_INFRASTRUCTURE_URL = root.find(\'metadata/galaxyUrl\').text\n+    # Sometimes this comes as `localhost` without a protocol\n+    if not GALAXY_INFRASTRUCTURE_URL.startswith(\'http\'):\n+        # so we\'ll prepend `http://` and hope for the best. Requests *should*\n+        # be GET and not POST so it should redirect OK\n+        GALAXY_INFRASTRUCTURE_URL = \'http://\' + GALAXY_INFRASTRUCTURE_URL\n+\n+    jc = JbrowseConnector(\n+        jbrowse=args.jbrowse,\n+        outdir=args.outdir,\n+        genomes=[\n+            {\n+                \'path\': os.path.realpath(x.attrib[\'path\']),\n+                \'meta\': metadata_from_node(x.find(\'metadata\')),\n+                \'label\': x.attrib[\'label\']\n+            }\n+            for x in root.findall(\'metadata/genomes/genome\')\n+        ]\n+    )\n+\n+    default_session_data = {\n+        \'visibility\': {\n+            \'default_on\': [],\n+            \'default_off\': [],\n+        },\n+        \'style\': {},\n+        \'style_labels\': {}\n+    }\n+\n+    # TODO add metadata to tracks\n+    for track in root.findall(\'tracks/track\'):\n+        track_conf = {}\n+        track_conf[\'trackfiles\'] = []\n+\n+        trackfiles = track.findall(\'files/trackFile\')\n+        if trackfiles:\n+            for x in track.findall(\'files/trackFile\'):\n+                if trackfiles:\n+                    metadata = metadata_from_node(x.find(\'metadata\'))\n+\n+                    track_conf[\'trackfiles\'].append((\n+                        os.path.realpath(x.attrib[\'path\']),\n+                        x.attrib[\'ext\'],\n+                        x.attrib[\'label\'],\n+                        metadata\n+                    ))\n+        else:\n+            # For tracks without files (rest, sparql)\n+            track_conf[\'trackfiles\'].append((\n+                \'\',  # N/A, no path for rest or sparql\n+                track.attrib[\'format\'],\n+                track.find(\'options/label\').text,\n+                {}\n+            ))\n+\n+        track_conf[\'category\'] = track.attrib[\'cat\']\n+        track_conf[\'format\'] = track.attrib[\'format\']\n+        track_conf[\'style\'] = {item.tag: parse_style_conf(item) for item in track.find(\'options/style\')}\n+\n+        track_conf[\'style\'] = {item.tag: parse_style_conf(item) for item in track.find(\'options/style\')}\n+\n+        track_conf[\'style_labels\'] = {item.tag: parse_style_conf(item) for item in track.find(\'options/style_labels\')}\n+\n+        track_conf[\'conf\'] = etree_to_dict(track.find(\'options\'))\n+        keys = jc.process_annotations(track_conf)\n+\n+        for key in keys:\n+            default_session_data[\'visibility\'][track.attrib.get(\'visibility\', \'default_off\')].append(key)\n+\n+        default_session_data[\'style\'][key] = track_conf[\'style\']  # TODO do we need this anymore?\n+        default_session_data[\'style_labels\'][key] = track_conf[\'style_labels\']\n+\n+    default_session_data[\'defaultLocation\'] = root.find(\'metadata/general/defaultLocation\').text\n+    default_session_data[\'session_name\'] = root.find(\'metadata/general/session_name\').text\n+\n+    general_data = {\n+        \'analytics\': root.find(\'metadata/general/analytics\').text,\n+        \'primary_color\': root.find(\'metadata/general/primary_color\').text,\n+        \'secondary_color\': root.find(\'metadata/general/secondary_color\').text,\n+        \'tertiary_color\': root.find(\'metadata/general/tertiary_color\').text,\n+        \'quaternary_color\': root.find(\'metadata/general/quaternary_color\').text,\n+        \'font_size\': root.find(\'metadata/general/font_size\').text,\n+    }\n+\n+    jc.add_default_session(default_session_data)\n+    jc.add_general_configuration(general_data)\n+    jc.text_index()\n+\n'
b
diff -r 247e17ce504b -r 1d86925dbb4c abjbrowse2.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/abjbrowse2.xml Mon Jan 22 11:52:19 2024 +0000
[
b'@@ -0,0 +1,1295 @@\n+<tool id="jbrowse2" name="JBrowse2" version="@TOOL_VERSION@+@WRAPPER_VERSION@">\n+    <description>genome browser</description>\n+    <macros>\n+        <import>macros.xml</import>\n+    </macros>\n+    <edam_topics>\n+        <edam_topic>topic_3307</edam_topic>\n+        <edam_topic>topic_0092</edam_topic>\n+    </edam_topics>\n+    <edam_operations>\n+        <edam_operation>operation_0573</edam_operation>\n+        <edam_operation>operation_0564</edam_operation>\n+    </edam_operations>\n+    <xrefs>\n+        <xref type="bio.tools">jbrowse</xref>\n+    </xrefs>\n+    <expand macro="requirements"/>\n+    <version_command>python \'${__tool_directory__}/jbrowse2.py\' --version</version_command>\n+    <command detect_errors="aggressive"><![CDATA[\n+mkdir -p $output.files_path &&\n+#if $action.action_select != "create":\n+    cp -R $action.update_jbrowse.extra_files_path/data $output.files_path/data &&\n+#end if\n+\n+## Copy the XML file into the directory, mostly for debugging\n+## but nice if users want to reproduce locally\n+cp $trackxml $output.files_path/galaxy.xml &&\n+\n+export JBROWSE2_SOURCE_DIR=\\$(dirname \\$(which jbrowse))/../opt/jbrowse2  &&\n+\n+## Once that\'s done, we run the python script to handle the real work\n+python \'$__tool_directory__/jbrowse2.py\'\n+\n+--jbrowse \\${JBROWSE2_SOURCE_DIR}\n+\n+--outdir $output.files_path\n+$trackxml &&\n+\n+cp $output.files_path/index.html $output;\n+\n+## Ugly testing hack since I cannot get <extra_files> to test the files I want to test. Hmph.\n+#if str($uglyTestingHack) == "enabled":\n+    cp $trackxml $output\n+#end if\n+  ]]></command>\n+  <configfiles>\n+      <configfile name="trackxml"><![CDATA[<?xml version="1.0"?>\n+<root>\n+    <metadata>\n+        <genomes>\n+            #if str($reference_genome.genome_type_select) == "indexed":\n+              <genome path="${reference_genome.genomes.fields.path}" label="${reference_genome.genomes.fields.name}">\n+                  <metadata />\n+              </genome>s\n+            #else\n+              <genome path="$reference_genome.genome" label="${reference_genome.genome.element_identifier}">\n+                <metadata>\n+                  <dataset id="${__app__.security.encode_id($reference_genome.genome.id)}" hid="${reference_genome.genome.hid}"\n+                      size="${reference_genome.genome.get_size(nice_size=True)}"\n+                      edam_format="${reference_genome.genome.datatype.edam_format}"\n+                      file_ext="${reference_genome.genome.ext}" />\n+                  <history id="${__app__.security.encode_id($reference_genome.genome.history_id)}"\n+                      #if $reference_genome.genome.history.user:\n+                      user_email="${reference_genome.genome.history.user.email}"\n+                      user_id="${reference_genome.genome.history.user_id}"\n+                      display_name="${reference_genome.genome.history.get_display_name()}"/>\n+                      #else\n+                      user_email="anonymous"\n+                      user_id="-1"\n+                      display_name="Unnamed History"/>\n+                      #end if\n+                  <metadata\n+                      #for (key, value) in $reference_genome.genome.get_metadata().items():\n+                      #if "_types" not in $key:\n+                        #if isinstance($value, list):\n+                          #set value_str = "[%s]" % \',\'.join([str(val) for val in value])\n+                          ${key}="$value_str"\n+                        #else\n+                          ${key}="${value}"\n+                        #end if\n+                      #end if\n+                      #end for\n+                      />\n+                  <tool\n+                      tool_id="${reference_genome.genome.creating_job.tool_id}"\n+                      tool_version="${reference_genome.genome.creating_job.tool_version}"\n+                      />\n+                </metadata>\n+              </genome>\n+            #end if\n+        </genomes>\n+        <gen'..b've upon this and provide more colour\n+scales. The Opacity option maps the highest scoring features to full\n+opacity, and everything else to lower ones.\n+\n+BAM Pileups\n+~~~~~~~~~~~\n+\n+We support BAM files and can automatically generate SNP tracks based on\n+that bam data.\n+\n+.. image:: bam.png\n+\n+This is *strongly discouraged* for high coverage density datasets.\n+Unfortunately there are no other configuration options exposed for bam\n+files.\n+\n+BlastXML\n+~~~~~~~~\n+\n+.. image:: blast.png\n+\n+JiG now supports both blastn and blastp datasets. JiG internally uses a\n+blastXML to gapped GFF3 tool to convert your blastxml datasets into a\n+format amenable to visualization in JBrowse. This tool is also\n+available separately from the IUC on the toolshed.\n+\n+**Minimum Gap Size** reflects how long a gap must be before it becomes a\n+real gap in the processed gff3 file. In the picture above, various sizes\n+of gaps can be seen. If the minimum gap size was set much higher, say\n+100nt, many of the smaller gaps would disappear, and the features on\n+both sides would be merged into one, longer feature. This setting is\n+inversely proportional to runtime and output file size. *Do not set this\n+to a low value for large datasets*. By setting this number lower, you\n+will have extremely large outputs and extremely long runtimes. The\n+default was configured based off of the author\'s experience, but the\n+author only works on small viruses. It is *strongly* recommended that\n+you filter your blast results before display, e.g. picking out the top\n+10 hits or so.\n+\n+**Protein blast search** option merely informs underlying tools that\n+they should adjust feature locations by 3x.\n+\n+Styling Options\n+^^^^^^^^^^^^^^^\n+\n+Please see the styling options for GFF3 datasets, they are identical.\n+\n+Feature Score Scaling & Coloring Options\n+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n+\n+Please see the score scaling and colouring options for GFF3 datasets,\n+they are identical. Remember to set your score scaling to "blast" method\n+if you do use it.\n+\n+Bigwig XY\n+~~~~~~~~~\n+\n+.. image:: bigwig.png\n+\n+**XYPlot**\n+\n+BigWig tracks can be displayed as a "density" plot which is continuous\n+line which varies in colour, or as an "XYplot." XYplots are preferable\n+for users to visually identify specific features in a bigwig track,\n+however density tracks are more visually compact.\n+\n+**Variance Band** is an option available to XYPlots, and can be seen in\n+the third and fourth tracks in the above picture. This overlays a mean\n+line, and 1 and 2 standard deviation areas.\n+\n+**Track Scaling** is different from colour scaling, instead it\n+configures how the track behaves inside of JBrowse. **Autoscaling\n+globally** means that JBrowse will determine the minimum and maximum for\n+the track, and fix the bounds of the viewport to that. E.g. if your\n+track ranges from 1-1000, and the region you\'re currently zoomed to only\n+goes from 0-50, then the viewport range will still show 1-1000. This is\n+good for global genomic context. However you may wish to consider\n+**autoscaling locally** instead. In the example of a region which varies\n+from 0-50, autoscaling locally would cause the individual track\'s\n+viewport to re-adjust and show just the 0-50 region. If neither of these\n+options are palatable, you may manually hardcode the minimum and\n+maximums for the track to scale to.\n+\n+Colour Options\n+^^^^^^^^^^^^^^\n+\n+BigWig tracks have two colours in JBrowse, a positive and a negative\n+colour.\n+\n+As always you may manually choose a colour, or let JiG choose for you.\n+\n+One of the more interesting options is the **Bicolor pivot**. This\n+option allows you to control the point at which JBrowse switches from\n+the positive colour to the negative. In the above graphic, you can see\n+this has been configured to "mean" for the first two (orange and blue)\n+tracks.\n+\n+VCFs/SNPs\n+~~~~~~~~~\n+\n+These tracks do not support any special configuration.\n+\n+@ATTRIBUTION@\n+]]></help>\n+    <expand macro="citations"/>\n+</tool>\n+\n'
b
diff -r 247e17ce504b -r 1d86925dbb4c jbrowse2.py
--- a/jbrowse2.py Sat Jan 20 10:04:08 2024 +0000
+++ b/jbrowse2.py Mon Jan 22 11:52:19 2024 +0000
[
@@ -1175,7 +1175,9 @@
         refName = None
         if data.get("defaultLocation", ""):
             ddl = data["defaultLocation"]
-            loc_match = re.search(r"^(\w.+):(\d+)\.+(\d+)$", ddl)
+            loc_match = re.search(
+                r"^([^:]+):(\d+)\.+(\d+)$", ddl
+            )  # was re.search(r"^(\w.+):(\d+)\.+(\d+)$"
             if loc_match:
                 refName = loc_match.group(1)
                 start = int(loc_match.group(2))
@@ -1190,7 +1192,7 @@
             start = 0
             end = 10000  # Booh, hard coded! waiting for https://github.com/GMOD/jbrowse-components/issues/2708
             logging.info(
-                "@@@ no defaultlocation found for default session - suggest adding one!"
+                "@@@ no defaultlocation found for default session - please add one"
             )
 
         if refName is not None:
@@ -1211,7 +1213,7 @@
             )
         else:
             logging.info(
-                "@@@ no assembly name found default session - suggest adding one!"
+                "@@@ no contig name found for default session - please add one!"
             )
         session_name = data.get("session_name", "New session")
         for key, value in mapped_chars.items():
b
diff -r 247e17ce504b -r 1d86925dbb4c macros.xml
--- a/macros.xml Sat Jan 20 10:04:08 2024 +0000
+++ b/macros.xml Mon Jan 22 11:52:19 2024 +0000
[
@@ -28,7 +28,6 @@
     <token name="@ATTRIBUTION@"><![CDATA[
 **Attribution**
 This Galaxy tool relies on the JBrowse2, maintained by the GMOD Community. The Galaxy wrapper is developed by the IUC
-This xml currently fails silently when profile=22.05 is set.
 ]]>
     </token>
     <xml name="genome_selector"
@@ -139,7 +138,7 @@
 
     <xml name="general_options">
         <section name="jbgen" title="General JBrowse Options [Advanced]" expanded="false">
-            <param label="Default location" type="text" name="defaultLocation" value="" help="Initial location to be shown for users who have never visited the browser before. Example: 'ctgA:1234..5678'"/>
+            <param label="Subset to display to new users" type="text" name="defaultLocation" value="" help="Initial subset to be shown for users who have never visited the browser before. Example: 'ctgA:1234..5678'"/>
             <param label="Session name" type="text" name="session_name" value="New session" help="Displayed at the top of the window"/>
             <param label="Enable analytics" help="Will send usage data to Google Analytics, see https://github.com/GMOD/jbrowse-components/issues/1166" name="enableAnalytics" type="boolean" checked="false" truevalue="true" falsevalue="false" />