text:
1.  summary Discussion of issues pertaining to modeling of absence in
    phenotype ontologies

Introduction
============

Much has been written on the subject of representing absence. Before
diving into the logical issues it is worth examining patterns in
existing phenotype ontologies to understand what user expectations may
typically be for absence.

Background
==========

`* `[`Absence_Phenotypes_in_OWL`](http://phenoscape.org/wiki/Absence_Phenotypes_in_OWL)` (Phenoscape Wiki)`\
`* (outdated) material on the old `[`PATO`
`wiki`](http://obofoundry.org/wiki/index.php/PATO:Revised_2008#Absence_and_counting)`.`

Details
=======

Strict logical absence vs absence of some
-----------------------------------------

It is not uncommon to see patterns such as

From a strict logical perspective, this is inverted. "absent incisors"
surely means "absence of all incisors", or put another way "the animal
has no incisors". Yet it would be possible to have an animal with
\*absent\* lower incisors and \*present\* upper incisors, yielding what
seems a contradiction (because the subClass axiom would say this
partial-incisor animal lacked all incisors).

If the ontology were in fact truly modeling "absence of \*all\* S" then
it would lead to a curious ontology structure, with the typical tree
structure of the anatomy ontology representing S inverted into a
polyhierarchical fan in the absent-S ontology.

From this it can be cautiously inferred that the intent of the phenotype
ontology curator and user is in fact to model "absence of \*some\* S"
rather than "absence of \*all\* S". This is not necessarily a universal
rule, and the intent may vary depending on whether we are talking about
a serially repeated structure or one that typically occurs in isolation.
The intent may also be to communicate that a \*significant number\* of S
is missing.

Absence as a type of morphology
-------------------------------

It is also not uncommon to see patterns such as:

Again, from a strict logical perspective this is false. If the spleen is
absent then what does the "morphology" of the parent refer to?

However, this inference is clearly a desirable one from the point of
view of the phenotype ontology editors and users, as it is common in
ontologies for a variety of structures. For example:

And:

These patterns can be formally defended on developmental biology
grounds. "absence" here is \_not\_ equivalent to logical absence. It
refers specifically to developmental absence.

Furthermore, strict logical absence leads to undesirable inferences. It
would be odd to include a nematode worm as having the phenotype "spleen
absent", because worms have not evolved spleens. But the logical
description of not having a spleen as part fets a worm.

Similarly, if the strict cardinality interpretation were intended, we
would expect to see:

i.e. if you're missing your entire hindlegs, you're \*necessarily\*
missing your femurs. But it must be emphatisized that this is \*not\*
how phenotype ontologies are classified. This goes for a wide range of
structures and other relationship types. In MP, "absent limb buds" are
\*not\* classified under "absent limbs", even though it is impossible
for a mammal to have limbs without having had limb buds.

### Absence as part of a size-morphology spectrum

The existing treatment of absence can be formally defended
morphologically by conceiving of a morphological value space, with
"large" at one end and "small" at the other. As we get continuously
smaller, there may come an arbitrary point whereby we say "surely this
is no longer a limb" (and of course, we are not talking about a pure
geometrical size transformation here - as a limb reaches extreme edges
of a size range various other morphological changes necessarily happen).
But this cutoff is arguably arbitrary, and the resulting discontinuity
causes problems. It is simpler to treat absence as being one end of a
size scale.

Summary
-------

This is barely touching the subject, and is intended to illustrate that
things may be more subtle than naively treating words like "absent" as
precisely equivalent to cardinality=0. An understanding of the medical,
developmental and evolutionary contexts are absolutely required,
together with an understanding of the entailments of different logical
formulations.

Even though existing phenotype ontologies may not be conceived of
formally, it is implicit than they do not model absence as being
equivalent to cardinality=0 / not(has\_part), because the structure of
these ontologies would look radically different.

TODO
----

Link to Jim Balhoff's PhenoDay paper and discussion

Here's the link: <http://phenoday2014.bio-lark.org/pdf/11.pdf>


text:
1.  summary How inference of abnormality works

Introduction
============

The current design patterns are such that the abnormal qualifier is only
added when the quality class in the definition is neutral.

However, we still need to be able to infer

`* Hyoplasia of right ventricle SubClassOf Abnormality of right ventricle`

Because the latter class definition includes qualifier some abnormal,
the SubClassOf axiom will not be entailed unless the qualifier is
explicitly stated or inferred

Details
=======

We achieve this by including an axiom to PATO such that decreased sizes
etc are inferred to be qualifier some abnormal.

We do this with an exiom in imports/extra.owl

`* 'deviation(from normal)' SubClassOf qualifier some abnormal`

Anything under 'increased', 'decreased' etc in PATO is pre-reasoned in
PATO to be here.

See the following explanation:

<http://phenotype-ontologies.googlecode.com/svn/trunk/doc/images/has-qualifier-inference.png>

Limitations
===========

For this strategy to work it requires the PATO classes themselves to be
classified under deviation from normal. This may not always be the case

Notes
=====

Do not be distracted by the fact the has-qualifier relation is named
has-component at the moment

<https://code.google.com/p/phenotype-ontologies/issues/detail?id=45>

Notes
=====

repo_name: obophenotype/upheno

repo_language: Makefile

mime_type: text/plain


text:
# Cross-species reasoning use cases

Monarch
ETC


text:
# DOSDP documentation stub

Do not overwrite, contents will be generated automatically,


text:
# Basic ODK workflow
name: Docs

# Controls when the action will run.
on:
  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:
  push:
    branches:
      - master

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  build:
    name: Deploy docs
    runs-on: ubuntu-latest
    steps:
      - name: Checkout main
        uses: actions/checkout@v2

      - name: Deploy docs
        uses: mhausenblas/mkdocs-deploy-gh-pages@master
        # Or use mhausenblas/mkdocs-deploy-gh-pages@nomaterial to build without the mkdocs-material theme
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          CONFIG_FILE: mkdocs.yaml


text:
# This is a basic workflow to help you get started with Actions

name: CI

# Controls when the action will run.
on:
  # Triggers the workflow on push or pull request events but only for the master branch
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "ontology_qc"
  ontology_qc:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest
    container: obolibrary/odkfull:v1.3.0

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v2

      - name: Run ontology QC checks
        env:
          DEFAULT_BRANCH: master
        run: cd src/ontology && make ROBOT_ENV='ROBOT_JAVA_ARGS=-Xmx6G' upheno_test IMP=false PAT=true


text:
---
layout: ontology_detail
id: upheno
title: Unified Phenotype Ontology
jobs:
  - id: https://travis-ci.org/obophenotype/upheno
    type: travis-ci
build:
  checkout: git clone https://github.com/obophenotype/upheno.git
  system: git
  path: "."
contact:
  email:
  label:
  github:
description: Unified Phenotype Ontology is an ontology...
domain: stuff
homepage: https://github.com/obophenotype/upheno
products:
  - id: upheno.owl
    name: "Unified Phenotype Ontology main release in OWL format"
  - id: upheno.obo
    name: "Unified Phenotype Ontology additional release in OBO format"
  - id: upheno.json
    name: "Unified Phenotype Ontology additional release in OBOJSon format"
  - id: upheno/upheno-base.owl
    name: "Unified Phenotype Ontology main release in OWL format"
  - id: upheno/upheno-base.obo
    name: "Unified Phenotype Ontology additional release in OBO format"
  - id: upheno/upheno-base.json
    name: "Unified Phenotype Ontology additional release in OBOJSon format"
dependencies:
- id: nbo
- id: pr
- id: go
- id: uberon
- id: ro
- id: chebi
- id: hsapdv
- id: pato
- id: cl
- id: mpath

tracker: https://github.com/obophenotype/upheno/issues
license:
  url: http://creativecommons.org/licenses/by/3.0/
  label: CC-BY
activity_status: active
---

Enter a detailed description of your ontology here. You can use arbitrary markdown and HTML.
You can also embed images too.


text:
# PURL configuration for http://purl.obolibrary.org/obo/upheno

idspace: UPHENO
base_url: /obo/upheno

products:
- upheno.owl: https://raw.githubusercontent.com/obophenotype/upheno/main/upheno.owl
- upheno.obo: https://raw.githubusercontent.com/obophenotype/upheno/main/upheno.obo

term_browser: ontobee
example_terms:
- UPHENO_0000000

entries:

- prefix: /releases/
  replacement: https://raw.githubusercontent.com/obophenotype/upheno/v

- prefix: /tracker/
  replacement: https://github.com/obophenotype/upheno/issues

- prefix: /about/
  replacement: http://www.ontobee.org/ontology/UPHENO?iri=http://purl.obolibrary.org/obo/

## generic fall-through, serve direct from github by default
- prefix: /
  replacement: https://raw.githubusercontent.com/obophenotype/upheno/main/


text:
Metadata files for the OBO Library

 * [upheno.yml](upheno.yml)
     * Determines how your purl.obolibrary.org/obo/upheno/ redirects will be handled
     * Go here: https://github.com/OBOFoundry/purl.obolibrary.org/tree/master/config
     * Click [New File](https://github.com/OBOFoundry/purl.obolibrary.org/new/master/config)
     * Paste in the contents of [upheno.yml](upheno.yml)
     * Click "Commit new file"
     * IMPORTANT: remember to make a pull request
     * An OBO admin will merge your Pull Request *providing it meets the requirements of the OBO library*
 * [upheno.md](upheno.md)
     * Determines how your metadata is shown on OBO Library, OLS and AberOWL
     * Go here: https://github.com/OBOFoundry/OBOFoundry.github.io/tree/master/ontology
     * Click [New File](https://github.com/OBOFoundry/OBOFoundry.github.io/new/master/ontology)
     * Paste in the contents of [upheno.md](upheno.md)
     * Click "Commit new file"
     * IMPORTANT: remember to make a pull request
     * An OBO admin will merge your Pull Request *providing it meets the requirements of the OBO library*

For more background see:

 * http://obofoundry.org/
 * http://obofoundry.org/faq/how-do-i-edit-metadata.html


text:
SELECT DISTINCT ?term
WHERE {
  { ?s1 ?p1 ?term . }
  UNION
  { ?term ?p2 ?o2 . }
  FILTER(isIRI(?term) && (STRSTARTS(str(?term), "http://purl.obolibrary.org/obo/UPHENO_") || STRSTARTS(str(?term), "http://purl.obolibrary.org/obo/UPHENO_")))
}


text:
# home: hp/sparql/trailing-whitespace-violation.sparql
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>

SELECT ?c ?p ?x WHERE
{
  ?c ?p ?x .

  FILTER( regex(STR(?x), "^ ") || regex(STR(?x), " $")  )
  FILTER( ?p != owl:annotatedTarget )
}


text:
prefix oio: <http://www.geneontology.org/formats/oboInOwl#>
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>

SELECT ?baseClass ?baseLabel ?equivalentClass ?equivalentLabel WHERE
{
  ?baseClass owl:equivalentClass ?equivalentClass .
  ?baseClass rdfs:label ?baseLabel .
  ?equivalentClass rdfs:label ?equivalentLabel .

  FILTER (!isBlank(?baseClass)) .
  FILTER (!isBlank(?equivalentClass))

}


text:
prefix obo: <http://purl.obolibrary.org/obo/>
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

SELECT ?x ?p ?y
WHERE {
  {?x rdfs:subClassOf [
    a owl:Restriction ;
    owl:onProperty ?p ;
    owl:someValuesFrom ?y ]
  }
  UNION {
   ?x rdfs:subClassOf ?y .
   BIND(rdfs:subClassOf AS ?p)
  }
  ?x a owl:Class .
  ?y a owl:Class .
}


text:
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX replaced_by: <http://purl.obolibrary.org/obo/IAO_0100001>
PREFIX consider: <http://www.geneontology.org/formats/oboInOwl#consider>

SELECT ?cls ?replCls ?consCls WHERE {
       ?cls a owl:Class  ;
	    owl:deprecated "true"^^xsd:boolean .
	OPTIONAL {?cls replaced_by: ?replCls}
	OPTIONAL {?cls consider: ?consCls}
}
ORDER BY ?cls


text:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX owl: <http://www.w3.org/2002/07/owl#>

DELETE {
  ?ontology ?ontology_annotation_property ?ontology_annotation_value .
}

WHERE {
  ?ontology rdf:type owl:Ontology .
  ?ontology ?ontology_annotation_property ?ontology_annotation_value .
  FILTER(?ontology_annotation_property != dc:source && ?ontology_annotation_property != rdf:type)

}


text:
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix oboInOwl: <http://www.geneontology.org/formats/oboInOwl#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>

SELECT ?cls ?pred ?val ?synType
WHERE
  { ?cls ?pred ?val ;
         a owl:Class .
    FILTER (
    ?pred = rdfs:label ||
    ?pred = oboInOwl:hasRelatedSynonym ||
    ?pred = oboInOwl:hasNarrowSynonym ||
    ?pred = oboInOwl:hasBroadSynonym ||
    ?pred = oboInOwl:hasExactSynonym
    )

    OPTIONAL {
      [
       a owl:Axiom ;
         owl:annotatedSource ?cls ;
         owl:annotatedProperty ?pred ;
         owl:annotatedTarget ?val ;
         oboInOwl:hasSynonymType ?synType
      ]
    }
  }


text:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

SELECT ?term ?value
WHERE {
  ?term rdfs:label ?value .
  FILTER (REGEX(?value, "http[s]?[:]"))
  FILTER(isIRI(?term) && (STRSTARTS(str(?term), "http://purl.obolibrary.org/obo/UPHENO_") || STRSTARTS(str(?term), "http://purl.obolibrary.org/obo/UPHENO_")))
}


text:
prefix oio: <http://www.geneontology.org/formats/oboInOwl#>
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>

WELECT *
WHERE {
  ?c rdfs:subClassOf ?d ;
     owl:equivalentClass [
        owl:intersectionOf TODO


text:
prefix oio: <http://www.geneontology.org/formats/oboInOwl#>
prefix def: <http://purl.obolibrary.org/obo/IAO_0000115>
prefix owl: <http://www.w3.org/2002/07/owl#>

SELECT ?cls ?def (group_concat(?xref) as ?xrefs) WHERE
{
  ?cls a owl:Class .
  OPTIONAL { ?cls oio:hasDbXref ?xref } .
  OPTIONAL { ?cls def: ?def } .
  FILTER (!isBlank(?cls))
}
GROUP BY ?cls ?def


text:
# home: hp
prefix hasDbXref: <http://www.geneontology.org/formats/oboInOwl#hasDbXref>
prefix oio: <http://www.geneontology.org/formats/oboInOwl#>
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>

SELECT ?c ?x WHERE
{
  ?c hasDbXref: ?x .

  FILTER( regex(STR(?x), " ") || regex(STR(?x), ";") || STR(?x) = ""  )

}


text:
prefix oio: <http://www.geneontology.org/formats/oboInOwl#>
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>

SELECT ?x ?xl ?y ?yl ?z ?zl WHERE
{
  ?x rdfs:subClassOf ?y ;
     rdfs:label ?xl .
  ?y rdfs:subClassOf+ ?z ;
     rdfs:label ?yl .
  ?x rdfs:subClassOf ?z .
  ?z rdfs:label ?zl .

}


text:
SELECT DISTINCT ?term
WHERE {
  { ?s1 ?p1 ?term . }
  UNION
  { ?term ?p2 ?o2 . }
  FILTER(isIRI(?term) && regex(str(?term), "http://purl.obolibrary.org/obo/UBERON_"))
}


text:
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix obo: <http://purl.obolibrary.org/obo/>

SELECT DISTINCT ?cls WHERE
{
  {?cls a owl:AnnotationProperty .}
  UNION
  {?cls a owl:ObjectProperty .}
  UNION
  {?x <http://www.geneontology.org/formats/oboInOwl#inSubset> ?cls}
  UNION
  {?x <http://www.geneontology.org/formats/oboInOwl#hasSynonymType> ?cls}
  FILTER (!isBlank(?cls))
}


text:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX dc: <http://purl.org/dc/terms/>

CONSTRUCT {
  <http://purl.obolibrary.org/obo/upheno/imports/zfa_import.owl> a owl:Ontology .
  <http://purl.obolibrary.org/obo/upheno/imports/zfa_import.owl> dc:source <http://purl.obolibrary.org/obo/zfa.owl> .
  <http://purl.obolibrary.org/obo/upheno/imports/zfa_import.owl> dc:requires <http://purl.obolibrary.org/obo/uberon/bridge/uberon-bridge-to-zfa.owl> .
  <http://purl.obolibrary.org/obo/upheno/imports/zfa_import.owl> dc:requires <http://purl.obolibrary.org/obo/uberon/bridge/cl-bridge-to-zfa.owl> .
  ?term a owl:Class .
  ?term ?p ?o .
  ?p a owl:AnnotationProperty .
  ?annotation a owl:Axiom .
  ?annotation owl:annotatedSource ?term .
  ?annotation owl:annotatedProperty ?p .
  ?annotation owl:annotatedTarget ?o .
  ?annotation ?ap ?ao .
  ?term rdfs:subClassOf ?super .
}
WHERE {
  ?term a owl:Class .
  ?term ?p ?o .
  ?p a owl:AnnotationProperty .
  FILTER(isIRI(?term))
  OPTIONAL {
    ?annotation a owl:Axiom .
    ?annotation owl:annotatedSource ?term .
    ?annotation owl:annotatedProperty ?p .
    ?annotation owl:annotatedTarget ?o .
    ?annotation ?ap ?ao .
  }
  OPTIONAL {
    ?term rdfs:subClassOf ?super .
    FILTER(isIRI(?super))
    FILTER NOT EXISTS {
      # Only include subclass axioms for terms that do not have a mapping in the uberon-bridge.
      # This works because ZFA has no equivalent class axioms at the current time.
      ?term owl:equivalentClass ?uberon_expression .
    }
  }
}


text:
prefix oio: <http://www.geneontology.org/formats/oboInOwl#>
prefix owl: <http://www.w3.org/2002/07/owl#>

SELECT ?defined_class ?xref WHERE
{
  ?defined_class a owl:Class ;
     oio:hasDbXref ?xref .
     FILTER(regex(str(?xref), "UBERON"))
}


text:
PREFIX : <http://www.test.com/ns/test#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

INSERT { ?y rdfs:subPropertyOf <http://www.geneontology.org/formats/oboInOwl#SubsetProperty> . }

WHERE {
  ?x <http://www.geneontology.org/formats/oboInOwl#inSubset>  ?y .
  FILTER(isIRI(?y))
  FILTER(regex(str(?y),"^(http://purl.obolibrary.org/obo/)") || regex(str(?y),"^(http://www.ebi.ac.uk/efo/)") || regex(str(?y),"^(https://w3id.org/biolink/)"))
}


text:
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

SELECT ?x (STR(?lab) AS ?label) WHERE {
	?x rdf:type owl:Class .
	OPTIONAL {?x rdfs:label ?lab}
}
ORDER BY ?x


text:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix owl: <http://www.w3.org/2002/07/owl#>
SELECT DISTINCT ?term
WHERE {
  {
    ?s1 ?p1 ?term .
    FILTER(?p1!=rdf:type)
  }
  UNION
  {
    ?term ?p2 ?o2 .
    FILTER(?o2!=owl:Ontology)
  }
  FILTER(isIRI(?term))
}


text:
PREFIX rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX oio: <http://www.geneontology.org/formats/oboInOwl#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

SELECT ?term WHERE {
  { ?term owl:equivalentClass [ owl:intersectionOf [ rdf:rest*/rdf:first ?term ] ] }
    UNION
  { ?term owl:equivalentClass [ owl:intersectionOf [ rdf:rest*/rdf:first [ owl:someValuesFrom ?term ] ] ] }
  FILTER(isIRI(?term) && (STRSTARTS(str(?term), "http://purl.obolibrary.org/obo/UPHENO_") || STRSTARTS(str(?term), "http://purl.obolibrary.org/obo/UPHENO_")))
}


text:
prefix oio: <http://www.geneontology.org/formats/oboInOwl#>
prefix def: <http://purl.obolibrary.org/obo/IAO_0000115>
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix inSubset: <http://www.geneontology.org/formats/oboInOwl#inSubset>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>

SELECT  ?subset ?clsLabel
WHERE
{
  ?cls a owl:Class ;
       inSubset: ?subset ;
       rdfs:label ?clsLabel
}
ORDER BY ?subset ?cls


text:
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix obo: <http://purl.obolibrary.org/obo/>

SELECT ?prefix (COUNT(DISTINCT ?cls) AS ?numberOfClasses) WHERE
{
  ?cls a owl:Class .
  FILTER (!isBlank(?cls))
  BIND( STRBEFORE(STRAFTER(str(?cls),"http://purl.obolibrary.org/obo/"), "_") AS ?prefix)
}
GROUP BY ?prefix


text:
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX replaced_by: <http://purl.obolibrary.org/obo/IAO_0100001>
PREFIX consider: <http://www.geneontology.org/formats/oboInOwl#consider>

SELECT ?cls ?clsLabel ?rule WHERE {
       ?cls a owl:Class  ;
            rdfs:label ?clsLabel ;
	    owl:deprecated "true"^^xsd:boolean
        {
          {
            FILTER ( ! regex(str(?clsLabel), "^obsolete ") )
            BIND ("obsolete label must start with obsolete" AS ?rule)
          }
          UNION
          {
            ?cls rdfs:subClassOf ?parent
            BIND("no logical axioms for obsolete" AS ?rule)
          }
        }
}
ORDER BY ?cls


text:
PREFIX never_in_taxon: <http://purl.obolibrary.org/obo/RO_0002161>
PREFIX present_in_taxon: <http://purl.obolibrary.org/obo/RO_0002175>
PREFIX oboInOwl: <http://www.geneontology.org/formats/oboInOwl#>
PREFIX dcterms: <http://purl.org/dc/terms/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>

SELECT ?term ?property ?value
WHERE {
  VALUES ?property {
    never_in_taxon:
    present_in_taxon:
    foaf:depicted_by
    oboInOwl:inSubset
    dcterms:contributor  }
  ?term ?property ?value .
  FILTER(isIRI(?term) && (STRSTARTS(str(?term), "http://purl.obolibrary.org/obo/UPHENO_") || STRSTARTS(str(?term), "http://purl.obolibrary.org/obo/UPHENO_")))
  FILTER (!isIRI(?value))
}


text:
SELECT DISTINCT ?term
WHERE {
  ?s ?p ?term .
  FILTER(isIRI(?term))
}


text:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX owl: <http://www.w3.org/2002/07/owl#>

#DELETE {
#  ?ontology ?ontology_annotation_property ?ontology_annotation_value .
#}

INSERT {
    ?ontology dc:source ?version_iri .
}

WHERE {
  ?ontology rdf:type owl:Ontology ;
        owl:versionIRI ?version_iri .
  #OPTIONAL {
  #  ?ontology ?ontology_annotation_property ?ontology_annotation_value .
  #}

}


text:
prefix oio: <http://www.geneontology.org/formats/oboInOwl#>
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>

SELECT ?baseClass ?baseLabel ?equivalentClass ?equivalentLabel WHERE
{
  ?baseClass owl:equivalentClass ?equivalentClass .
  ?baseClass rdfs:label ?baseLabel .
  ?equivalentClass rdfs:label ?equivalentLabel .

  FILTER (!isBlank(?baseClass)) .
  FILTER (!isBlank(?equivalentClass))

}


text:
prefix oio: <http://www.geneontology.org/formats/oboInOwl#>
prefix owl: <http://www.w3.org/2002/07/owl#>

SELECT ?cls ?xref WHERE
{
  ?cls a owl:Class ;
     oio:hasDbXref ?xref
}


text:
prefix oio: <http://www.geneontology.org/formats/oboInOwl#>
prefix def: <http://purl.obolibrary.org/obo/IAO_0000115>
prefix owl: <http://www.w3.org/2002/07/owl#>

SELECT ?cls ?def (group_concat(?xref) as ?xrefs) WHERE
{
  ?cls a owl:Class .
  OPTIONAL { ?cls oio:hasDbXref ?xref } .
  OPTIONAL { ?cls def: ?def } .
  FILTER (!isBlank(?cls))
}
GROUP BY ?cls ?def


text:
# Sparql checks

[SPARQL](https://www.w3.org/TR/rdf-sparql-query/) is a W3C standard
query language for RDF. This directory contains useful SPARQL queries
for perfoming over the ontology.

SPARQL can be executed on a triplestore or directly on any OWL
file. The queries here are all executed on either upheno-edit.obo or
downstream products in the [ontology](../ontology/) folder. We use
`robot` as this allows easy execution over any Obo-format or OWL file.

We break the queries into 3 categories:

## Constraint Violation checks

These are all named `*violation.sparql`. A subset of these are
configured to be executed via travis. If these return any results,
then the build will fail.

Consult the individual sparql files to see the intent of the check

## Construct queries

These are named `construct*.sparql`, and always have the form `CONSTRUCT ...`.

These are used to generate new OWL axioms that can be inserted back
into the ontology.

## Reports

The remaining SPARQL queries are for informative purposes. A subset
may be executed with each release.


text:
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX replaced_by: <http://purl.obolibrary.org/obo/IAO_0100001>

SELECT ?cls WHERE {
	?cls a owl:Class
	FILTER NOT EXISTS {?cls rdfs:label ?lab}
	FILTER NOT EXISTS {?cls replaced_by: ?replCls}
        FILTER (!isBlank(?cls))
        FILTER ( regex(str(?cls), "^http://purl.obolibrary.org/obo/GO_"))
}
ORDER BY ?cls


text:
Prefix(:=<http://purl.obolibrary.org/obo/upheno.owl#>)
Prefix(owl:=<http://www.w3.org/2002/07/owl#>)
Prefix(rdf:=<http://www.w3.org/1999/02/22-rdf-syntax-ns#>)
Prefix(xml:=<http://www.w3.org/XML/1998/namespace>)
Prefix(xsd:=<http://www.w3.org/2001/XMLSchema#>)
Prefix(rdfs:=<http://www.w3.org/2000/01/rdf-schema#>)
Prefix(dce:=<http://purl.org/dc/elements/1.1/>)
Prefix(dcterms:=<http://purl.org/dc/terms/>)

Ontology(<http://purl.obolibrary.org/obo/upheno.owl>

Import(<http://purl.obolibrary.org/obo/upheno/imports/nbo_import.owl>)

Import(<http://purl.obolibrary.org/obo/upheno/imports/pr_import.owl>)

Import(<http://purl.obolibrary.org/obo/upheno/imports/go_import.owl>)

Import(<http://purl.obolibrary.org/obo/upheno/imports/uberon_import.owl>)

Import(<http://purl.obolibrary.org/obo/upheno/imports/ro_import.owl>)

Import(<http://purl.obolibrary.org/obo/upheno/imports/chebi_import.owl>)

Import(<http://purl.obolibrary.org/obo/upheno/imports/hsapdv_import.owl>)

Import(<http://purl.obolibrary.org/obo/upheno/imports/pato_import.owl>)

Import(<http://purl.obolibrary.org/obo/upheno/imports/cl_import.owl>)

Import(<http://purl.obolibrary.org/obo/upheno/imports/mpath_import.owl>)

Import(<http://purl.obolibrary.org/obo/upheno/patterns/definitions.owl>)

Annotation(dce:title "Unified Phenotype Ontology")
Annotation(dcterms:license <https://creativecommons.org/licenses/unspecified>)
Annotation(dce:description "None")

Declaration(Class(<http://purl.obolibrary.org/obo/UPHENO_00000000>))

############################
#   Classes
############################

# Class: <http://purl.obolibrary.org/obo/UPHENO_00000000>

AnnotationAssertion(rdfs:label <http://purl.obolibrary.org/obo/UPHENO_00000000> "root node"@en)

)


text:
## ID Ranges File
Prefix: rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
Prefix: idsfor: <http://purl.obolibrary.org/obo/IAO_0000598>
Prefix: dc: <http://purl.org/dc/elements/1.1/>
Prefix: xsd: <http://www.w3.org/2001/XMLSchema#>
Prefix: allocatedto: <http://purl.obolibrary.org/obo/IAO_0000597>
Prefix: xml: <http://www.w3.org/XML/1998/namespace>
Prefix: idprefix: <http://purl.obolibrary.org/obo/IAO_0000599>
Prefix: iddigits: <http://purl.obolibrary.org/obo/IAO_0000596>
Prefix: rdfs: <http://www.w3.org/2000/01/rdf-schema#>
Prefix: idrange: <http://purl.obolibrary.org/obo/ro/idrange/>
Prefix: owl: <http://www.w3.org/2002/07/owl#>

Ontology: <http://purl.obolibrary.org/obo/upheno/upheno-idranges.owl>

Annotations:
    idsfor: "UPHENO",
    idprefix: "http://purl.obolibrary.org/obo/UPHENO_",
    iddigits: 7

AnnotationProperty: idprefix:

AnnotationProperty: iddigits:

AnnotationProperty: idsfor:

AnnotationProperty: allocatedto:

Datatype: idrange:1

    Annotations:
        allocatedto: "ONTOLOGY-CREATOR"

    EquivalentTo:
        xsd:integer[>= 0 , <= 999999]

Datatype: idrange:2

    Annotations:
        allocatedto: "ADDITIONAL EDITOR"

    EquivalentTo:
        xsd:integer[>= 1000000 , <= 1999999]

Datatype: xsd:integer
Datatype: rdf:PlainLiteral


text:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<catalog prefer="public" xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<group id="Folder Repository, directory=, recursive=false, Auto-Update=false, version=2" prefer="public" xml:base="">

  <uri name="http://purl.obolibrary.org/obo/upheno/imports/nbo_import.owl" uri="imports/nbo_import.owl"/>
  <uri name="http://purl.obolibrary.org/obo/upheno/imports/nbo_import.obo" uri="imports/nbo_import.obo"/>

  <uri name="http://purl.obolibrary.org/obo/upheno/imports/pr_import.owl" uri="imports/pr_import.owl"/>
  <uri name="http://purl.obolibrary.org/obo/upheno/imports/pr_import.obo" uri="imports/pr_import.obo"/>

  <uri name="http://purl.obolibrary.org/obo/upheno/imports/go_import.owl" uri="imports/go_import.owl"/>
  <uri name="http://purl.obolibrary.org/obo/upheno/imports/go_import.obo" uri="imports/go_import.obo"/>

  <uri name="http://purl.obolibrary.org/obo/upheno/imports/uberon_import.owl" uri="imports/uberon_import.owl"/>
  <uri name="http://purl.obolibrary.org/obo/upheno/imports/uberon_import.obo" uri="imports/uberon_import.obo"/>

  <uri name="http://purl.obolibrary.org/obo/upheno/imports/ro_import.owl" uri="imports/ro_import.owl"/>
  <uri name="http://purl.obolibrary.org/obo/upheno/imports/ro_import.obo" uri="imports/ro_import.obo"/>

  <uri name="http://purl.obolibrary.org/obo/upheno/imports/chebi_import.owl" uri="imports/chebi_import.owl"/>
  <uri name="http://purl.obolibrary.org/obo/upheno/imports/chebi_import.obo" uri="imports/chebi_import.obo"/>

  <uri name="http://purl.obolibrary.org/obo/upheno/imports/hsapdv_import.owl" uri="imports/hsapdv_import.owl"/>
  <uri name="http://purl.obolibrary.org/obo/upheno/imports/hsapdv_import.obo" uri="imports/hsapdv_import.obo"/>

  <uri name="http://purl.obolibrary.org/obo/upheno/imports/pato_import.owl" uri="imports/pato_import.owl"/>
  <uri name="http://purl.obolibrary.org/obo/upheno/imports/pato_import.obo" uri="imports/pato_import.obo"/>

  <uri name="http://purl.obolibrary.org/obo/upheno/imports/cl_import.owl" uri="imports/cl_import.owl"/>
  <uri name="http://purl.obolibrary.org/obo/upheno/imports/cl_import.obo" uri="imports/cl_import.obo"/>

  <uri name="http://purl.obolibrary.org/obo/upheno/imports/mpath_import.owl" uri="imports/mpath_import.owl"/>
  <uri name="http://purl.obolibrary.org/obo/upheno/imports/mpath_import.obo" uri="imports/mpath_import.obo"/>

  <uri name="http://purl.obolibrary.org/obo/upheno/patterns/definitions.owl" uri="../patterns/definitions.owl"/>
</group>
</catalog>


text:
#!/bin/sh
# Wrapper script for docker.
#
# This is used primarily for wrapping the GNU Make workflow.
# Instead of typing "make TARGET", type "./run.sh make TARGET".
# This will run the make workflow within a docker container.
#
# The assumption is that you are working in the src/ontology folder;
# we therefore map the whole repo (../..) to a docker volume.
#
# See README-editors.md for more details.

IMAGE=${IMAGE:-odkfull}

ODK_DEBUG=${ODK_DEBUG:-no}

TIMECMD=
if [ x$ODK_DEBUG = xyes ]; then
    # If you wish to change the format string, take care of using
    # non-breaking spaces (U+00A0) instead of normal spaces, to
    # prevent the shell from tokenizing the format string.
    TIMECMD="/usr/bin/time -f ### DEBUG STATS ###\nElapsed time: %E\nPeak memory: %M kb"
fi

docker run -v $PWD/../../:/work -w /work/src/ontology -e ROBOT_JAVA_ARGS='-Xmx10G' -e JAVA_OPTS='-Xmx10G' --rm -ti obolibrary/$IMAGE $TIMECMD "$@"


text:
## Customize Makefile settings for upheno
##
## If you need to customize your Makefile, make
## changes here rather than in the main Makefile

OBO=http://purl.obolibrary.org/obo
OT_MEMO=160G
OWLTOOLS=OWLTOOLS_MEMORY=$(OT_MEMO) owltools --no-logging

$(TMPDIR)/pattern_schema_checks_dev: $(ALL_PATTERN_FILES) | $(TMPDIR)
	$(PATTERN_TESTER) $(PATTERNDIR)/dosdp-dev/ && touch $@

$(TMPDIR)/pattern_schema_checks_main: $(ALL_PATTERN_FILES) | $(TMPDIR)
	$(PATTERN_TESTER) $(PATTERNDIR)/dosdp-patterns/ && touch $@

../patterns/pattern-dev.owl: $(TMPDIR)/pattern_schema_checks_dev
	$(DOSDPT) prototype --obo-prefixes true --template=../patterns/dosdp-dev --outfile=$@

../patterns/pattern-main.owl: $(TMPDIR)/pattern_schema_checks_main
	$(DOSDPT) prototype --obo-prefixes true --template=../patterns/dosdp-patterns --outfile=$@

../patterns/pattern-merged.owl: ../patterns/pattern-dev.owl ../patterns/pattern-main.owl
	$(ROBOT) merge -i ../patterns/pattern-dev.owl -i ../patterns/pattern-main.owl annotate -V $(ONTBASE)/releases/`date +%Y-%m-%d`/$(ONT)-pattern.owl annotate --ontology-iri $(ONTBASE)/$(ONT)-pattern.owl -o $@

../patterns/imports/seed.txt: ../patterns/pattern-merged.owl
	$(ROBOT) query -f csv -i $< --query ../sparql/terms.sparql $@

../patterns/imports/seed_sorted.txt: ../patterns/imports/seed.txt
	cat ../patterns/imports/seed.txt | sort | uniq > $@

PATTERN_IMPORTS = pato ro uberon go cl caro uberon-bridge-to-caro chebi mpath nbo
PATTERN_IMPORTS_OWL = $(patsubst %, ../patterns/imports/%_import.owl, $(PATTERN_IMPORTS))
../patterns/imports/%_import.owl: mirror/%.owl ../patterns/imports/seed_sorted.txt
	if [ $(MIR) = true ] && [ $(IMP) = true ]; then $(ROBOT) extract -i $< -T ../patterns/imports/seed_sorted.txt --method BOT -O mirror/$*.owl annotate --ontology-iri $(OBO)/$(ONT)/patterns/imports/$*_import.owl -o $@; fi

mirror/uberon-bridge-to-caro.owl:
	if [ $(MIR) = true ] && [ $(IMP) = true ]; then $(ROBOT) convert -I http://purl.obolibrary.org/obo/uberon/bridge/uberon-bridge-to-caro.owl -o $@.tmp.owl && mv $@.tmp.owl $@; fi
.PRECIOUS: mirror/uberon-bridge-to-caro.owl

../patterns/pattern-with-imports.owl: ../patterns/pattern-merged.owl $(PATTERN_IMPORTS_OWL)
	$(ROBOT) merge $(addprefix -i , $^) unmerge -i components/pattern-ontology-remove-axioms.owl -o $@

../patterns/pattern.owl: ../patterns/pattern-with-imports.owl
	$(ROBOT) merge -i ../patterns/pattern-with-imports.owl remove --term http://www.w3.org/2002/07/owl#Nothing reason reduce annotate --ontology-iri $(OBO)/$(ONT)/patterns/pattern.owl -o $@

../patterns/pattern-simple.owl: ../patterns/pattern.owl
	$(ROBOT) merge -i ../patterns/pattern.owl \
	filter --select "<http://purl.obolibrary.org/obo/upheno/patterns*>" --select "self annotations" --signature true --trim true -o ../patterns/pattern-simple.owl

../patterns/dosdp-patterns/README.md: .FORCE
	python ../scripts/patterns_create_overview.py "../patterns/dosdp-patterns|../patterns/dosdp-dev" $@

.PHONY: pattern_ontology
pattern_ontology: ../patterns/pattern-simple.owl

.PHONY: pattern_readmes
pattern_readmes: ../patterns/dosdp-patterns/README.md

.PHONY: upheno_test
upheno_test: $(TMPDIR)/pattern_schema_checks_main $(TMPDIR)/pattern_schema_checks_dev ../patterns/pattern-simple.owl

##################################################
####### Similarity tables ########################
##################################################

hp_mp_phenodigm_2_5.tsv: mp_hp.owl
	$(OWLTOOLS) $< --sim-save-phenodigm-class-scores -m 2.5 -x HP,MP -a $@

####################################################

PATTERN_IN=https://docs.google.com/spreadsheets/d/e/2PACX-1vRb36ExWkOYjM9Mc-IpbEev5o9nlkOUf9xQbdaSB-oD5l4K6CkSLZv3-xLlaPJWCQKhlW0R4tXVifqv/pub?gid=510110305&single=true&output=tsv
PATTERN_TEMPLATE=../patterns/dosdp-dev/fracturedAnatomicalEntity.yaml

#PATTERN_IN=https://docs.google.com/spreadsheets/d/e/2PACX-1vSj7QlW6Skmw4g9cy4kNWFx4634TTchAHCbd7MKL_Hpf9Dba2l8fv16f7H_4lLfuOpV1davS-oZ_uzl/pub?gid=657591629&single=true&output=tsv
#PATTERN_TEMPLATE=../patterns/dosdp-dev/abnormalProportionOfCellTypeInLocation.yaml

generated_pattern.tsv:
	wget "$(PATTERN_IN)" -O $@

generated_pattern.owl: generated_pattern.tsv
	$(DOSDPT) generate --infile=$< --template=$(PATTERN_TEMPLATE) --ontology=../patterns/pattern.owl --obo-prefixes=true --outfile=$@

gp: generated_pattern.owl


text:
id: upheno
title: "Unified Phenotype Ontology"
github_org: obophenotype
git_main_branch: master
repo: upheno
report_fail_on: none
use_dosdps: TRUE
dosdp_tools_options: "--obo-prefixes=true --restrict-axioms-to=logical"
robot_opts: -vv
robot_java_args: -Xmx10G
timeout_external_processes: 36000
working_directory: /work/src
overwrite_matches: False
skip_pattern_download: True
max_upheno_id: 9999999
min_upheno_id: 500
overwrite_ontologies: False
overwrite_upheno_intermediate: True
match_owl_thing: False
allow_non_upheno_eq: False
upheno_axiom_blacklist: ../ontology/components/upheno-removed-axioms.owl
clean: False
upheno_intermediate_layer_depth: 0
namespaces:
  - http://purl.obolibrary.org/obo/UPHENO_
legal_fillers:
  - http://purl.obolibrary.org/obo/GO_
  - http://purl.obolibrary.org/obo/UBERON_
  - http://purl.obolibrary.org/obo/NBO_
  - http://purl.obolibrary.org/obo/PR_
  - http://purl.obolibrary.org/obo/CHEBI_
  - http://purl.obolibrary.org/obo/PATO_
remove_disjoints:
  - http://purl.obolibrary.org/obo/BFO_0000002
  - http://purl.obolibrary.org/obo/BFO_0000003
  - http://purl.obolibrary.org/obo/BFO_0000004
  - http://purl.obolibrary.org/obo/UBERON_0000466
  - http://purl.obolibrary.org/obo/BFO_0000040
  - http://purl.obolibrary.org/obo/BFO_0000050
  - http://purl.obolibrary.org/obo/GO_0003674
  - http://purl.obolibrary.org/obo/GO_0005575
  - http://purl.obolibrary.org/obo/GO_0008150
  - http://purl.obolibrary.org/obo/CL_0000000
  - http://purl.obolibrary.org/obo/GO_0043226
  - http://purl.obolibrary.org/obo/GO_0005623
  - http://purl.obolibrary.org/obo/UBERON_0004367
  - http://purl.obolibrary.org/obo/UBERON_0001135
  - http://purl.obolibrary.org/obo/UBERON_0000476
blacklisted_upheno_iris:
  - http://purl.obolibrary.org/obo/UPHENO_0000001
  - http://purl.obolibrary.org/obo/UPHENO_0000501
  - http://purl.obolibrary.org/obo/UPHENO_0000502
  - http://purl.obolibrary.org/obo/UPHENO_0000503
  - http://purl.obolibrary.org/obo/UPHENO_0000504
  - http://purl.obolibrary.org/obo/UPHENO_0000505
  - http://purl.obolibrary.org/obo/UPHENO_0000506
  - http://purl.obolibrary.org/obo/UPHENO_0001001
  - http://purl.obolibrary.org/obo/UPHENO_0001002
  - http://purl.obolibrary.org/obo/UPHENO_0001003
  - http://purl.obolibrary.org/obo/UPHENO_9000001
  - http://purl.obolibrary.org/obo/UPHENO_9000002
  - http://purl.obolibrary.org/obo/UPHENO_9000003
  - http://purl.obolibrary.org/obo/UPHENO_9000004
instantiate_superclasses_pattern_vars:
  - anatomical_entity
  - biological_process
sources:
  - id: fbbt
    mirror_from: http://purl.obolibrary.org/obo/fbbt/fbbt-base.owl
  - id: fbdv
    mirror_from: http://purl.obolibrary.org/obo/fbdv/fbdv-base.owl
  - id: nbo
    mirror_from: http://purl.obolibrary.org/obo/nbo/nbo-base.owl
  - id: pr
    mirror_from: http://purl.obolibrary.org/obo/pr.owl.gz
  - id: go
    mirror_from: http://purl.obolibrary.org/obo/go/go-base.owl
  - id: uberon
    mirror_from: http://purl.obolibrary.org/obo/uberon/uberon-base.owl
  - id: ro
    mirror_from: http://purl.obolibrary.org/obo/ro.owl
  - id: chebi
    mirror_from: http://purl.obolibrary.org/obo/chebi.owl
  - id: hsapdv
    mirror_from: http://purl.obolibrary.org/obo/hsapdv.owl
  - id: pato
    mirror_from: http://purl.obolibrary.org/obo/pato.owl
  - id: cl
    mirror_from: http://purl.obolibrary.org/obo/cl/cl-base.owl
  - id: mpath
    mirror_from: http://purl.obolibrary.org/obo/mpath.owl
  - id: iao
    mirror_from: http://purl.obolibrary.org/obo/iao.owl
  - id: bspo
    mirror_from: http://purl.obolibrary.org/obo/bspo.owl
  - id: hsapdv
    mirror_from: http://purl.obolibrary.org/obo/hsapdv.owl
  - id: wbls
    mirror_from: http://purl.obolibrary.org/obo/wbls.owl
  - id: wbbt
    mirror_from: http://purl.obolibrary.org/obo/wbbt.owl
  - id: ncbitaxon
    mirror_from: http://purl.obolibrary.org/obo/ncbitaxon/subsets/taxslim.owl
  - id: plana
    mirror_from: http://purl.obolibrary.org/obo/plana.owl
  - id: bfo
    mirror_from: http://purl.obolibrary.org/obo/bfo.owl
  - id: zfa
    mirror_from: http://purl.obolibrary.org/obo/zfa.owl
  - id: ncit
    mirror_from: http://purl.obolibrary.org/obo/ncit.owl
  - id: xao
    mirror_from: http://purl.obolibrary.org/obo/xao.owl
  - id: zfa-uberon
    mirror_from: http://purl.obolibrary.org/obo/uberon/bridge/uberon-bridge-to-zfa.owl
  - id: bspo-uberon
    mirror_from: https://raw.githubusercontent.com/obophenotype/uberon/master/bridge/uberon-bridge-to-bspo.obo
  - id: caro-uberon
    mirror_from: http://purl.obolibrary.org/obo/uberon/bridge/uberon-bridge-to-caro.owl
  - id: xao-uberon
    mirror_from: http://purl.obolibrary.org/obo/uberon/bridge/uberon-bridge-to-xao.owl
  - id: wbbt-uberon
    mirror_from: http://purl.obolibrary.org/obo/uberon/bridge/uberon-bridge-to-wbbt.owl
  #- id: plana-uberon
  #  mirror_from: xref
  - id: mp
    mirror_from: http://purl.obolibrary.org/obo/mp/mp-base.owl
    taxon: http://purl.obolibrary.org/obo/MP
    taxon_label: MPO
    modifier: PATO:0000460
    root: http://purl.obolibrary.org/obo/MP_0000001
    prefix_iri: http://purl.obolibrary.org/obo/MP_
    class_hierarchy: asserted
    dependencies:
      - nbo
      - pr
      - chebi
      - cl
      - mpath
  - id: hp
    taxon: http://purl.obolibrary.org/obo/HP
    taxon_label: HPO
    root: http://purl.obolibrary.org/obo/HP_0000118
    prefix_iri: http://purl.obolibrary.org/obo/HP_
    mirror_from: http://purl.obolibrary.org/obo/hp.owl
    modifier: PATO:0000460
    dependencies:
      - nbo
      - pr
      - chebi
      - hsapdv
      - cl
      - mpath
  - id: wbphenotype
    mirror_from: http://purl.obolibrary.org/obo/wbphenotype/wbphenotype-base.owl
    root: http://purl.obolibrary.org/obo/WBPhenotype_0000886
    prefix_iri: http://purl.obolibrary.org/obo/WBPhenotype_
    taxon: http://purl.obolibrary.org/obo/WBPhenotype
    taxon_label: WBP
    modifier: PATO:0000460
    dependencies:
      - bfo
      - wbbt
      - wbls
      - chebi
      - cl
      - wbbt-uberon
  - id: xpo
    mirror_from: http://purl.obolibrary.org/obo/xpo/xpo-base.owl
    root: http://purl.obolibrary.org/obo/XPO_00000000
    prefix_iri: http://purl.obolibrary.org/obo/XPO_
    taxon: http://purl.obolibrary.org/obo/XPO
    taxon_label: XPO
    modifier: PATO:0000460
    dependencies:
      - chebi
      - bfo
      - xao
      - xao-uberon
      - bspo-uberon
      - caro-uberon
  - id: planp
    mirror_from: http://purl.obolibrary.org/obo/planp/planp-base.owl
    root: http://purl.obolibrary.org/obo/PLANP_00000000
    prefix_iri: http://purl.obolibrary.org/obo/PLANP_
    taxon: http://purl.obolibrary.org/obo/PLANP
    taxon_label: PLANP
    modifier: PATO:0000460
    anatomy: plana
    dependencies:
      - plana
      #- plana-uberon
      - bspo-uberon
      - caro-uberon
      #- ncit
  - id: zp
    mirror_from: http://purl.obolibrary.org/obo/zp/zp-base.owl
    root: http://purl.obolibrary.org/obo/ZP_00000000
    prefix_iri: http://purl.obolibrary.org/obo/ZP_
    taxon: http://purl.obolibrary.org/obo/ZP
    taxon_label: ZPO
    modifier: PATO:0000460
    dependencies:
      - zfa
      - chebi
      - bspo
      - mpath
      - bfo
      - zfa-uberon
      - bspo-uberon
      - caro-uberon
  - id: dpo
    mirror_from: http://purl.obolibrary.org/obo/dpo/dpo-base.owl
    root: http://purl.obolibrary.org/obo/FBcv_0001347
    prefix_iri: http://purl.obolibrary.org/obo/FBcv_
    taxon: http://purl.obolibrary.org/obo/DPO
    taxon_label: DPO
    modifier: PATO:0000460
    dependencies:
      - fbdv
      - fbbt
      - cl
      - chebi
common_dependencies:
  - go
  - uberon
  - pato
  - ro
  - iao
  - ncbitaxon
species_modules:
  - mp
  - hp
  - wbphenotype
  - xpo
  - dpo
  - planp
  - zp
upheno_profiles:
  - id: mp-hp
    species_modules:
    - mp
    - hp
  - id: mp-hp-dpo
    species_modules:
    - mp
    - hp
    - dpo
  - id: all
    species_modules:
    - mp
    - hp
    - dpo
    - xpo
    - planp
    - wbphenotype
pattern_repos:
  - obophenotype/upheno/contents/src/patterns/dosdp-dev
  - obophenotype/upheno/contents/src/patterns/dosdp-patterns
release_artefacts:
  - base
  - simple-non-classified
  - full
primary_release: full
export_formats:
  - owl
  - obo
  - json
import_group:
  products:
    - id: nbo
    - id: pr
    - id: go
    - id: uberon
    - id: ro
    - id: chebi
    - id: hsapdv
    - id: pato
    - id: cl
    - id: mpath
documentation:
  documentation_system: mkdocs


text:
# ----------------------------------------
# Makefile for upheno
# Generated using ontology-development-kit
# ODK Version: v1.3.0
# ----------------------------------------
# IMPORTANT: DO NOT EDIT THIS FILE. To override default make goals, use upheno.Makefile instead

# ----------------------------------------
# More information: https://github.com/INCATools/ontology-development-kit/

# ----------------------------------------
# Standard Constants
# ----------------------------------------
# these can be overwritten on the command line

URIBASE=                    http://purl.obolibrary.org/obo
ONT=                        upheno
ONTBASE=                    $(URIBASE)/$(ONT)
EDIT_FORMAT=                owl
SRC =                       $(ONT)-edit.$(EDIT_FORMAT)
CATALOG=                    catalog-v001.xml
ROBOT=                      robot --catalog $(CATALOG)

OWLTOOLS=                   owltools --use-catalog
RELEASEDIR=                 ../..
REPORTDIR=                  reports
TEMPLATEDIR=                ../templates
TMPDIR=                     tmp
MIRRORDIR=                  mirror
IMPORTDIR=                  imports
SUBSETDIR=                  subsets
SCRIPTSDIR=                 ../scripts
SPARQLDIR =                 ../sparql
COMPONENTSDIR =             components
REPORT_FAIL_ON =            None
REPORT_LABEL =              -l true
REPORT_PROFILE_OPTS =
OBO_FORMAT_OPTIONS =
SPARQL_VALIDATION_CHECKS =  owldef-self-reference iri-range label-with-iri
SPARQL_EXPORTS =            basic-report class-count-by-prefix edges xrefs obsoletes synonyms
ODK_VERSION_MAKEFILE =      v1.3.0

TODAY ?=                    $(shell date +%Y-%m-%d)
OBODATE ?=                  $(shell date +'%d:%m:%Y %H:%M')
VERSION=                    $(TODAY)
ANNOTATE_ONTOLOGY_VERSION = annotate -V $(ONTBASE)/releases/$(VERSION)/$@ --annotation owl:versionInfo $(VERSION)
OTHER_SRC =                 $(PATTERNDIR)/definitions.owl
ONTOLOGYTERMS =             $(TMPDIR)/ontologyterms.txt
PATTERNDIR=                 ../patterns
PATTERN_TESTER=              dosdp validate -i
DOSDPT=                      dosdp-tools
PATTERN_RELEASE_FILES=       $(PATTERNDIR)/definitions.owl $(PATTERNDIR)/pattern.owl

FORMATS = $(sort  owl obo json owl)
FORMATS_INCL_TSV = $(sort $(FORMATS) tsv)
RELEASE_ARTEFACTS = $(sort $(ONT)-base $(ONT)-simple-non-classified $(ONT)-full $(ONT)-base $(ONT)-full)

# ----------------------------------------
# Top-level targets
# ----------------------------------------

.PHONY: .FORCE

.PHONY: all
all: odkversion test all_assets

.PHONY: test
test: odkversion dosdp_validation sparql_test robot_reports $(REPORTDIR)/validate_profile_owl2dl_$(ONT).owl.txt
	$(ROBOT) reason --input $(SRC) --reasoner ELK  --equivalent-classes-allowed asserted-only --exclude-tautologies structural --output test.owl && rm test.owl && echo "Success"

.PHONY: odkversion
odkversion:
	echo "ODK Makefile version: $(ODK_VERSION_MAKEFILE) (this is the version of the ODK with which this Makefile was generated, not the version of the ODK you are running)" &&\
	echo "ROBOT version (ODK): " && $(ROBOT) --version

$(TMPDIR) $(REPORTDIR) $(MIRRORDIR) $(IMPORTDIR) $(COMPONENTSDIR) $(SUBSETDIR):
	mkdir -p $@

# ----------------------------------------
# Release assets
# ----------------------------------------

MAIN_PRODUCTS = $(sort $(foreach r,$(RELEASE_ARTEFACTS), $(r)) $(ONT))
MAIN_GZIPPED  =
MAIN_FILES    = $(foreach n,$(MAIN_PRODUCTS), $(foreach f,$(FORMATS), $(n).$(f))) $(MAIN_GZIPPED)
SRCMERGED     = $(TMPDIR)/merged-$(SRC)

.PHONY: all_main
all_main: $(MAIN_FILES)

# ----------------------------------------
# Import assets
# ----------------------------------------

IMPORTS =  nbo pr go uberon ro chebi hsapdv pato cl mpath

IMPORT_ROOTS = $(patsubst %, $(IMPORTDIR)/%_import, $(IMPORTS))
IMPORT_OWL_FILES = $(foreach n,$(IMPORT_ROOTS), $(n).owl)
IMPORT_FILES = $(IMPORT_OWL_FILES)

.PHONY: all_imports
all_imports: $(IMPORT_FILES)

# ----------------------------------------
# Subset assets
# ----------------------------------------

SUBSETS =

SUBSET_ROOTS = $(patsubst %, $(SUBSETDIR)/%, $(SUBSETS))
SUBSET_FILES = $(foreach n,$(SUBSET_ROOTS), $(foreach f,$(FORMATS_INCL_TSV), $(n).$(f)))

.PHONY: all_subsets
all_subsets: $(SUBSET_FILES)

# ----------------------------------------
# QC Reports & Utilities
# ----------------------------------------

OBO_REPORT =  $(SRC)-obo-report
REPORTS = $(OBO_REPORT)
REPORT_FILES = $(patsubst %, $(REPORTDIR)/%.tsv, $(REPORTS))

.PHONY: robot_reports
robot_reports: $(REPORT_FILES)

.PHONY: all_reports
all_reports: custom_reports robot_reports

# ----------------------------------------
# ROBOT OWL Profile checking
# ----------------------------------------

# The conversion to functional syntax is necessary to avoid undeclared entity violations.
$(REPORTDIR)/validate_profile_owl2dl_%.txt: % | $(REPORTDIR) $(TMPDIR)
	$(ROBOT) merge -i $< convert -f ofn -o $(TMPDIR)/validate.ofn
	$(ROBOT) validate-profile --profile DL -i $(TMPDIR)/validate.ofn -o $@ || { cat $@ && exit 1; }
.PRECIOUS: $(REPORTDIR)/validate_profile_owl2dl_%.txt

validate_profile_%: $(REPORTDIR)/validate_profile_owl2dl_%.txt
	echo "$* profile validation completed."

# ----------------------------------------
# Sparql queries: Q/C
# ----------------------------------------

# these live in the ../sparql directory, and have suffix -violation.sparql
# adding the name here will make the violation check live.

SPARQL_VALIDATION_QUERIES = $(foreach V,$(SPARQL_VALIDATION_CHECKS),$(SPARQLDIR)/$(V)-violation.sparql)

sparql_test: $(SRC) catalog-v001.xml | $(REPORTDIR)
ifneq ($(SPARQL_VALIDATION_QUERIES),)
	$(ROBOT) verify  --catalog catalog-v001.xml -i $< --queries $(SPARQL_VALIDATION_QUERIES) -O $(REPORTDIR)
endif

# ----------------------------------------
# ROBOT report
# ----------------------------------------

$(REPORTDIR)/$(SRC)-obo-report.tsv: $(SRCMERGED) | $(REPORTDIR)
	$(ROBOT) report -i $< $(REPORT_LABEL) $(REPORT_PROFILE_OPTS) --fail-on $(REPORT_FAIL_ON) --print 5 -o $@

$(REPORTDIR)/%-obo-report.tsv: % | $(REPORTDIR)
	$(ROBOT) report -i $< $(REPORT_LABEL) $(REPORT_PROFILE_OPTS) --fail-on $(REPORT_FAIL_ON) --print 5 -o $@

# ----------------------------------------
# Release assets
# ----------------------------------------

ASSETS = \
  $(IMPORT_FILES) \
  $(MAIN_FILES) \
  $(PATTERN_RELEASE_FILES) \
  $(REPORT_FILES) \
  $(SUBSET_FILES)

RELEASE_ASSETS = \
  $(MAIN_FILES) \
  $(SUBSET_FILES)

.PHONY: all_assets
all_assets: $(ASSETS)

.PHONY: show_assets
show_assets:
	echo $(ASSETS)
	du -sh $(ASSETS)

# ----------------------------------------
# Release Management
# ----------------------------------------

CLEANFILES=$(MAIN_FILES) $(SRCMERGED)
# This should be executed by the release manager whenever time comes to make a release.
# It will ensure that all assets/files are fresh, and will copy to release folder

.PHONY: prepare_release
prepare_release: all
	rsync -R $(RELEASE_ASSETS) $(RELEASEDIR) &&\
	mkdir -p $(RELEASEDIR)/patterns && cp -rf $(PATTERN_RELEASE_FILES) $(RELEASEDIR)/patterns &&\
	rm -f $(CLEANFILES) &&\
	echo "Release files are now in $(RELEASEDIR) - now you should commit, push and make a release on your git hosting site such as GitHub or GitLab"

.PHONY: prepare_initial_release
prepare_initial_release: all_assets
	rsync -R $(RELEASE_ASSETS) $(RELEASEDIR) &&\
	mkdir -p $(RELEASEDIR)/patterns && cp -rf $(PATTERN_RELEASE_FILES) $(RELEASEDIR)/patterns &&\
	rm -f $(patsubst %, ./%, $(CLEANFILES)) &&\
	cd $(RELEASEDIR) && git add $(RELEASE_ASSETS)

# ------------------------
# Imports: Seeding system
# ------------------------

# seed.txt contains all referenced entities
IMPORTSEED=$(TMPDIR)/seed.txt
PRESEED=$(TMPDIR)/pre_seed.txt

$(SRCMERGED): $(SRC) $(OTHER_SRC)
	$(ROBOT) remove --input $< --select imports --trim false \
		merge  $(patsubst %, -i %, $(OTHER_SRC)) -o $@

$(PRESEED): $(SRCMERGED)
	$(ROBOT) query -f csv -i $< --query ../sparql/terms.sparql $@.tmp &&\
	cat $@.tmp | sort | uniq >  $@

ALLSEED = $(PRESEED)  $(TMPDIR)/all_pattern_terms.txt \

$(IMPORTSEED): $(ALLSEED) | $(TMPDIR)
	if [ $(IMP) = true ]; then cat $(ALLSEED) | sort | uniq > $@; fi

ANNOTATION_PROPERTIES=rdfs:label IAO:0000115

# ----------------------------------------
# Import modules
# ----------------------------------------
# Most ontologies are modularly constructed using portions of other ontologies
# These live in the imports/ folder
# This pattern uses ROBOT to generate an import module

# Should be able to drop this if robot can just take a big messy list of terms as input.
$(IMPORTDIR)/%_terms_combined.txt: $(IMPORTSEED) $(IMPORTDIR)/%_terms.txt
	if [ $(IMP) = true ]; then cat $^ | grep -v ^# | sort | uniq >  $@; fi

$(IMPORTDIR)/%_import.owl: $(MIRRORDIR)/%.owl $(IMPORTDIR)/%_terms_combined.txt
	if [ $(IMP) = true ]; then $(ROBOT) query -i $< --update ../sparql/preprocess-module.ru \
		extract -T $(IMPORTDIR)/$*_terms_combined.txt --force true --copy-ontology-annotations true --individuals include --method BOT \
		query --update ../sparql/inject-subset-declaration.ru --update ../sparql/postprocess-module.ru \
		annotate --ontology-iri $(ONTBASE)/$@ $(ANNOTATE_ONTOLOGY_VERSION) --output $@.tmp.owl && mv $@.tmp.owl $@; fi

.PRECIOUS: $(IMPORTDIR)/%_import.owl

.PHONY: refresh-imports
refresh-imports:
	make IMP=true MIR=true PAT=false IMP_LARGE=true all_imports -B

.PHONY: no-mirror-refresh-imports
no-mirror-refresh-imports:
	make IMP=true MIR=false PAT=false IMP_LARGE=true all_imports -B

.PHONY: refresh-imports-excluding-large
refresh-imports-excluding-large:
	make IMP=true MIR=true PAT=false IMP_LARGE=false all_imports -B

.PHONY: refresh-%
refresh-%:
	make IMP=true IMP_LARGE=true MIR=true PAT=false $(IMPORTDIR)/$*_import.owl -B

.PHONY: no-mirror-refresh-%
no-mirror-refresh-%:
	make IMP=true IMP_LARGE=true MIR=false PAT=false $(IMPORTDIR)/$*_import.owl -B

# ----------------------------------------
# Mirroring upstream ontologies
# ----------------------------------------

IMP=true # Global parameter to bypass import generation
MIR=true # Global parameter to bypass mirror generation
IMP_LARGE=true # Global parameter to bypass handling of large imports

## ONTOLOGY: nbo
.PHONY: mirror-nbo
.PRECIOUS: $(MIRRORDIR)/nbo.owl
mirror-nbo: | $(TMPDIR)
	if [ $(MIR) = true ] && [ $(IMP) = true ]; then curl -L $(URIBASE)/nbo.owl --create-dirs -o $(MIRRORDIR)/nbo.owl --retry 4 --max-time 200 && $(ROBOT) convert -i $(MIRRORDIR)/nbo.owl -o $@.tmp.owl && mv $@.tmp.owl $(TMPDIR)/$@.owl; fi

## ONTOLOGY: pr
.PHONY: mirror-pr
.PRECIOUS: $(MIRRORDIR)/pr.owl
mirror-pr: | $(TMPDIR)
	if [ $(MIR) = true ] && [ $(IMP) = true ]; then curl -L $(URIBASE)/pr.owl --create-dirs -o $(MIRRORDIR)/pr.owl --retry 4 --max-time 200 && $(ROBOT) convert -i $(MIRRORDIR)/pr.owl -o $@.tmp.owl && mv $@.tmp.owl $(TMPDIR)/$@.owl; fi

## ONTOLOGY: go
.PHONY: mirror-go
.PRECIOUS: $(MIRRORDIR)/go.owl
mirror-go: | $(TMPDIR)
	if [ $(MIR) = true ] && [ $(IMP) = true ]; then curl -L $(URIBASE)/go.owl --create-dirs -o $(MIRRORDIR)/go.owl --retry 4 --max-time 200 && $(ROBOT) convert -i $(MIRRORDIR)/go.owl -o $@.tmp.owl && mv $@.tmp.owl $(TMPDIR)/$@.owl; fi

## ONTOLOGY: uberon
.PHONY: mirror-uberon
.PRECIOUS: $(MIRRORDIR)/uberon.owl
mirror-uberon: | $(TMPDIR)
	if [ $(MIR) = true ] && [ $(IMP) = true ]; then curl -L $(URIBASE)/uberon.owl --create-dirs -o $(MIRRORDIR)/uberon.owl --retry 4 --max-time 200 && $(ROBOT) convert -i $(MIRRORDIR)/uberon.owl -o $@.tmp.owl && mv $@.tmp.owl $(TMPDIR)/$@.owl; fi

## ONTOLOGY: ro
.PHONY: mirror-ro
.PRECIOUS: $(MIRRORDIR)/ro.owl
mirror-ro: | $(TMPDIR)
	if [ $(MIR) = true ] && [ $(IMP) = true ]; then curl -L $(URIBASE)/ro.owl --create-dirs -o $(MIRRORDIR)/ro.owl --retry 4 --max-time 200 && $(ROBOT) convert -i $(MIRRORDIR)/ro.owl -o $@.tmp.owl && mv $@.tmp.owl $(TMPDIR)/$@.owl; fi

## ONTOLOGY: chebi
.PHONY: mirror-chebi
.PRECIOUS: $(MIRRORDIR)/chebi.owl
mirror-chebi: | $(TMPDIR)
	if [ $(MIR) = true ] && [ $(IMP) = true ]; then curl -L $(URIBASE)/chebi.owl --create-dirs -o $(MIRRORDIR)/chebi.owl --retry 4 --max-time 200 && $(ROBOT) convert -i $(MIRRORDIR)/chebi.owl -o $@.tmp.owl && mv $@.tmp.owl $(TMPDIR)/$@.owl; fi

## ONTOLOGY: hsapdv
.PHONY: mirror-hsapdv
.PRECIOUS: $(MIRRORDIR)/hsapdv.owl
mirror-hsapdv: | $(TMPDIR)
	if [ $(MIR) = true ] && [ $(IMP) = true ]; then curl -L $(URIBASE)/hsapdv.owl --create-dirs -o $(MIRRORDIR)/hsapdv.owl --retry 4 --max-time 200 && $(ROBOT) convert -i $(MIRRORDIR)/hsapdv.owl -o $@.tmp.owl && mv $@.tmp.owl $(TMPDIR)/$@.owl; fi

## ONTOLOGY: pato
.PHONY: mirror-pato
.PRECIOUS: $(MIRRORDIR)/pato.owl
mirror-pato: | $(TMPDIR)
	if [ $(MIR) = true ] && [ $(IMP) = true ]; then curl -L $(URIBASE)/pato.owl --create-dirs -o $(MIRRORDIR)/pato.owl --retry 4 --max-time 200 && $(ROBOT) convert -i $(MIRRORDIR)/pato.owl -o $@.tmp.owl && mv $@.tmp.owl $(TMPDIR)/$@.owl; fi

## ONTOLOGY: cl
.PHONY: mirror-cl
.PRECIOUS: $(MIRRORDIR)/cl.owl
mirror-cl: | $(TMPDIR)
	if [ $(MIR) = true ] && [ $(IMP) = true ]; then curl -L $(URIBASE)/cl.owl --create-dirs -o $(MIRRORDIR)/cl.owl --retry 4 --max-time 200 && $(ROBOT) convert -i $(MIRRORDIR)/cl.owl -o $@.tmp.owl && mv $@.tmp.owl $(TMPDIR)/$@.owl; fi

## ONTOLOGY: mpath
.PHONY: mirror-mpath
.PRECIOUS: $(MIRRORDIR)/mpath.owl
mirror-mpath: | $(TMPDIR)
	if [ $(MIR) = true ] && [ $(IMP) = true ]; then curl -L $(URIBASE)/mpath.owl --create-dirs -o $(MIRRORDIR)/mpath.owl --retry 4 --max-time 200 && $(ROBOT) convert -i $(MIRRORDIR)/mpath.owl -o $@.tmp.owl && mv $@.tmp.owl $(TMPDIR)/$@.owl; fi

$(MIRRORDIR)/%.owl: mirror-% | $(MIRRORDIR)
	if [ $(IMP) = true ] && [ $(MIR) = true ]; then if cmp -s $(TMPDIR)/mirror-$*.owl $@ ; then echo "Mirror identical, ignoring."; else echo "Mirrors different, updating." && cp $(TMPDIR)/mirror-$*.owl $@; fi; fi

# ----------------------------------------
# Subsets
# ----------------------------------------
$(SUBSETDIR)/%.tsv: $(SUBSETDIR)/%.owl
	$(ROBOT) query -f tsv -i $< -s ../sparql/labels.sparql $@
.PRECIOUS: $(SUBSETDIR)/%.tsv

$(SUBSETDIR)/%.owl: $(ONT).owl | $(SUBSETDIR)
	$(OWLTOOLS) $< --extract-ontology-subset --fill-gaps --subset $* -o $@.tmp.owl && mv $@.tmp.owl $@ &&\
	$(ROBOT) annotate --input $@ --ontology-iri $(ONTBASE)/$@ $(ANNOTATE_ONTOLOGY_VERSION) -o $@.tmp.owl && mv $@.tmp.owl $@
.PRECIOUS: $(SUBSETDIR)/%.owl

$(SUBSETDIR)/%.obo: $(SUBSETDIR)/%.owl
	$(ROBOT) convert --input $< --check false -f obo $(OBO_FORMAT_OPTIONS) -o $@.tmp.obo && grep -v ^owl-axioms $@.tmp.obo > $@ && rm $@.tmp.obo

$(SUBSETDIR)/%.json: $(SUBSETDIR)/%.owl
	$(ROBOT) convert --input $< --check false -f json -o $@.tmp.json &&\
	jq -S 'walk(if type == "array" then sort else . end)' $@.tmp.json > $@ && rm $@.tmp.json

# ---------------------------------------------
# Sparql queries: Table exports / Query Reports
# ---------------------------------------------

SPARQL_EXPORTS_ARGS = $(foreach V,$(SPARQL_EXPORTS),-s $(SPARQLDIR)/$(V).sparql $(REPORTDIR)/$(V).tsv)
# This combines all into one single command

.PHONY: custom_reports
custom_reports: $(SRC) | $(REPORTDIR)
ifneq ($(SPARQL_EXPORTS_ARGS),)
	$(ROBOT) query -f tsv --use-graphs true -i $< $(SPARQL_EXPORTS_ARGS)
endif
# ----------------------------------------
# DOSDP Templates/Patterns
# ----------------------------------------

PAT=true # Global parameter to bypass pattern generation
ALL_PATTERN_FILES=$(wildcard $(PATTERNDIR)/dosdp-patterns/*.yaml)
ALL_PATTERN_NAMES=$(strip $(patsubst %.yaml,%, $(notdir $(wildcard $(PATTERNDIR)/dosdp-patterns/*.yaml))))

PATTERN_CLEAN_FILES=../patterns/all_pattern_terms.txt \
	$(DOSDP_OWL_FILES_DEFAULT) $(DOSDP_TERM_FILES_DEFAULT) \

# Note to future generations: prepending ./ is a safety measure to ensure that
# the environment does not malicously set `PATTERN_CLEAN_FILES` to `\`.
.PHONY: pattern_clean
pattern_clean:
	rm -f $(PATTERN_CLEAN_FILES)

.PHONY: patterns
patterns dosdp:
	echo "Validating all DOSDP templates"
	make dosdp_validation
	echo "Building $(PATTERNDIR)/definitions.owl"
	make $(PATTERNDIR)/pattern.owl $(PATTERNDIR)/definitions.owl

# DOSDP Template Validation

$(TMPDIR)/pattern_schema_checks: $(ALL_PATTERN_FILES) | $(TMPDIR)
	$(PATTERN_TESTER) $(PATTERNDIR)/dosdp-patterns/ && touch $@

.PHONY: pattern_schema_checks
pattern_schema_checks dosdp_validation: $(TMPDIR)/pattern_schema_checks

.PHONY: update_patterns
update_patterns: download_patterns
	cp -r $(TMPDIR)/dosdp/*.yaml $(PATTERNDIR)/dosdp-patterns

# This command is a workaround for the absence of -N and -i in wget of alpine (the one ODK depend on now).
# It downloads all patterns specified in external.txt
.PHONY: download_patterns
download_patterns:
	if [ $(PAT) = true ]; then rm -f $(TMPDIR)/dosdp/*.yaml.1 || true; fi
	if [ $(PAT) = true ] && [ -s $(PATTERNDIR)/dosdp-patterns/external.txt ]; then wget -i $(PATTERNDIR)/dosdp-patterns/external.txt --backups=1 -P $(TMPDIR)/dosdp; fi
	if [ $(PAT) = true ]; then rm -f $(TMPDIR)/dosdp/*.yaml.1 || true; fi

$(PATTERNDIR)/dospd-patterns/%.yml: download_patterns
	if [ $(PAT) = true ] ; then if cmp -s $(TMPDIR)/dosdp-$*.yml $@ ; then echo "DOSDP templates identical."; else echo "DOSDP templates different, updating." && cp $(TMPDIR)/dosdp-$*.yml $@; fi; fi

# DOSDP Template: Pipelines
# Each pipeline gets its own directory structure

# DOSDP default pipeline

DOSDP_TSV_FILES_DEFAULT = $(wildcard $(PATTERNDIR)/data/default/*.tsv)
DOSDP_OWL_FILES_DEFAULT = $(patsubst %.tsv, $(PATTERNDIR)/data/default/%.ofn, $(notdir $(wildcard $(PATTERNDIR)/data/default/*.tsv)))
DOSDP_TERM_FILES_DEFAULT = $(patsubst %.tsv, $(PATTERNDIR)/data/default/%.txt, $(notdir $(wildcard $(PATTERNDIR)/data/default/*.tsv)))
DOSDP_PATTERN_NAMES_DEFAULT = $(strip $(patsubst %.tsv,%, $(notdir $(wildcard $(PATTERNDIR)/data/default/*.tsv))))

$(DOSDP_OWL_FILES_DEFAULT): $(SRC) $(DOSDP_TSV_FILES_DEFAULT) $(ALL_PATTERN_FILES)
	if [ $(PAT) = true ] && [ "${DOSDP_PATTERN_NAMES_DEFAULT}" ]; then $(DOSDPT) generate --catalog=catalog-v001.xml --infile=$(PATTERNDIR)/data/default/ --template=$(PATTERNDIR)/dosdp-patterns --batch-patterns="$(DOSDP_PATTERN_NAMES_DEFAULT)" --ontology=$< --obo-prefixes=true --restrict-axioms-to=logical --outfile=$(PATTERNDIR)/data/default; fi

# Generate template file seeds

## Generate template file seeds
$(PATTERNDIR)/data/default/%.txt: $(PATTERNDIR)/dosdp-patterns/%.yaml $(PATTERNDIR)/data/default/%.tsv
	if [ $(PAT) = true ]; then $(DOSDPT) terms --infile=$(word 2, $^) --template=$< --obo-prefixes=true --outfile=$@; fi

# Generating the seed file from all the TSVs. If Pattern generation is deactivated, we still extract a seed from definitions.owl
$(TMPDIR)/all_pattern_terms.txt: $(DOSDP_TERM_FILES_DEFAULT)   $(TMPDIR)/pattern_owl_seed.txt
	if [ $(PAT) = true ]; then cat $^ | sort | uniq > $@; else $(ROBOT) query --use-graphs true -f csv -i $(PATTERNDIR)/definitions.owl --query ../sparql/terms.sparql $@; fi

$(TMPDIR)/pattern_owl_seed.txt: $(PATTERNDIR)/pattern.owl
	if [ $(PAT) = true ]; then $(ROBOT) query --use-graphs true -f csv -i $< --query ../sparql/terms.sparql $@; fi

# Pattern pipeline main targets: the generated OWL files

# Create pattern.owl, an ontology of all DOSDP patterns
$(PATTERNDIR)/pattern.owl: $(ALL_PATTERN_FILES)
	if [ $(PAT) = true ]; then $(DOSDPT) prototype --obo-prefixes true --template=$(PATTERNDIR)/dosdp-patterns --outfile=$@; fi

# Generating the individual pattern modules and merging them into definitions.owl
$(PATTERNDIR)/definitions.owl: $(DOSDP_OWL_FILES_DEFAULT)
	if [ $(PAT) = true ] && [ "${DOSDP_PATTERN_NAMES_DEFAULT}" ]   && [ $(PAT) = true ]; then $(ROBOT) merge $(addprefix -i , $^) \
		annotate --ontology-iri $(ONTBASE)/patterns/definitions.owl  --version-iri $(ONTBASE)/releases/$(TODAY)/patterns/definitions.owl --annotation owl:versionInfo $(VERSION) -o definitions.ofn && mv definitions.ofn $@; fi

# ----------------------------------------
# Release artefacts: export formats
# ----------------------------------------

$(ONT)-base.obo: $(ONT)-base.owl
	$(ROBOT) convert --input $< --check false -f obo $(OBO_FORMAT_OPTIONS) -o $@.tmp.obo && grep -v ^owl-axioms $@.tmp.obo > $@ && rm $@.tmp.obo
$(ONT)-base.json: $(ONT)-base.owl
	$(ROBOT) annotate --input $< --ontology-iri $(ONTBASE)/$@ $(ANNOTATE_ONTOLOGY_VERSION) \
		convert --check false -f json -o $@.tmp.json &&\
	jq -S 'walk(if type == "array" then sort else . end)' $@.tmp.json > $@ && rm $@.tmp.json
$(ONT)-simple-non-classified.obo: $(ONT)-simple-non-classified.owl
	$(ROBOT) convert --input $< --check false -f obo $(OBO_FORMAT_OPTIONS) -o $@.tmp.obo && grep -v ^owl-axioms $@.tmp.obo > $@ && rm $@.tmp.obo
$(ONT)-simple-non-classified.json: $(ONT)-simple-non-classified.owl
	$(ROBOT) annotate --input $< --ontology-iri $(ONTBASE)/$@ $(ANNOTATE_ONTOLOGY_VERSION) \
		convert --check false -f json -o $@.tmp.json &&\
	jq -S 'walk(if type == "array" then sort else . end)' $@.tmp.json > $@ && rm $@.tmp.json
$(ONT)-full.obo: $(ONT)-full.owl
	$(ROBOT) convert --input $< --check false -f obo $(OBO_FORMAT_OPTIONS) -o $@.tmp.obo && grep -v ^owl-axioms $@.tmp.obo > $@ && rm $@.tmp.obo
$(ONT)-full.json: $(ONT)-full.owl
	$(ROBOT) annotate --input $< --ontology-iri $(ONTBASE)/$@ $(ANNOTATE_ONTOLOGY_VERSION) \
		convert --check false -f json -o $@.tmp.json &&\
	jq -S 'walk(if type == "array" then sort else . end)' $@.tmp.json > $@ && rm $@.tmp.json
# We always want a base - even if it is not explicitly configured..
# We always want a full release - even if it is not explicitly configured..
# ----------------------------------------
# Release artefacts: main release artefacts
# ----------------------------------------

$(ONT).owl: $(ONT)-full.owl
	$(ROBOT) annotate --input $< --ontology-iri $(URIBASE)/$@ $(ANNOTATE_ONTOLOGY_VERSION) \
		convert -o $@.tmp.owl && mv $@.tmp.owl $@

$(ONT).obo: $(ONT).owl
	$(ROBOT) convert --input $< --check false -f obo $(OBO_FORMAT_OPTIONS) -o $@.tmp.obo && grep -v ^owl-axioms $@.tmp.obo > $@ && rm $@.tmp.obo
$(ONT).json: $(ONT)-full.owl
	$(ROBOT) annotate --input $< --ontology-iri $(URIBASE)/$@ $(ANNOTATE_ONTOLOGY_VERSION) \
		convert --check false -f json -o $@.tmp.json && \
	jq -S 'walk(if type == "array" then sort else . end)' $@.tmp.json > $@ && rm $@.tmp.json
# -----------------------------------------------------
# Release artefacts: variants (base, full, simple, etc)
# -----------------------------------------------------
SHARED_ROBOT_COMMANDS =

$(ONTOLOGYTERMS): $(SRC) $(OTHER_SRC)
	touch $(ONTOLOGYTERMS) && \
	$(ROBOT) query --use-graphs true -f csv -i $< --query ../sparql/upheno_terms.sparql $@

# base: OTHER sources of interest, such as definitions owl
$(ONT)-base.owl: $(SRC) $(OTHER_SRC)
	$(ROBOT) remove --input $< --select imports --trim false \
		merge $(patsubst %, -i %, $(OTHER_SRC)) \
		 $(SHARED_ROBOT_COMMANDS) annotate --link-annotation http://purl.org/dc/elements/1.1/type http://purl.obolibrary.org/obo/IAO_8000001 \
		--ontology-iri $(ONTBASE)/$@ $(ANNOTATE_ONTOLOGY_VERSION) \
		--output $@.tmp.owl && mv $@.tmp.owl $@

# Full: The full artefacts with imports merged, reasoned
$(ONT)-full.owl: $(SRC) $(OTHER_SRC) $(IMPORT_FILES)
	$(ROBOT) merge --input $< \
		reason --reasoner ELK --equivalent-classes-allowed asserted-only --exclude-tautologies structural \
		relax \
		reduce -r ELK \
		$(SHARED_ROBOT_COMMANDS) annotate --ontology-iri $(ONTBASE)/$@ $(ANNOTATE_ONTOLOGY_VERSION) --output $@.tmp.owl && mv $@.tmp.owl $@

# foo-simple-non-classified (edit->relax,reduce,drop imports, drop every axiom which contains an entity outside the "namespaces of interest") - aka the HPO use case, no reason.
# Should this be the non-classified ontology with the drop foreign axiom filter?
# Consider adding remove --term "http://www.geneontology.org/formats/oboInOwl#hasOBONamespace"

$(ONT)-simple-non-classified.owl: $(SRC) $(OTHER_SRC) $(ONTOLOGYTERMS) $(IMPORT_FILES)
	$(ROBOT) remove --input $< --select imports --trim true \
		merge  $(patsubst %, -i %, $(OTHER_SRC))  \
		remove --axioms equivalent \
		reduce -r ELK \
		filter --select ontology --term-file $(ONTOLOGYTERMS) --trim false \
		$(SHARED_ROBOT_COMMANDS) annotate --ontology-iri $(ONTBASE)/$@ $(ANNOTATE_ONTOLOGY_VERSION) --output $@.tmp.owl && mv $@.tmp.owl $@
# ----------------------------------------
# Debugging Tools
# ----------------------------------------

explain_unsat: $(SRC)
	$(ROBOT) explain -i $(SRC) -M unsatisfiability --unsatisfiable random:10 --explanation $(TMPDIR)/$@.md

# ----------------------------------------
# General Validation
# ----------------------------------------
TSV=
ALL_TSV_FILES=$(DOSDP_TSV_FILES_DEFAULT)

validate-tsv: $(TSV) | $(TMPDIR)
	for FILE in $< ; do \
		tsvalid $$FILE > $(TMPDIR)/validate.txt; \
		if [ -s $(TMPDIR)/validate.txt ]; then cat $(TMPDIR)/validate.txt && exit 1; fi ; \
	done

validate-all-tsv: $(ALL_TSV_FILES)
	make validate-tsv TSV="$^"

# ----------------------------------------
# Editors Utilities
# ----------------------------------------

.PHONY: normalize_src
normalize_src: $(SRC)
	$(ROBOT) convert -i $< -f ofn -o $(TMPDIR)/normalise && mv $(TMPDIR)/normalise $<

.PHONY: validate_idranges
validate_idranges:
	amm $(SCRIPTSDIR)/validate_id_ranges.sc upheno-idranges.owl

.PHONY: update_repo
update_repo:
	sh $(SCRIPTSDIR)/update_repo.sh

update_docs:
	mkdocs gh-deploy --config-file ../../mkdocs.yaml

# Note to future generations: prepending ./ is a safety measure to ensure that
# the environment does not malicously set `CLEANFILES` to `\`.
.PHONY: clean
clean:
	make pattern_clean
	[ -n "$(MIRRORDIR)" ] && [ $(MIRRORDIR) != "." ] && [ $(MIRRORDIR) != "/" ] && [ $(MIRRORDIR) != ".." ] && [ -d ./$(MIRRORDIR) ] && rm -rf ./$(MIRRORDIR)/*
	[ -n "$(TMPDIR)" ] && [ $(TMPDIR) != "." ] && [ $(TMPDIR) != "/" ] && [ $(TMPDIR) != ".." ] && [ -d ./$(TMPDIR) ] && rm -rf ./$(TMPDIR)/*
	rm -f $(CLEANFILES)

.PHONY: help
help:
	@echo "$$data"

define data
Usage: [IMAGE=(odklite|odkfull)] [ODK_DEBUG=yes] sh run.sh make [(IMP|MIR|IMP_LARGE|PAT)=(false|true)] command

----------------------------------------
	Command reference
----------------------------------------

Core commands:
* prepare_release:	Run the entire release pipeline. Use make IMP=false prepare_release to avoid rerunning the imports
* update_repo:		Update the ODK repository setup using the config file upheno-odk.yaml
* test:			Running all validation tests
* odkversion:		Show the current version of the ODK Makefile and ROBOT.
* clean:		Delete all temporary files
* help:			Print ODK Usage information

Imports management:
* refresh-imports:			Refresh all imports and mirrors.
* no-mirror-refresh-imports:		Refresh all imports without downloading mirrors.
* refresh-imports-excluding-large:	Refresh all imports and mirrors, but skipping the ones labelled as 'is_large'.
* refresh-%:				Refresh a single import, i.e. refresh-go will refresh 'imports/go_import.owl'.
* no-mirror-refresh-%:			Refresh a single import without updating the mirror, i.e. refresh-go will refresh 'imports/go_import.owl'.
* mirror-%:				Refresh a single mirror.

DOSDP templates
* dosdp:			Run the DOSDP patterns pipeline: Run tests, then build OWL files from the tables.
* patterns:			Alias of the 'dosdp' command
* pattern_clean:		Delete all temporary pattern files
* dosdp_validation:		Run all validation checks on DOSDP template files and tables
* pattern_schema_checks:	Alias of the 'dosdp_validation' command
* update_patterns:		Pull updated patterns listed in dosdp-patterns/external.txt
* dosdp-matches-%:		Run the DOSDP matches/query pipeline as configured in your upheno-odk.yaml file.

Editor utilities:
* validate_idranges:	Make sure your ID ranges file is formatted correctly
* normalize_src:	Load and safe your upheno-edit file after you to make sure its serialised correctly
* explain_unsat:	If you have unsatisfiable classes, this command will create a markdown file (tmp/explain_unsat.md) which will explain all your unsatisfiable classes
* validate-all-tsv:	Check all your tsv files for possible problems in syntax. Use ALL_TSV_FILES variable to list files
* validate-tsv:		Check a tsv file for syntactic problems with tsvalid. Use TSV variable to pass filepath, e.g. make TSV=../my.tsv validate-tsv.

Additional build commands (advanced users)
* all:			Run the entire pipeline (like prepare_release), but without copying the release files to the release directory.
* all_subsets:		Build all subsets
* custom_reports:	Generate all custom sparql reports you have configured in your upheno-odk.yaml file.
* all_assets:		Build all assets
* show_assets:		Print a list of all assets that would be build by the release pipeline

Additional QC commands (advanced users)
* robot_reports:	Run all configured ROBOT reports
* validate_profile_%:	Run an OWL2 DL profile validation check, for example validate_profile_upheno-edit.owl.

Examples:
* sh run.sh make IMP=false prepare_release
* sh run.sh make update_repo
* sh run.sh make test

Tricks:
* Add -B to the end of your command to force re-running it even if nothing has changed
* Use the IMAGE parameter to the run.sh script to use a different image like odklite
* Use ODK_DEBUG=yes sh run.sh make ... to print information about timing and debugging

endef
export data

include upheno.Makefile


text:
These notes are for the EDITORS of upheno

This project was created using the [ontology development kit](https://github.com/INCATools/ontology-development-kit). See the site for details.

For more details on ontology management, please see the [OBO tutorial](https://github.com/jamesaoverton/obo-tutorial) or the [Gene Ontology Editors Tutorial](https://go-protege-tutorial.readthedocs.io/en/latest/)

You may also want to read the [GO ontology editors guide](http://go-ontology.readthedocs.org/)

## Requirements

 1. Protege (for editing)
 2. A git client (we assume command line git)
 3. [docker](https://www.docker.com/get-docker) (for managing releases)

## Editors Version

Make sure you have an ID range in the [idranges file](upheno-idranges.owl)

If you do not have one, get one from the maintainer of this repo.

The editors version is [upheno-edit.owl](upheno-edit.owl)

** DO NOT EDIT upheno.obo OR upheno.owl in the top level directory **

[../../upheno.owl](../../upheno.owl) is the release version

To edit, open the file in Protege. First make sure you have the repository cloned, see [the GitHub project](https://github.com/obophenotype/upheno) for details.

You should discuss the git workflow you should use with the maintainer
of this repo, who should document it here. If you are the maintainer,
you can contact the odk developers for assistance. You may want to
copy the flow an existing project, for example GO: [Gene Ontology
Editors Tutorial](https://go-protege-tutorial.readthedocs.io/en/latest/).

In general, it is bad practice to commit changes to master. It is
better to make changes on a branch, and make Pull Requests.

## ID Ranges

These are stored in the file

 * [upheno-idranges.owl](upheno-idranges.owl)

** ONLY USE IDs WITHIN YOUR RANGE!! **

If you have only just set up this repository, modify the idranges file
	and add yourself or other editors. Note Protege does not read the file
- it is up to you to ensure correct Protege configuration.

### Setting ID ranges in Protege

We aim to put this up on the technical docs for OBO on http://obofoundry.org/

For now, consult the [GO Tutorial on configuring Protege](http://go-protege-tutorial.readthedocs.io/en/latest/Entities.html#new-entities)

## Imports

All import modules are in the [imports/](imports/) folder.

There are two ways to include new classes in an import module

 1. Reference an external ontology class in the edit ontology. In Protege: "add new entity", then paste in the PURL
 2. Add to the imports/ont_terms.txt file, for example imports/go_terms.txt

After doing this, you can run

`./run.sh make all_imports`

to regenerate imports.

Note: the ont_terms.txt file may include 'starter' classes seeded from
the ontology starter kit. It is safe to remove these.

## Design patterns

You can automate (class) term generation from design patterns by placing DOSDP
yaml file and tsv files under src/patterns. Any pair of files in this
folder that share a name (apart from the extension) are assumed to be
a DOSDP design pattern and a corresponding tsv specifying terms to
add.

Design patterns can be used to maintain and generate complete terms
(names, definitions, synonyms etc) or to generate logical axioms
only, with other axioms being maintained in editors file.  This can be
specified on a per-term basis in the TSV file.

Design pattern docs are checked for validity via Travis, but can be
tested locally using

`./run.sh make patterns`

In addition to running standard tests, this command generates an owl
file (`src/patterns/pattern.owl`), which demonstrates the relationships
between design patterns.

(At the time of writing, the following import statements need to be
added to `src/patterns/pattern.owl` for all imports generated in
`src/imports/*_import.owl`.   This will be automated in a future release.')

To compile design patterns to terms run:

`./run.sh make ../patterns/definitions.owl`

This generates a file (`src/patterns/definitions.owl`).  You then need
to add an import statement to the editor's file to import the
definitions file.
## Release Manager notes

You should only attempt to make a release AFTER the edit version is
committed and pushed, AND the travis build passes.

These instructions assume you have
[docker](https://www.docker.com/get-docker). This folder has a script
[run.sh](run.sh) that wraps docker commands.

to release:

first type

    git branch

to make sure you are on master

    cd src/ontology
    sh run.sh make all

If this looks good type:

    sh run.sh make prepare_release

This generates derived files such as upheno.owl and upheno.obo and places
them in the top level (../..).

Note that the versionIRI value automatically will be added, and will
end with YYYY-MM-DD, as per OBO guidelines.

Commit and push these files.

    git commit -a

And type a brief description of the release in the editor window

Finally type:

    git push origin master

IMMEDIATELY AFTERWARDS (do *not* make further modifications) go here:

 * https://github.com/obophenotype/upheno/releases
 * https://github.com/obophenotype/upheno/releases/new

__IMPORTANT__: The value of the "Tag version" field MUST be

    vYYYY-MM-DD

The initial lowercase "v" is REQUIRED. The YYYY-MM-DD *must* match
what is in the `owl:versionIRI` of the derived upheno.owl (`data-version` in
upheno.obo). This will be today's date.

This cannot be changed after the fact, be sure to get this right!

Release title should be YYYY-MM-DD, optionally followed by a title (e.g. "january release")

You can also add release notes (this can also be done after the fact). These are in markdown format.
In future we will have better tools for auto-generating release notes.

Then click "publish release"

__IMPORTANT__: NO MORE THAN ONE RELEASE PER DAY.

The PURLs are already configured to pull from github. This means that
BOTH ontology purls and versioned ontology purls will resolve to the
correct ontologies. Try it!

 * http://purl.obolibrary.org/obo/upheno.owl <-- current ontology PURL
 * http://purl.obolibrary.org/obo/upheno/releases/YYYY-MM-DD.owl <-- change to the release you just made

For questions on this contact Chris Mungall or email obo-admin AT obofoundry.org

# Travis Continuous Integration System

Check the build status here: [![Build Status](https://travis-ci.org/obophenotype/upheno.svg?branch=master)](https://travis-ci.org/obophenotype/upheno)

Note: if you have only just created this project you will need to authorize travis for this repo.

 1. Go to [https://travis-ci.org/profile/obophenotype](https://travis-ci.org/profile/obophenotype)
 2. click the "Sync account" button
 3. Click the tick symbol next to upheno

Travis builds should now be activated


text:
<?xml version="1.0"?>
<rdf:RDF
     xml:base="http://purl.obolibrary.org/obo/"
     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
     xmlns:owl="http://www.w3.org/2002/07/owl#"
     xmlns:oboInOwl="http://www.geneontology.org/formats/oboInOwl#"
     xmlns:xml="http://www.w3.org/XML/1998/namespace"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
     xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
     xmlns:obo="http://purl.obolibrary.org/obo/">
    <owl:Ontology rdf:about="http://purl.obolibrary.org/obo/upheno/imports/ro_import.owl"/>

    <!-- This is a placeholder, it will be regenerated when makefile is first executed -->
</rdf:RDF>


text:
<?xml version="1.0"?>
<rdf:RDF
     xml:base="http://purl.obolibrary.org/obo/"
     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
     xmlns:owl="http://www.w3.org/2002/07/owl#"
     xmlns:oboInOwl="http://www.geneontology.org/formats/oboInOwl#"
     xmlns:xml="http://www.w3.org/XML/1998/namespace"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
     xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
     xmlns:obo="http://purl.obolibrary.org/obo/">
    <owl:Ontology rdf:about="http://purl.obolibrary.org/obo/upheno/imports/pr_import.owl"/>

    <!-- This is a placeholder, it will be regenerated when makefile is first executed -->
</rdf:RDF>


text:
<?xml version="1.0"?>
<rdf:RDF
     xml:base="http://purl.obolibrary.org/obo/"
     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
     xmlns:owl="http://www.w3.org/2002/07/owl#"
     xmlns:oboInOwl="http://www.geneontology.org/formats/oboInOwl#"
     xmlns:xml="http://www.w3.org/XML/1998/namespace"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
     xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
     xmlns:obo="http://purl.obolibrary.org/obo/">
    <owl:Ontology rdf:about="http://purl.obolibrary.org/obo/upheno/imports/hsapdv_import.owl"/>

    <!-- This is a placeholder, it will be regenerated when makefile is first executed -->
</rdf:RDF>


text:
<?xml version="1.0"?>
<rdf:RDF
     xml:base="http://purl.obolibrary.org/obo/"
     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
     xmlns:owl="http://www.w3.org/2002/07/owl#"
     xmlns:oboInOwl="http://www.geneontology.org/formats/oboInOwl#"
     xmlns:xml="http://www.w3.org/XML/1998/namespace"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
     xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
     xmlns:obo="http://purl.obolibrary.org/obo/">
    <owl:Ontology rdf:about="http://purl.obolibrary.org/obo/upheno/imports/nbo_import.owl"/>

    <!-- This is a placeholder, it will be regenerated when makefile is first executed -->
</rdf:RDF>


text:
<?xml version="1.0"?>
<rdf:RDF
     xml:base="http://purl.obolibrary.org/obo/"
     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
     xmlns:owl="http://www.w3.org/2002/07/owl#"
     xmlns:oboInOwl="http://www.geneontology.org/formats/oboInOwl#"
     xmlns:xml="http://www.w3.org/XML/1998/namespace"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
     xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
     xmlns:obo="http://purl.obolibrary.org/obo/">
    <owl:Ontology rdf:about="http://purl.obolibrary.org/obo/upheno/imports/mpath_import.owl"/>

    <!-- This is a placeholder, it will be regenerated when makefile is first executed -->
</rdf:RDF>


text:
<?xml version="1.0"?>
<rdf:RDF
     xml:base="http://purl.obolibrary.org/obo/"
     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
     xmlns:owl="http://www.w3.org/2002/07/owl#"
     xmlns:oboInOwl="http://www.geneontology.org/formats/oboInOwl#"
     xmlns:xml="http://www.w3.org/XML/1998/namespace"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
     xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
     xmlns:obo="http://purl.obolibrary.org/obo/">
    <owl:Ontology rdf:about="http://purl.obolibrary.org/obo/upheno/imports/chebi_import.owl"/>

    <!-- This is a placeholder, it will be regenerated when makefile is first executed -->
</rdf:RDF>


text:
<?xml version="1.0"?>
<rdf:RDF
     xml:base="http://purl.obolibrary.org/obo/"
     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
     xmlns:owl="http://www.w3.org/2002/07/owl#"
     xmlns:oboInOwl="http://www.geneontology.org/formats/oboInOwl#"
     xmlns:xml="http://www.w3.org/XML/1998/namespace"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
     xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
     xmlns:obo="http://purl.obolibrary.org/obo/">
    <owl:Ontology rdf:about="http://purl.obolibrary.org/obo/upheno/imports/uberon_import.owl"/>

    <!-- This is a placeholder, it will be regenerated when makefile is first executed -->
</rdf:RDF>


text:
<?xml version="1.0"?>
<rdf:RDF
     xml:base="http://purl.obolibrary.org/obo/"
     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
     xmlns:owl="http://www.w3.org/2002/07/owl#"
     xmlns:oboInOwl="http://www.geneontology.org/formats/oboInOwl#"
     xmlns:xml="http://www.w3.org/XML/1998/namespace"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
     xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
     xmlns:obo="http://purl.obolibrary.org/obo/">
    <owl:Ontology rdf:about="http://purl.obolibrary.org/obo/upheno/imports/pato_import.owl"/>

    <!-- This is a placeholder, it will be regenerated when makefile is first executed -->
</rdf:RDF>


text:
<?xml version="1.0"?>
<rdf:RDF
     xml:base="http://purl.obolibrary.org/obo/"
     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
     xmlns:owl="http://www.w3.org/2002/07/owl#"
     xmlns:oboInOwl="http://www.geneontology.org/formats/oboInOwl#"
     xmlns:xml="http://www.w3.org/XML/1998/namespace"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
     xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
     xmlns:obo="http://purl.obolibrary.org/obo/">
    <owl:Ontology rdf:about="http://purl.obolibrary.org/obo/upheno/imports/go_import.owl"/>

    <!-- This is a placeholder, it will be regenerated when makefile is first executed -->
</rdf:RDF>


text:
<?xml version="1.0"?>
<rdf:RDF
     xml:base="http://purl.obolibrary.org/obo/"
     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
     xmlns:owl="http://www.w3.org/2002/07/owl#"
     xmlns:oboInOwl="http://www.geneontology.org/formats/oboInOwl#"
     xmlns:xml="http://www.w3.org/XML/1998/namespace"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
     xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
     xmlns:obo="http://purl.obolibrary.org/obo/">
    <owl:Ontology rdf:about="http://purl.obolibrary.org/obo/upheno/imports/cl_import.owl"/>

    <!-- This is a placeholder, it will be regenerated when makefile is first executed -->
</rdf:RDF>


text:
Prefix(:=<http://purl.obolibrary.org/obo/upheno/pattern-ontology-remove-axioms.owl>)
Prefix(owl:=<http://www.w3.org/2002/07/owl#>)
Prefix(obo:=<http://purl.obolibrary.org/obo/>)
Prefix(rdf:=<http://www.w3.org/1999/02/22-rdf-syntax-ns#>)
Prefix(xml:=<http://www.w3.org/XML/1998/namespace>)
Prefix(xsd:=<http://www.w3.org/2001/XMLSchema#>)
Prefix(rdfs:=<http://www.w3.org/2000/01/rdf-schema#>)

Ontology(<http://purl.obolibrary.org/obo/upheno/pattern-ontology-remove-axioms.owl>

# Removed to prevent the inference that inLocation patterns are equivalent to their counterparts
# https://github.com/obophenotype/upheno/issues/510#issuecomment-585729298
SubClassOf(obo:CARO_0030000 ObjectSomeValuesFrom(obo:BFO_0000050 obo:CARO_0010004))

)


text:
#################################################
### Phenotype Ontology Makefile extension #######
#################################################

## This Makfile is intended for use in phenotype
## Ontologies.

MAKEFILE_URL=https://raw.githubusercontent.com/obophenotype/upheno/master/src/ontology/config/pheno.Makefile

.PHONY: update_pheno_makefile
update_pheno_makefile: pheno.Makefile
	echo "Update completed. Please make sure you use make update_pheno_makefile -B to ensure you use the latest version."

pheno.Makefile:
	wget $(MAKEFILE_URL) -O $@

$(SCRIPTSDIR):
	mkdir -p $@

#################################################
### Code for EQ direct relation component #######
#################################################

UPHENO_JAR="https://github.com/obophenotype/upheno-dev/raw/master/src/scripts/upheno-relationship-augmentation.jar"
UPHENO_RELATIONS="https://raw.githubusercontent.com/obophenotype/upheno-dev/master/src/ontology/components/upheno-relations.owl"

$(SCRIPTSDIR)/upheno-relationship-augmentation.jar: | $(SCRIPTSDIR)
	wget $(UPHENO_JAR) -O $@

$(TMPDIR)/phenotype_classes.txt: $(SRC) | $(TMPDIR)
	$(ROBOT) query -i $< --query ../sparql/mp_terms.sparql $@

$(TMPDIR)/$(ONT)-merged-reasoned.owl: $(SRC)
	$(ROBOT) merge -i $< reason -o $@

$(TMPDIR)/upheno_has_phenotype_affecting.owl: ../scripts/upheno-relationship-augmentation.jar $(TMPDIR)/$(ONT)-merged-reasoned.owl $(TMPDIR) tmp/phenotype_classes.txt
	java -jar $^

$(TMPDIR)/upheno-relations.owl: | $(TMPDIR)
	wget $(UPHENO_RELATIONS) -O $@

$(COMPONENTSDIR)/eq-relations.owl: $(TMPDIR)/upheno_has_phenotype_affecting.owl $(TMPDIR)/upheno-relations.owl
	$(ROBOT) merge $(patsubst %, -i %, $^) annotate --ontology-iri $(ONTBASE)/$@ -o $@


text:
echo "This (experimental) update script will create a new repo according to your config file. It will:"
echo "(1) overwrite your repositories Makefile, ODK sparql queries (your custom queries wont be touched) and docker wrapper (run.sh)."
echo "(2) and add missing files, if any."

set -e

OID=upheno
ROOTDIR=../..
SRCDIR=..
CONFIG=$OID"-odk.yaml"

rm -rf target
mkdir target
/tools/odk.py seed -c -g -C $CONFIG
ls -l target/$OID/src
ls -l $SRCDIR/
cp target/$OID/src/scripts/update_repo.sh $SRCDIR/scripts/
rsync -r -u --ignore-existing --exclude 'patterns/data/default/example.tsv' --exclude 'patterns/dosdp-patterns/example.yaml' target/$OID/src/ $SRCDIR/

rsync -r -u --ignore-existing target/$OID/docs/ $ROOTDIR/docs
mkdir -p $ROOTDIR/docs/odk-workflows
rm -rf $ROOTDIR/docs/odk-workflows/*
cp -r target/$OID/docs/odk-workflows/* $ROOTDIR/docs/odk-workflows
cp target/$OID/src/ontology/Makefile $SRCDIR/ontology/
cp target/$OID/src/ontology/run.sh $SRCDIR/ontology/
cp -r target/$OID/src/sparql/* $SRCDIR/sparql/
mkdir -p $ROOTDIR/.github
mkdir -p $ROOTDIR/.github/workflows
cp -n target/$OID/.github/workflows/qc.yml $ROOTDIR/.github/workflows/qc.yml

cp -n target/$OID/.github/workflows/docs.yml $ROOTDIR/.github/workflows/docs.yml

cp -n target/$OID/mkdocs.yaml $ROOTDIR/

echo "WARNING: These files should be manually migrated: mkdocs.yaml, .gitignore, src/ontology/catalog.xml (if you added a new import or component)"
echo "Update successfully completed."


text:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Oct 8 14:24:37 2018

@author: Nicolas Matentzoglu
"""

import os, shutil, sys
import yaml
import re
import pandas as pd
import requests
from time import sleep
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
import urllib.request

### Configuration

pattern_dirs = sys.argv[1]
md_file = sys.argv[2]

#pattern_dir="/ws/upheno/src/patterns/dosdp-dev"
#md_file=pattern_dir+"/README.md"
config_file = "https://raw.githubusercontent.com/obophenotype/upheno-dev/master/src/curation/upheno-config.yaml"
pattern_matches_location = "https://bbop-ontologies.s3.amazonaws.com/upheno/current/pattern-matches"
pattern_matches_location_gh = "https://bbop-ontologies.s3.amazonaws.com/upheno/current/pattern-matches"
config = yaml.load(urllib.request.urlopen(config_file), Loader=yaml.FullLoader)

phenotype_ontologies = config.get("species_modules")

THRESHOLD=99999999

lines = []

lines.append("# Pattern directory")
lines.append("This is a listing of all the patterns hosted as part of this directory")
lines.append("")

i = 0

for pattern_dir in pattern_dirs.split("|"):
    lines.append("## Patterns in {}".format(os.path.basename(pattern_dir)))
    files = os.listdir(pattern_dir)
    files.sort()

    for filename in files:
        if filename.endswith(".yaml"):
            f_path = os.path.join(pattern_dir,filename)
            f = open(f_path)
            try:
                y = yaml.load(f, Loader=yaml.FullLoader)
                fn = os.path.basename(filename)
                splitted = " ".join(re.sub('([A-Z][a-z]+)', r' \1', re.sub('([A-Z]+)', r' \1', fn)).split()).replace(".yaml","")
                splitted = splitted.lower().capitalize()
                variables = ""
                classes = ""
                contributors = ""

                for v in y['vars']:
                    vs = re.sub("[^0-9a-zA-Z _]", "", y['vars'][v])
                    vsv = re.sub("[']", "", y['vars'][v])
                    variables = variables+vs+" ("+y['classes'][vsv]+"), "

                for v in y['classes']:
                    cid = y['classes'][v]
                    classes = classes+cid+", "

                if 'contributors' in y:
                    for v in y['contributors']:
                        contributors = contributors+"["+re.sub("https[:][/][/]orcid[.]org[/]","",v)+"]("+v+"), "

                examples = []
                tsv = fn.replace(".yaml",".tsv")
                for o in phenotype_ontologies:
                    url = "{}/{}/{}".format(pattern_matches_location,o,tsv)
                    ghurl = "{}/{}/{}".format(pattern_matches_location_gh,o,tsv)
                    print(url)
                    if i < THRESHOLD:
                        try:
                            df=pd.read_csv(url,sep="\t")
                            if not df.empty:
                                examples.append('[{}]({})'.format(o,ghurl))
                                i = i +1
                            else:
                                print("No matches!")
                            sleep(0.2)
                        except Exception as e:
                            print("No matches!")

                lines.append("### "+splitted)
                lines.append("*" + y['description']+"*")
                lines.append("")
                lines.append("| Attribute | Info |")
                lines.append("|----------|----------|")
                lines.append("| IRI | " + y['pattern_iri'] + " |")
                lines.append("| Name | " + y['pattern_name'] + " |")
                lines.append("| Classes | "+classes+" |")
                lines.append("| Variables | "+variables+" |")
                lines.append("| Contributors | "+contributors+" |")
                lines.append("| Examples | "+' '.join(examples)+" |")
                lines.append("")

            except yaml.YAMLError as exc:
                print(exc)

with open(md_file, 'w') as f:
    for item in lines:
        f.write("%s\n" % item)