EBISPOT / ols4

Version 4 of the EMBL-EBI Ontology Lookup Service (OLS)
http://www.ebi.ac.uk/ols4/
Apache License 2.0
47 stars 21 forks source link

Implement OLS3 graph endpoints #59

Closed jamesamcl closed 1 year ago

jamesamcl commented 2 years ago

For legacy plugins

https://www.ebi.ac.uk/ols/api/ontologies/efo/terms/http%253A%252F%252Fwww.ebi.ac.uk%252Fefo%252FEFO_0000400/graph

{
  "nodes" : [ {
    "iri" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "diabetes mellitus"
  }, {
    "iri" : "http://www.ebi.ac.uk/efo/EFO_0009406",
    "label" : "glucose metabolism disease"
  }, {
    "iri" : "http://purl.obolibrary.org/obo/MONDO_0001933",
    "label" : "endocrine pancreas disorder"
  }, {
    "iri" : "http://purl.obolibrary.org/obo/MONDO_0011273",
    "label" : "H syndrome"
  }, {
    "iri" : "http://www.ebi.ac.uk/efo/EFO_1001121",
    "label" : "prediabetes syndrome"
  }, {
    "iri" : "http://purl.obolibrary.org/obo/MONDO_0008185",
    "label" : "hereditary chronic pancreatitis"
  }, {
    "iri" : "http://purl.obolibrary.org/obo/MONDO_0013225",
    "label" : "congenital generalized lipodystrophy type 4"
  }, {
    "iri" : "http://purl.obolibrary.org/obo/MONDO_0013478",
    "label" : "PLIN1-related familial partial lipodystrophy"
  }, {
    "iri" : "http://www.ebi.ac.uk/efo/EFO_0004593",
    "label" : "gestational diabetes"
  }, {
    "iri" : "http://purl.obolibrary.org/obo/MONDO_0015308",
    "label" : "laminopathy type Decaudain-Vigouroux"
  }, {
    "iri" : "http://purl.obolibrary.org/obo/MONDO_0010785",
    "label" : "maternally-inherited diabetes and deafness"
  }, {
    "iri" : "http://purl.obolibrary.org/obo/MONDO_0010773",
    "label" : "myopathy and diabetes mellitus"
  }, {
    "iri" : "http://purl.obolibrary.org/obo/MONDO_0009874",
    "label" : "Rabson-Mendenhall syndrome"
  }, {
    "iri" : "http://purl.obolibrary.org/obo/MONDO_0010802",
    "label" : "pancreatic hypoplasia-diabetes-congenital heart disease syndrome"
  }, {
    "iri" : "http://www.ebi.ac.uk/efo/EFO_1001511",
    "label" : "monogenic diabetes"
  }, {
    "iri" : "http://purl.obolibrary.org/obo/MONDO_0019193",
    "label" : "acquired generalized lipodystrophy"
  }, {
    "iri" : "http://purl.obolibrary.org/obo/MONDO_0005147",
    "label" : "type 1 diabetes mellitus"
  }, {
    "iri" : "http://purl.obolibrary.org/obo/MONDO_0005148",
    "label" : "type 2 diabetes mellitus"
  }, {
    "iri" : "http://purl.obolibrary.org/obo/MONDO_0017230",
    "label" : "autosomal semi-dominant severe lipodystrophic laminopathy"
  }, {
    "iri" : "http://purl.obolibrary.org/obo/MONDO_0012520",
    "label" : "insulin-resistance syndrome type A"
  }, {
    "iri" : "http://purl.obolibrary.org/obo/MONDO_0010026",
    "label" : "SHORT syndrome"
  }, {
    "iri" : "http://purl.obolibrary.org/obo/MONDO_0009192",
    "label" : "Wolcott-Rallison syndrome"
  }, {
    "iri" : "http://purl.obolibrary.org/obo/MONDO_0009419",
    "label" : "Woodhouse-Sakati syndrome"
  }, {
    "iri" : "http://purl.obolibrary.org/obo/MONDO_0009575",
    "label" : "thiamine-responsive megaloblastic anemia syndrome"
  }, {
    "iri" : "http://purl.obolibrary.org/obo/MONDO_0009517",
    "label" : "Donohue syndrome"
  }, {
    "iri" : "http://www.ebi.ac.uk/efo/EFO_0007498",
    "label" : "Stiff-Person syndrome"
  }, {
    "iri" : "http://purl.obolibrary.org/obo/MONDO_0019017",
    "label" : "short fifth metacarpals-insulin resistance syndrome"
  }, {
    "iri" : "http://purl.obolibrary.org/obo/MONDO_0014497",
    "label" : "polyendocrine-polyneuropathy syndrome"
  }, {
    "iri" : "http://www.orpha.net/ORDO/Orphanet_183625",
    "label" : "Rare genetic diabetes mellitus"
  }, {
    "iri" : "http://www.ebi.ac.uk/efo/EFO_0010164",
    "label" : "insulin-resistant diabetes mellitus"
  }, {
    "iri" : "http://purl.obolibrary.org/obo/MONDO_0016391",
    "label" : "neonatal diabetes mellitus"
  }, {
    "iri" : "http://purl.obolibrary.org/obo/MONDO_0018911",
    "label" : "maturity-onset diabetes of the young"
  }, {
    "iri" : "http://purl.obolibrary.org/obo/MONDO_0016464",
    "label" : "insulin-resistance syndrome type B"
  }, {
    "iri" : "http://purl.obolibrary.org/obo/HP_0000857",
    "label" : "Neonatal insulin-dependent diabetes mellitus"
  }, {
    "iri" : "http://purl.obolibrary.org/obo/MONDO_0008696",
    "label" : "acanthosis nigricans-insulin resistance-muscle cramps-acral enlargement syndrome"
  }, {
    "iri" : "http://purl.obolibrary.org/obo/MONDO_0008812",
    "label" : "AREDYLD syndrome"
  }, {
    "iri" : "http://purl.obolibrary.org/obo/MONDO_0018320",
    "label" : "primary microcephaly-mild intellectual disability-young-onset diabetes syndrome"
  }, {
    "iri" : "http://purl.obolibrary.org/obo/MONDO_0018575",
    "label" : "microcephalic primordial dwarfism-insulin resistance syndrome"
  }, {
    "iri" : "http://www.ebi.ac.uk/efo/EFO_1000897",
    "label" : "diabetic ketoacidosis"
  }, {
    "iri" : "http://www.ebi.ac.uk/efo/EFO_0004467",
    "label" : "insulin measurement"
  }, {
    "iri" : "http://www.ebi.ac.uk/efo/EFO_0008465",
    "label" : "glucagon-like peptide-1 measurement"
  }, {
    "iri" : "http://www.ebi.ac.uk/efo/EFO_0008464",
    "label" : "glucose-dependent insulinotropic peptide measurement"
  }, {
    "iri" : "http://www.ebi.ac.uk/efo/EFO_0008463",
    "label" : "glucagon measurement"
  }, {
    "iri" : "http://www.ebi.ac.uk/efo/EFO_0008473",
    "label" : "insulin response measurement"
  }, {
    "iri" : "http://purl.obolibrary.org/obo/MONDO_0000489",
    "label" : "diabetic encephalopathy"
  }, {
    "iri" : "http://www.ebi.ac.uk/efo/EFO_0003770",
    "label" : "diabetic retinopathy"
  }, {
    "iri" : "http://www.ebi.ac.uk/efo/EFO_0005766",
    "label" : "skin fluorescence measurement"
  }, {
    "iri" : "http://www.ebi.ac.uk/efo/EFO_0000401",
    "label" : "diabetic nephropathy"
  }, {
    "iri" : "http://www.ebi.ac.uk/efo/EFO_1000783",
    "label" : "diabetic neuropathy"
  } ],
  "edges" : [ {
    "source" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0009406",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "target" : "http://purl.obolibrary.org/obo/MONDO_0001933",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://purl.obolibrary.org/obo/MONDO_0011273",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://www.ebi.ac.uk/efo/EFO_1001121",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://purl.obolibrary.org/obo/MONDO_0008185",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://purl.obolibrary.org/obo/MONDO_0013225",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://purl.obolibrary.org/obo/MONDO_0013478",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://www.ebi.ac.uk/efo/EFO_0004593",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://purl.obolibrary.org/obo/MONDO_0015308",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://purl.obolibrary.org/obo/MONDO_0010785",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://purl.obolibrary.org/obo/MONDO_0010773",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://purl.obolibrary.org/obo/MONDO_0009874",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://purl.obolibrary.org/obo/MONDO_0010802",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://www.ebi.ac.uk/efo/EFO_1001511",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://purl.obolibrary.org/obo/MONDO_0019193",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://purl.obolibrary.org/obo/MONDO_0005147",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://purl.obolibrary.org/obo/MONDO_0005148",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://purl.obolibrary.org/obo/MONDO_0017230",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://purl.obolibrary.org/obo/MONDO_0012520",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://purl.obolibrary.org/obo/MONDO_0010026",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://purl.obolibrary.org/obo/MONDO_0009192",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://purl.obolibrary.org/obo/MONDO_0009419",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://purl.obolibrary.org/obo/MONDO_0009575",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://purl.obolibrary.org/obo/MONDO_0009517",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://www.ebi.ac.uk/efo/EFO_0007498",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://purl.obolibrary.org/obo/MONDO_0019017",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://purl.obolibrary.org/obo/MONDO_0014497",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://www.orpha.net/ORDO/Orphanet_183625",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://www.ebi.ac.uk/efo/EFO_0010164",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://purl.obolibrary.org/obo/MONDO_0016391",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://purl.obolibrary.org/obo/MONDO_0018911",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://purl.obolibrary.org/obo/MONDO_0016464",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://purl.obolibrary.org/obo/HP_0000857",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://purl.obolibrary.org/obo/MONDO_0008696",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://purl.obolibrary.org/obo/MONDO_0008812",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://purl.obolibrary.org/obo/MONDO_0018320",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://purl.obolibrary.org/obo/MONDO_0018575",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://www.ebi.ac.uk/efo/EFO_1000897",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is a",
    "uri" : "http://www.w3.org/2000/01/rdf-schema#subClassOf"
  }, {
    "source" : "http://www.ebi.ac.uk/efo/EFO_0004467",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is_about",
    "uri" : "http://purl.obolibrary.org/obo/IAO_0000136"
  }, {
    "source" : "http://www.ebi.ac.uk/efo/EFO_0008465",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is_about",
    "uri" : "http://purl.obolibrary.org/obo/IAO_0000136"
  }, {
    "source" : "http://www.ebi.ac.uk/efo/EFO_0008464",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is_about",
    "uri" : "http://purl.obolibrary.org/obo/IAO_0000136"
  }, {
    "source" : "http://www.ebi.ac.uk/efo/EFO_0008463",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is_about",
    "uri" : "http://purl.obolibrary.org/obo/IAO_0000136"
  }, {
    "source" : "http://www.ebi.ac.uk/efo/EFO_0008473",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is_about",
    "uri" : "http://purl.obolibrary.org/obo/IAO_0000136"
  }, {
    "source" : "http://purl.obolibrary.org/obo/MONDO_0000489",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "disease arises from feature",
    "uri" : "http://purl.obolibrary.org/obo/RO_0004022"
  }, {
    "source" : "http://www.ebi.ac.uk/efo/EFO_0003770",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "disease arises from feature",
    "uri" : "http://purl.obolibrary.org/obo/RO_0004022"
  }, {
    "source" : "http://www.ebi.ac.uk/efo/EFO_0005766",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "is_about",
    "uri" : "http://purl.obolibrary.org/obo/IAO_0000136"
  }, {
    "source" : "http://www.ebi.ac.uk/efo/EFO_0000401",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "disease arises from feature",
    "uri" : "http://purl.obolibrary.org/obo/RO_0004022"
  }, {
    "source" : "http://www.ebi.ac.uk/efo/EFO_1000783",
    "target" : "http://www.ebi.ac.uk/efo/EFO_0000400",
    "label" : "disease arises from feature",
    "uri" : "http://purl.obolibrary.org/obo/RO_0004022"
  } ]
}
jamesamcl commented 2 years ago

