Skip to content

Commit

Permalink
Merge pull request #15 from INCATools/custom-schema
Browse files Browse the repository at this point in the history
custom schema
  • Loading branch information
cmungall authored Apr 12, 2022
2 parents df31f74 + 3de8496 commit b34a7e0
Show file tree
Hide file tree
Showing 22 changed files with 1,271 additions and 27 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ test:

## Compiled

MODELS = ontology_metadata obograph validation_datamodel summary_statistics_datamodel lexical_index mapping_rules_datamodel text_annotator search_results
MODELS = ontology_metadata obograph validation_datamodel summary_statistics_datamodel lexical_index mapping_rules_datamodel text_annotator search_results oxo

pyclasses: $(patsubst %, src/oaklib/datamodels/%.py, $(MODELS))
jsonschema: $(patsubst %, src/oaklib/datamodels/%.schema.json, $(MODELS))
Expand Down
2 changes: 2 additions & 0 deletions docs/cli.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.. cli:
Command Line
============

Expand Down
19 changes: 19 additions & 0 deletions docs/intro/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
.. _tutorial:

Tutorial
===============

.. note::

The tutorial is still highly incomplete. Additions welcome!

.. toctree::
:maxdepth: 3
:caption: Contents:

tutorial01
tutorial02
tutorial03
tutorial04
tutorial05

97 changes: 94 additions & 3 deletions docs/intro/tutorial01.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
Part 1
=======

First we will install the package and then we will try some command line examples querying the fruitfly anatomy ontology.

Installation
-------------

Expand Down Expand Up @@ -29,9 +34,95 @@ Then install:
runoak --help
Download files
---------------
You should see a list of all commands.

You can get help on a specific command:

.. code-block::
runoak search --help
See also the :ref:`cli` section of this documentation

Query the OBO Library
---------------------

Next try using the "search" command to search for a term in the Drosophila anatomy ontology (`fbbt <http://obofoundry.org/ontology/fbbt>`_).

The base command takes an "--input" (or just "-i") option that specifies the input implementation. We will return to the full syntax later,
but one pattern that is useful to know is "obolibrary:<ontology-file>".

.. code-block::
runoak -i obolibrary:fbbt.obo search 'wing vein'
The first time you run this there will be a lag as the file is downloaded, but after that it will be cached. This is using the Pronto
library under the hood.

After the lag you will get results like:

.. code-block::
FBbt:00004751 ! wing vein
FBbt:00004754 ! axillary vein
FBbt:00004759 ! wing vein L1
FBbt:00004760 ! wing vein L2
.. code-block::
wget http://purl.obolibrary.org/obo/fbbt.obo
runoak -i fbbt.obo search 'wing vein'
Fetching ancestors
------------------

Next we will try a different command, plugging in an ID we got from the previous search.

We will use the "ancestors" command to find all rdfs:subClassOf and part-of (BFO:0000050) ancestors of 'wing vein'.

.. code-block::
runoak -i obolibrary:fbbt.obo ancestors FBbt:00004751 -p i,p
*Here we are using built-in shorthands, but you can get the same effect with the full :ref:`CURIE`s, rdfs:subClassOf and BFO:0000050)
You should see body parts such as cuticle, wing, etc, alongside their ID

Later on we will see how we can make images like:

.. image:: wing-vein.png

Using other backends
--------------------

.. code-block::
wget
runoak -i ubergraph: search 'wing vein'
This searches the ubergraph backend using the blazegraph search interface. Note that in addition to searching over a wider range
of ontologies, this returns a ranked list that might include matches only to "wing" or "vein". Currently each backend implements
search a little differently, but this will be more unified and controllable in the future.

Using BioPortal
--------------------

First you will need to go to `BioPortal <https://bioportal.bioontology.org/>`_ and get an API key, if you don't already have one.

You will then need to set it:

.. code-block::
runoak set-apikey bioportal YOUR-API-KEY
This stores it in an OS-dependent folder

.. code-block::
runoak -i bioportal: search 'wing vein'
Again the results are relevance ranked, and there are a lot of them, as this includes multiple ontologies, you may want to ctrl-C to kill before the end

Next steps
----------

You can play around with some of the other commands, or go right into the next section on programmatic usage!
37 changes: 37 additions & 0 deletions docs/intro/tutorial02.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
Part 2: Basic Python
=====================

Some basic Python knowledge is assumed

Install Poetry
--------------

For this section we are going to use `Poetry <https://python-poetry.org/>`_ to set up a project. If you are an experienced
developer feel free to adapt these instructions to your favored package manager, otherwise we advise sticking closely to
the instructions.

Create a new project
--------------

.. code-block::
poetry new --src -n my-oak-demo
cd my-oak-demo
poetry add oaklib
Code the first example
----------

We are going to use an example from the :ref:`BasicOntologyInterface`, using a :ref:`ProntoImplementation`

Edit a file using your favorite IDE

``src/my_oak_demo/demo.py``

.. code-block:: python
TODO
.. note::

this is still to be filled in. For now consult test_pronto.py in tests/test_implementations
6 changes: 6 additions & 0 deletions docs/intro/tutorial03.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Part 3: Ubergraph
=======

Previously we have been working with local ontology files in obo format

