Mercurial > repos > iuc > jbrowse
diff jbrowse.py @ 8:ad4b9d7eae6a draft
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 9a243c616a4a3156347e38fdb5f35863ae5133f9
author | iuc |
---|---|
date | Tue, 29 Nov 2016 10:55:30 -0500 |
parents | ae9382cfb6ac |
children | 1a6d882d340d |
line wrap: on
line diff
--- a/jbrowse.py Sun Jun 26 10:50:15 2016 -0400 +++ b/jbrowse.py Tue Nov 29 10:55:30 2016 -0500 @@ -1,17 +1,19 @@ #!/usr/bin/env python -import os +import argparse import copy -import argparse -import subprocess import hashlib +import json +import logging +import os +import shutil import struct +import subprocess import tempfile -import shutil -import json +import xml.etree.ElementTree as ET +from collections import defaultdict + from Bio.Data import CodonTable -import xml.etree.ElementTree as ET -import logging -from collections import defaultdict + logging.basicConfig(level=logging.INFO) log = logging.getLogger('jbrowse') @@ -79,11 +81,11 @@ """, 'blast': """ var opacity = 0; - if(score == 0.0) {{ + if(score == 0.0) { opacity = 1; - }} else {{ + } else{ opacity = (20 - Math.log10(score)) / 180; - }} + } """ } @@ -125,7 +127,7 @@ def rgb_from_hex(self, hexstr): # http://stackoverflow.com/questions/4296249/how-do-i-convert-a-hex-triplet-to-an-rgb-tuple-and-back - return struct.unpack('BBB',hexstr.decode('hex')) + return struct.unpack('BBB', hexstr.decode('hex')) def min_max_gff(self, gff_file): min_val = None @@ -154,6 +156,31 @@ self.brewer_colour_idx += 1 return r, g, b + def parse_menus(self, track): + trackConfig = {'menuTemplate': [{}, {}, {}]} + + if 'menu' in track['menus']: + menu_list = [track['menus']['menu']] + if isinstance(track['menus']['menu'], list): + menu_list = track['menus']['menu'] + + for m in menu_list: + tpl = { + 'action': m['action'], + 'label': m.get('label', '{name}'), + 'iconClass': m.get('iconClass', 'dijitIconBookmark'), + } + if 'url' in m: + tpl['url'] = m['url'] + if 'content' in m: + tpl['content'] = m['content'] + if 'title' in m: + tpl['title'] = m['title'] + + trackConfig['menuTemplate'].append(tpl) + + return trackConfig + def parse_colours(self, track, trackFormat, gff3=None): # Wiggle tracks have a bicolor pallete trackConfig = {'style': {}} @@ -166,7 +193,6 @@ trackConfig['style']['neg_color'] = self.hex_from_rgb(*self._get_colours()) trackConfig['style']['pos_color'] = self.hex_from_rgb(*self._get_colours()) - # Wiggle tracks can change colour at a specified place bc_pivot = track['wiggle']['bicolor_pivot'] if bc_pivot not in ('mean', 'zero'): @@ -223,7 +249,7 @@ auto_color = "'%s'" % self.hex_from_rgb(*self._get_colours()) color_function = self.COLOR_FUNCTION_TEMPLATE_QUAL.format(**{ - 'opacity': self.OPACITY_MATH[algo].format(**{'max': max_val,'min': min_val}), + 'opacity': self.OPACITY_MATH[algo].format(**{'max': max_val, 'min': min_val}), 'user_spec_color': user_color, 'auto_gen_color': auto_color, }) @@ -240,14 +266,14 @@ for dc in map(etree_to_dict, children): for k, v in dc.iteritems(): dd[k].append(v) - d = {t.tag: {k:v[0] if len(v) == 1 else v for k, v in dd.iteritems()}} + d = {t.tag: {k: v[0] if len(v) == 1 else v for k, v in dd.iteritems()}} if t.attrib: d[t.tag].update(('@' + k, v) for k, v in t.attrib.iteritems()) if t.text: text = t.text.strip() if children or t.attrib: if text: - d[t.tag]['#text'] = text + d[t.tag]['#text'] = text else: d[t.tag] = text return d @@ -274,6 +300,7 @@ self.genome_paths = genomes self.standalone = standalone self.gencode = gencode + self.tracksToIndex = [] if standalone: self.clone_jbrowse(self.jbrowse, self.outdir) @@ -302,7 +329,6 @@ with open(trackList, 'w') as handle: json.dump(trackListData, handle, indent=2) - def subprocess_check_call(self, command): log.debug('cd %s && %s', self.outdir, ' '.join(command)) subprocess.check_call(command, cwd=self.outdir) @@ -316,11 +342,23 @@ 'perl', self._jbrowse_bin('prepare-refseqs.pl'), '--fasta', genome_path]) - # Generate name - # self.subprocess_check_call([ - # 'perl', self._jbrowse_bin('generate-names.pl'), - # '--hashBits', '16' - # ]) + def generate_names(self): + # Generate names + + args = [ + 'perl', self._jbrowse_bin('generate-names.pl'), + '--hashBits', '16' + ] + + tracks = ','.join(self.tracksToIndex) + + if tracks: + args += ['--tracks', tracks] + else: + # No tracks to index, index only the refseq + args += ['--tracks', 'DNA'] + + self.subprocess_check_call(args) def _add_json(self, json_data): @@ -343,7 +381,6 @@ self.subprocess_check_call(cmd) os.unlink(tmp.name) - def _blastxml_to_gff3(self, xml, min_gap=10): gff3_unrebased = tempfile.NamedTemporaryFile(delete=False) cmd = ['python', os.path.join(INSTALLED_TO, 'blastxml_to_gapped_gff3.py'), @@ -389,6 +426,9 @@ self.subprocess_check_call(cmd) os.unlink(gff3) + if blastOpts.get('index', 'false') == 'true': + self.tracksToIndex.append("%s" % trackData['label']) + def add_bigwig(self, data, trackData, wiggleOpts, **kwargs): dest = os.path.join('data', 'raw', trackData['label'] + '.bw') cmd = ['ln', data, dest] @@ -425,7 +465,6 @@ "storeClass": "JBrowse/Store/SeqFeature/BAM", }) - self._add_track_json(trackData) if bamOpts.get('auto_snp', 'false') == 'true': @@ -433,7 +472,7 @@ trackData2.update({ "type": "JBrowse/View/Track/SNPCoverage", "key": trackData['key'] + " - SNPs/Coverage", - "label": trackData['label'] + "_autosnp", + "label": trackData['label'] + "_autosnp", }) self._add_track_json(trackData2) @@ -468,7 +507,7 @@ clientConfig = trackData['style'] del config['style'] - if 'match' in gffOpts: + if 'match' in gffOpts: config['glyph'] = 'JBrowse/View/FeatureGlyph/Segments' cmd += ['--type', gffOpts['match']] @@ -488,12 +527,14 @@ self.subprocess_check_call(cmd) + if gffOpts.get('index', 'false') == 'true': + self.tracksToIndex.append("%s" % trackData['label']) def process_annotations(self, track): outputTrackConfig = { 'style': { - 'label': track['style'].get('label', 'description'), - 'className': track['style'].get('className', 'feature'), + 'label': track['style'].get('label', 'description'), + 'className': track['style'].get('className', 'feature'), 'description': track['style'].get('description', ''), }, 'category': track['category'], @@ -516,11 +557,14 @@ else: outputTrackConfig[key] = colourOptions[key] + menus = self.cs.parse_menus(track['conf']['options']) + outputTrackConfig.update(menus) + # import pprint; pprint.pprint(track) # import sys; sys.exit() if dataset_ext in ('gff', 'gff3', 'bed'): self.add_features(dataset_path, dataset_ext, outputTrackConfig, - track['conf']['options']['gff']) + track['conf']['options']['gff']) elif dataset_ext == 'bigwig': self.add_bigwig(dataset_path, outputTrackConfig, track['conf']['options']['wiggle']) @@ -645,14 +689,14 @@ try: # Only pertains to gff3 + blastxml. TODO? track_conf['style'] = {t.tag: t.text for t in track.find('options/style')} - except TypeError, te: + except TypeError: track_conf['style'] = {} pass track_conf['conf'] = etree_to_dict(track.find('options')) keys = jc.process_annotations(track_conf) - for key in keys: extra_data['visibility'][track.attrib.get('visibility', 'default_off')].append(key) jc.add_final_data(extra_data) + jc.generate_names()