In OLS3 this seems to be based on "related from" relations.

    String relatedGraphQuery = "MATCH path = (n:Class)-[r:SUBCLASSOF|Related]-(parent)\n"+
            "WHERE n.ontology_name = {0} AND n.iri = {1}\n"+
            "UNWIND nodes(path) as p\n" +
            "UNWIND rels(path) as r1\n" +
            "RETURN {nodes: collect( distinct {iri: p.iri, label: p.label})[0..200], " +
            "edges: collect (distinct {source: startNode(r1).iri, target: endNode(r1).iri, label: r1.label, uri: r1.uri}  )[0..200]} as result";

    String relatedFromQuery =  "MATCH (x)-[r:Related]->(n:Class) WHERE n.ontology_name = {0} AND n.iri = {1} RETURN r.label as relation, collect( {iri: x.iri, label: x.label})[0..99] as terms limit 100";

    String usageQuery = "MATCH (n:Resource)<-[r:REFERSTO]-(x) WHERE n.iri = {0} RETURN distinct ({name: x.ontology_name, prefix: x.ontology_prefix}) as usage";
    private Collection<Individual> instances;

    public Object getGraphJson(String ontologyName, String iri, int distance) {

        Map<String, Object> paramt = new HashMap<>();
        paramt.put("0", ontologyName);
        paramt.put("1", iri);
        Result res = graphDatabaseService.execute(relatedGraphQuery, paramt);

        return res.next().get("result");

    }

    public Map<String, Collection<Map<String, String>>> getRelatedFrom(String ontologyId, String iri) {
        Map<String, Object> paramt = new HashMap<>();
        paramt.put("0", ontologyId);
        paramt.put("1", iri);
        Result res = graphDatabaseService.execute(relatedFromQuery, paramt);

        Map<String, Collection<Map<String, String>>> relatedFromMap = new HashMap<>();
        while (res.hasNext()) {
            Map<String, Object> r = res.next();
            String relationLabel = r.get("relation").toString();
            relatedFromMap.put(relationLabel, (Collection<Map<String, String>>) r.get("terms"));
        }

        return relatedFromMap;
    }

    public Collection<Map<String, String>> getOntologyUsage (String iri) {
        Map<String, Object> paramt = new HashMap<>();
        paramt.put("0", iri);
        Result res = graphDatabaseService.execute(usageQuery,paramt);
        Collection<Map<String, String>> usageInfo = new HashSet<>();
        while (res.hasNext()) {
            Map<String, Object> r = res.next();
            usageInfo.add((Map<String, String>) r.get("usage"));
        }

        return usageInfo;
    }

