Mercurial > repos > fubar > jbrowse2
comparison jbrowse2.py @ 127:fbabf7498471 draft
planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/jbrowse2 commit 116b1a4bbd62251ad552306df2dc8aa8f46c6721
author | fubar |
---|---|
date | Mon, 07 Oct 2024 02:11:55 +0000 |
parents | 160f33c6ba85 |
children | fce4ed3b1702 |
comparison
equal
deleted
inserted
replaced
126:fd0fc6fdc7c5 | 127:fbabf7498471 |
---|---|
359 # exit early | 359 # exit early |
360 return metadata | 360 return metadata |
361 except Exception: | 361 except Exception: |
362 return {} | 362 return {} |
363 | 363 |
364 for (key, value) in node.findall("dataset")[0].attrib.items(): | 364 for key, value in node.findall("dataset")[0].attrib.items(): |
365 metadata["dataset_%s" % key] = value | 365 metadata["dataset_%s" % key] = value |
366 | 366 |
367 if node.findall("history"): | 367 if node.findall("history"): |
368 for (key, value) in node.findall("history")[0].attrib.items(): | 368 for key, value in node.findall("history")[0].attrib.items(): |
369 metadata["history_%s" % key] = value | 369 metadata["history_%s" % key] = value |
370 | 370 |
371 if node.findall("metadata"): | 371 if node.findall("metadata"): |
372 for (key, value) in node.findall("metadata")[0].attrib.items(): | 372 for key, value in node.findall("metadata")[0].attrib.items(): |
373 metadata["metadata_%s" % key] = value | 373 metadata["metadata_%s" % key] = value |
374 # Additional Mappings applied: | 374 # Additional Mappings applied: |
375 metadata[ | 375 metadata["dataset_edam_format"] = ( |
376 "dataset_edam_format" | 376 '<a target="_blank" href="http://edamontology.org/{0}">{1}</a>'.format( |
377 ] = '<a target="_blank" href="http://edamontology.org/{0}">{1}</a>'.format( | 377 metadata["dataset_edam_format"], metadata["dataset_file_ext"] |
378 metadata["dataset_edam_format"], metadata["dataset_file_ext"] | 378 ) |
379 ) | 379 ) |
380 metadata["history_user_email"] = '<a href="mailto:{0}">{0}</a>'.format( | 380 metadata["history_user_email"] = '<a href="mailto:{0}">{0}</a>'.format( |
381 metadata["history_user_email"] | 381 metadata["history_user_email"] |
382 ) | 382 ) |
383 metadata["hist_name"] = metadata["history_display_name"] | 383 metadata["hist_name"] = metadata["history_display_name"] |
384 metadata[ | 384 metadata["history_display_name"] = ( |
385 "history_display_name" | 385 '<a target="_blank" href="{galaxy}/history/view/{encoded_hist_id}">{hist_name}</a>'.format( |
386 ] = '<a target="_blank" href="{galaxy}/history/view/{encoded_hist_id}">{hist_name}</a>'.format( | 386 galaxy=GALAXY_INFRASTRUCTURE_URL, |
387 galaxy=GALAXY_INFRASTRUCTURE_URL, | 387 encoded_hist_id=metadata.get("history_id", "not available"), |
388 encoded_hist_id=metadata.get("history_id", "not available"), | 388 hist_name=metadata.get("history_display_name", "not available"), |
389 hist_name=metadata.get("history_display_name", "not available"), | 389 ) |
390 ) | 390 ) |
391 if node.findall("tool"): | 391 if node.findall("tool"): |
392 for (key, value) in node.findall("tool")[0].attrib.items(): | 392 for key, value in node.findall("tool")[0].attrib.items(): |
393 metadata["tool_%s" % key] = value | 393 metadata["tool_%s" % key] = value |
394 metadata[ | 394 metadata["tool_tool"] = ( |
395 "tool_tool" | 395 '<a target="_blank" href="{galaxy}/datasets/{encoded_id}/show_params">{tool_id}{tool_version}</a>'.format( |
396 ] = '<a target="_blank" href="{galaxy}/datasets/{encoded_id}/show_params">{tool_id}{tool_version}</a>'.format( | 396 galaxy=GALAXY_INFRASTRUCTURE_URL, |
397 galaxy=GALAXY_INFRASTRUCTURE_URL, | 397 encoded_id=metadata.get("dataset_id", ""), |
398 encoded_id=metadata.get("dataset_id", ""), | 398 tool_id=metadata.get("tool_tool_id", ""), |
399 tool_id=metadata.get("tool_tool_id", ""), | 399 tool_version=metadata.get("tool_tool_version", ""), |
400 tool_version=metadata.get("tool_tool_version", ""), | 400 ) |
401 ) | 401 ) |
402 return metadata | 402 return metadata |
403 | 403 |
404 | 404 |
405 class JbrowseConnector(object): | 405 class JbrowseConnector(object): |
617 with open(self.config_json_file, "w") as fp: | 617 with open(self.config_json_file, "w") as fp: |
618 json.dump(self.config_json, fp, indent=2) | 618 json.dump(self.config_json, fp, indent=2) |
619 | 619 |
620 def text_index(self): | 620 def text_index(self): |
621 # Index tracks | 621 # Index tracks |
622 args = [ | 622 args = ["jbrowse", "text-index"] |
623 "jbrowse", | |
624 "text-index" | |
625 ] | |
626 self.subprocess_check_call(args) | 623 self.subprocess_check_call(args) |
627 | 624 |
628 def add_hic(self, data, trackData): | 625 def add_hic(self, data, trackData): |
629 """ | 626 """ |
630 HiC adapter. | 627 HiC adapter. |
674 ], | 671 ], |
675 "category": [ | 672 "category": [ |
676 categ, | 673 categ, |
677 ], | 674 ], |
678 "adapter": {"type": "HicAdapter", "hicLocation": {"uri": uri}}, | 675 "adapter": {"type": "HicAdapter", "hicLocation": {"uri": uri}}, |
679 | |
680 } | 676 } |
681 self.tracksToAdd[trackData["assemblyNames"]].append(copy.copy(trackDict)) | 677 self.tracksToAdd[trackData["assemblyNames"]].append(copy.copy(trackDict)) |
682 self.trackIdlist.append(tId) | 678 self.trackIdlist.append(tId) |
683 | 679 |
684 def add_maf(self, data, trackData): | 680 def add_maf(self, data, trackData): |
1125 style_json = self._prepare_track_style(trackDict) | 1121 style_json = self._prepare_track_style(trackDict) |
1126 trackDict["style"] = style_json | 1122 trackDict["style"] = style_json |
1127 if self.config_json.get("plugins", None): | 1123 if self.config_json.get("plugins", None): |
1128 self.config_json["plugins"].append(bedPlugin) | 1124 self.config_json["plugins"].append(bedPlugin) |
1129 else: | 1125 else: |
1130 self.config_json["plugins"] = [bedPlugin,] | 1126 self.config_json["plugins"] = [ |
1127 bedPlugin, | |
1128 ] | |
1131 self.tracksToAdd[trackData["assemblyNames"]].append(copy.copy(trackDict)) | 1129 self.tracksToAdd[trackData["assemblyNames"]].append(copy.copy(trackDict)) |
1132 self.trackIdlist.append(tId) | 1130 self.trackIdlist.append(tId) |
1133 | 1131 |
1134 def add_paf(self, data, trackData, pafOpts, **kwargs): | 1132 def add_paf(self, data, trackData, pafOpts, **kwargs): |
1135 tname = trackData["name"] | 1133 tname = trackData["name"] |
1136 tId = trackData["label"] | 1134 tId = trackData["label"] |
1137 url = tId | 1135 url = tId |
1136 usePIF = False # much faster if indexed remotely or locally | |
1138 useuri = data.startswith("http://") or data.startswith("https://") | 1137 useuri = data.startswith("http://") or data.startswith("https://") |
1139 if not useuri: | 1138 if not useuri: |
1140 dest = os.path.join(self.outdir, url) | 1139 dest = os.path.join(self.outdir, url) |
1141 self.symlink_or_copy(os.path.realpath(data), dest) | 1140 self.symlink_or_copy(os.path.realpath(data), dest) |
1141 cmd = ["jbrowse", "make-pif", dest] | |
1142 self.subprocess_check_call(cmd) | |
1143 usePIF = True | |
1144 url = '%s.pif.gz' % tId | |
1142 nrow = self.getNrow(dest) | 1145 nrow = self.getNrow(dest) |
1143 else: | 1146 else: |
1144 url = data | 1147 url = data |
1145 nrow = self.getNrow(url) | 1148 if data.endswith(".pif.gz") or data.endswith(".paf.gz"): # is tabix |
1149 usePIF = True | |
1150 nrow = 1 | |
1151 else: | |
1152 nrow = self.getNrow(url) | |
1146 categ = trackData["category"] | 1153 categ = trackData["category"] |
1147 pg = pafOpts["genome"].split(",") | 1154 pg = pafOpts["genome"].split(",") |
1148 pgc = [x.strip() for x in pg if x.strip() > ""] | 1155 pgc = [x.strip() for x in pg if x.strip() > ""] |
1149 gnomes = [x.split(" ~ ") for x in pgc] | 1156 gnomes = [x.split(" ~ ") for x in pgc] |
1150 logging.debug("pg=%s, gnomes=%s" % (pg, gnomes)) | 1157 logging.debug("pg=%s, gnomes=%s" % (pg, gnomes)) |
1173 "assemblyNames": passnames, | 1180 "assemblyNames": passnames, |
1174 "category": [ | 1181 "category": [ |
1175 categ, | 1182 categ, |
1176 ], | 1183 ], |
1177 "name": tname, | 1184 "name": tname, |
1178 "adapter": { | 1185 "displays": [ |
1186 { | |
1187 "type": "LGVSyntenyDisplay", | |
1188 "displayId": "%s-LGVSyntenyDisplay" % tId, | |
1189 }, | |
1190 { | |
1191 "type": "DotplotDisplay", | |
1192 "displayId": "%s-DotplotDisplay" % tId, | |
1193 }, | |
1194 { | |
1195 "type": "LinearComparativeDisplay", | |
1196 "displayId": "%s-LinearComparativeDisplay" % tId, | |
1197 }, | |
1198 { | |
1199 "type": "LinearBasicDisplay", | |
1200 "displayId": "%s-LinearSyntenyDisplay" % tId, | |
1201 }, | |
1202 ], | |
1203 } | |
1204 if usePIF: | |
1205 trackDict["adapter"] = { | |
1206 "type": "PairwiseIndexedPAFAdapter", | |
1207 "pifGzLocation": {"uri": url}, | |
1208 "assemblyNames": passnames, | |
1209 "index": { | |
1210 "location": { | |
1211 "uri": url + ".tbi", | |
1212 } | |
1213 }, | |
1214 } | |
1215 else: | |
1216 trackDict["adapter"] = { | |
1179 "type": "PAFAdapter", | 1217 "type": "PAFAdapter", |
1180 "pafLocation": {"uri": url}, | 1218 "pafLocation": {"uri": url}, |
1181 "assemblyNames": passnames, | 1219 "assemblyNames": passnames, |
1182 }, | 1220 } |
1183 "displays": [ | 1221 if (not usePIF) and (nrow > 10000): |
1184 { | |
1185 "type": "LGVSyntenyDisplay", | |
1186 "displayId": "%s-LGVSyntenyDisplay" % tId, | |
1187 }, | |
1188 { | |
1189 "type": "DotplotDisplay", | |
1190 "displayId": "%s-DotplotDisplay" % tId, | |
1191 }, | |
1192 { | |
1193 "type": "LinearComparativeDisplay", | |
1194 "displayId": "%s-LinearComparativeDisplay" % tId, | |
1195 }, | |
1196 { | |
1197 "type": "LinearBasicDisplay", | |
1198 "displayId": "%s-LinearSyntenyDisplay" % tId, | |
1199 }, | |
1200 ], | |
1201 } | |
1202 if nrow > 10000: | |
1203 style_json = { | 1222 style_json = { |
1204 "type": "LGVSyntenyDisplay", | 1223 "type": "LGVSyntenyDisplay", |
1205 "displayId": "%s-LGVSyntenyDisplay" % tId, | 1224 "displayId": "%s-LGVSyntenyDisplay" % tId, |
1206 } | 1225 } |
1207 else: | 1226 else: |
1334 default session settings are hard and fragile. | 1353 default session settings are hard and fragile. |
1335 .add_default_view() and other configuration code adapted from | 1354 .add_default_view() and other configuration code adapted from |
1336 https://github.com/abretaud/tools-iuc/blob/jbrowse2/tools/jbrowse2/jbrowse2.py | 1355 https://github.com/abretaud/tools-iuc/blob/jbrowse2/tools/jbrowse2/jbrowse2.py |
1337 """ | 1356 """ |
1338 # TODO using the default session for now, but check out session specs in the future https://github.com/GMOD/jbrowse-components/issues/2708 | 1357 # TODO using the default session for now, but check out session specs in the future https://github.com/GMOD/jbrowse-components/issues/2708 |
1339 bpPerPx = self.bpPerPx # Browser window width is unknown and default session cannot be used to figure it out in JB2 code so could be 200-2000+ pixels. | 1358 bpPerPx = ( |
1359 self.bpPerPx | |
1360 ) # Browser window width is unknown and default session cannot be used to figure it out in JB2 code so could be 200-2000+ pixels. | |
1340 track_types = {} | 1361 track_types = {} |
1341 with open(self.config_json_file, "r") as config_file: | 1362 with open(self.config_json_file, "r") as config_file: |
1342 config_json = json.load(config_file) | 1363 config_json = json.load(config_file) |
1343 if self.config_json: | 1364 if self.config_json: |
1344 config_json.update(self.config_json) | 1365 config_json.update(self.config_json) |
1359 logging.debug( | 1380 logging.debug( |
1360 "No style data for %s in available default data %s" | 1381 "No style data for %s in available default data %s" |
1361 % (tId, default_data) | 1382 % (tId, default_data) |
1362 ) | 1383 ) |
1363 else: | 1384 else: |
1364 logging.debug( | 1385 logging.debug("style data for %s = %s" % (tId, style_data)) |
1365 "style data for %s = %s" | 1386 if style_data.get("type", None) is None: |
1366 % (tId, style_data) | |
1367 ) | |
1368 if style_data.get('type', None) is None: | |
1369 style_data["type"] = "LinearBasicDisplay" | 1387 style_data["type"] = "LinearBasicDisplay" |
1370 if "displays" in track_conf: | 1388 if "displays" in track_conf: |
1371 disp = track_conf["displays"][0]["type"] | 1389 disp = track_conf["displays"][0]["type"] |
1372 style_data["type"] = disp | 1390 style_data["type"] = disp |
1373 if track_conf.get("displays", None): | 1391 if track_conf.get("displays", None): |
1374 style_data["configuration"] = track_conf["displays"][0]["displayId"] | 1392 style_data["configuration"] = track_conf["displays"][0][ |
1393 "displayId" | |
1394 ] | |
1375 else: | 1395 else: |
1376 logging.debug("no display in track_conf for %s" % tId) | 1396 logging.debug("no display in track_conf for %s" % tId) |
1377 if track_conf.get("style_labels", None): | 1397 if track_conf.get("style_labels", None): |
1378 # TODO fix this: it should probably go in a renderer block (SvgFeatureRenderer) but still does not work | 1398 # TODO fix this: it should probably go in a renderer block (SvgFeatureRenderer) but still does not work |
1379 # TODO move this to per track displays? | 1399 # TODO move this to per track displays? |
1416 view_json = { | 1436 view_json = { |
1417 "type": "LinearGenomeView", | 1437 "type": "LinearGenomeView", |
1418 "offsetPx": 0, | 1438 "offsetPx": 0, |
1419 "bpPerPx": bpPerPx, | 1439 "bpPerPx": bpPerPx, |
1420 "minimized": False, | 1440 "minimized": False, |
1421 "tracks": tracks_data | 1441 "tracks": tracks_data, |
1422 } | 1442 } |
1423 if drdict.get("refName", None): | 1443 if drdict.get("refName", None): |
1424 # TODO displayedRegions is not just zooming to the region, it hides the rest of the chromosome | 1444 # TODO displayedRegions is not just zooming to the region, it hides the rest of the chromosome |
1425 view_json["displayedRegions"] = [ | 1445 view_json["displayedRegions"] = [ |
1426 drdict, | 1446 drdict, |
1537 with open(config_path, "w") as config_file: | 1557 with open(config_path, "w") as config_file: |
1538 json.dump(self.config_json, config_file, indent=2) | 1558 json.dump(self.config_json, config_file, indent=2) |
1539 | 1559 |
1540 def clone_jbrowse(self, realclone=False): | 1560 def clone_jbrowse(self, realclone=False): |
1541 """ | 1561 """ |
1542 Clone a JBrowse directory into a destination directory. | 1562 Clone a JBrowse directory into a destination directory. |
1543 | 1563 |
1544 `realclone=true` will use the `jbrowse create` command. | 1564 `realclone=true` will use the `jbrowse create` command. |
1545 To allow running on internet-less compute and for reproducibility | 1565 To allow running on internet-less compute and for reproducibility |
1546 use frozen code with `realclone=false | 1566 use frozen code with `realclone=false |
1547 | 1567 |
1548 """ | 1568 """ |
1549 dest = self.outdir | 1569 dest = self.outdir |
1550 if (not os.path.exists(self.jbrowse2path)) or realclone: | 1570 if (not os.path.exists(self.jbrowse2path)) or realclone: |
1551 self.subprocess_check_call( | 1571 self.subprocess_check_call( |
1568 else: | 1588 else: |
1569 os.remove(path) | 1589 os.remove(path) |
1570 except OSError as e: | 1590 except OSError as e: |
1571 log.error("Error: %s - %s." % (e.filename, e.strerror)) | 1591 log.error("Error: %s - %s." % (e.filename, e.strerror)) |
1572 for neededfile in ["jb2_webserver.py", "bedscoreplugin.js"]: | 1592 for neededfile in ["jb2_webserver.py", "bedscoreplugin.js"]: |
1573 shutil.copyfile(os.path.join(INSTALLED_TO, neededfile), os.path.join(dest, neededfile)) | 1593 shutil.copyfile( |
1594 os.path.join(INSTALLED_TO, neededfile), os.path.join(dest, neededfile) | |
1595 ) | |
1574 | 1596 |
1575 | 1597 |
1576 def parse_style_conf(item): | 1598 def parse_style_conf(item): |
1577 if item.text.lower() in ["false", "true", "yes", "no"]: | 1599 if item.text.lower() in ["false", "true", "yes", "no"]: |
1578 return item.text.lower in ("yes", "true") | 1600 return item.text.lower in ("yes", "true") |
1590 parser.add_argument("--outdir", help="Output directory", default="out") | 1612 parser.add_argument("--outdir", help="Output directory", default="out") |
1591 parser.add_argument("--version", "-V", action="version", version=JB2VER) | 1613 parser.add_argument("--version", "-V", action="version", version=JB2VER) |
1592 args = parser.parse_args() | 1614 args = parser.parse_args() |
1593 tree = ET.parse(args.xml) | 1615 tree = ET.parse(args.xml) |
1594 root = tree.getroot() | 1616 root = tree.getroot() |
1595 removeMe = string.punctuation.replace('.', ' ').replace('/', '').replace('-', '') | 1617 removeMe = string.punctuation.replace(".", " ").replace("/", "").replace("-", "") |
1596 # first is a space because space needs to be added here for removal from labels as paths. | 1618 # first is a space because space needs to be added here for removal from labels as paths. |
1597 nopunct = str.maketrans(dict.fromkeys(removeMe)) | 1619 nopunct = str.maketrans(dict.fromkeys(removeMe)) |
1598 # This should be done ASAP | 1620 # This should be done ASAP |
1599 GALAXY_INFRASTRUCTURE_URL = root.find("metadata/galaxyUrl").text | 1621 GALAXY_INFRASTRUCTURE_URL = root.find("metadata/galaxyUrl").text |
1600 # Sometimes this comes as `localhost` without a protocol | 1622 # Sometimes this comes as `localhost` without a protocol |
1644 | 1666 |
1645 trackfiles = track.findall("files/trackFile") | 1667 trackfiles = track.findall("files/trackFile") |
1646 if trackfiles: | 1668 if trackfiles: |
1647 for x in trackfiles: | 1669 for x in trackfiles: |
1648 isBed = False | 1670 isBed = False |
1649 if x.attrib['ext'] == "bed": | 1671 if x.attrib["ext"] == "bed": |
1650 isBed = True | 1672 isBed = True |
1651 track_conf["label"] = "%s_%d" % ( | 1673 track_conf["label"] = "%s_%d" % ( |
1652 x.attrib["label"].translate(nopunct), | 1674 x.attrib["label"].translate(nopunct), |
1653 trackI, | 1675 trackI, |
1654 ) | 1676 ) |
1662 os.path.realpath(x.attrib["path"]), | 1684 os.path.realpath(x.attrib["path"]), |
1663 ) | 1685 ) |
1664 ) | 1686 ) |
1665 else: | 1687 else: |
1666 metadata = metadata_from_node(x.find("metadata")) | 1688 metadata = metadata_from_node(x.find("metadata")) |
1667 track_conf["dataset_id"] = metadata.get( | 1689 track_conf["dataset_id"] = metadata.get("dataset_id", "None") |
1668 "dataset_id", "None" | |
1669 ) | |
1670 if x.attrib["useuri"].lower() == "yes": | 1690 if x.attrib["useuri"].lower() == "yes": |
1671 tfa = ( | 1691 tfa = ( |
1672 x.attrib["path"], | 1692 x.attrib["path"], |
1673 x.attrib["ext"], | 1693 x.attrib["ext"], |
1674 x.attrib["useuri"], | 1694 x.attrib["useuri"], |