Unverified Commit f33eb423 authored by Marius van den Beek's avatar Marius van den Beek Committed by GitHub
Browse files

Merge pull request #20466 from pvanheus/add_auspicejson_datatype

[25.0] Add Auspice JSON datatype
parents 0aa5616b 182f6c2b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -148,6 +148,7 @@
    <datatype extension="vitessce.json" type="galaxy.datatypes.text:VitessceJson" mimetype="application/json" display_in_upload="True">
      <visualization plugin="vitessce" />
    </datatype>
    <datatype extension="auspice.json" type="galaxy.datatypes.text:AuspiceJson" mimetype="application/json" display_in_upload="True" />
    <datatype extension="data_manager_json" type="galaxy.datatypes.text:DataManagerJson" mimetype="application/json" subclass="true" display_in_upload="false"/>
    <datatype extension="dbn" type="galaxy.datatypes.sequence:DotBracket" display_in_upload="true" description="Dot-Bracket format is a text-based format for storing both an RNA sequence and its corresponding 2D structure." description_url="https://wiki.galaxyproject.org/Learn/Datatypes#Dbn"/>
    <datatype extension="fai" type="galaxy.datatypes.tabular:Tabular" display_in_upload="true" subclass="true" description="A Fasta Index File is a text file consisting of lines each with five TAB-delimited columns : Name, Length, offset, linebases, Linewidth" description_url="http://www.htslib.org/doc/faidx.html"/>
@@ -1387,6 +1388,7 @@
    <sniffer type="galaxy.datatypes.text:CytoscapeJson"/>
    <sniffer type="galaxy.datatypes.text:GeoJson"/>
    <sniffer type="galaxy.datatypes.text:VitessceJson"/>
    <snipper type="galaxy.datatypes.text:AuspiceJson"/>
    <sniffer type="galaxy.datatypes.text:PithyaResult"/>
    <sniffer type="galaxy.datatypes.text:BCSLts"/>
    <sniffer type="galaxy.datatypes.text:Json"/>
+14 −0
Original line number Diff line number Diff line
{
  "version": "v2",
  "meta": {
    "title": "Minimal AuspiceJSON",
    "updated": "2025-02-05",
    "panels": ["tree"]
  },
  "tree": {
    "name": "1",
    "node_attrs": {
      "div": 1
    }
  }
}
+51 −0
Original line number Diff line number Diff line
@@ -695,6 +695,57 @@ class VitessceJson(Json):
        return False


@build_sniff_from_prefix
class AuspiceJson(Json):
    """
    Auspice is a visualization tool for phylogenetic trees and associated data.
    It uses JSON format to represent the tree structure and metadata.
    """

    file_ext = "auspice.json"

    def set_peek(self, dataset: DatasetProtocol, **kwd) -> None:
        super().set_peek(dataset)
        if not dataset.dataset.purged:
            dataset.blurb = "AuspiceJSON"

    def sniff_prefix(self, file_prefix: FilePrefix) -> bool:
        """
        Determines whether the file is in Auspice v2 JSON by looking for keys
        like "version", "meta" and "updated" that are both required by the
        https://docs.nextstrain.org/projects/auspice/en/stable/releases/v2.html format
        and also will be in the first part of the file

        >>> from galaxy.datatypes.sniff import get_test_fname
        >>> fname = get_test_fname( '1.json' )
        >>> AuspiceJson().sniff( fname )
        False
        >>> fname = get_test_fname( '1.auspicejson' )
        >>> AuspiceJson().sniff( fname )
        True
        """
        is_auspicejson = False
        if self._looks_like_json(file_prefix):
            is_auspicejson = self._looks_like_is_auspicejson(file_prefix)
        return is_auspicejson

    def _looks_like_is_auspicejson(self, file_prefix: FilePrefix, load_size: int = 20000) -> bool:
        """
        Expects JSON to start with { and 'meta', 'tree', 'updated' and 'nodes' to be present as keys in the JSON structure.
        """
        try:
            with open(file_prefix.filename) as fh:
                segment_str = fh.read(load_size)

                if segment_str.startswith("{") and all(
                    x in segment_str for x in ["version", "meta", "updated", "panels"]
                ):
                    return True
        except Exception:
            pass
        return False


@build_sniff_from_prefix
class Obo(Text):
    """