https://github.com/EBISPOT/OLS/blob/4b54a687386c255ba6457f8db689e2f9d7c3a924/ols-neo4j/src/main/java/uk/ac/ebi/spot/ols/neo4j/service/OntologyTermGraphService.java

Everything else just uses the termRepository methods which should already be implemented.

jamesamcl commented 2 years ago

Here is what Related relations look like in OLS3:

@RelationshipEntity (type = "Related")
public class Related {

    @GraphId
    Long id;

    String uri;
    String label;

    @GraphProperty(propertyName="ontology_name")
    @JsonProperty(value = "ontology_name")
    String ontologyName;

    @StartNode
    private Term relatedFrom;

    @EndNode
    private Term relatedTo;

Seems to be populated like this in AbstractOWLOntologyLoader:


        // map of related parent terms for hierarchy views
        Map<IRI, Collection<IRI>> relatedParentTerms = new HashMap<>();

        // find direct related terms
        Map<IRI, Collection<IRI>> relatedTerms = new HashMap<>();
        Map<IRI, Collection<IRI>> relatedIndividualsToClasses = new HashMap<>();

        Set<String> relatedDescriptions = new HashSet<>();

        EntitySearcher.getSuperClasses(owlClass, getManager().ontologies()).forEach(expression -> {

            // only want existential with named class as filler
            if (expression.isAnonymous()) {

                if (expression instanceof OWLObjectSomeValuesFrom) {

                    OWLObjectSomeValuesFrom someValuesFrom = (OWLObjectSomeValuesFrom) expression;

                    if (!someValuesFrom.getFiller().isAnonymous() && !someValuesFrom.getProperty().isAnonymous()) {
                        IRI propertyIRI = someValuesFrom.getProperty().asOWLObjectProperty().getIRI();
                        IRI relatedTerm = someValuesFrom.getFiller().asOWLClass().getIRI();

                        // skip terms that are related to themselves as this can cause nasty cycles

                        if (!relatedTerms.containsKey(propertyIRI)) {
                            relatedTerms.put(propertyIRI, new HashSet<>());
                        }
                        relatedTerms.get(propertyIRI).add(relatedTerm);

                        // check if hierarchical
                        if (hierarchicalRels.contains(propertyIRI) || isPartOf(propertyIRI)) {
                            if (owlClass.getIRI().equals(relatedTerm)) {
                                getLogger().warn("Ignoring Iri that is related to itself: " + owlClass.getIRI());
                            } else {
                                if (!relatedParentTerms.containsKey(propertyIRI)) {
                                    relatedParentTerms.put(propertyIRI, new HashSet<>());
                                }
                                relatedParentTerms.get(propertyIRI).add(relatedTerm);
                                addRelatedChildTerm(relatedTerm, owlClass.getIRI());
                            }

                        }

                    } else if (someValuesFrom.getFiller().isAnonymous() && !someValuesFrom.getProperty().isAnonymous()) {
                        indexTermToIndividualRelations(someValuesFrom, relatedIndividualsToClasses);
                    }

                } else if (expression instanceof OWLObjectHasValue) {
                    OWLObjectSomeValuesFrom someValuesFrom = (OWLObjectSomeValuesFrom) ((OWLObjectHasValue) expression).asSomeValuesFrom();
                    indexTermToIndividualRelations(someValuesFrom, relatedIndividualsToClasses);
                }

                // store stringified form of class description
                relatedDescriptions.add(renderHtml(expression));
            }
        });

