Skip to content

Commit

Permalink
Merge branch 'master' into robot-header
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesaoverton authored Nov 29, 2023
2 parents a5f7581 + 4630074 commit e29282c
Show file tree
Hide file tree
Showing 10 changed files with 219 additions and 108 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
-- Added option to input template strings from external file [##1152]

### Fixed
- '--annotate-with-source true' does not work with extract --method subset [#1160]
- Fix how Template adds entities to the QuotedEntityChecker [#1104]

## [1.9.5] - 2023-09-20

### Added
Expand Down Expand Up @@ -379,9 +383,11 @@ First official release of ROBOT!
[`template`]: http://robot.obolibrary.org/template
[`validate`]: http://robot.obolibrary.org/validate

[#1160]: https://github.com/ontodev/robot/pull/1160
[#1148]: https://github.com/ontodev/robot/pull/1148
[#1135]: https://github.com/ontodev/robot/pull/1135
[#1119]: https://github.com/ontodev/robot/pull/1119
[#1104]: https://github.com/ontodev/robot/pull/1104
[#1100]: https://github.com/ontodev/robot/pull/1100
[#1091]: https://github.com/ontodev/robot/issues/1091
[#1089]: https://github.com/ontodev/robot/issues/1089
Expand Down
14 changes: 8 additions & 6 deletions docs/extract.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,14 @@ For more details see the [MIREOT paper](http://dx.doi.org/10.3233/AO-2011-0087).

The subset method extracts a sub-ontology that contains only the seed terms (that you specify with `--term` and `--term-file` options) and the relations between them. This method uses the [relation-graph](https://github.com/balhoff/relation-graph) to materialize the existential relations among the seed terms. Procedurally, the subset method materializes the input ontology and adds the inferred axioms to the input ontology. Then filters the ontology with the given seed terms. Finally, it reduces the filtered ontology to remove redundant subClassOf axioms.

robot extract --method subset \
--input subset.obo \
--term "obo:ONT_1" \
--term "obo:ONT_5" \
--term "BFO:0000050" \
--output results/subset_result.owl
```
robot extract --method subset \
--input subset.obo \
--term "obo:ONT_1" \
--term "obo:ONT_5" \
--term "BFO:0000050" \
--output results/subset_result.owl
```
ROBOT expects any `--term` or IRI in the `--term-file` to exist in the input ontology. If none of the input terms exist, the command will fail with an [empty terms error](errors#empty-terms-error). This can be overridden by including `--force true`.

Expand Down
8 changes: 4 additions & 4 deletions docs/rename.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ The mappings for renaming should be specified with the `--mappings` (for full re
For a full rename (you can use prefixes as long as they are defined by the defaults, `--prefix`, or `--add-prefix`):

```tsv
Old IRI New IRI
obo:BFO_0000051 fb:BFO_1234567
Old IRI New IRI
obo:BFO_0000051 fb:BFO_1234567
```

If you also want to update the `rdfs:label` of the term you replaced, you can add a third column with the new label value (note that this removes *all* old label annotations):
Expand All @@ -68,8 +68,8 @@ obo:BFO_0000051 fb:BFO_1234567 foo bar
For a prefix rename:

```tsv
Old Base New Base
http://purl.obolibrary.org/obo/ http://foo.bar/
Old Base New Base
http://purl.obolibrary.org/obo/ http://foo.bar/
```

The `rename` command expects the first line to contain headers.
Expand Down
45 changes: 31 additions & 14 deletions robot-core/src/main/java/org/obolibrary/robot/ExtractOperation.java
Original file line number Diff line number Diff line change
Expand Up @@ -189,20 +189,7 @@ public static OWLOntology extract(
}
// Maybe annotate entities with rdfs:isDefinedBy
if (OptionsHelper.optionIsTrue(options, "annotate-with-source")) {
Set<OWLAnnotationAxiom> sourceAxioms = new HashSet<>();
for (OWLEntity entity : OntologyHelper.getEntities(outputOntology)) {
// Check if rdfs:isDefinedBy already exists
Set<OWLAnnotationValue> existingValues =
OntologyHelper.getAnnotationValues(outputOntology, isDefinedBy, entity.getIRI());
if (existingValues == null || existingValues.size() == 0) {
// If not, add it
OWLAnnotationAxiom def = getIsDefinedBy(entity, sourceMap);
if (def != null) {
sourceAxioms.add(def);
}
}
}
manager.addAxioms(outputOntology, sourceAxioms);
annotateWithSource(sourceMap, outputOntology, manager);
}

// Determine what to do based on intermediates
Expand All @@ -219,6 +206,31 @@ public static OWLOntology extract(
}
}

/**
* Annotates entities of the outputOntology with rdfs:isDefinedBy.
*
* @param sourceMap map of term IRI to source IRI, or null.
* @param outputOntology output ontology.
* @param manager OWL ontology manager.
*/
private static void annotateWithSource(
Map<IRI, IRI> sourceMap, OWLOntology outputOntology, OWLOntologyManager manager) {
Set<OWLAnnotationAxiom> sourceAxioms = new HashSet<>();
for (OWLEntity entity : OntologyHelper.getEntities(outputOntology)) {
// Check if rdfs:isDefinedBy already exists
Set<OWLAnnotationValue> existingValues =
OntologyHelper.getAnnotationValues(outputOntology, isDefinedBy, entity.getIRI());
if (existingValues == null || existingValues.size() == 0) {
// If not, add it
OWLAnnotationAxiom def = getIsDefinedBy(entity, sourceMap);
if (def != null) {
sourceAxioms.add(def);
}
}
}
manager.addAxioms(outputOntology, sourceAxioms);
}

/**
* Extracts a materialized sub-ontology from the given ontology that only contains the given terms
* and the relations between them. The input ontology is not changed.
Expand Down Expand Up @@ -249,6 +261,11 @@ public static OWLOntology extractSubset(
copyPropertyAnnotations(inputOntology, filteredOnt);
ReduceOperation.reduce(filteredOnt, new org.semanticweb.elk.owlapi.ElkReasonerFactory());

// Maybe annotate entities with rdfs:isDefinedBy
if (OptionsHelper.optionIsTrue(options, "annotate-with-source")) {
annotateWithSource(sourceMap, filteredOnt, OWLManager.createOWLOntologyManager());
}

return filteredOnt;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,9 @@ public void add(OWLEntity entity, String name) {
if (entity == null) {
return;
}
if (name == null) {
return;
}

Map<String, IRI> map = pickMap(entity);
if (map == null) {
Expand Down
171 changes: 87 additions & 84 deletions robot-core/src/main/java/org/obolibrary/robot/Template.java
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ public Template(@Nonnull String name, @Nonnull List<List<String>> rows) throws E

// Add the contents of the tableRows
addTable(rows);
addLabels();
addEntities();
createParser();
}

Expand Down Expand Up @@ -203,7 +203,7 @@ public Template(@Nonnull String name, @Nonnull List<List<String>> rows, IOHelper

// Add the contents of the tableRows
addTable(rows);
addLabels();
addEntities();
createParser();
}

Expand Down Expand Up @@ -237,7 +237,7 @@ public Template(@Nonnull String name, @Nonnull List<List<String>> rows, OWLOntol

// Add the contents of the tableRows
addTable(rows);
addLabels();
addEntities();
createParser();
}

Expand Down Expand Up @@ -276,7 +276,7 @@ public Template(

// Add the contents of the tableRows
addTable(rows);
addLabels();
addEntities();
createParser();
}

Expand Down Expand Up @@ -320,7 +320,7 @@ public Template(

// Add the contents of the tableRows
addTable(rows);
addLabels();
addEntities();
createParser();
parser.setOWLEntityChecker(this.checker);
}
Expand Down Expand Up @@ -564,102 +564,103 @@ private void addTable(List<List<String>> rows) throws Exception {
}
}

/** Add the labels from the rows of the template to the QuotedEntityChecker. */
private void addLabels() {
// If there's no label column, we can't add labels
if (labelColumn == -1) {
/** Add the entities from the rows of the template to the QuotedEntityChecker. */
private void addEntities() {
for (List<String> row : tableRows) {
addEntity(row);
}
}

/** Add the entity from this row of the template to the QuotedEntityChecker. */
private void addEntity(List<String> row) {
String id = null;
try {
id = row.get(idColumn);
} catch (IndexOutOfBoundsException e) {
// ignore
}

if (id == null) {
return;
}
for (List<String> row : tableRows) {
String id = null;
if (idColumn != -1) {
try {
id = row.get(idColumn);
} catch (IndexOutOfBoundsException e) {
// ignore
}
}

String label = null;
String label = null;
try {
label = row.get(labelColumn);
} catch (IndexOutOfBoundsException e) {
// ignore
}

String type = null;
if (typeColumn != -1) {
try {
label = row.get(labelColumn);
type = row.get(typeColumn);
} catch (IndexOutOfBoundsException e) {
// ignore
}
}
if (type == null || type.trim().isEmpty()) {
type = "class";
}

if (idColumn != -1 && id == null) {
continue;
}

if (id == null || label == null) {
continue;
}

String type = null;
if (typeColumn != -1) {
try {
type = row.get(typeColumn);
} catch (IndexOutOfBoundsException e) {
// ignore
}
}
if (type == null || type.trim().isEmpty()) {
type = "class";
}
IRI iri = ioHelper.createIRI(id);
if (iri == null) {
iri = IRI.create(id);
}

IRI iri = ioHelper.createIRI(id);
if (iri == null) {
iri = IRI.create(id);
}
// Try to resolve a CURIE
IRI typeIRI = ioHelper.createIRI(type);

// Try to resolve a CURIE
IRI typeIRI = ioHelper.createIRI(type);
// Set to IRI string or to type string
String typeOrIRI = type;
if (typeIRI != null) {
typeOrIRI = typeIRI.toString();
}

// Set to IRI string or to type string
String typeOrIRI = type;
if (typeIRI != null) {
typeOrIRI = typeIRI.toString();
}
// Check against builtin types (ignore case), otherwise treat as individual
OWLEntity entity;
String lowerCaseType = typeOrIRI.toLowerCase();
switch (lowerCaseType) {
case "":
case "http://www.w3.org/2002/07/owl#class":
case "class":
entity = dataFactory.getOWLEntity(EntityType.CLASS, iri);
break;

// Check against builtin types (ignore case), otherwise treat as individual
OWLEntity entity;
String lowerCaseType = typeOrIRI.toLowerCase();
switch (lowerCaseType) {
case "":
case "http://www.w3.org/2002/07/owl#class":
case "class":
entity = dataFactory.getOWLEntity(EntityType.CLASS, iri);
break;
case "http://www.w3.org/2002/07/owl#objectproperty":
case "object property":
entity = dataFactory.getOWLEntity(EntityType.OBJECT_PROPERTY, iri);
break;

case "http://www.w3.org/2002/07/owl#objectproperty":
case "object property":
entity = dataFactory.getOWLEntity(EntityType.OBJECT_PROPERTY, iri);
break;
case "http://www.w3.org/2002/07/owl#dataproperty":
case "data property":
entity = dataFactory.getOWLEntity(EntityType.DATA_PROPERTY, iri);
break;

case "http://www.w3.org/2002/07/owl#dataproperty":
case "data property":
entity = dataFactory.getOWLEntity(EntityType.DATA_PROPERTY, iri);
break;
case "http://www.w3.org/2002/07/owl#annotationproperty":
case "annotation property":
entity = dataFactory.getOWLEntity(EntityType.ANNOTATION_PROPERTY, iri);
break;

case "http://www.w3.org/2002/07/owl#annotationproperty":
case "annotation property":
entity = dataFactory.getOWLEntity(EntityType.ANNOTATION_PROPERTY, iri);
break;
case "http://www.w3.org/2002/07/owl#datatype":
case "datatype":
entity = dataFactory.getOWLEntity(EntityType.DATATYPE, iri);
break;

case "http://www.w3.org/2002/07/owl#datatype":
case "datatype":
entity = dataFactory.getOWLEntity(EntityType.DATATYPE, iri);
break;
case "http://www.w3.org/2002/07/owl#individual":
case "individual":
case "http://www.w3.org/2002/07/owl#namedindividual":
case "named individual":
default:
// Assume type is an individual (checked later)
entity = dataFactory.getOWLEntity(EntityType.NAMED_INDIVIDUAL, iri);
break;
}

case "http://www.w3.org/2002/07/owl#individual":
case "individual":
case "http://www.w3.org/2002/07/owl#namedindividual":
case "named individual":
default:
// Assume type is an individual (checked later)
entity = dataFactory.getOWLEntity(EntityType.NAMED_INDIVIDUAL, iri);
break;
}
if (id != null) {
checker.add(entity, id);
}
if (label != null) {
checker.add(entity, label);
}
}
Expand Down Expand Up @@ -802,6 +803,8 @@ private void processRow(List<String> row) throws Exception {
case "http://www.w3.org/2002/07/owl#namedindividual":
case "named individual":
default:
// This is a bit unsafe imo, for example in the case of where the datatype turns out to be
// http://www.w3.org/2002/07/owl#DatatypeProperty""
addIndividualAxioms(iri, row);
break;
}
Expand Down
Loading

0 comments on commit e29282c

Please sign in to comment.