diff --git a/util/dashboard/fp_001.py b/util/dashboard/fp_001.py index 9a21f37..d877863 100755 --- a/util/dashboard/fp_001.py +++ b/util/dashboard/fp_001.py @@ -5,17 +5,21 @@ ## Discussion on this check can be [found here](https://github.com/OBOFoundry/OBOFoundry.github.io/issues/1019). ## ##### Requirements +## ## 1. The ontology **must** have a license both in the registry data and in the ontology file. -## 2. The licenese **must** be the same in both files. -## 3. The license *should* be one of the CC0 or CC-BY licenses. +## 2. The license **must** be the same in both files. +## 3. The license _should_ be one of the CC0 or CC-BY licenses. ## ## ### Fixes ## ## #### Choosing a license +## ## See [Open Recommendations](http://obofoundry.org/principles/fp-001-open.html#recommendations) for appropriate licenses. ## ## #### Adding a license to the registry data +## ## First, read the [FAQ](http://obofoundry.github.io/faq/how-do-i-edit-metadata.html) on how to edit the metadata for your ontology. Then, add the following to your [metadata file](https://github.com/OBOFoundry/OBOFoundry.github.io/tree/master/ontology) (replacing with the correct license and license label): +## ## ``` ## license: ## url: http://creativecommons.org/licenses/by/4.0/ @@ -23,13 +27,15 @@ ## ``` ## ## #### Adding a license to the ontology file +## ## See [Open Implementation](http://obofoundry.org/principles/fp-001-open.html#implementation) for details on adding license to OWL and OBO files. ## ## ### Implementation +## ## The registry data entry is validated with JSON schema using the [license schema](https://raw.githubusercontent.com/OBOFoundry/OBOFoundry.github.io/master/util/schema/license.json). The license schema ensures that a license entry is present and that the entry has a `url` and `label`. The license schema also checks that the license is one of the CC0 or CC-BY licenses. OWL API is then used to check the ontology as an `OWLOntology` object. Annotations on the ontology are retrieved and the `dcterms:license` property is found. The python script ensures that the correct `dcterms:license` property is used. The script compares this license to the registry license to ensure that they are the same. -import jsonschema import dash_utils +import jsonschema def is_open(ontology, data, schema): @@ -293,7 +299,7 @@ def compare_licenses(registry_license, ontology_license): ontology_license (str): license URL from the ontology Return: - True if registry license matches ontology licences; + True if registry license matches ontology license; False if the licenses do not match; None if one or both licenses are missing. """ @@ -369,7 +375,7 @@ def process_results(registry_license, level = 'ERROR' issues.append(missing_ontology_license) - # matches_ontology = None if missing ontology licenese + # matches_ontology = None if missing ontology license if matches_ontology is False: level = 'ERROR' issues.append(no_match.format(ontology_license, registry_license)) diff --git a/util/dashboard/fp_002.py b/util/dashboard/fp_002.py index 98f66c6..c042532 100644 --- a/util/dashboard/fp_002.py +++ b/util/dashboard/fp_002.py @@ -5,12 +5,15 @@ ## Discussion on this check can be [found here](https://github.com/OBOFoundry/OBOFoundry.github.io/issues/1018). ## ## ### Requirements +## ## 1. Released ontology **must** be in RDF/XML format ## ## ### Fixes +## ## See the [Common Format Recommendations](http://obofoundry.org/principles/fp-002-format.html#recommendations). [ROBOT](http://robot.obolibrary.org/convert) offers functionality to convert a variety of formats, including OBO, to RDF/XML. Protégé allows you to save ontologies in RDF/XML, as well. The [Ontology 101 Tutorial](https://ontology101tutorial.readthedocs.io/en/latest/StartingProtege.html) has directions on starting and saving in Protégé. ## ## ### Implementation +## ## Current implementation attempts to load the ontology using OWL API. If the ontology is loaded, it is assumed that it is in a good format, although it may not be RDF/XML. For large ontologies, the ontology is a valid format (either RDF/XML or Turtle) if it can be [loaded with Jena](http://robot.obolibrary.org/query#executing-on-disk) to run the ROBOT report over. import dash_utils diff --git a/util/dashboard/fp_003.py b/util/dashboard/fp_003.py index bff7b24..a78657d 100644 --- a/util/dashboard/fp_003.py +++ b/util/dashboard/fp_003.py @@ -5,29 +5,34 @@ ## Discussion on this check can be [found here](https://github.com/OBOFoundry/OBOFoundry.github.io/issues/1017). ## ## ### Requirements +## ## 1. All entities in the ontology namespace **must** use an underscore to separate the namespace and local ID. -## 2. The local ID *should* not be semantically significant, and *should* be numeric. +## 2. The local ID _should_ not be semantically significant, and _should_ be numeric. ## ## ### Fixes +## ## Edit problematic IRIs to resolve the problems. [Click here](https://ontology101tutorial.readthedocs.io/en/latest/EntitiesTab.html#renaming-an-entity) for details on editing an IRI in Protégé. ## ## The full OBO Foundry ID Policy can be found [here](http://www.obofoundry.org/id-policy). In short, all IRIs should begin with your unique OBO Foundry namespace (e.g., `http://purl.obolibrary.org/obo/OBI_`). The local ID, which comes after the unique namespace, should be numeric (e.g., `http://purl.obolibrary.org/obo/OBI_0000001`). We recommend using seven digits. ## ## #### Updating an IRI +## ## 1. Add an `owl:deprecated` annotation with a boolean value of `true` to the problematic term ## 2. Add `obsolete` to the beginning of the term's label to prevent duplicating labels ## 3. Create a new term with a valid IRI to replace this old term ## 4. Copy the old annotations (label, definition, etc., excluding the `owl:deprecated`) over to the new term ## 5. Add a [`IAO:0100001` (term replaced by)](http://purl.obolibrary.org/obo/IAO_0100001) annotation to the old term with a value of the new term's IRI -## * Make sure this is an IRI annotation by selecting "IRI Editor" when adding the annotation in Protégé +## - Make sure this is an IRI annotation by selecting "IRI Editor" when adding the annotation in Protégé ## ## ### Implementation +## ## All entity IRIs are retrieved from the ontology, excluding annotation properties. Annotation properties may use hashtags and words due to legacy OBO conversions for subset properties. All other IRIs are checked if they are in the ontology's namespace. If the IRI begins with the ontology namespace, the next character must be an underscore. If not, this is an error. The IRI is also compared to a regex pattern to check if the local ID after the underscore is numeric. If not, this is a warning. -import dash_utils import os import re +import dash_utils + iri_pattern = r'http:\/\/purl\.obolibrary\.org\/obo\/%s_[0-9]{1,9}' owl_deprecated = 'http://www.w3.org/2002/07/owl#deprecated' diff --git a/util/dashboard/fp_004.py b/util/dashboard/fp_004.py index 425e168..3b9868a 100644 --- a/util/dashboard/fp_004.py +++ b/util/dashboard/fp_004.py @@ -5,31 +5,35 @@ ## Discussion on this check can be [found here](https://github.com/OBOFoundry/OBOFoundry.github.io/issues/1016). ## ## ### Requirements +## ## 1. The released ontology **must** have a version IRI. -## 2. The version IRI *should* follow a dated format (`NS/YYYY-MM-DD/ontology.owl`) +## 2. The version IRI _should_ follow a dated format (`NS/YYYY-MM-DD/ontology.owl`) ## ## ### Fixes +## ## First, make sure you have a valid version IRI pattern. See [Versioning Implementation](http://obofoundry.org/principles/fp-004-versioning.html#implementation) for more details. ## ## #### Adding a Version IRI in Protégé +## ## The "Ontology Version IRI" input is located in the "Active Ontology" tab that appears when you open your ontology in Protégé. ## ## #### Adding a Version IRI with ROBOT +## ## You may use the [ROBOT annotate](http://robot.obolibrary.org/annotate) command the add a version IRI. ## ## Please be aware that the [Ontology Development Kit](https://github.com/INCATools/ontology-development-kit) comes standard with a release process that will automatically generate a dated version IRI for your ontology release. ## ## ### Implementation +## ## The version IRI is retrieved from the ontology using OWL API. For very large ontologies, the RDF/XML ontology header is parsed to find the owl:versionIRI declaration. If found, the IRI is compared to a regex pattern to determine if it is in date format. If it is not in date format, a warning is issued. If the version IRI is not present, this is an error. +import re from typing import Optional from urllib.parse import urlparse import dash_utils -import re from lib import url_exists - # regex pattern to match purl obolibrary url pat = r'http:\/\/purl\.obolibrary\.org/obo/.*/.*/.*' PATTERN = re.compile(pat) diff --git a/util/dashboard/fp_005.py b/util/dashboard/fp_005.py index 6484f3e..4576fc0 100644 --- a/util/dashboard/fp_005.py +++ b/util/dashboard/fp_005.py @@ -5,15 +5,19 @@ ## Discussion on this check can be [found here](https://github.com/OBOFoundry/OBOFoundry.github.io/issues/1015). ## ## ### Requirements +## ## 1. A scope ('domain') **must** be declared in the registry data ## ## ### Fixes +## ## First, read the [FAQ](http://obofoundry.github.io/faq/how-do-i-edit-metadata.html) on how to edit the metadata for your ontology. Then, add the following to your [metadata file](https://github.com/OBOFoundry/OBOFoundry.github.io/tree/master/ontology) (replacing with your domain): +## ## ``` ## domain: experiments ## ``` ## ## ### Implementation +## ## First, the registry data is checked for a 'domain' tag. If missing, that is an error. If it is present, the domain is compared to all other ontology domains. If the ontology shares a domain with one or more other ontologies, we return a list of those ontologies in an info message. import dash_utils diff --git a/util/dashboard/fp_006.py b/util/dashboard/fp_006.py index 8a0c2b6..fa07537 100644 --- a/util/dashboard/fp_006.py +++ b/util/dashboard/fp_006.py @@ -5,25 +5,31 @@ ## Discussion on this check can be [found here](https://github.com/OBOFoundry/OBOFoundry.github.io/issues/1010). ## ## ### Requirements +## ## 1. Each definition **must** be unique. ## 2. Each entity **must** not have more than one textual definition. -## 3. Each entity *should* have a textual definition using [`IAO:0000115` (definition)](http://purl.obolibrary.org/obo/IAO_0000115). +## 3. Each entity _should_ have a textual definition using [`IAO:0000115` (definition)](http://purl.obolibrary.org/obo/IAO_0000115). ## ## ### Fixes ## ## #### Uniqueness +## ## Update each duplicate definition to have some detail that differentiates one term from another. ## ## #### Multiples +## ## If a term has more than one defintion, combine the two definitions. Alternatively, change one definition to an `rdfs:comment` if it just contains further details. ## ## #### Missing Definitions +## ## Add an [`IAO:0000115` (definition)](http://purl.obolibrary.org/obo/IAO_0000115) annotation to each term that is missing a definition. For help writing good definitions, see [Textual Definitions Recommendations](http://obofoundry.org/principles/fp-006-textual-definitions.html#recommendation). ## -## For adding defintions in bulk, check out [ROBOT template](http://robot.obolibrary.org/template). +## For adding definitions in bulk, check out [ROBOT template](http://robot.obolibrary.org/template). ## ## ### Implementation -## [ROBOT report](http://robot.obolibrary.org/report) is run over the ontology. A count of violations for each of the following checks is retrieved from the report object: [duplicate definition](http://robot.obolibrary.org/report_queries/duplicate_definition), [multiple definitions](http://robot.obolibrary.org/report_queries/multiple_definitions), and [missing definition](http://robot.obolibrary.org/report_queries/missing_definition). If there are any duplicate or multiple defintions, it is an error. If there are missing definitions, it is a warning. +## +## [ROBOT report](http://robot.obolibrary.org/report) is run over the ontology. A count of violations for each of the following checks is retrieved from the report object: [duplicate definition](http://robot.obolibrary.org/report_queries/duplicate_definition), [multiple definitions](http://robot.obolibrary.org/report_queries/multiple_definitions), and [missing definition](http://robot.obolibrary.org/report_queries/missing_definition). If there are any duplicate or multiple definitions, it is an error. If there are missing definitions, it is a warning. +## Note: Even a single duplicate or multiple definition will result in an error status, while missing definitions will only trigger a warning status regardless of count. import dash_utils from dash_utils import format_msg diff --git a/util/dashboard/fp_007.py b/util/dashboard/fp_007.py index b6d40c8..1792113 100644 --- a/util/dashboard/fp_007.py +++ b/util/dashboard/fp_007.py @@ -5,29 +5,33 @@ ## Discussion on this check can be [found here](https://github.com/OBOFoundry/OBOFoundry.github.io/issues/981). ## ## ### Requirements +## ## 1. The ontology **must not** duplicate existing RO properties. -## 2. The ontology *should* use existing RO properties, rather than creating new propeties. +## 2. The ontology _should_ use existing RO properties, rather than creating new properties. ## ## ### Fixes ## ## #### Duplicated Properties +## ## 1. Add an `owl:deprecated` annotation with a boolean value of `true` to the problematic property in your ontology ## 2. Add `obsolete` to the beginning of the property's label ## 3. Replace all usages of that property with the duplicated RO property ## ## #### Non-RO Properties +## ## Review your non-RO properties to see if any can be replaced with an RO property using the steps above. Often, a corresponding property will not exist in RO and that is OK. ## ## ### Implementation +## ## The object and data properties from the ontology are compared to existing RO properties. If any labels match existing RO properties, but do not use the correct RO IRI, this is an error. Any non-RO properties (no label match and do not use an RO IRI) will be listed as INFO messages. import csv -import dash_utils import os import unicodedata - from io import TextIOWrapper +import dash_utils + owl_deprecated = 'http://www.w3.org/2002/07/owl#deprecated' # Violation messages diff --git a/util/dashboard/fp_008.py b/util/dashboard/fp_008.py index d77b030..d533f7f 100644 --- a/util/dashboard/fp_008.py +++ b/util/dashboard/fp_008.py @@ -5,32 +5,41 @@ ## Discussion on this check can be [found here](https://github.com/OBOFoundry/OBOFoundry.github.io/issues/1009). ## ## ### Requirements +## ## 1. The ontology **must** have a homepage. ## 2. The homepage URL **must** resolve. ## 3. The ontology **must** have a description. ## ## ### Fixes +## ## First, read the [FAQ](http://obofoundry.github.io/faq/how-do-i-edit-metadata.html) on how to edit the metadata for your ontology. ## ## #### Adding or Updating a Homepage +## ## Add the following to your [metadata file](https://github.com/OBOFoundry/OBOFoundry.github.io/tree/master/ontology) (replacing with your homepage, which may just be your GitHub repository): +## ## ``` ## homepage: http://obi-ontology.org ## ``` +## ## If your homepage is not resolving, determine why (Is the server down? Is the URL wrong?) and update your homepage URL if needed. ## ## #### Adding a Description +## ## Add the following to your [metadata file](https://github.com/OBOFoundry/OBOFoundry.github.io/tree/master/ontology) (replacing with a short description about your ontology): +## ## ``` ## description: An integrated ontology for the description of life-science and clinical investigations ## ``` ## ## ### Implementation -## The registry data is checked for 'homepage' and 'description' entries. If either is missing, this is an error. If the homepage is present, the URL is checked to see if it resolves (does not return an HTTP status of greater than 400). If the URL does not resolve, this is also an error. +## +## The registry data is checked for 'homepage' and 'description' entries. If either is missing, this is an error. If the homepage is present, the URL is checked to see if it returns a successful HTTP status code (200-299) rather than an error code (400+). If the URL does not resolve, this is also an error. from lib import url_exists + def has_documentation(data): """Check fp 8 - documentation. diff --git a/util/dashboard/fp_009.py b/util/dashboard/fp_009.py index ecbf67d..c5765d7 100644 --- a/util/dashboard/fp_009.py +++ b/util/dashboard/fp_009.py @@ -5,22 +5,28 @@ ## Discussion on this check can be [found here](https://github.com/OBOFoundry/OBOFoundry.github.io/issues/1008). ## ## ### Requirements +## ## 1. The ontology **must** have a tracker. ## 2. The ontology **must** have usages. ## ## ### Fixes +## ## First, read the [FAQ](http://obofoundry.github.io/faq/how-do-i-edit-metadata.html) on how to edit the metadata for your ontology. ## ## #### Adding a Tracker +## ## If you do not already have a version control repository that has an [Issues Tracker](https://help.github.com/en/github/managing-your-work-on-github/about-issues), create one. We recommend creating a [GitHub Repository](https://help.github.com/en/github/getting-started-with-github/create-a-repo). To do this, you will need to [create a GitHub account](https://github.com/join) if you do not already have one. ## ## Once you have a version control repository, add the following to your [metadata file](https://github.com/OBOFoundry/OBOFoundry.github.io/tree/master/ontology) (replacing with the link to your repository's issue tracker): +## ## ``` ## tracker: https://github.com/DiseaseOntology/HumanDiseaseOntology/issues ## ``` ## ## #### Adding Usages +## ## Determine what other groups are using your ontology and how they are using it. Then, add the following to your [metadata file](https://github.com/OBOFoundry/OBOFoundry.github.io/tree/master/ontology) (replacing with the correct group name, link, and description): +## ## ``` ## usages: ## - user: http://www.informatics.jax.org/disease (link to group) @@ -29,10 +35,12 @@ ## - url: http://www.informatics.jax.org/disease/DOID:4123 (link to specific example) ## description: Human genes and mouse homology associated with nail diseases (description of specific example) ## ``` -## You may have multiple exampels for each user, and mulitple users under the `usages` tag. +## +## You may have multiple examples for each user, and multiple users under the `usages` tag. ## ## ### Implementation -## The registry data is checked for 'tracker' and 'usage' entries. If either is missing, this is an error. +## +## The registry data is checked for 'tracker' and 'usage' entries. If either is missing, this is an error. The tracker should be a valid URL to an issue tracking system, and usages should contain at least one user with a valid URL and description. import dash_utils from dash_utils import format_msg diff --git a/util/dashboard/fp_011.py b/util/dashboard/fp_011.py index 3c2313b..d15cd1f 100644 --- a/util/dashboard/fp_011.py +++ b/util/dashboard/fp_011.py @@ -5,12 +5,15 @@ ## Discussion on this check can be [found here](https://github.com/OBOFoundry/OBOFoundry.github.io/issues/1007). ## ## ### Requirements +## ## 1. The ontology **must** have a single contact person ## ## ### Fixes +## ## First, read the [FAQ](http://obofoundry.github.io/faq/how-do-i-edit-metadata.html) on how to edit the metadata for your ontology. ## ## Next, determine who the point person for your ontology project is. This *must not* be a mailing list. If this person does not already have a GitHub account, we request that they [create one](https://github.com/join). Then, add the following to your [metadata file](https://github.com/OBOFoundry/OBOFoundry.github.io/tree/master/ontology) (replacing with the correct email, name, and GitHub username): +## ## ``` ## contact: ## email: foo@bar.com @@ -19,13 +22,14 @@ ## ``` ## ## ### Implementation +## ## The registry data entry is validated with JSON schema using the [contact schema](https://raw.githubusercontent.com/OBOFoundry/OBOFoundry.github.io/master/util/schema/contact.json). The contact schema ensures that a contact entry is present and that the entry has a name and email address. -import jsonschema - import dash_utils +import jsonschema from dash_utils import format_msg + def has_contact(data, contact_schema): """Check fp 11 - locus of authority. diff --git a/util/dashboard/fp_012.py b/util/dashboard/fp_012.py index c839a73..0952519 100644 --- a/util/dashboard/fp_012.py +++ b/util/dashboard/fp_012.py @@ -5,28 +5,34 @@ ## Discussion on this check can be [found here](https://github.com/OBOFoundry/OBOFoundry.github.io/issues/1006). ## ## ### Requirements +## ## 1. Each label **must** be unique. ## 2. Each entity **must** not have more than one label. -## 3. Each entity *should* have a label using `rdfs:label`. +## 3. Each entity _should_ have a label using `rdfs:label`. ## ## ### Fixes ## ## #### Uniqueness +## ## Update at least one label to distinguish between the two terms. Add the original label to a `oboInOwl:hasExactSynonym` (alternatively, narrow, related, or broad) or [`IAO:0000118` (alternative term)](http://purl.obolibrary.org/obo/IAO_0000118) annotation. ## ## If the terms are exactly the same: +## ## 1. Obsolete one of them by adding the `owl:deprecated` annotation property with a boolean value of `true` ## 2. Add `obsolete` to the beginning of this term's label ## 3. Add a [`IAO:0100001` (term replaced by)](http://purl.obolibrary.org/obo/IAO_0100001) annotation to this term pointing to the other, non-deprecated term. -## * Make sure this is an IRI annotation by selecting "IRI Editor" when adding the annotation in Protégé +## - Make sure this is an IRI annotation by selecting "IRI Editor" when adding the annotation in Protégé ## ## #### Multiple Labels +## ## Determine which label most accurately describes the term. Change the other label(s) to `oboInOwl:hasExactSynonym` (alternatively, narrow, related, or broad) or [`IAO:0000118` (alternative term)](http://purl.obolibrary.org/obo/IAO_0000118). ## ## #### Missing Labels +## ## Add an `rdfs:label` annotation to each term that is missing a label. For adding labels in bulk, check out [ROBOT template](http://robot.obolibrary.org/template). ## ## ### Implementation +## ## [ROBOT report](http://robot.obolibrary.org/report) is run over the ontology. A count of violations for each of the following checks is retrieved from the report object: [duplicate label](http://robot.obolibrary.org/report_queries/duplicate_label), [multiple labels](http://robot.obolibrary.org/report_queries/multiple_labels), and [missing label](http://robot.obolibrary.org/report_queries/missing_label). If there are any of these violations, it is an error. import dash_utils diff --git a/util/dashboard/fp_016.py b/util/dashboard/fp_016.py index f8c5c14..c572284 100644 --- a/util/dashboard/fp_016.py +++ b/util/dashboard/fp_016.py @@ -5,12 +5,15 @@ ## Discussion on this check can be [found here](https://github.com/OBOFoundry/OBOFoundry.github.io/issues/1020). ## ## ### Requirements -## 1. The ontology *should* be regularly updated. +## +## 1. The ontology _should_ be regularly updated. ## ## ### Fixes +## ## Make sure all content in your ontology is up-to-date with scientific literature. If you make regular changes, make sure to have regular releases. ## ## ### Implementation +## ## A version IRI is retrieved from the ontology, either using OWL API or parsing RDF/XML for large ontologies. This version IRI is checked against a regex pattern to determine if it is in date format. If so, the date is retrieved. If the last version IRI date is older than three years, this is an error. If it is older than two years, this is a warning. If it is older than one year, this will be an info message. import datetime diff --git a/util/dashboard/fp_020.py b/util/dashboard/fp_020.py index 9a685e7..a1850c2 100644 --- a/util/dashboard/fp_020.py +++ b/util/dashboard/fp_020.py @@ -5,20 +5,25 @@ ## Discussion on this check can be [found here](https://github.com/OBOFoundry/OBOFoundry.github.io/issues/959). ## ## ### Requirements +## ## 1. The ontology **must** have a tracker. ## ## ### Fixes +## ## First, read the [FAQ](http://obofoundry.github.io/faq/how-do-i-edit-metadata.html) on how to edit the metadata for your ontology. ## ## #### Adding a Tracker +## ## If you do not already have a version control repository that has an [Issues Tracker](https://help.github.com/en/github/managing-your-work-on-github/about-issues), create one. We recommend creating a [GitHub Repository](https://help.github.com/en/github/getting-started-with-github/create-a-repo). To do this, you will need to [create a GitHub account](https://github.com/join) if you do not already have one. ## ## Once you have a version control repository, add the following to your [metadata file](https://github.com/OBOFoundry/OBOFoundry.github.io/tree/master/ontology) (replacing with the link to your repository's issue tracker): +## ## ``` ## tracker: https://github.com/DiseaseOntology/HumanDiseaseOntology/issues ## ``` ## ## ### Implementation +## ## The registry data is checked for 'tracker' entry. If it is missing, this is an error. import dash_utils @@ -41,6 +46,6 @@ def is_responsive(data): tracker = None if tracker is None: - return {'status': 'ERROR', 'comment': 'Missing tracker and usages'} + return {'status': 'ERROR', 'comment': 'Missing tracker'} return {'status': 'PASS'}