        if (!relatedTerms.isEmpty()) {
            setRelatedTerms(owlClass.getIRI(), relatedTerms);
        }

        if (!relatedIndividualsToClasses.isEmpty()) {
            setRelatedIndividualsToClasses(owlClass.getIRI(), relatedIndividualsToClasses);
        }

        setRelatedParentTerms(owlClass.getIRI(), relatedParentTerms);

        if (!relatedDescriptions.isEmpty()) {

            setSuperClassDescriptions(owlClass.getIRI(), relatedDescriptions);

        }
        // todo find transitive closure of related terms
jamesamcl commented 2 years ago

The distance parameter is not implemented at all in OLS3. Instead it seems to return the first 200 nodes and edges. Excerpt from above:

    String relatedGraphQuery = "MATCH path = (n:Class)-[r:SUBCLASSOF|Related]-(parent)\n"+
            "WHERE n.ontology_name = {0} AND n.iri = {1}\n"+
            "UNWIND nodes(path) as p\n" +
            "UNWIND rels(path) as r1\n" +
            "RETURN {nodes: collect( distinct {iri: p.iri, label: p.label})[0..200], " +
            "edges: collect (distinct {source: startNode(r1).iri, target: endNode(r1).iri, label: r1.label, uri: r1.uri}  )[0..200]} as result";

I suppose there are two separate issues here:

1. Implementing the graph functionality in the backwards compatible OLS3 API. I will do this with just subClassOf to begin with. This is now implemented for directParent.

  1. Implementing Related relations in OLS4. So far it looks like they are only used for this, but no harm in adding them to the database. The hard part is working out exactly what "related" means because the code above will take some work to understand.