Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Template Rework #403

Merged
merged 48 commits into from
Jun 25, 2019
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
99927b2
First pass at template rework
Nov 5, 2018
a44b33b
Add tests for new template operation
Nov 7, 2018
e10c681
Update tests and docs for template
Nov 15, 2018
9e19d14
Add more details to template docs
Nov 15, 2018
4bbe022
Merge remote-tracking branch 'upstream/master' into template
Nov 15, 2018
364338c
Merge branch 'master' of https://github.com/ontodev/robot into template
jamesaoverton Mar 1, 2019
2e22b93
Partial fix from code review
Mar 1, 2019
0449588
Code review fixes, fix equivalent classes bug
Mar 2, 2019
df364ba
Remove old error message
Mar 2, 2019
2c3157a
Fix test cases for LABEL change
Mar 2, 2019
a62177c
Update docs
Mar 4, 2019
ec985ef
Add note to manchester error
Mar 4, 2019
59f68e0
Collect all exceptions and fail at the end
Mar 15, 2019
735fdec
Fix backwards compatibility
Mar 15, 2019
4c72438
Remove extra file
Mar 18, 2019
1aeeab7
Rework exceptions
Mar 18, 2019
49e5ccf
Rework --force
Mar 18, 2019
b4d8b28
Fix property assertion template strings
Apr 12, 2019
ea1252f
Add custom label-property option
May 6, 2019
a6bcc92
Use checker to resolve label property
May 7, 2019
8020ffb
Fix null pointer exception
May 7, 2019
4c0cc11
Revision updates
May 8, 2019
da2ab0b
Allow LABEL keyword to create labels
May 8, 2019
1633aad
Fix closing tag
May 8, 2019
80d7f1f
Change expression template strings
May 8, 2019
e94bc49
Fix property parsing bugs
May 9, 2019
0d1da47
Fix label checking
May 9, 2019
f93d2ab
Revert example files
Jun 6, 2019
77a1cf8
Remove extra white space
Jun 6, 2019
754b3a8
Remove extra newline
Jun 6, 2019
627c139
Remove extra newline
Jun 6, 2019
0ae4528
Merge branch 'master' into template
Jun 12, 2019
57ffd6b
Make ECs separate equivalent class statements
Jun 12, 2019
f17aa7f
Fix doc for EC
Jun 12, 2019
291bcda
Revise template docs
jamesaoverton Jun 12, 2019
962831b
Add CHARACTERISTIC for properties
Jun 13, 2019
e318d35
Add error docs
Jun 13, 2019
6d59871
Fix NI documentation
Jun 18, 2019
02fbd5d
Merge branch 'master' into template
Jun 18, 2019
f895de7
Code review updates
Jun 18, 2019
bdb38a3
Do not use single quotes for properties
Jun 18, 2019
6aebb31
Add test with new template strings
Jun 18, 2019
f51d8a4
Fix issue with new labels from multiple templates
Jun 19, 2019
d23e83c
Fix type resolution
Jun 19, 2019
3376622
Update tests for legacy and new formats
Jun 20, 2019
72c71d8
Remove import
Jun 20, 2019
94665c4
Remove unused var
Jun 21, 2019
4051527
Fix Javadocs
jamesaoverton Jun 25, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/examples/reasoned.owl
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?xml version="1.0"?>
<rdf:RDF xmlns="http://purl.obolibrary.org/obo/go.owl#"
xml:base="http://purl.obolibrary.org/obo/go.owl"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
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#">
Expand Down Expand Up @@ -256,5 +256,5 @@



<!-- Generated by the OWL API (version 0.0.1-SNAPSHOT) https://github.com/owlcs/owlapi -->
<!-- Generated by the OWL API (version 4.5.6) https://github.com/owlcs/owlapi -->

6 changes: 0 additions & 6 deletions docs/examples/template.owl
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,6 @@



<!-- http://www.w3.org/1999/02/22-rdf-syntax-ns#type -->

<owl:AnnotationProperty rdf:about="http://www.w3.org/1999/02/22-rdf-syntax-ns#type"/>



