Skip to main content

OntoMeter

Ontology quality assessment. Point it at an OWL/RDF/Turtle file and it computes the sixteen OQuaRE metrics, scales each to 1–5, rolls them up into quality characteristics, and — where a language model is configured — adds a review of the things structural metrics cannot see.

pip install ontometer
ontometer eval my-ontology.ttl

1. What you get

$ ontometer eval my-ontology.ttl --no-review

# Ontology evaluation — `my-ontology.ttl`

**Overall 3.41/5** across 7 characteristics, aggregated by `mean`.

## Characteristics

| Characteristic      | Score |         |
|---------------------|-------|---------|
| Functional adequacy | 2.73  | `███··` |
| Structural          | 4.12  | `████·` |
| Maintainability     | 5.00  | `█████` |

## Metrics

| Metric    | Name               | Value | Score | Formula                                       |
|-----------|--------------------|-------|-------|-----------------------------------------------|
| `AROnto`  | Attribute richness | 0.167 | 1/5   | datatype-property domain axioms / \|classes\| |
| `CROnto`  | Class population   | 0.167 | 1/5   | \|individuals\| / \|classes\|                 |
| `DITOnto` | Depth of hierarchy | 2.000 | 5/5   | max longest-path depth from a local root      |

## Weakest metrics, and what drives them

**AROnto** (Attribute richness) — 1/5
  - `http://example.org/#hasOwner`
  - `http://example.org/#worksFor`

Every metric reports the formula it actually computed. That is not decoration: the published OQuaRE sources disagree with each other on several metrics, and one of them gives the same definition twice for two different metrics. Rather than pick a reading and leave you to discover the difference from a diverging number, each one states its own.

2. The review

Structural metrics cannot tell you whether an ontology models its domain correctly, whether its terms mean what their names suggest, or whether it is internally consistent. OQuaRE knows this — a large minority of its sub-characteristics have no supporting metric at all:

ontometer model --what unsupported

That gap is what the review is for. It receives the weakest metrics and the specific entities driving them, and returns findings ranked by what they actually break:

  • defect — changes what a reasoner concludes. A property declared rdfs:subPropertyOf a datatype; two rdfs:domain triples on one property, which OWL reads as conjunction so every subject is inferred into both classes at once; a cycle in the subsumption hierarchy.
  • weakness — sound but will cause trouble. Undeclared domains, absent inverse properties on a graph built for navigation.
  • suggestion — style and documentation.

The model never produces a number. Metrics are computed; the review explains and recommends.

export LLM_PROVIDER=ollama
export LLM_MODEL_NAME=llama3.1
ontometer eval my-ontology.ttl

Configuration is read from the process environment:

Variable Meaning Default
LLM_PROVIDER openai or ollama openai
LLM_MODEL_NAME Model identifier gpt-4o-mini
LLM_BASE_URL Endpoint override; any OpenAI-compatible server works provider default
LLM_API_KEY Required for openai, unused for ollama
LLM_TEMPERATURE Sampling temperature 0.0
LLM_PARSE_RETRIES Retries when the reply does not validate 2

Metrics compute with or without a provider. With none configured the report still renders and says why the review is missing, because a quality checker that fails closed on an absent API key is useless in the CI pipelines most of these will run in.

3. Using it in CI

ontometer eval ontology.ttl --no-review --format json -o report.json
ontometer eval ontology.ttl --no-review --fail-under 3.5

--fail-under exits non-zero when the overall score drops below a threshold. Treat the overall number as a tripwire for regressions, not as a verdict — OQuaRE defines no overall score, and this one is an unweighted mean of characteristic scores.

4. The quality model is configuration

Thresholds and the characteristic → sub-characteristic → metric map ship as YAML read at runtime, not compiled in. OQuaRE's own thresholds live in online resources rather than the archival record and were never fixed in a citable form, so they are editable rather than authoritative.

ontometer model --what metrics          # every metric and its formula
ontometer model --what scales           # threshold families and cut points
ontometer model --what characteristics  # the full rollup map
ontometer model --what unsupported      # what no metric covers