TODO: fill this part of the tutorial in; for now see test_ubergraph is tests/test_implementations
40 changes: 40 additions & 0 deletions docs/intro/tutorial04.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
Part 4: OboGraphs
=======

So far we have been using the :ref:`BasicOntologyInterface` which provides basic lookup operations. All methods in this interface
return 'simple' python objects, such as strings, lists of strings, or dictionaries or :ref:`iterators` composing these elements.

Sometimes more powerful abstractions are required. For example, many bioinformatics applications work with a graph-abstraction
of an ontology which allows for graph-theoretic operations and visualizations. In contrast, many ontology management and QC
applications require an OWL "axiom-oriented" view of an ontology.

OAK does not favor any one view or abstraction or datamodel. The general philosophy is:

- be pluralistic - provide different interfaces with different abstractions, and allow the application developer or user to choose
- ensure each interface follows a well-documented datamodel, adhering to standards if they exist

To illustrate this we will first introduce the :ref:`OboGraphInterface` which uses the :ref:`OboGraph` datamodel

OboGraphs
---------

In this datamodel, an ontology is conceived of as a Graph, with a graph consisting of

- nodes
- edges

Nodes are typically ontology :ref:`Class`es but are not restricted to this.

Edges are typed relationships between nodes - for example, finger part-of hand.

OboGraph Interface
-----------

Like most datamodels in OAK, the OboGraph datamodel follows a Data Access Object (DAO) pattern - the objects are intentionally limited
in their behavior. For example, you cannot ask a node what edges come out or go in; these is stored at the top level graph object.

"Smarter" operations are provided by the interface



TODO: see tests for examples for now
36 changes: 36 additions & 0 deletions docs/intro/tutorial05.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
Part 5: Graph Visualization
=====================

Install OBOGraphViz
--------------

.. code-block::
npm install obographviz
Command Line Usage
-----------------

.. code-block::
runoak -i obolibrary:fbbt.obo viz FBbt:00004751 -p i,p -o wing-vein.png
Then open wing-vein.png

If you omit the --output option then the png will be written to a temp file and immediately opened:

.. code-block::
runoak -i obolibrary:fbbt.obo viz FBbt:00004751 -p i,p
How this works
---------------

- First,

Programmatic usage
---------------

TODO: use test_obograph_utils for example


13 changes: 13 additions & 0 deletions docs/intro/tutorial06.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Part 6: Working With OWO
=====================

OAK comes bundled with the `funowl <https://github.com/hsolbrig/funowl/>`_ library

TODO: funowl is not yet bundled, we are waiting for one rdflib PR (https://github.com/RDFLib/rdflib/pull/1686) to be merged...

OWL Datamodel
--------------


OwlInterface
------------
2 changes: 2 additions & 0 deletions docs/intro/tutorial07.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Part 7: SQLite files
=============
29 changes: 22 additions & 7 deletions src/oaklib/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from typing import Dict, List, Sequence, TextIO, Tuple, Any, Type

import click
from linkml_runtime.dumpers import yaml_dumper
from linkml_runtime.dumpers import yaml_dumper, json_dumper
from oaklib.datamodels.validation_datamodel import ValidationConfiguration
from oaklib.implementations.bioportal.bioportal_implementation import BioportalImplementation
from oaklib.implementations.ontobee.ontobee_implementation import OntobeeImplementation
Expand Down Expand Up @@ -64,7 +64,7 @@ class Settings:
output_type_option = click.option(
"-O",
"--output-type",
help=f'Desired output type, e.g. {",".join([])}',
help=f'Desired output type',
)
predicates_option = click.option(
"-p",
Expand Down Expand Up @@ -237,8 +237,12 @@ def annotate(words, output: str):
help='overrides for stylemap, specified as yaml. E.g. `-C "styles: [filled, rounded]" `')
@click.argument("terms", nargs=-1)
@predicates_option
@output_option
def viz(terms, predicates, down, view, stylemap, configure, output: str):
@output_type_option
# TODO: the main output option uses a filelike object
@click.option('-o', '--output',
help="Path to output file")
#@output_option
def viz(terms, predicates, down, view, stylemap, configure, output_type: str, output: str):
"""
Visualizing an ancestor graph using obographviz
Expand Down Expand Up @@ -273,9 +277,20 @@ def viz(terms, predicates, down, view, stylemap, configure, output: str):
else:
graph = impl.ancestor_graph(curies, predicates=actual_predicates)
logging.info(f'Drawing graph seeded from {curies}')
imgfile = graph_to_image(graph, seeds=curies, stylemap=stylemap, configure=configure, imgfile=output)
if view:
subprocess.run(['open', imgfile])
if output_type == 'json':
if output:
json_dumper.dump(graph, to_file=output)
else:
print(json_dumper.dumps(graph))
elif output_type == 'yaml':
if output:
yaml_dumper.dump(graph, to_file=output)
else:
print(yaml_dumper.dumps(graph))
else:
imgfile = graph_to_image(graph, seeds=curies, stylemap=stylemap, configure=configure, imgfile=output)
if view:
subprocess.run(['open', imgfile])
else:
raise NotImplementedError(f'Cannot execute this using {impl} of type {type(impl)}')

Expand Down
Loading

0 comments on commit b34a7e0

Please sign in to comment.