Mercurial > repos > iuc > jbrowse
annotate jbrowse.py @ 4:d022577ff9cf draft
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit c7ca55fb4e5789f5a0f6fbc0ee7becd56e40e3df
author | iuc |
---|---|
date | Fri, 29 Jan 2016 13:27:30 -0500 |
parents | 7342f467507b |
children | ae9382cfb6ac |
rev | line source |
---|---|
0
2c9e5136b416
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 685773d3da40afdc4d14846d4935b3b0a100f56e
iuc
parents:
diff
changeset
|
1 #!/usr/bin/env python |
2c9e5136b416
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 685773d3da40afdc4d14846d4935b3b0a100f56e
iuc
parents:
diff
changeset
|
2 import os |
3 | 3 import copy |
0
2c9e5136b416
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 685773d3da40afdc4d14846d4935b3b0a100f56e
iuc
parents:
diff
changeset
|
4 import argparse |
2c9e5136b416
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 685773d3da40afdc4d14846d4935b3b0a100f56e
iuc
parents:
diff
changeset
|
5 import subprocess |
2c9e5136b416
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 685773d3da40afdc4d14846d4935b3b0a100f56e
iuc
parents:
diff
changeset
|
6 import hashlib |
3 | 7 import struct |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
8 import tempfile |
3 | 9 import shutil |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
10 import json |
3 | 11 from Bio.Data import CodonTable |
12 import xml.etree.ElementTree as ET | |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
13 import logging |
3 | 14 from collections import defaultdict |
15 logging.basicConfig(level=logging.INFO) | |
16 log = logging.getLogger('jbrowse') | |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
17 |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
18 |
3 | 19 class ColorScaling(object): |
20 | |
21 COLOR_FUNCTION_TEMPLATE = """ | |
22 function(feature, variableName, glyphObject, track) {{ | |
23 var score = {score}; | |
24 {opacity} | |
25 return 'rgba({red}, {green}, {blue}, ' + opacity + ')'; | |
26 }} | |
27 """ | |
28 | |
29 COLOR_FUNCTION_TEMPLATE_QUAL = """ | |
30 function(feature, variableName, glyphObject, track) {{ | |
31 var search_up = function self(sf, attr){{ | |
32 if(sf.get(attr) !== undefined){{ | |
33 return sf.get(attr); | |
34 }} | |
35 if(sf.parent() === undefined) {{ | |
36 return; | |
37 }}else{{ | |
38 return self(sf.parent(), attr); | |
39 }} | |
40 }}; | |
0
2c9e5136b416
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 685773d3da40afdc4d14846d4935b3b0a100f56e
iuc
parents:
diff
changeset
|
41 |
3 | 42 var search_down = function self(sf, attr){{ |
43 if(sf.get(attr) !== undefined){{ | |
44 return sf.get(attr); | |
45 }} | |
46 if(sf.children() === undefined) {{ | |
47 return; | |
48 }}else{{ | |
49 var kids = sf.children(); | |
50 for(var child_idx in kids){{ | |
51 var x = self(kids[child_idx], attr); | |
52 if(x !== undefined){{ | |
53 return x; | |
54 }} | |
55 }} | |
56 return; | |
57 }} | |
58 }}; | |
59 | |
60 var color = ({user_spec_color} || search_up(feature, 'color') || search_down(feature, 'color') || {auto_gen_color}); | |
61 var score = (search_up(feature, 'score') || search_down(feature, 'score')); | |
62 {opacity} | |
63 var result = /^#?([a-f\d]{{2}})([a-f\d]{{2}})([a-f\d]{{2}})$/i.exec(color); | |
64 var red = parseInt(result[1], 16); | |
65 var green = parseInt(result[2], 16); | |
66 var blue = parseInt(result[3], 16); | |
67 if(isNaN(opacity) || opacity < 0){{ opacity = 0; }} | |
68 return 'rgba(' + red + ',' + green + ',' + blue + ',' + opacity + ')'; | |
69 }} | |
70 """ | |
0
2c9e5136b416
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 685773d3da40afdc4d14846d4935b3b0a100f56e
iuc
parents:
diff
changeset
|
71 |
3 | 72 OPACITY_MATH = { |
73 'linear': """ | |
74 var opacity = (score - ({min})) / (({max}) - ({min})); | |
75 """, | |
76 'logarithmic': """ | |
77 var opacity = (score - ({min})) / (({max}) - ({min})); | |
78 opacity = Math.log10(opacity) + Math.log10({max}); | |
79 """, | |
80 'blast': """ | |
81 var opacity = 0; | |
82 if(score == 0.0) { | |
83 opacity = 1; | |
84 } else{ | |
85 opacity = (20 - Math.log10(score)) / 180; | |
86 } | |
87 """ | |
88 } | |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
89 |
3 | 90 BREWER_COLOUR_IDX = 0 |
91 BREWER_COLOUR_SCHEMES = [ | |
92 (166, 206, 227), | |
93 (31, 120, 180), | |
94 (178, 223, 138), | |
95 (51, 160, 44), | |
96 (251, 154, 153), | |
97 (227, 26, 28), | |
98 (253, 191, 111), | |
99 (255, 127, 0), | |
100 (202, 178, 214), | |
101 (106, 61, 154), | |
102 (255, 255, 153), | |
103 (177, 89, 40), | |
104 (228, 26, 28), | |
105 (55, 126, 184), | |
106 (77, 175, 74), | |
107 (152, 78, 163), | |
108 (255, 127, 0), | |
109 ] | |
110 | |
111 BREWER_DIVERGING_PALLETES = { | |
112 'BrBg': ("#543005", "#003c30"), | |
113 'PiYg': ("#8e0152", "#276419"), | |
114 'PRGn': ("#40004b", "#00441b"), | |
115 'PuOr': ("#7f3b08", "#2d004b"), | |
116 'RdBu': ("#67001f", "#053061"), | |
117 'RdGy': ("#67001f", "#1a1a1a"), | |
118 'RdYlBu': ("#a50026", "#313695"), | |
119 'RdYlGn': ("#a50026", "#006837"), | |
120 'Spectral': ("#9e0142", "#5e4fa2"), | |
121 } | |
122 | |
123 def __init__(self): | |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
124 self.brewer_colour_idx = 0 |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
125 |
3 | 126 def rgb_from_hex(self, hexstr): |
127 # http://stackoverflow.com/questions/4296249/how-do-i-convert-a-hex-triplet-to-an-rgb-tuple-and-back | |
128 return struct.unpack('BBB',hexstr.decode('hex')) | |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
129 |
3 | 130 def min_max_gff(self, gff_file): |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
131 min_val = None |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
132 max_val = None |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
133 with open(gff_file, 'r') as handle: |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
134 for line in handle: |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
135 try: |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
136 value = float(line.split('\t')[5]) |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
137 min_val = min(value, (min_val or value)) |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
138 max_val = max(value, (max_val or value)) |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
139 |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
140 if value < min_val: |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
141 min_val = value |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
142 |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
143 if value > max_val: |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
144 max_val = value |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
145 except Exception: |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
146 pass |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
147 return min_val, max_val |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
148 |
3 | 149 def hex_from_rgb(self, r, g, b): |
150 return '#%02x%02x%02x' % (r, g, b) | |
151 | |
152 def _get_colours(self): | |
153 r, g, b = self.BREWER_COLOUR_SCHEMES[self.brewer_colour_idx] | |
154 self.brewer_colour_idx += 1 | |
155 return r, g, b | |
156 | |
157 def parse_colours(self, track, trackFormat, gff3=None): | |
158 # Wiggle tracks have a bicolor pallete | |
159 trackConfig = {'style': {}} | |
160 if trackFormat == 'wiggle': | |
161 | |
162 trackConfig['style']['pos_color'] = track['wiggle']['color_pos'] | |
163 trackConfig['style']['neg_color'] = track['wiggle']['color_neg'] | |
164 | |
165 if trackConfig['style']['pos_color'] == '__auto__': | |
166 trackConfig['style']['neg_color'] = self.hex_from_rgb(*self._get_colours()) | |
167 trackConfig['style']['pos_color'] = self.hex_from_rgb(*self._get_colours()) | |
168 | |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
169 |
3 | 170 # Wiggle tracks can change colour at a specified place |
171 bc_pivot = track['wiggle']['bicolor_pivot'] | |
172 if bc_pivot not in ('mean', 'zero'): | |
173 # The values are either one of those two strings | |
174 # or a number | |
175 bc_pivot = float(bc_pivot) | |
176 trackConfig['bicolor_pivot'] = bc_pivot | |
177 elif 'scaling' in track: | |
178 if track['scaling']['method'] == 'ignore': | |
179 if track['scaling']['scheme']['color'] != '__auto__': | |
180 trackConfig['style']['color'] = track['scaling']['scheme']['color'] | |
181 else: | |
182 trackConfig['style']['color'] = self.hex_from_rgb(*self._get_colours()) | |
183 else: | |
184 # Scored method | |
185 algo = track['scaling']['algo'] | |
186 # linear, logarithmic, blast | |
187 scales = track['scaling']['scales'] | |
188 # type __auto__, manual (min, max) | |
189 scheme = track['scaling']['scheme'] | |
190 # scheme -> (type (opacity), color) | |
191 # ================================== | |
192 # GENE CALLS OR BLAST | |
193 # ================================== | |
194 if trackFormat == 'blast': | |
195 red, green, blue = self._get_colours() | |
196 color_function = self.COLOR_FUNCTION_TEMPLATE.format(**{ | |
197 'score': "feature._parent.get('score')", | |
198 'opacity': self.OPACITY_MATH['blast'], | |
199 'red': red, | |
200 'green': green, | |
201 'blue': blue, | |
202 }) | |
203 trackConfig['style']['color'] = color_function.replace('\n', '') | |
204 elif trackFormat == 'gene_calls': | |
205 # Default values, based on GFF3 spec | |
206 min_val = 0 | |
207 max_val = 1000 | |
208 # Get min/max and build a scoring function since JBrowse doesn't | |
209 if scales['type'] == 'automatic': | |
210 min_val, max_val = self.min_max_gff(gff3) | |
211 else: | |
212 min_val = scales['min'] | |
213 max_val = scales['max'] | |
214 | |
215 if scheme['color'] == '__auto__': | |
216 user_color = 'undefined' | |
217 auto_color = "'%s'" % self.hex_from_rgb(*self._get_colours()) | |
218 elif scheme['color'].startswith('#'): | |
219 user_color = "'%s'" % self.hex_from_rgb(*self.rgb_from_hex(scheme['color'][1:])) | |
220 auto_color = 'undefined' | |
221 else: | |
222 user_color = 'undefined' | |
223 auto_color = "'%s'" % self.hex_from_rgb(*self._get_colours()) | |
224 | |
225 color_function = self.COLOR_FUNCTION_TEMPLATE_QUAL.format(**{ | |
226 'opacity': self.OPACITY_MATH[algo].format(**{'max': max_val,'min': min_val}), | |
227 'user_spec_color': user_color, | |
228 'auto_gen_color': auto_color, | |
229 }) | |
230 | |
231 trackConfig['style']['color'] = color_function.replace('\n', '') | |
232 return trackConfig | |
233 | |
234 | |
235 def etree_to_dict(t): | |
236 d = {t.tag: {} if t.attrib else None} | |
237 children = list(t) | |
238 if children: | |
239 dd = defaultdict(list) | |
240 for dc in map(etree_to_dict, children): | |
241 for k, v in dc.iteritems(): | |
242 dd[k].append(v) | |
243 d = {t.tag: {k:v[0] if len(v) == 1 else v for k, v in dd.iteritems()}} | |
244 if t.attrib: | |
245 d[t.tag].update(('@' + k, v) for k, v in t.attrib.iteritems()) | |
246 if t.text: | |
247 text = t.text.strip() | |
248 if children or t.attrib: | |
249 if text: | |
250 d[t.tag]['#text'] = text | |
251 else: | |
252 d[t.tag] = text | |
253 return d | |
254 | |
255 | |
256 # score comes from feature._parent.get('score') or feature.get('score') | |
257 | |
258 INSTALLED_TO = os.path.dirname(os.path.realpath(__file__)) | |
259 | |
260 | |
261 class JbrowseConnector(object): | |
262 | |
263 def __init__(self, jbrowse, outdir, genomes, standalone=False, gencode=1): | |
264 self.TN_TABLE = { | |
265 'gff3': '--gff', | |
266 'gff': '--gff', | |
267 'bed': '--bed', | |
268 'genbank': '--gbk', | |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
269 } |
3 | 270 |
271 self.cs = ColorScaling() | |
272 self.jbrowse = jbrowse | |
273 self.outdir = outdir | |
274 self.genome_paths = genomes | |
275 self.standalone = standalone | |
276 self.gencode = gencode | |
277 | |
278 if standalone: | |
279 self.clone_jbrowse(self.jbrowse, self.outdir) | |
280 else: | |
281 try: | |
282 os.makedirs(self.outdir) | |
283 except OSError: | |
284 # Ignore if the folder exists | |
285 pass | |
286 | |
287 self.process_genomes() | |
288 self.update_gencode() | |
289 | |
290 def update_gencode(self): | |
291 table = CodonTable.unambiguous_dna_by_id[int(self.gencode)] | |
292 trackList = os.path.join(self.outdir, 'data', 'trackList.json') | |
293 with open(trackList, 'r') as handle: | |
294 trackListData = json.load(handle) | |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
295 |
3 | 296 trackListData['tracks'][0].update({ |
297 'codonStarts': table.start_codons, | |
298 'codonStops': table.stop_codons, | |
299 'codonTable': table.forward_table, | |
300 }) | |
301 | |
302 with open(trackList, 'w') as handle: | |
303 json.dump(trackListData, handle, indent=2) | |
304 | |
305 | |
306 def subprocess_check_call(self, command): | |
307 log.debug('cd %s && %s', self.outdir, ' '.join(command)) | |
308 subprocess.check_call(command, cwd=self.outdir) | |
309 | |
310 def _jbrowse_bin(self, command): | |
311 return os.path.realpath(os.path.join(self.jbrowse, 'bin', command)) | |
312 | |
313 def process_genomes(self): | |
314 for genome_path in self.genome_paths: | |
315 self.subprocess_check_call([ | |
316 'perl', self._jbrowse_bin('prepare-refseqs.pl'), | |
317 '--fasta', genome_path]) | |
318 | |
319 def _add_json(self, json_data): | |
320 if len(json_data.keys()) == 0: | |
321 return | |
322 | |
323 tmp = tempfile.NamedTemporaryFile(delete=False) | |
324 tmp.write(json.dumps(json_data)) | |
325 tmp.close() | |
326 cmd = ['perl', self._jbrowse_bin('add-track-json.pl'), tmp.name, | |
327 os.path.join('data', 'trackList.json')] | |
328 self.subprocess_check_call(cmd) | |
329 os.unlink(tmp.name) | |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
330 |
3 | 331 def _add_track_json(self, json_data): |
332 if len(json_data.keys()) == 0: | |
333 return | |
334 | |
335 tmp = tempfile.NamedTemporaryFile(delete=False) | |
336 tmp.write(json.dumps(json_data)) | |
337 tmp.close() | |
338 cmd = ['perl', self._jbrowse_bin('add-track-json.pl'), tmp.name, | |
339 os.path.join('data', 'trackList.json')] | |
340 self.subprocess_check_call(cmd) | |
341 os.unlink(tmp.name) | |
342 | |
343 | |
344 def _blastxml_to_gff3(self, xml, min_gap=10): | |
345 gff3_unrebased = tempfile.NamedTemporaryFile(delete=False) | |
346 cmd = ['python', os.path.join(INSTALLED_TO, 'blastxml_to_gapped_gff3.py'), | |
347 '--trim', '--trim_end', '--min_gap', str(min_gap), xml] | |
348 log.debug('cd %s && %s > %s', self.outdir, ' '.join(cmd), gff3_unrebased.name) | |
349 subprocess.check_call(cmd, cwd=self.outdir, stdout=gff3_unrebased) | |
350 gff3_unrebased.close() | |
351 return gff3_unrebased.name | |
352 | |
353 def add_blastxml(self, data, trackData, blastOpts, **kwargs): | |
354 gff3 = self._blastxml_to_gff3(data, min_gap=blastOpts['min_gap']) | |
0
2c9e5136b416
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 685773d3da40afdc4d14846d4935b3b0a100f56e
iuc
parents:
diff
changeset
|
355 |
3 | 356 if 'parent' in blastOpts: |
357 gff3_rebased = tempfile.NamedTemporaryFile(delete=False) | |
358 cmd = ['python', os.path.join(INSTALLED_TO, 'gff3_rebase.py')] | |
359 if blastOpts.get('protein', 'false') == 'true': | |
360 cmd.append('--protein2dna') | |
361 cmd.extend([os.path.realpath(blastOpts['parent']), gff3]) | |
362 log.debug('cd %s && %s > %s', self.outdir, ' '.join(cmd), gff3_rebased.name) | |
363 subprocess.check_call(cmd, cwd=self.outdir, stdout=gff3_rebased) | |
364 gff3_rebased.close() | |
365 | |
366 # Replace original gff3 file | |
367 shutil.copy(gff3_rebased.name, gff3) | |
368 os.unlink(gff3_rebased.name) | |
369 | |
370 config = { | |
371 'glyph': 'JBrowse/View/FeatureGlyph/Segments', | |
372 "category": trackData['category'], | |
373 } | |
374 | |
375 clientConfig = trackData['style'] | |
376 | |
377 cmd = ['perl', self._jbrowse_bin('flatfile-to-json.pl'), | |
378 '--gff', gff3, | |
379 '--trackLabel', trackData['label'], | |
380 '--key', trackData['key'], | |
381 '--clientConfig', json.dumps(clientConfig), | |
382 '--config', json.dumps(config), | |
383 '--trackType', 'JBrowse/View/Track/CanvasFeatures' | |
384 ] | |
385 | |
386 self.subprocess_check_call(cmd) | |
387 os.unlink(gff3) | |
388 | |
389 def add_bigwig(self, data, trackData, wiggleOpts, **kwargs): | |
390 dest = os.path.join('data', 'raw', trackData['label'] + '.bw') | |
391 cmd = ['ln', data, dest] | |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
392 self.subprocess_check_call(cmd) |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
393 |
3 | 394 trackData.update({ |
395 "urlTemplate": os.path.join('..', dest), | |
396 "storeClass": "JBrowse/Store/SeqFeature/BigWig", | |
397 "type": "JBrowse/View/Track/Wiggle/Density", | |
398 }) | |
399 | |
400 trackData['type'] = wiggleOpts['type'] | |
401 trackData['variance_band'] = True if wiggleOpts['variance_band'] == 'true' else False | |
402 | |
403 if 'min' in wiggleOpts and 'max' in wiggleOpts: | |
404 trackData['min_score'] = wiggleOpts['min'] | |
405 trackData['max_score'] = wiggleOpts['max'] | |
406 else: | |
407 trackData['autoscale'] = wiggleOpts.get('autoscale', 'local') | |
408 | |
409 self._add_track_json(trackData) | |
410 | |
411 def add_bam(self, data, trackData, bamOpts, bam_index=None, **kwargs): | |
412 dest = os.path.join('data', 'raw', trackData['label'] + '.bam') | |
413 cmd = ['ln', '-s', os.path.realpath(data), dest] | |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
414 self.subprocess_check_call(cmd) |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
415 |
3 | 416 cmd = ['ln', '-s', os.path.realpath(bam_index), dest + '.bai'] |
417 self.subprocess_check_call(cmd) | |
418 | |
419 trackData.update({ | |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
420 "urlTemplate": os.path.join('..', dest), |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
421 "type": "JBrowse/View/Track/Alignments2", |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
422 "storeClass": "JBrowse/Store/SeqFeature/BAM", |
3 | 423 }) |
424 | |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
425 |
3 | 426 self._add_track_json(trackData) |
427 | |
428 if bamOpts.get('auto_snp', 'false') == 'true': | |
429 trackData2 = copy.copy(trackData) | |
430 trackData2.update({ | |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
431 "type": "JBrowse/View/Track/SNPCoverage", |
3 | 432 "key": trackData['key'] + " - SNPs/Coverage", |
433 "label": trackData['label'] + "_autosnp", | |
434 }) | |
435 self._add_track_json(trackData2) | |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
436 |
3 | 437 def add_vcf(self, data, trackData, vcfOpts={}, **kwargs): |
438 dest = os.path.join('data', 'raw', trackData['label'] + '.vcf') | |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
439 # ln? |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
440 cmd = ['ln', '-s', data, dest] |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
441 self.subprocess_check_call(cmd) |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
442 cmd = ['bgzip', dest] |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
443 self.subprocess_check_call(cmd) |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
444 cmd = ['tabix', '-p', 'vcf', dest + '.gz'] |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
445 self.subprocess_check_call(cmd) |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
446 |
3 | 447 trackData.update({ |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
448 "urlTemplate": os.path.join('..', dest + '.gz'), |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
449 "type": "JBrowse/View/Track/HTMLVariants", |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
450 "storeClass": "JBrowse/Store/SeqFeature/VCFTabix", |
3 | 451 }) |
452 self._add_track_json(trackData) | |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
453 |
3 | 454 def add_features(self, data, format, trackData, gffOpts, **kwargs): |
455 cmd = [ | |
456 'perl', self._jbrowse_bin('flatfile-to-json.pl'), | |
457 self.TN_TABLE.get(format, 'gff'), | |
458 data, | |
459 '--trackLabel', trackData['label'], | |
460 '--trackType', 'JBrowse/View/Track/CanvasFeatures', | |
461 '--key', trackData['key'] | |
462 ] | |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
463 |
3 | 464 config = copy.copy(trackData) |
465 clientConfig = trackData['style'] | |
466 del config['style'] | |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
467 |
3 | 468 if 'match' in gffOpts: |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
469 config['glyph'] = 'JBrowse/View/FeatureGlyph/Segments' |
3 | 470 cmd += ['--type', gffOpts['match']] |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
471 |
3 | 472 cmd += ['--clientConfig', json.dumps(clientConfig), |
473 '--trackType', 'JBrowse/View/Track/CanvasFeatures' | |
474 ] | |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
475 |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
476 cmd.extend(['--config', json.dumps(config)]) |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
477 |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
478 self.subprocess_check_call(cmd) |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
479 |
3 | 480 |
481 def process_annotations(self, track): | |
482 outputTrackConfig = { | |
483 'style': { | |
484 'label': track['style'].get('label', 'description'), | |
485 'className': track['style'].get('className', 'feature'), | |
486 'description': track['style'].get('description', ''), | |
487 }, | |
488 'category': track['category'], | |
489 } | |
490 | |
491 for i, (dataset_path, dataset_ext, track_human_label) in enumerate(track['trackfiles']): | |
492 log.info('Processing %s / %s', track['category'], track_human_label) | |
493 outputTrackConfig['key'] = track_human_label | |
494 hashData = [dataset_path, track_human_label, track['category']] | |
495 outputTrackConfig['label'] = hashlib.md5('|'.join(hashData)).hexdigest() + '_%s' % i | |
496 | |
497 # Colour parsing is complex due to different track types having | |
498 # different colour options. | |
499 colourOptions = self.cs.parse_colours(track['conf']['options'], track['format'], gff3=dataset_path) | |
500 # This used to be done with a dict.update() call, however that wiped out any previous style settings... | |
501 for key in colourOptions: | |
502 if key == 'style': | |
503 for subkey in colourOptions['style']: | |
504 outputTrackConfig['style'][subkey] = colourOptions['style'][subkey] | |
505 else: | |
506 outputTrackConfig[key] = colourOptions[key] | |
507 | |
508 if dataset_ext in ('gff', 'gff3', 'bed'): | |
509 self.add_features(dataset_path, dataset_ext, outputTrackConfig, | |
510 track['conf']['options']['gff']) | |
511 elif dataset_ext == 'bigwig': | |
512 self.add_bigwig(dataset_path, outputTrackConfig, | |
513 track['conf']['options']['wiggle']) | |
514 elif dataset_ext == 'bam': | |
515 real_indexes = track['conf']['options']['pileup']['bam_indices']['bam_index'] | |
516 if not isinstance(real_indexes, list): | |
517 # <bam_indices> | |
518 # <bam_index>/path/to/a.bam.bai</bam_index> | |
519 # </bam_indices> | |
520 # | |
521 # The above will result in the 'bam_index' key containing a | |
522 # string. If there are two or more indices, the container | |
523 # becomes a list. Fun! | |
524 real_indexes = [real_indexes] | |
525 | |
526 self.add_bam(dataset_path, outputTrackConfig, | |
527 track['conf']['options']['pileup'], | |
528 bam_index=real_indexes[i]) | |
529 elif dataset_ext == 'blastxml': | |
530 self.add_blastxml(dataset_path, outputTrackConfig, track['conf']['options']['blast']) | |
531 elif dataset_ext == 'vcf': | |
532 self.add_vcf(dataset_path, outputTrackConfig) | |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
533 |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
534 def clone_jbrowse(self, jbrowse_dir, destination): |
3 | 535 """Clone a JBrowse directory into a destination directory. |
536 """ | |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
537 # JBrowse seems to have included some bad symlinks, cp ignores bad symlinks |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
538 # unlike copytree |
3 | 539 cmd = ['cp', '-r', os.path.join(jbrowse_dir, '.'), destination] |
540 log.debug(' '.join(cmd)) | |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
541 subprocess.check_call(cmd) |
3 | 542 cmd = ['mkdir', '-p', os.path.join(destination, 'data', 'raw')] |
543 log.debug(' '.join(cmd)) | |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
544 subprocess.check_call(cmd) |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
545 |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
546 # http://unix.stackexchange.com/a/38691/22785 |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
547 # JBrowse releases come with some broken symlinks |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
548 cmd = ['find', destination, '-type', 'l', '-xtype', 'l', '-exec', 'rm', "'{}'", '+'] |
3 | 549 log.debug(' '.join(cmd)) |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
550 subprocess.check_call(cmd) |
0
2c9e5136b416
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 685773d3da40afdc4d14846d4935b3b0a100f56e
iuc
parents:
diff
changeset
|
551 |
2c9e5136b416
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 685773d3da40afdc4d14846d4935b3b0a100f56e
iuc
parents:
diff
changeset
|
552 |
2c9e5136b416
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 685773d3da40afdc4d14846d4935b3b0a100f56e
iuc
parents:
diff
changeset
|
553 if __name__ == '__main__': |
2c9e5136b416
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 685773d3da40afdc4d14846d4935b3b0a100f56e
iuc
parents:
diff
changeset
|
554 parser = argparse.ArgumentParser(description="", epilog="") |
3 | 555 parser.add_argument('xml', type=file, help='Track Configuration') |
0
2c9e5136b416
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 685773d3da40afdc4d14846d4935b3b0a100f56e
iuc
parents:
diff
changeset
|
556 |
2c9e5136b416
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 685773d3da40afdc4d14846d4935b3b0a100f56e
iuc
parents:
diff
changeset
|
557 parser.add_argument('--jbrowse', help='Folder containing a jbrowse release') |
2c9e5136b416
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 685773d3da40afdc4d14846d4935b3b0a100f56e
iuc
parents:
diff
changeset
|
558 parser.add_argument('--outdir', help='Output directory', default='out') |
3 | 559 parser.add_argument('--standalone', help='Standalone mode includes a copy of JBrowse', action='store_true') |
0
2c9e5136b416
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 685773d3da40afdc4d14846d4935b3b0a100f56e
iuc
parents:
diff
changeset
|
560 args = parser.parse_args() |
2c9e5136b416
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 685773d3da40afdc4d14846d4935b3b0a100f56e
iuc
parents:
diff
changeset
|
561 |
3 | 562 tree = ET.parse(args.xml.name) |
563 root = tree.getroot() | |
564 | |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
565 jc = JbrowseConnector( |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
566 jbrowse=args.jbrowse, |
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
567 outdir=args.outdir, |
3 | 568 genomes=[os.path.realpath(x.text) for x in root.findall('metadata/genomes/genome')], |
569 standalone=args.standalone, | |
570 gencode=root.find('metadata/gencode').text | |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
571 ) |
0
2c9e5136b416
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 685773d3da40afdc4d14846d4935b3b0a100f56e
iuc
parents:
diff
changeset
|
572 |
3 | 573 for track in root.findall('tracks/track'): |
574 track_conf = {} | |
575 track_conf['trackfiles'] = [ | |
576 (os.path.realpath(x.attrib['path']), x.attrib['ext'], x.attrib['label']) | |
577 for x in track.findall('files/trackFile') | |
578 ] | |
1
497c6bb3b717
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse commit 0887009a23d176b21536c9fd8a18c4fecc417d4f
iuc
parents:
0
diff
changeset
|
579 |
3 | 580 track_conf['category'] = track.attrib['cat'] |
581 track_conf['format'] = track.attrib['format'] | |
582 try: | |
583 # Only pertains to gff3 + blastxml. TODO? | |
584 track_conf['style'] = {t.tag: t.text for t in track.find('options/style')} | |
585 except TypeError, te: | |
586 track_conf['style'] = {} | |
587 pass | |
588 track_conf['conf'] = etree_to_dict(track.find('options')) | |
589 jc.process_annotations(track_conf) |