Skip to content
93 changes: 76 additions & 17 deletions tools/jbrowse2/jbrowse2.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@
"}": "__cc__",
"@": "__at__",
"#": "__pd__",
"": "__cn__",
"\n": "__cn__",
"\r": "__cr__",
"\t": "__tc__",
}


Expand Down Expand Up @@ -62,6 +64,14 @@ def etree_to_dict(t):
INSTALLED_TO = os.path.dirname(os.path.realpath(__file__))


def unsanitize(input):

for key, value in mapped_chars.items():
input = input.replace(value, key)

return input


def metadata_from_node(node):
metadata = {}

Expand All @@ -74,7 +84,7 @@ def metadata_from_node(node):
metadata[f"history_{key}"] = value

for key, value in node.findall("metadata")[0].attrib.items():
metadata[f"metadata_{key}"] = value
metadata[f"metadata_{key}"] = unsanitize(value)

for key, value in node.findall("tool")[0].attrib.items():
metadata[f"tool_{key}"] = value
Expand Down Expand Up @@ -265,15 +275,11 @@ def _prepare_format_details(self, xml_conf):
}

if "feature" in xml_conf["formatdetails"]:
feat_jexl = xml_conf["formatdetails"]["feature"]
for key, value in mapped_chars.items():
feat_jexl = feat_jexl.replace(value, key)
feat_jexl = unsanitize(xml_conf["formatdetails"]["feature"])
formatDetails["feature"] = feat_jexl

if "subfeature" in xml_conf["formatdetails"]:
sfeat_jexl = xml_conf["formatdetails"]["subfeature"]
for key, value in mapped_chars.items():
sfeat_jexl = sfeat_jexl.replace(value, key)
sfeat_jexl = unsanitize(xml_conf["formatdetails"]["subfeature"])
formatDetails["subfeatures"] = sfeat_jexl

if "depth" in xml_conf["formatdetails"]:
Expand Down Expand Up @@ -773,6 +779,54 @@ def add_gff(self, parent, data, format, trackData, gffOpts, **kwargs):
remote=trackData['remote']
)

def add_gtf(self, parent, data, format, trackData, gffOpts, **kwargs):
# Not a super recommended format
# https://github.com/GMOD/jbrowse-components/pull/2389
# https://github.com/GMOD/jbrowse-components/issues/3876
if trackData['remote']:
rel_dest = data
else:
rel_dest = os.path.join("data", trackData["label"] + ".gtf")
dest = os.path.join(self.outdir, rel_dest)
shutil.copy(os.path.realpath(data), dest)

json_track_data = {
"type": "FeatureTrack",
"trackId": trackData["label"],
"name": trackData["key"],
"adapter": {
"type": "GtfAdapter",
"gtfLocation": {
"uri": rel_dest,
"locationType": "UriLocation"
},
},
"category": [trackData["category"]],
"assemblyNames": [parent['uniq_id']],
}

style_json = self._prepare_track_style(trackData)

formatdetails = self._prepare_format_details(trackData)

style_json.update(formatdetails)

track_metadata = self._prepare_track_metadata(trackData)

style_json.update(track_metadata)

json_track_data.update(style_json)

self.subprocess_check_call(
[
"jbrowse",
"add-track-json",
"--target",
self.outdir,
json.dumps(json_track_data),
]
)

def add_bed(self, parent, data, format, trackData, gffOpts, **kwargs):
if trackData['remote']:
rel_dest = data
Expand Down Expand Up @@ -1115,8 +1169,7 @@ def process_annotations(self, track, parent):
extra_metadata,
) in enumerate(track["trackfiles"]):
# Unsanitize labels (element_identifiers are always sanitized by Galaxy)
for key, value in mapped_chars.items():
track_human_label = track_human_label.replace(value, key)
track_human_label = unsanitize(track_human_label)

is_multi = type(dataset_path) is list

Expand Down Expand Up @@ -1180,6 +1233,14 @@ def process_annotations(self, track, parent):
outputTrackConfig,
track["conf"]["options"]["gff"],
)
elif dataset_ext in ("gtf"):
self.add_gtf(
parent,
dataset_path,
dataset_ext,
outputTrackConfig,
track["conf"]["options"]["gff"],
)
elif dataset_ext == "bed":
self.add_bed(
parent,
Expand Down Expand Up @@ -1288,13 +1349,10 @@ def process_annotations(self, track, parent):
track["conf"]["options"]["hic"]
)
elif dataset_ext == "sparql":
sparql_query = track["conf"]["options"]["sparql"]["query"]
for key, value in mapped_chars.items():
sparql_query = sparql_query.replace(value, key)
sparql_query = unsanitize(track["conf"]["options"]["sparql"]["query"])
sparql_query_refnames = track["conf"]["options"]["sparql"].get("query_refnames", "")
if sparql_query_refnames:
for key, value in mapped_chars.items():
sparql_query_refnames = sparql_query_refnames.replace(value, key)
sparql_query_refnames = unsanitize(sparql_query_refnames)
self.add_sparql(
parent,
track["conf"]["options"]["sparql"]["url"],
Expand All @@ -1308,7 +1366,7 @@ def process_annotations(self, track, parent):
outputTrackConfig,
)
else:
log.error(f"Do not know how to handle {dataset_ext}")
raise RuntimeError(f"Do not know how to handle dataset of type '{dataset_ext}'")

track_labels.append(outputTrackConfig["label"])

Expand Down Expand Up @@ -1710,7 +1768,8 @@ def validate_synteny(real_root):

track_labels = jc.process_annotations(track_conf, genome)

if track.attrib["visibility"] == "default_on":
if track.attrib["visibility"] == "default_on" and \
(track_conf["format"] != "synteny" or track_conf["style"]["display"] != "LinearSyntenyDisplay"):
for tlabel in track_labels:
default_tracks_on.append(tlabel)

Expand Down
Loading