<!--
///////////////////////////////////////////////////////////////////////////////////////
//
Expand Down
82 changes: 77 additions & 5 deletions docs/template.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,96 @@ The `template` command accepts an optional input ontology, either using the `--i

## Template Strings

### Generic Template Strings

- `ID`: Every term must have an IRI to identify it. This can be specified with an `ID` column. Usually this will be a prefixed ID like `GO:12345`. See the `--prefix` options for details. Rows with an empty ID cell will be skipped.
- `LABEL`: If a term exists in an ontology, or its ID has been defined elsewhere (perhaps in a previous template), then the `LABEL` column can specify an `rdfs:label` that uniquely identifies the target term. This can be easier the numeric IDs for human readers.
- `LABEL`: If a term exists in an ontology, or its ID has been defined elsewhere (perhaps in a previous template), then the `LABEL` column can specify an `rdfs:label` that uniquely identifies the target term. This can be easier the numeric IDs for human readers. The `LABEL` column DOES NOT create an `rdfs:label` annotation for an entity.
- `TYPE`: this is the `rdf:type` for the row. Because ROBOT is focused on ontology development, the default value is `owl:Class` and this column is optional. When creating an OWLIndividual, specify the class to which it belongs in this column.
- `CLASS_TYPE`: ROBOT creates a class for each row of data. You must specify a CLASS_TYPE, which can be either:
- `subclass`: the created class will be asserted to be a subclass of each templated class expression
- `equivalent`: the created class will be asserted to be equivalent to the intersection of all the templated class expressions
- `class` or `owl:Class`
- `object property` or `owl:ObjectProperty`
- `data property` or `owl:DataProperty`
- `annotation property` or `owl:AnnotationProperty`
- `datatype` or `owl:Datatype`
- **annotations**: ROBOT can attach annotations to your class. There are four options:
- `A` string annotation: If the template string starts with an `A` and a space then it will be interpreted as a string annotation. The rest of the template string should be the label or compact IRI of an annotation property, e.g. `label` or `rdfs:label`. The cell value will be the literal value of the annotation with type `xsd:string`.
- `AT` typed annotation: If the template string starts with an `AT` and a space then it will be interpreted as a typed annotation. The `^^` characters must be used to separate the annotation property from the datatype, e.g. `rdfs:comment^^xsd:integer`. The cell value will be the typed literal value of the annotation.
- `AL` language annotation: If the template string starts with an `AL` and a space then it will be interpreted as a language annotation. The `@` character must be used to separate the annotation property from the language code, e.g. `rdfs:comment@en`.
- `AI` annotation IRI: If the template string starts with an `AI` and a space, then the annotation will be made as with a string annotation, except that the cell value will be interpreted as an IRI.
- `C` **class expression**: If the template string starts with a `C` and a space then it will be interpreted as a class expression. The value of the current cell will be substituted into the template, replacing all occurrences of the percent `%` character. Then the result will be parsed into an OWL class expression. ROBOT uses the same syntax for class expressions as Protégé: [Manchester Syntax](http://www.w3.org/2007/OWL/wiki/ManchesterSyntax). This means that an entity can be referred to by its rdfs:label (enclosing in single quotes if it has a space in it). If it does not recognize a label, ROBOT will assume that you're trying to refer to a class by its IRI (or compact IRI). This can lead to unexpected behaviour, but it allows you to refer to classes (by IRI) without loading them into the input ontology. This is particularly useful when the input ontology would be too large, such as the NCBI Taxonomy.
- **axiom annotations**: ROBOT can also annotate logical and annotation axioms.
- `>A` annotation on annotation: Annotates the annotation axiom created from the cell to the left with the cell value. The column to the left must be an `A*` template string.
- `>C` annotation on class expression: Annotates the class expression axiom created from the cell to the left with the cell value. The column to the left must be a `C` template string.
beckyjackson marked this conversation as resolved.
Show resolved Hide resolved
- `>P` annotation on property expression: Annotates the property expression axiom created fromt eh cell to the left with the cell value. The column to the left must be a `P` template string.

Sometimes you want to include zero or more values in a single spreadsheet cell, for example when you want to allow for multiple annotations or have seperate logical axioms. If a template string also contains `SPLIT=|`, then ROBOT will use the `|` character to split the contents of a cell in that column and add an annotation for each result (if there are any). Instead of `|` you can specify a string of characters of your choice - other than pure whitespace - to split on (e.g. `SPLIT=, `).

### Class Template Strings

- `CLASS_TYPE`: ROBOT creates a class for each row of data with a that has a `TYPE` of `class` or `owl:Class`. The class type can be:
- `subclass`: the created class will be asserted to be a subclass of each templated class expression (default)
- `disjoint`: the created class will be disjoint from each templated class expression, meaning the classes cannot share subclasses
- `equivalent`: the created class will be asserted to be equivalent to the intersection of all the templated class expressions
- `C` **class expression**: If the template string starts with a `C` and a space then it will be interpreted as a class expression. The value of the current cell will be substituted into the template, replacing all occurrences of the percent `%` character. Then the result will be parsed into an OWL class expression. ROBOT uses the same syntax for class expressions as Protégé: [Manchester Syntax](http://www.w3.org/2007/OWL/wiki/ManchesterSyntax). This means that an entity can be referred to by its rdfs:label (enclosing in single quotes if it has a space in it). If it does not recognize a label, ROBOT will assume that you're trying to refer to a class by its IRI (or compact IRI). This can lead to unexpected behaviour, but it allows you to refer to classes (by IRI) without loading them into the input ontology. This is particularly useful when the input ontology would be too large, such as the NCBI Taxonomy.

#### Example of Class Template Strings

| TYPE | CLASS_TYPE | C % | C part_of some % |
| --- | --- | --- | --- |
| class | Class 1 | |
| class | disjoint | Class 1 | |
| class | equivalent | | Class 1 |

The first class will be a subclass of `Class 1`, as there is no included `CLASS_TYPE`.

### Property Template Strings

- `PROPERTY_TYPE`: ROBOT creates a property for each row of data that has a `TYPE` of either an object or data property. The property type can be (any type followed by a \* can ONLY be used for object properties):
beckyjackson marked this conversation as resolved.
Show resolved Hide resolved
- **logical types**: these types link the created property to other properties (annotation properties can *only* use `subproperty`)
- `subproperty`: the created property will be a subproperty of each templated property expression (default)
- `equivalent`: the created property will be equivalent to all of the templated property expressions
- `disjoint`: the created property will be disjoint from each templated property expression and the values cannot be the same
- `inverse`\*: the created object property will be the inverse of each templated property expression
- **property types**: these types define the type of the created property, and will not work with annotation properties
- `functional`: the created property will be functional, meaning each entity (subject) can have at most one value
- `inverse functional`\*: the created object property will be inverse functional, meaning each value can have at most one subject
- `irreflexive`\*: the created object property will be irreflexive, meaning the subject cannot also be the value
- `reflexive`\*: the created object property will be reflexive, meaning each subject is also a value
- `symmetric`\*: the created object property will be symmetric, meaning the subject and value can be reversed
- `asymmetric`\*: the created object property will be asymmetric, meaning the subject and value cannot be reversed
- `transitive`\*: the created object property will be transitive, meaning the property can be chained
- `P` **property expression**: If the template string starts with a `P` and a space then it will be interpreted as a property expression. The value of the current cell will be substituted into the template, replacing all occurrences of the `%` character. Then the result will be parsed into an OWL property expression. ROBOT uses the same syntax for property expressions as Protégé: [Manchester Syntax](http://www.w3.org/2007/OWL/wiki/ManchesterSyntax). If it does not recognize a name, ROBOT will assume that you're trying to refer to an entity by its IRI or CURIE. This can lead to unexpected behavior, but it allows you to refer to entities without loading them into the input ontology.
- **object properties**: the only supported object property expression is the inverse object property expression. The template string is `P inverse(%)`. A single object property for a value can be specified by `P %`.
- **data properties**: data property expressions are not yet supported by OWL. A data property for a value (e.g. for a parent property) can be specified by `P %`.
- **annotation properties**: annotation property expressions are not possible. An annotation property for a value (e.g. for a parent property) can be specified by `P %`.
- `DOMAIN`: The domain to a property is a class expression in [Manchester Syntax](http://www.w3.org/2007/OWL/wiki/ManchesterSyntax) (for object and data properties). For annotation properties, the domain must be a single class specified by label, CURIE, or IRI.
- `RANGE`: The range to a property is either a class expression in [Manchester Syntax](http://www.w3.org/2007/OWL/wiki/ManchesterSyntax) (for object properties) or the name, CURIE, or IRI of a datatype (for annotation and data properties).

#### Example of Property Template Strings

| TYPE | PROPERTY_TYPE | P % | DOMAIN | RANGE |
| --- | --- | --- | --- | --- |
| owl:ObjectProperty | subproperty | Property 1 | Class 1 | Class 2 |
| owl:DataProperty | functional | Property 2 | Class 2 | xsd:string |

The `functional` data property will still default to a `subproperty` logical axiom for the `P %` template string, unless a different logical property type (`equivalent`, `disjoint`) is provided. Property type can be split, e.g. `PROPERTY_TYPE SPLIT=|`.

### Individual Template Strings

- `INDIVIDUAL_TYPE`: ROBOT creates an individual for each or of data that has a `TYPE` of another class. The individual type can be:
beckyjackson marked this conversation as resolved.
Show resolved Hide resolved
- `named`: the created individual will be a default named individual. When the `INDIVIDUAL_TYPE` is left blank, this is the default. This should be used when adding object property or data property assertions
- `same`: the created individual will be asserted to be the same individual as each templated individual in the row
- `different`: the created individual will be asserted to be a different individual than any of the templated individuals in the row
- `I` **individual assertion**:
- `I property %`: when creating a `named` individual, replace property with an object property or data property to add assertions. The `%` will be replaced by the template cell value or values. For object property assertions, this is another individual. For data property assertions, this is a literal value.
- `I %`: when creating a `same` or `different` individual, this template string is used to specify which individual will be the value of the same or different individual axiom.

#### Example of Individual Template Strings

| TYPE | INDIVIDUAL_TYPE | I part_of some % | I % |
| --- | --- | --- | --- |
| Class 1 | named | Individual 2 | |
| Class 2 | different | | Individual 1 |

<!-- ### Datatype Template Strings -->

## Merging

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package org.obolibrary.robot;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Options;
import org.obolibrary.robot.template.Template;
import org.obolibrary.robot.template.TemplateHelper;
import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.model.OWLOntology;
import org.slf4j.Logger;
Expand Down Expand Up @@ -137,7 +135,16 @@ public CommandState execute(CommandState state, String[] args) throws Exception
tables.put(templatePath, TemplateHelper.readTable(templatePath));
}

OWLOntology outputOntology = TemplateOperation.template(tables, inputOntology, null, ioHelper);
beckyjackson marked this conversation as resolved.
Show resolved Hide resolved
// Process the templates
List<OWLOntology> ontologies = new ArrayList<>();
for (String table : tables.keySet()) {
Template template = new Template(table, tables.get(table), inputOntology, ioHelper);
OWLOntology ont = template.generateOutputOntology();
ontologies.add(ont);
}
OWLOntology outputOntology = MergeOperation.merge(ontologies);
// OWLOntology outputOntology = TemplateOperation.template(tables, inputOntology, null,
// ioHelper);

boolean collapseImports =
CommandLineHelper.getBooleanValue(line, "collapse-import-closure", false);
Expand All @@ -149,7 +156,6 @@ public CommandState execute(CommandState state, String[] args) throws Exception
// from the inputOntology, with just their labels.
// Do not MIREOT the terms defined in the template,
// just their dependencies!
List<OWLOntology> ontologies;
boolean hasAncestors = CommandLineHelper.getBooleanValue(line, "ancestors", false, true);
if (hasAncestors && inputOntology != null) {
Set<IRI> iris = OntologyHelper.getIRIs(outputOntology);
Expand Down Expand Up @@ -178,8 +184,8 @@ public CommandState execute(CommandState state, String[] args) throws Exception
MergeOperation.mergeInto(ontologies, inputOntology, includeAnnotations, collapseImports);
} else {
// Set ontology and version IRI
String ontologyIRI = CommandLineHelper.getOptionalValue(line, "ontology-iri");
String versionIRI = CommandLineHelper.getOptionalValue(line, "version-iri");
String ontologyIRI = CommandLineHelper.getOptionalValue(line, "ontology-iri");
if (ontologyIRI != null || versionIRI != null) {
OntologyHelper.setOntologyIRI(outputOntology, ontologyIRI, versionIRI);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.obolibrary.obo2owl.OWLAPIOwl2Obo;
import org.obolibrary.oboformat.model.OBODoc;
import org.obolibrary.oboformat.writer.OBOFormatWriter;
import org.obolibrary.robot.template.TemplateHelper;
jamesaoverton marked this conversation as resolved.
Show resolved Hide resolved
import org.semanticweb.owlapi.apibinding.OWLManager;
import org.semanticweb.owlapi.formats.FunctionalSyntaxDocumentFormat;
import org.semanticweb.owlapi.formats.ManchesterSyntaxDocumentFormat;
Expand Down
Loading