Aggregation from metrics to a sub-characteristic score is the one thing OQuaRE never specifies. This build uses the unweighted mean — the weakest available assumption, declared in quality_model.yaml rather than hidden in code.

5. As a library

from ontometer import evaluate

result = evaluate("my-ontology.ttl", with_review=False)

result.assessment.metrics["DITOnto"].score       # 5
result.assessment.characteristics["structural"]  # 4.12
result.assessment.worst_metrics(3)               # the three weakest
result.assessment.seeds["ANOnto"]                # undocumented classes
result.view.external_namespaces                  # vocabulary borrowed, not declared

6. The corpus half

OntoMeter is also a research project on ontologies as a population — how they depend on each other, how attention to them is distributed across domains, how they change. That half lives in ontometer.corpus and needs a heavier dependency set, so it sits behind an extra:

pip install "ontometer[corpus]"

It fetches from ten registries (six OntoPortal Alliance instances, OBO Foundry, Ontohub, OKG, LOV), parses each file for its structural and metadata footprint, deduplicates across sources and versions, and assembles a dependency network distinguishing declared reuse (owl:imports) from actual reuse — terms used from a namespace that was never imported. The gap between those two is a measurement in its own right.

  • ontometer/corpus/README.md — reproducing the pipeline from a clean checkout
  • ontometer/corpus/pipeline/README.md — fetch → parse → dedup, phase by phase
  • ontometer/corpus/network/README.md — the node and edge model, precisely
export ONTOLOGY_DIR="$HOME/ontometer-data"    # raw files and structural sidecars
uv run python run/fetch_ontologies.py --sources lov --ontoportal BioPortal
uv run python run/process.py --phases seed,parse,dedup
uv run python -m ontometer.corpus.network.construction

Corpus artifacts live in data/ (override with ONTOMETER_DATA_DIR) and are tracked in git, because they cannot be re-fetched into existence: registries move underneath you, and a crawl run today produces a different corpus rather than this one. They are kept compact deliberately — the registry metadata is projected to a field allowlist before storage, which is what keeps the database around 34 MiB rather than the 98 MiB it reached when the verbatim API responses were retained. What is not tracked is the raw object store of ontology files itself. See ontometer/corpus/README.md for what reproducing the corpus does and does not mean.

7. Prior art

OntoMeter is not the first tool to compute OQuaRE. OntoInsight pairs the metrics with LLM recommendations over a Java OWL API engine; oquare-metrics wraps the same engine as a CI action; NEOntometrics computes OQuaRE and OntoQA at scale with version tracking.

What is different here: pure Python, so there is no JVM to install; external-namespace coupling, which OQuaRE does not model at all; and the population dimension — every tool in that list is strictly single-ontology, so none of them can tell you whether a score is unusual.

8. Development

uv sync --extra dev                 # add --extra corpus for the research half
uv run pytest test
uv run ruff check && uv run ruff format
uv run pre-commit install

License

Apache-2.0. See LICENSE and NOTICE.

Release files for ontometer 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ontometer 0.1.0
File Size Uploaded
ontometer-0.1.0.tar.gz 135.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ontometer 0.1.0
File Interpreter ABI Platform
ontometer-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 278.8 kB

Release files / ontometer-0.1.0.tar.gz

Download URL ontometer-0.1.0.tar.gz
Size 135.0 kB
Tags Source
SHA-256 checksum
How to use checksums
c9b718c6f488ca13c04678f026851ee7662cf8ae18328a677084210936683c49
BLAKE2b-256 checksum
How to use checksums
4f4324511f45748069cfd4ab80b9e944c447486ed451e086b34ff3e4e872af7e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / ontometer-0.1.0-py3-none-any.whl

Download URL ontometer-0.1.0-py3-none-any.whl
Size 143.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d268cbfa46f599c8059ddbcdd4b3957265d1c6ac3594aca2924cfefcaf9cb3b7
BLAKE2b-256 checksum
How to use checksums
1f30b8312ec9e2a0618375473a46b181bd7186892a0b4c2963cfb609af060304
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

0.1.1

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page