Mercurial > repos > fubar > jbrowse2
comparison jbrowse2.py @ 19:bde6b1d09f7d draft
planemo upload for repository https://github.com/usegalaxy-eu/temporary-tools/tree/master/jbrowse2 commit 1290bf486bc55c02fecd0327de10a28655a18e81-dirty
author | fubar |
---|---|
date | Tue, 30 Jan 2024 06:05:03 +0000 |
parents | 4c201a3d4755 |
children | 39b717d934a8 |
comparison
equal
deleted
inserted
replaced
18:2e6c48910819 | 19:bde6b1d09f7d |
---|---|
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # change to accumulating all configuration for config.json based on the default from the clone | 2 # change to accumulating all configuration for config.json based on the default from the clone |
3 import argparse | 3 import argparse |
4 import binascii | 4 import binascii |
5 import datetime | 5 import datetime |
6 import hashlib | |
7 import json | 6 import json |
8 import logging | 7 import logging |
9 import os | 8 import os |
10 import re | 9 import re |
11 import shutil | 10 import shutil |
21 JB2VER = "v2.10.1" | 20 JB2VER = "v2.10.1" |
22 # version pinned for cloning | 21 # version pinned for cloning |
23 | 22 |
24 TODAY = datetime.datetime.now().strftime("%Y-%m-%d") | 23 TODAY = datetime.datetime.now().strftime("%Y-%m-%d") |
25 GALAXY_INFRASTRUCTURE_URL = None | 24 GALAXY_INFRASTRUCTURE_URL = None |
26 JB2REL = "v2.10.0" | 25 JB2REL = "v2.10.1" |
27 # version pinned for cloning | 26 # version pinned for cloning |
28 | 27 |
29 mapped_chars = { | 28 mapped_chars = { |
30 ">": "__gt__", | 29 ">": "__gt__", |
31 "<": "__lt__", | 30 "<": "__lt__", |
230 bc_pivot = float(bc_pivot) | 229 bc_pivot = float(bc_pivot) |
231 trackConfig["bicolor_pivot"] = bc_pivot | 230 trackConfig["bicolor_pivot"] = bc_pivot |
232 elif "scaling" in track: | 231 elif "scaling" in track: |
233 if track["scaling"]["method"] == "ignore": | 232 if track["scaling"]["method"] == "ignore": |
234 if track["scaling"]["scheme"]["color"] != "__auto__": | 233 if track["scaling"]["scheme"]["color"] != "__auto__": |
235 trackConfig["style"]["color"] = track["scaling"]["scheme"]["color"] | 234 trackConfig["style"]["color"] = track["scaling"]["scheme"][ |
235 "color" | |
236 ] | |
236 else: | 237 else: |
237 trackConfig["style"]["color"] = self.hex_from_rgb( | 238 trackConfig["style"]["color"] = self.hex_from_rgb( |
238 *self._get_colours() | 239 *self._get_colours() |
239 ) | 240 ) |
240 else: | 241 else: |
257 "red": red, | 258 "red": red, |
258 "green": green, | 259 "green": green, |
259 "blue": blue, | 260 "blue": blue, |
260 } | 261 } |
261 ) | 262 ) |
262 trackConfig["style"]["color"] = color_function.replace("\n", "") | 263 trackConfig["style"]["color"] = color_function.replace( |
264 "\n", "" | |
265 ) | |
263 elif trackFormat == "gene_calls": | 266 elif trackFormat == "gene_calls": |
264 # Default values, based on GFF3 spec | 267 # Default values, based on GFF3 spec |
265 min_val = 0 | 268 min_val = 0 |
266 max_val = 1000 | 269 max_val = 1000 |
267 # Get min/max and build a scoring function since JBrowse doesn't | 270 # Get min/max and build a scoring function since JBrowse doesn't |
268 if scales["type"] == "automatic" or scales["type"] == "__auto__": | 271 if ( |
272 scales["type"] == "automatic" | |
273 or scales["type"] == "__auto__" | |
274 ): | |
269 min_val, max_val = self.min_max_gff(gff3) | 275 min_val, max_val = self.min_max_gff(gff3) |
270 else: | 276 else: |
271 min_val = scales.get("min", 0) | 277 min_val = scales.get("min", 0) |
272 max_val = scales.get("max", 1000) | 278 max_val = scales.get("max", 1000) |
273 | 279 |
274 if scheme["color"] == "__auto__": | 280 if scheme["color"] == "__auto__": |
275 user_color = "undefined" | 281 user_color = "undefined" |
276 auto_color = "'%s'" % self.hex_from_rgb(*self._get_colours()) | 282 auto_color = "'%s'" % self.hex_from_rgb( |
283 *self._get_colours() | |
284 ) | |
277 elif scheme["color"].startswith("#"): | 285 elif scheme["color"].startswith("#"): |
278 user_color = "'%s'" % self.hex_from_rgb( | 286 user_color = "'%s'" % self.hex_from_rgb( |
279 *self.rgb_from_hex(scheme["color"][1:]) | 287 *self.rgb_from_hex(scheme["color"][1:]) |
280 ) | 288 ) |
281 auto_color = "undefined" | 289 auto_color = "undefined" |
282 else: | 290 else: |
283 user_color = "undefined" | 291 user_color = "undefined" |
284 auto_color = "'%s'" % self.hex_from_rgb(*self._get_colours()) | 292 auto_color = "'%s'" % self.hex_from_rgb( |
293 *self._get_colours() | |
294 ) | |
285 | 295 |
286 color_function = self.COLOR_FUNCTION_TEMPLATE_QUAL.format( | 296 color_function = self.COLOR_FUNCTION_TEMPLATE_QUAL.format( |
287 **{ | 297 **{ |
288 "opacity": self.OPACITY_MATH[algo].format( | 298 "opacity": self.OPACITY_MATH[algo].format( |
289 **{"max": max_val, "min": min_val} | 299 **{"max": max_val, "min": min_val} |
291 "user_spec_color": user_color, | 301 "user_spec_color": user_color, |
292 "auto_gen_color": auto_color, | 302 "auto_gen_color": auto_color, |
293 } | 303 } |
294 ) | 304 ) |
295 | 305 |
296 trackConfig["style"]["color"] = color_function.replace("\n", "") | 306 trackConfig["style"]["color"] = color_function.replace( |
307 "\n", "" | |
308 ) | |
297 return trackConfig | 309 return trackConfig |
298 | 310 |
299 | 311 |
300 def etree_to_dict(t): | 312 def etree_to_dict(t): |
301 if t is None: | 313 if t is None: |
334 return {} | 346 return {} |
335 | 347 |
336 for (key, value) in node.findall("dataset")[0].attrib.items(): | 348 for (key, value) in node.findall("dataset")[0].attrib.items(): |
337 metadata["dataset_%s" % key] = value | 349 metadata["dataset_%s" % key] = value |
338 | 350 |
339 for (key, value) in node.findall("history")[0].attrib.items(): | 351 if node.findall("history"): |
340 metadata["history_%s" % key] = value | 352 for (key, value) in node.findall("history")[0].attrib.items(): |
341 | 353 metadata["history_%s" % key] = value |
342 for (key, value) in node.findall("metadata")[0].attrib.items(): | 354 |
343 metadata["metadata_%s" % key] = value | 355 if node.findall("metadata"): |
344 | 356 for (key, value) in node.findall("metadata")[0].attrib.items(): |
345 for (key, value) in node.findall("tool")[0].attrib.items(): | 357 metadata["metadata_%s" % key] = value |
346 metadata["tool_%s" % key] = value | 358 # Additional Mappings applied: |
347 | 359 metadata[ |
348 # Additional Mappings applied: | 360 "dataset_edam_format" |
349 metadata[ | 361 ] = '<a target="_blank" href="http://edamontology.org/{0}">{1}</a>'.format( |
350 "dataset_edam_format" | 362 metadata["dataset_edam_format"], metadata["dataset_file_ext"] |
351 ] = '<a target="_blank" href="http://edamontology.org/{0}">{1}</a>'.format( | 363 ) |
352 metadata["dataset_edam_format"], metadata["dataset_file_ext"] | 364 metadata["history_user_email"] = '<a href="mailto:{0}">{0}</a>'.format( |
353 ) | 365 metadata["history_user_email"] |
354 metadata["history_user_email"] = '<a href="mailto:{0}">{0}</a>'.format( | 366 ) |
355 metadata["history_user_email"] | 367 metadata["hist_name"] = metadata["history_display_name"] |
356 ) | 368 metadata[ |
357 metadata["hist_name"] = metadata["history_display_name"] | 369 "history_display_name" |
358 metadata[ | 370 ] = '<a target="_blank" href="{galaxy}/history/view/{encoded_hist_id}">{hist_name}</a>'.format( |
359 "history_display_name" | 371 galaxy=GALAXY_INFRASTRUCTURE_URL, |
360 ] = '<a target="_blank" href="{galaxy}/history/view/{encoded_hist_id}">{hist_name}</a>'.format( | 372 encoded_hist_id=metadata["history_id"], |
361 galaxy=GALAXY_INFRASTRUCTURE_URL, | 373 hist_name=metadata["history_display_name"], |
362 encoded_hist_id=metadata["history_id"], | 374 ) |
363 hist_name=metadata["history_display_name"], | 375 if node.findall("tool"): |
364 ) | 376 for (key, value) in node.findall("tool")[0].attrib.items(): |
365 metadata[ | 377 metadata["tool_%s" % key] = value |
366 "tool_tool" | 378 metadata[ |
367 ] = '<a target="_blank" href="{galaxy}/datasets/{encoded_id}/show_params">{tool_id}</a>'.format( | 379 "tool_tool" |
368 galaxy=GALAXY_INFRASTRUCTURE_URL, | 380 ] = '<a target="_blank" href="{galaxy}/datasets/{encoded_id}/show_params">{tool_id}{tool_version}</a>'.format( |
369 encoded_id=metadata["dataset_id"], | 381 galaxy=GALAXY_INFRASTRUCTURE_URL, |
370 tool_id=metadata["tool_tool_id"], | 382 encoded_id=metadata.get("dataset_id", ""), |
371 # tool_version=metadata['tool_tool_version'], | 383 tool_id=metadata.get("tool_tool_id", ""), |
372 ) | 384 tool_version=metadata.get("tool_tool_version",""), |
385 ) | |
373 return metadata | 386 return metadata |
374 | 387 |
375 | 388 |
376 class JbrowseConnector(object): | 389 class JbrowseConnector(object): |
377 def __init__(self, outdir, genomes): | 390 def __init__(self, outdir, genomes): |
387 self.config_json_file = os.path.join(outdir, "config.json") | 400 self.config_json_file = os.path.join(outdir, "config.json") |
388 self.clone_jbrowse() | 401 self.clone_jbrowse() |
389 | 402 |
390 def subprocess_check_call(self, command, output=None): | 403 def subprocess_check_call(self, command, output=None): |
391 if output: | 404 if output: |
392 log.debug("cd %s && %s > %s", self.outdir, " ".join(command), output) | 405 log.debug( |
406 "cd %s && %s > %s", self.outdir, " ".join(command), output | |
407 ) | |
393 subprocess.check_call(command, cwd=self.outdir, stdout=output) | 408 subprocess.check_call(command, cwd=self.outdir, stdout=output) |
394 else: | 409 else: |
395 log.debug("cd %s && %s", self.outdir, " ".join(command)) | 410 log.debug("cd %s && %s", self.outdir, " ".join(command)) |
396 subprocess.check_call(command, cwd=self.outdir) | 411 subprocess.check_call(command, cwd=self.outdir) |
397 | 412 |
466 self.config_json["assemblies"] += assemblies | 481 self.config_json["assemblies"] += assemblies |
467 else: | 482 else: |
468 self.config_json["assemblies"] = assemblies | 483 self.config_json["assemblies"] = assemblies |
469 | 484 |
470 def make_assembly(self, fapath, gname): | 485 def make_assembly(self, fapath, gname): |
471 hashData = [ | 486 |
472 fapath, | 487 faname = gname + ".fa.gz" |
473 gname, | |
474 ] | |
475 hashData = "|".join(hashData).encode("utf-8") | |
476 ghash = hashlib.md5(hashData).hexdigest() | |
477 faname = ghash + ".fa.gz" | |
478 fadest = os.path.join(self.outdir, faname) | 488 fadest = os.path.join(self.outdir, faname) |
479 cmd = "bgzip -i -c %s -I %s.gzi > %s && samtools faidx %s" % ( | 489 cmd = "bgzip -i -c %s -I %s.gzi > %s && samtools faidx %s" % ( |
480 fapath, | 490 fapath, |
481 fadest, | 491 fadest, |
482 fadest, | 492 fadest, |
493 }, | 503 }, |
494 "gziLocation": { | 504 "gziLocation": { |
495 "uri": faname + ".gzi", | 505 "uri": faname + ".gzi", |
496 }, | 506 }, |
497 } | 507 } |
508 self.genome_sequence_adapter = adapter | |
498 trackDict = { | 509 trackDict = { |
499 "name": gname, | 510 "name": gname, |
500 "sequence": { | 511 "sequence": { |
501 "type": "ReferenceSequenceTrack", | 512 "type": "ReferenceSequenceTrack", |
502 "trackId": gname, | 513 "trackId": gname, |
602 """ | 613 """ |
603 mafPlugin = { | 614 mafPlugin = { |
604 "plugins": [ | 615 "plugins": [ |
605 { | 616 { |
606 "name": "MafViewer", | 617 "name": "MafViewer", |
607 "url": "https://unpkg.com/browse/jbrowse-plugin-mafviewer@1.0.6/dist/jbrowse-plugin-mafviewer.umd.production.min.js", | 618 "url": "https://unpkg.com/jbrowse-plugin-mafviewer/dist/jbrowse-plugin-mafviewer.umd.production.min.js" |
608 } | 619 } |
609 ] | 620 ] |
610 } | 621 } |
611 tId = trackData["label"] | 622 tId = trackData["label"] |
612 fname = "%s.bed" % tId | 623 fname = "%s.bed" % tId |
621 dest, | 632 dest, |
622 ] | 633 ] |
623 self.subprocess_check_call(cmd) | 634 self.subprocess_check_call(cmd) |
624 # Construct samples list | 635 # Construct samples list |
625 # We could get this from galaxy metadata, not sure how easily. | 636 # We could get this from galaxy metadata, not sure how easily. |
626 ps = subprocess.Popen(["grep", "^s [^ ]*", "-o", data], stdout=subprocess.PIPE) | 637 ps = subprocess.Popen( |
638 ["grep", "^s [^ ]*", "-o", data], stdout=subprocess.PIPE | |
639 ) | |
627 output = subprocess.check_output(("sort", "-u"), stdin=ps.stdout) | 640 output = subprocess.check_output(("sort", "-u"), stdin=ps.stdout) |
628 ps.wait() | 641 ps.wait() |
629 outp = output.decode("ascii") | 642 outp = output.decode("ascii") |
630 soutp = outp.split("\n") | 643 soutp = outp.split("\n") |
631 samp = [x.split("s ")[1] for x in soutp if x.startswith("s ")] | 644 samp = [x.split("s ")[1] for x in soutp if x.startswith("s ")] |
781 fname = "%s.bam" % trackData["label"] | 794 fname = "%s.bam" % trackData["label"] |
782 dest = "%s/%s" % (self.outdir, fname) | 795 dest = "%s/%s" % (self.outdir, fname) |
783 url = fname | 796 url = fname |
784 self.subprocess_check_call(["cp", data, dest]) | 797 self.subprocess_check_call(["cp", data, dest]) |
785 bloc = {"uri": url} | 798 bloc = {"uri": url} |
786 if bam_index is not None and os.path.exists(os.path.realpath(bam_index)): | 799 if bam_index is not None and os.path.exists( |
800 os.path.realpath(bam_index) | |
801 ): | |
787 # bai most probably made by galaxy and stored in galaxy dirs, need to copy it to dest | 802 # bai most probably made by galaxy and stored in galaxy dirs, need to copy it to dest |
788 self.subprocess_check_call( | 803 self.subprocess_check_call( |
789 ["cp", os.path.realpath(bam_index), dest + ".bai"] | 804 ["cp", os.path.realpath(bam_index), dest + ".bai"] |
790 ) | 805 ) |
791 else: | 806 else: |
792 # Can happen in exotic condition | 807 # Can happen in exotic condition |
793 # e.g. if bam imported as symlink with datatype=unsorted.bam, then datatype changed to bam | 808 # e.g. if bam imported as symlink with datatype=unsorted.bam, then datatype changed to bam |
794 # => no index generated by galaxy, but there might be one next to the symlink target | 809 # => no index generated by galaxy, but there might be one next to the symlink target |
795 # this trick allows to skip the bam sorting made by galaxy if already done outside | 810 # this trick allows to skip the bam sorting made by galaxy if already done outside |
796 if os.path.exists(os.path.realpath(data) + ".bai"): | 811 if os.path.exists(os.path.realpath(data) + ".bai"): |
797 self.symlink_or_copy(os.path.realpath(data) + ".bai", dest + ".bai") | 812 self.symlink_or_copy( |
813 os.path.realpath(data) + ".bai", dest + ".bai" | |
814 ) | |
798 else: | 815 else: |
799 log.warn("Could not find a bam index (.bai file) for %s", data) | 816 log.warn("Could not find a bam index (.bai file) for %s", data) |
800 trackDict = { | 817 trackDict = { |
801 "type": "AlignmentsTrack", | 818 "type": "AlignmentsTrack", |
802 "trackId": tId, | 819 "trackId": tId, |
821 style_json = self._prepare_track_style(trackDict) | 838 style_json = self._prepare_track_style(trackDict) |
822 trackDict["style"] = style_json | 839 trackDict["style"] = style_json |
823 self.tracksToAdd.append(trackDict) | 840 self.tracksToAdd.append(trackDict) |
824 self.trackIdlist.append(tId) | 841 self.trackIdlist.append(tId) |
825 | 842 |
843 def add_cram(self, data, trackData, cramOpts, cram_index=None, **kwargs): | |
844 tId = trackData["label"] | |
845 fname = "%s.cram" % trackData["label"] | |
846 dest = "%s/%s" % (self.outdir, fname) | |
847 url = fname | |
848 self.subprocess_check_call(["cp", data, dest]) | |
849 bloc = {"uri": url} | |
850 if cram_index is not None and os.path.exists( | |
851 os.path.realpath(cram_index) | |
852 ): | |
853 # most probably made by galaxy and stored in galaxy dirs, need to copy it to dest | |
854 self.subprocess_check_call( | |
855 ["cp", os.path.realpath(cram_index), dest + ".crai"] | |
856 ) | |
857 else: | |
858 # Can happen in exotic condition | |
859 # e.g. if bam imported as symlink with datatype=unsorted.bam, then datatype changed to bam | |
860 # => no index generated by galaxy, but there might be one next to the symlink target | |
861 # this trick allows to skip the bam sorting made by galaxy if already done outside | |
862 if os.path.exists(os.path.realpath(data) + ".crai"): | |
863 self.symlink_or_copy( | |
864 os.path.realpath(data) + ".crai", dest + ".crai" | |
865 ) | |
866 else: | |
867 log.warn( | |
868 "Could not find a cram index (.crai file) for %s", data | |
869 ) | |
870 trackDict = { | |
871 "type": "AlignmentsTrack", | |
872 "trackId": tId, | |
873 "name": trackData["name"], | |
874 "assemblyNames": [self.genome_name], | |
875 "adapter": { | |
876 "type": "CramAdapter", | |
877 "cramLocation": bloc, | |
878 "craiLocation": {"uri": fname + ".crai",}, | |
879 "sequenceAdapter": self.genome_sequence_adapter, | |
880 }, | |
881 "displays": [ | |
882 { | |
883 "type": "LinearAlignmentsDisplay", | |
884 "displayId": "%s-LinearAlignmentsDisplay" % tId, | |
885 }, | |
886 ], | |
887 } | |
888 style_json = self._prepare_track_style(trackDict) | |
889 trackDict["style"] = style_json | |
890 self.tracksToAdd.append(trackDict) | |
891 self.trackIdlist.append(tId) | |
892 | |
826 def add_vcf(self, data, trackData): | 893 def add_vcf(self, data, trackData): |
827 tId = trackData["label"] | 894 tId = trackData["label"] |
828 url = "%s/api/datasets/%s/display" % ( | 895 # url = "%s/api/datasets/%s/display" % ( |
829 self.giURL, | 896 # self.giURL, |
830 trackData["metadata"]["dataset_id"], | 897 # trackData["metadata"]["dataset_id"], |
831 ) | 898 # ) |
832 url = "%s.vcf.gz" % tId | 899 url = "%s.vcf.gz" % tId |
833 dest = "%s/%s" % (self.outdir, url) | 900 dest = "%s/%s" % (self.outdir, url) |
834 cmd = "bgzip -c %s > %s" % (data, dest) | 901 cmd = "bgzip -c %s > %s" % (data, dest) |
835 self.subprocess_popen(cmd) | 902 self.subprocess_popen(cmd) |
836 cmd = ["tabix", "-f", "-p", "vcf", dest] | 903 cmd = ["tabix", "-f", "-p", "vcf", dest] |
877 cmd = "jbrowse sort-gff %s | bgzip -c > %s.gz" % ( | 944 cmd = "jbrowse sort-gff %s | bgzip -c > %s.gz" % ( |
878 data, | 945 data, |
879 dest, | 946 dest, |
880 ) # "gff3sort.pl --precise '%s' | grep -v \"^$\" > '%s'" | 947 ) # "gff3sort.pl --precise '%s' | grep -v \"^$\" > '%s'" |
881 self.subprocess_popen(cmd) | 948 self.subprocess_popen(cmd) |
882 self.subprocess_check_call(["tabix", "-f", "-p", "gff", dest + ".gz"]) | 949 self.subprocess_check_call( |
950 ["tabix", "-f", "-p", "gff", dest + ".gz"] | |
951 ) | |
883 | 952 |
884 def _sort_bed(self, data, dest): | 953 def _sort_bed(self, data, dest): |
885 # Only index if not already done | 954 # Only index if not already done |
886 if not os.path.exists(dest): | 955 if not os.path.exists(dest): |
887 cmd = "sort -k1,1 -k2,2n %s | bgzip -c > %s" % (data, dest) | 956 cmd = "sort -k1,1 -k2,2n %s | bgzip -c > %s" % (data, dest) |
1083 "style": {}, | 1152 "style": {}, |
1084 } | 1153 } |
1085 | 1154 |
1086 outputTrackConfig["key"] = track_human_label | 1155 outputTrackConfig["key"] = track_human_label |
1087 | 1156 |
1088 # We add extra data to hash for the case of REST + SPARQL. | |
1089 if ( | |
1090 "conf" in track | |
1091 and "options" in track["conf"] | |
1092 and "url" in track["conf"]["options"] | |
1093 ): | |
1094 rest_url = track["conf"]["options"]["url"] | |
1095 else: | |
1096 rest_url = "" | |
1097 outputTrackConfig["trackset"] = track.get("trackset", {}) | 1157 outputTrackConfig["trackset"] = track.get("trackset", {}) |
1098 # I chose to use track['category'] instead of 'category' here. This | 1158 outputTrackConfig["label"] = "%s_%i_%s" % ( |
1099 # is intentional. This way re-running the tool on a different date | 1159 dataset_ext, |
1100 # will not generate different hashes and make comparison of outputs | 1160 i, |
1101 # much simpler. | |
1102 hashData = [ | |
1103 str(dataset_path), | |
1104 track_human_label, | 1161 track_human_label, |
1105 track["category"], | 1162 ) |
1106 rest_url, | |
1107 ] | |
1108 hashData = "|".join(hashData).encode("utf-8") | |
1109 outputTrackConfig["label"] = hashlib.md5(hashData).hexdigest() + "_%s" % i | |
1110 outputTrackConfig["metadata"] = extra_metadata | 1163 outputTrackConfig["metadata"] = extra_metadata |
1111 outputTrackConfig["name"] = track_human_label | 1164 outputTrackConfig["name"] = track_human_label |
1112 | 1165 |
1113 if dataset_ext in ("gff", "gff3"): | 1166 if dataset_ext in ("gff", "gff3"): |
1114 self.add_gff( | 1167 self.add_gff( |
1136 self.add_bigwig( | 1189 self.add_bigwig( |
1137 dataset_path, | 1190 dataset_path, |
1138 outputTrackConfig, | 1191 outputTrackConfig, |
1139 ) | 1192 ) |
1140 elif dataset_ext == "bam": | 1193 elif dataset_ext == "bam": |
1141 real_indexes = track["conf"]["options"]["pileup"]["bam_indices"][ | 1194 real_indexes = track["conf"]["options"]["pileup"][ |
1142 "bam_index" | 1195 "bam_indices" |
1143 ] | 1196 ]["bam_index"] |
1144 if not isinstance(real_indexes, list): | 1197 if not isinstance(real_indexes, list): |
1145 # <bam_indices> | |
1146 # <bam_index>/path/to/a.bam.bai</bam_index> | |
1147 # </bam_indices> | |
1148 # | |
1149 # The above will result in the 'bam_index' key containing a | |
1150 # string. If there are two or more indices, the container | |
1151 # becomes a list. Fun! | |
1152 real_indexes = [real_indexes] | 1198 real_indexes = [real_indexes] |
1153 | 1199 |
1154 self.add_bam( | 1200 self.add_bam( |
1155 dataset_path, | 1201 dataset_path, |
1156 outputTrackConfig, | 1202 outputTrackConfig, |
1157 track["conf"]["options"]["pileup"], | 1203 track["conf"]["options"]["pileup"], |
1158 bam_index=real_indexes[i], | 1204 bam_index=real_indexes[i], |
1205 ) | |
1206 elif dataset_ext == "cram": | |
1207 real_indexes = track["conf"]["options"]["cram"][ | |
1208 "cram_indices" | |
1209 ]["cram_index"] | |
1210 if not isinstance(real_indexes, list): | |
1211 real_indexes = [real_indexes] | |
1212 | |
1213 self.add_cram( | |
1214 dataset_path, | |
1215 outputTrackConfig, | |
1216 track["conf"]["options"]["cram"], | |
1217 cram_index=real_indexes[i], | |
1159 ) | 1218 ) |
1160 elif dataset_ext == "blastxml": | 1219 elif dataset_ext == "blastxml": |
1161 self.add_blastxml( | 1220 self.add_blastxml( |
1162 dataset_path, | 1221 dataset_path, |
1163 outputTrackConfig, | 1222 outputTrackConfig, |
1288 config_json = {} | 1347 config_json = {} |
1289 if self.config_json: | 1348 if self.config_json: |
1290 config_json.update(self.config_json) | 1349 config_json.update(self.config_json) |
1291 config_data = {} | 1350 config_data = {} |
1292 | 1351 |
1293 config_data["disableAnalytics"] = data.get("analytics", "false") == "true" | 1352 config_data["disableAnalytics"] = ( |
1353 data.get("analytics", "false") == "true" | |
1354 ) | |
1294 | 1355 |
1295 config_data["theme"] = { | 1356 config_data["theme"] = { |
1296 "palette": { | 1357 "palette": { |
1297 "primary": {"main": data.get("primary_color", "#0D233F")}, | 1358 "primary": {"main": data.get("primary_color", "#0D233F")}, |
1298 "secondary": {"main": data.get("secondary_color", "#721E63")}, | 1359 "secondary": {"main": data.get("secondary_color", "#721E63")}, |
1299 "tertiary": {"main": data.get("tertiary_color", "#135560")}, | 1360 "tertiary": {"main": data.get("tertiary_color", "#135560")}, |
1300 "quaternary": {"main": data.get("quaternary_color", "#FFB11D")}, | 1361 "quaternary": { |
1362 "main": data.get("quaternary_color", "#FFB11D") | |
1363 }, | |
1301 }, | 1364 }, |
1302 "typography": {"fontSize": int(data.get("font_size", 10))}, | 1365 "typography": {"fontSize": int(data.get("font_size", 10))}, |
1303 } | 1366 } |
1304 if not config_json.get("configuration", None): | 1367 if not config_json.get("configuration", None): |
1305 config_json["configuration"] = {} | 1368 config_json["configuration"] = {} |
1349 | 1412 |
1350 if __name__ == "__main__": | 1413 if __name__ == "__main__": |
1351 parser = argparse.ArgumentParser(description="", epilog="") | 1414 parser = argparse.ArgumentParser(description="", epilog="") |
1352 parser.add_argument("--xml", help="Track Configuration") | 1415 parser.add_argument("--xml", help="Track Configuration") |
1353 parser.add_argument("--outdir", help="Output directory", default="out") | 1416 parser.add_argument("--outdir", help="Output directory", default="out") |
1354 parser.add_argument("--version", "-V", action="version", version="%(prog)s 2.0.1") | 1417 parser.add_argument( |
1418 "--version", "-V", action="version", version="%(prog)s 2.0.1" | |
1419 ) | |
1355 args = parser.parse_args() | 1420 args = parser.parse_args() |
1356 | |
1357 tree = ET.parse(args.xml) | 1421 tree = ET.parse(args.xml) |
1358 root = tree.getroot() | 1422 root = tree.getroot() |
1359 | 1423 |
1360 # This should be done ASAP | 1424 # This should be done ASAP |
1361 GALAXY_INFRASTRUCTURE_URL = root.find("metadata/galaxyUrl").text | 1425 GALAXY_INFRASTRUCTURE_URL = root.find("metadata/galaxyUrl").text |
1446 ) | 1510 ) |
1447 track_conf["category"] = track.attrib["cat"] | 1511 track_conf["category"] = track.attrib["cat"] |
1448 track_conf["format"] = track.attrib["format"] | 1512 track_conf["format"] = track.attrib["format"] |
1449 if track.find("options/style"): | 1513 if track.find("options/style"): |
1450 track_conf["style"] = { | 1514 track_conf["style"] = { |
1451 item.tag: parse_style_conf(item) for item in track.find("options/style") | 1515 item.tag: parse_style_conf(item) |
1516 for item in track.find("options/style") | |
1452 } | 1517 } |
1453 if track.find("options/style_labels"): | 1518 if track.find("options/style_labels"): |
1454 track_conf["style_labels"] = { | 1519 track_conf["style_labels"] = { |
1455 item.tag: parse_style_conf(item) | 1520 item.tag: parse_style_conf(item) |
1456 for item in track.find("options/style_labels") | 1521 for item in track.find("options/style_labels") |
1459 track_conf["conf"] = etree_to_dict(track.find("options")) | 1524 track_conf["conf"] = etree_to_dict(track.find("options")) |
1460 track_conf["category"] = track.attrib["cat"] | 1525 track_conf["category"] = track.attrib["cat"] |
1461 track_conf["format"] = track.attrib["format"] | 1526 track_conf["format"] = track.attrib["format"] |
1462 try: | 1527 try: |
1463 # Only pertains to gff3 + blastxml. TODO? | 1528 # Only pertains to gff3 + blastxml. TODO? |
1464 track_conf["style"] = {t.tag: t.text for t in track.find("options/style")} | 1529 track_conf["style"] = { |
1530 t.tag: t.text for t in track.find("options/style") | |
1531 } | |
1465 except TypeError: | 1532 except TypeError: |
1466 track_conf["style"] = {} | 1533 track_conf["style"] = {} |
1467 pass | 1534 pass |
1468 track_conf["conf"] = etree_to_dict(track.find("options")) | 1535 track_conf["conf"] = etree_to_dict(track.find("options")) |
1469 keys = jc.process_annotations(track_conf) | 1536 keys = jc.process_annotations(track_conf) |
1490 general_data = { | 1557 general_data = { |
1491 "analytics": root.find("metadata/general/analytics").text, | 1558 "analytics": root.find("metadata/general/analytics").text, |
1492 "primary_color": root.find("metadata/general/primary_color").text, | 1559 "primary_color": root.find("metadata/general/primary_color").text, |
1493 "secondary_color": root.find("metadata/general/secondary_color").text, | 1560 "secondary_color": root.find("metadata/general/secondary_color").text, |
1494 "tertiary_color": root.find("metadata/general/tertiary_color").text, | 1561 "tertiary_color": root.find("metadata/general/tertiary_color").text, |
1495 "quaternary_color": root.find("metadata/general/quaternary_color").text, | 1562 "quaternary_color": root.find( |
1563 "metadata/general/quaternary_color" | |
1564 ).text, | |
1496 "font_size": root.find("metadata/general/font_size").text, | 1565 "font_size": root.find("metadata/general/font_size").text, |
1497 } | 1566 } |
1498 jc.add_general_configuration(general_data) | 1567 jc.add_general_configuration(general_data) |
1499 trackconf = jc.config_json.get("tracks", None) | 1568 trackconf = jc.config_json.get("tracks", None) |
1500 if trackconf: | 1569 if trackconf: |