Textual Definitions Automated Check

Discussion on this check can be found here.

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).

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) annotation to each term that is missing a definition. For help writing good definitions, see Textual Definitions Recommendations.

For adding definitions in bulk, check out ROBOT template.

Implementation

ROBOT report is run over the ontology. A count of violations for each of the following checks is retrieved from the report object: duplicate definition, multiple definitions, and 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

# violation messages
DUPLICATE_MSG = '{0} duplicate definitions.'
MULTIPLE_MSG = '{0} multiple definitions.'
MISSING_MSG = '{0} missing definitions.'
HELP_MSG = 'See ROBOT Report for details.'


def has_valid_definitions(report):
   """Check fp 6 - textual definitions.

   If the ontology passes all ROBOT report definition checks, PASS. If there
   are any violations, return that level of violation and a summary of the
   violations.

   Args:
       report (Report): ROBOT report object
   """
   if report is None:
       return {'status': 'INFO',
               'comment': 'ROBOT Report could not be generated'}

   # error level violations
   duplicates = report.getViolationCount('duplicate_definition')
   multiples = report.getViolationCount('multiple_definitions')

   # warn level violation
   missing = report.getViolationCount('missing_definition')

   if not duplicates > 0 and not multiples > 0 and not missing > 0:
       return {'status': 'PASS'}
   if not missing == 0 and not duplicates > 0 and not multiples > 0:
       return {'status': 'WARN',
               'comment': ' '.join([MISSING_MSG.format(missing), HELP_MSG])}

   comment = [f'{DUPLICATE_MSG.format(duplicates) if duplicates > 0 else ""}',
              f'{MULTIPLE_MSG.format(multiples) if multiples > 0 else ""}',
              f'{MISSING_MSG.format(missing) if missing > 0 else ""}',
              HELP_MSG]

   return {'status': 'ERROR',
           'comment': ' '.join(comment).strip()}