diff --git a/CHANGELOG.md b/CHANGELOG.md index 1566b99c9..33be4c4e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Add `--clean-obo` option to [`convert`] [#995] +- Allow interpolation of ontology IRI and version IRI within annotation values [#1241] ### Fixed - Update owl-diff dependency for stable ordering and to avoid large string creation [#1227] diff --git a/docs/annotate.md b/docs/annotate.md index 79f7dd41e..22f92b1f9 100644 --- a/docs/annotate.md +++ b/docs/annotate.md @@ -31,6 +31,19 @@ Including at least the following annotations is recommended: * Description (`dcterms:description`) * License (`dcterms:license`) +If the `--interpolate` option is used, then some placeholders, of the form `%{NAME}`, can be used within the annotation values and will be automatically replaced by computed values. Currently supported placeholers are: + + * `%{ontology_iri}`, replaced by the ontology's IRI; + * `%{version_iri}`, replaced by the ontology's version IRI. + +Example: + + robot annotate --input fbcv-module.owl \ + --interpolate true \ + --link-annotation dc:source %{version_iri} \ + --annotation rdfs:comment "Derived from %{ontology_iri}" \ + --output results/fbcv-annotated.owl + This command can also remove all ontology annotations from your file with `--remove-annotations`. You can combine this with options to add new annotations: robot annotate --input annotated.owl \ diff --git a/docs/examples/fbcv-annotated.owl b/docs/examples/fbcv-annotated.owl new file mode 100644 index 000000000..e490cdd81 --- /dev/null +++ b/docs/examples/fbcv-annotated.owl @@ -0,0 +1,176 @@ + + + + + + Derived from http://purl.obolibrary.org/obo/dpo/simple + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Phenotype that is a defect in thermotaxis (GO:0043052). 'thermotaxis' is defined as: '$sub_GO:0043052' + thermotaxis behaviour defective + phenotypic_class + FBcv:0000002 + thermotaxis behavior defective + + + + + Phenotype that is a defect in thermotaxis (GO:0043052). 'thermotaxis' is defined as: '$sub_GO:0043052' + FBC:DOS + + + + + + + + + phenotypic_class + FBcv:0000347 + phenotypic class + + + + + + + + + Phenotype that is a defect in response to temperature stimulus (GO:0009266). 'response to temperature stimulus' is defined as: '$sub_GO:0009266' + djs93 + 2010-02-23T12:51:02Z + phenotypic_class + FBcv:0000683 + fbcvsubset_mgiribbons + temperature response defective + + + + + + + + + A defect in or loss of some anatomical structure or biological process compared to wild-type. + phenotypic class + phenotypic_class + FBcv:0001347 + do_not_annotate + The subclasses of this term classify Drosophila phenotypes into different common categories. They have been chosen by FlyBase to reflect phenotype terms most often reported by Drosophila researchers in the published literature. + phenotype + + + + + A defect in or loss of some anatomical structure or biological process compared to wild-type. + FBC:DOS + + + + + + + diff --git a/robot-command/src/main/java/org/obolibrary/robot/AnnotateCommand.java b/robot-command/src/main/java/org/obolibrary/robot/AnnotateCommand.java index e35fc36b0..981846145 100644 --- a/robot-command/src/main/java/org/obolibrary/robot/AnnotateCommand.java +++ b/robot-command/src/main/java/org/obolibrary/robot/AnnotateCommand.java @@ -75,6 +75,8 @@ public AnnotateCommand() { "annotate-defined-by", true, "if true, annotate all entities in the ontology with the ontology IRI"); + o.addOption( + "e", "interpolate", true, "if true, interpolate placeholders within annotation values"); options = o; @@ -187,6 +189,7 @@ public CommandState execute(CommandState state, String[] args) throws Exception String property; String value; + boolean interpolate = CommandLineHelper.getBooleanValue(line, "interpolate", false); // Add annotations with PROP VALUE List annotationItems = CommandLineHelper.getOptionValues(line, "annotation"); @@ -199,6 +202,9 @@ public CommandState execute(CommandState state, String[] args) throws Exception } catch (IndexOutOfBoundsException e) { throw new IllegalArgumentException(annotationFormatError, e); } + if (interpolate) { + value = expandValue(value, ontology); + } IRI iri = CommandLineHelper.maybeCreateIRI(ioHelper, property, "property"); OntologyHelper.addOntologyAnnotation(ontology, iri, IOHelper.createLiteral(value)); } @@ -214,6 +220,9 @@ public CommandState execute(CommandState state, String[] args) throws Exception } catch (IndexOutOfBoundsException e) { throw new IllegalArgumentException(linkAnnotationFormatError, e); } + if (interpolate) { + value = expandValue(value, ontology); + } IRI propIRI = CommandLineHelper.maybeCreateIRI(ioHelper, property, "property"); IRI valueIRI = CommandLineHelper.maybeCreateIRI(ioHelper, value, "value"); OntologyHelper.addOntologyAnnotation(ontology, propIRI, valueIRI); @@ -232,6 +241,9 @@ public CommandState execute(CommandState state, String[] args) throws Exception } catch (IndexOutOfBoundsException e) { throw new IllegalArgumentException(langAnnotationFormatError, e); } + if (interpolate) { + value = expandValue(value, ontology); + } IRI iri = CommandLineHelper.maybeCreateIRI(ioHelper, property, "property"); OntologyHelper.addOntologyAnnotation( ontology, iri, IOHelper.createTaggedLiteral(value, lang)); @@ -250,6 +262,9 @@ public CommandState execute(CommandState state, String[] args) throws Exception } catch (IndexOutOfBoundsException e) { throw new IllegalArgumentException(typedAnnotationFormatError, e); } + if (interpolate) { + value = expandValue(value, ontology); + } IRI iri = CommandLineHelper.maybeCreateIRI(ioHelper, property, "property"); OntologyHelper.addOntologyAnnotation(ontology, iri, ioHelper.createTypedLiteral(value, type)); } @@ -265,6 +280,9 @@ public CommandState execute(CommandState state, String[] args) throws Exception } catch (IndexOutOfBoundsException e) { throw new IllegalArgumentException(axiomAnnotationFormatError, e); } + if (interpolate) { + value = expandValue(value, ontology); + } IRI iri = CommandLineHelper.maybeCreateIRI(ioHelper, property, "property"); OntologyHelper.addAxiomAnnotations(ontology, iri, IOHelper.createLiteral(value)); } @@ -334,4 +352,31 @@ public CommandState execute(CommandState state, String[] args) throws Exception return state; } + + /** + * Expands placeholders within the given string with values derived from the ontology. + * + *

Placeholders are keywords enclosed within %{...}. Currently supported + * placeholders are: + * + *

+ * + * @param value the string in which to replace placeholders + * @param ontology the ontology from which placeholder values should be derived + * @return the updated string + */ + private String expandValue(String value, OWLOntology ontology) { + IRI ontologyIRI = ontology.getOntologyID().getOntologyIRI().orNull(); + IRI versionIRI = ontology.getOntologyID().getVersionIRI().orNull(); + if (ontologyIRI != null) { + value = value.replace("%{ontology_iri}", ontologyIRI.toString()); + } + if (versionIRI != null) { + value = value.replace("%{version_iri}", versionIRI.toString()); + } + return value; + } }