Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
4babe57
Implement initial SSSOM export
cthoyt Aug 26, 2026
cb070f1
Update sssom.py
cthoyt Aug 26, 2026
c15b3f9
Update sssom.py
cthoyt Aug 26, 2026
053c093
Update docs
cthoyt Aug 26, 2026
fd8fac4
Update sssom.py
cthoyt Aug 26, 2026
ca2e3f5
Merge pull request #126 from sciknoworg/main
HamedBabaei Aug 26, 2026
09ac435
Add tests
cthoyt Aug 26, 2026
24c2d67
Defend against bad confidence scores
cthoyt Aug 26, 2026
437dbb8
:sparkles: Add SSSOM export support
abhishekreddyallu Aug 27, 2026
c0ca409
:bug:
abhishekreddyallu Aug 27, 2026
fea28a5
:bug: PropMatch encoder bugs fixes
abhishekreddyallu Aug 27, 2026
bf57407
:bug:
abhishekreddyallu Aug 27, 2026
b4ecf19
:bug: ICV aligner fixes
abhishekreddyallu Aug 27, 2026
9ce43a4
:bug:
abhishekreddyallu Aug 27, 2026
72c690a
:bug: LLM aligner bugs fixes
abhishekreddyallu Aug 27, 2026
02d72ab
:bug: Flora aligner fixes
abhishekreddyallu Aug 27, 2026
1b169e1
:bug: Ensemble voting fixes
abhishekreddyallu Aug 27, 2026
55d5cb2
:bug:
abhishekreddyallu Aug 27, 2026
d991247
:pencil2: minor changes
abhishekreddyallu Aug 27, 2026
7041797
Implement initial SSSOM export (PR #124 from cthoyt-forks/sssom-export)
HamedBabaei Aug 31, 2026
3c52c45
:recycle: refactor sssom_pydantic alingment exporter
HamedBabaei Aug 31, 2026
4fa6dae
:recycle: refactor sssom alingment generator
HamedBabaei Aug 31, 2026
ce4790b
:recycle: refactor sssom alingment generator
HamedBabaei Aug 31, 2026
f369433
Merge branch 'dev' into feature-dev
HamedBabaei Aug 31, 2026
b701b1a
Merge pull request #128 from sciknoworg/feature-dev
HamedBabaei Aug 31, 2026
42068c8
Bug fixes (PR #129 from sciknoworg/fixes)
HamedBabaei Sep 1, 2026
591f586
:test_tube: sssom unittests
HamedBabaei Sep 1, 2026
6033e4c
Merge remote-tracking branch 'origin/dev' into dev
HamedBabaei Sep 1, 2026
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
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ Build the same RAG-based alignment yourself for full control over every stage:

```python
from ontoaligner.ontology import GenericOMDataset
from ontoaligner.utils import metrics, xmlify
from ontoaligner.utils import metrics, xmlify, sssom_pydantic
from ontoaligner.aligner import MistralLLMBERTRetrieverRAG
from ontoaligner.encoder import ConceptParentRAGEncoder
from ontoaligner.postprocess import rag_hybrid_postprocessor
Expand Down Expand Up @@ -129,6 +129,9 @@ print("Hybrid Matching Evaluation Report:", evaluation)
# Step 7: Convert matchings to XML format and save the XML representation
xml_str = xmlify.xml_alignment_generator(matchings=hybrid_matchings)
open("matchings.xml", "w", encoding="utf-8").write(xml_str)

# Or you can explicitly convert to SSSOM and write to disk
sssom_pydantic.sssom_alignment_generator(hybrid_matchings, "matchings.sssom.tsv")
```

### Advanced `AlignerPipeline`
Expand Down
38 changes: 19 additions & 19 deletions docs/source/aligner/kge.rst
Original file line number Diff line number Diff line change
Expand Up @@ -187,55 +187,55 @@ The following table lists the available KGE aligners:

* - ``ConvEAligner``
- Based on ConvE, which uses 2D convolutions over reshaped entity and relation embeddings to model complex interactions.
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/kge/models.py#L17-L18>`_
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/graph/models.py#L17-L18>`_
* - ``TransDAligner``
- Based on TransD, which constructs relation-specific projection matrices dynamically from both entity and relation vectors.
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/kge/models.py#L21-L22>`_
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/graph/models.py#L21-L22>`_
* - ``TransEAligner``
- Based on TransE, a translation-based model that learns embeddings where :math:`h + r \approx t`.
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/kge/models.py#L25-L26>`_
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/graph/models.py#L25-L26>`_
* - ``TransFAligner``
- Based on TransF, which enables flexible translations for complex relations without increasing model complexity.
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/kge/models.py#L29-L230>`_
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/graph/models.py#L29-L230>`_
* - ``TransHAligner``
- Based on TransH, which projects entities onto relation-specific hyperplanes before translation.
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/kge/models.py#L33-L234>`_
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/graph/models.py#L33-L234>`_
* - ``TransRAligner``
- Based on TransR, which embeds entities and relations in separate spaces using relation-specific projections.
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/kge/models.py#L37-L38>`_
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/graph/models.py#L37-L38>`_
* - ``DistMultAligner``
- Based on DistMult, a bilinear model that uses diagonal matrices for efficient relational modeling.
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/kge/models.py#L41-L42>`_
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/graph/models.py#L41-L42>`_
* - ``ComplExAligner``
- Based on ComplEx, which uses complex-valued embeddings to model symmetric and antisymmetric relations; includes a custom similarity function using real parts of complex dot products.
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/kge/models.py#L45-L49>`_
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/graph/models.py#L45-L49>`_
* - ``HolEAligner``
- Based on HolE, which combines compositional and holographic representations using circular correlation.
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/kge/models.py#L51-L52>`_
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/graph/models.py#L51-L52>`_
* - ``RotatEAligner``
- Based on RotatE, which models relations as rotations in complex space and supports rich relational patterns; includes a similarity override.
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/kge/models.py#L55-L60>`_
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/graph/models.py#L55-L60>`_
* - ``SimplEAligner``
- Based on SimplE, which learns dependent embeddings for each entity and supports fully expressive factorization.
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/kge/models.py#L62-L63>`_
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/graph/models.py#L62-L63>`_
* - ``CrossEAligner``
- Based on CrossE, which learns both general and triple-specific embeddings to capture bidirectional interactions.
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/kge/models.py#L66-L67>`_
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/graph/models.py#L66-L67>`_
* - ``BoxEAligner``
- Based on BoxE, which models relations as boxes in vector space to support hierarchies and logical rules.
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/kge/models.py#L70-L71>`_
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/graph/models.py#L70-L71>`_
* - ``CompGCNAligner``
- Based on CompGCN, a graph convolutional network designed for multi-relational graphs using composition operations.
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/kge/models.py#L74-L75>`_
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/graph/models.py#L74-L75>`_
* - ``MuREAligner``
- Based on MuRE, which embeds entities in hyperbolic space to better model hierarchies and relation-specific transformations.
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/kge/models.py#L78-L79>`_
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/graph/models.py#L78-L79>`_
* - ``QuatEAligner``
- Based on QuatE, which uses quaternion embeddings and custom similarity logic to model expressive 4D rotations and relational structure.
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/kge/models.py#L82-L133>`_
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/graph/models.py#L82-L133>`_
* - ``SEAligner``
- Based on SE, a neural model that embeds symbolic knowledge into vector space using learned neural transformations.
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/kge/models.py#L134-L135>`_
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/graph/models.py#L134-L135>`_

To use KGE aligner based technique:

Expand Down Expand Up @@ -279,8 +279,8 @@ KGE Retriever

.. sidebar:: Key Parameters:

- ``retruever``: boolean
- ``top_K``: integer
- ``retriever``: boolean
- ``top_k``: integer

In addition to one-to-one alignments, OntoAligner also supports retriever-based alignment. When retriever mode is enabled (``retriever=True``), the aligner returns the top-k candidate target entities for each source entity, along with their similarity scores (similar to retriever aligner). This model is useful if you want to build downstream candidate filtering pipelines, apply human-in-the-loop validation, or integrate with reranking modules (e.g., LLMs or supervised classifiers).

Expand Down
2 changes: 1 addition & 1 deletion docs/source/aligner/olala.rst
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ Usage

.. code-block:: python

task = OLaLaOMDataset(language="en")
task = OLaLaOMDataset()
print("Task:", task)

dataset = task.collect(
Expand Down
6 changes: 3 additions & 3 deletions docs/source/aligner/rag.rst
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ ICV-RAG Aligner
[1] Liu, S., Ye, H., Xing, L., & Zou, J. (2023). `In-context vectors: Making in context learning more effective and controllable through latent space steering <https://arxiv.org/abs/2311.06668>`_. arXiv preprint arXiv:2311.06668.


This RAG variant performs ontology matching using ``ConceptRAGEncoder`` only. The In-Contect Vectors introduced by [1](https://github.com/shengliu66/ICV) tackle in-context learning as in-context vectors (ICV). We used LLMs in this perspective in the RAG module. The workflow is the same as RAG or FewShot RAG with the following differences:
This RAG variant performs ontology matching using ``ConceptRAGEncoder`` only. The In-Context Vectors introduced by [1](https://github.com/shengliu66/ICV) tackle in-context learning as in-context vectors (ICV). We used LLMs in this perspective in the RAG module. The workflow is the same as RAG or FewShot RAG with the following differences:


1. Incorporate the ``ConceptRAGEncoder`` and also provide reference (or examples to build up the ICV vectors).
Expand Down Expand Up @@ -314,7 +314,7 @@ Embedded ICV-RAG aligners within OntoAligner:
- Link

* - ``FalconLLMAdaRetrieverICVRAG``
- Falcon LLM with Ada retriever for iterative consistency verification (ICV) alignment.
- Falcon LLM with Ada retriever for ICV-driven alignment.
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/icv/models.py#L47-L54>`__

* - ``FalconLLMBERTRetrieverICVRAG``
Expand Down Expand Up @@ -342,7 +342,7 @@ Embedded ICV-RAG aligners within OntoAligner:
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/icv/models.py#L67-L74>`__

* - ``VicunaLLMBERTRetrieverICVRAG``
- Vicuna model paired with BERT-based retrieval for iterative consistency verification.
- Vicuna model paired with BERT-based retrieval for ICV-driven alignment.
- `Source <https://github.com/sciknoworg/OntoAligner/blob/main/ontoaligner/aligner/icv/models.py#L77-L84>`__


Expand Down
130 changes: 130 additions & 0 deletions examples/retriever_sssom.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import json

# Import necessary modules from the 'ontoaligner' library
# The library provides tools for ontology alignment tasks, including dataset management, encoding, retrieval models, and postprocessing.
from ontoaligner import ontology, encoder
from ontoaligner.utils import metrics
from ontoaligner.utils.sssom import sssom_alignment_generator
from ontoaligner.aligner import SBERTRetrieval # Other available modules: AdaRetrieval, SVMBERTRetrieval, BM25Retrieval
from ontoaligner.postprocess import retriever_postprocessor


# Step 1: Initialize the ontology matching task
# The task is created using the Mouse-Human ontology matching dataset,
# which includes source and target anatomy ontologies and reference matchings for evaluation.
task = ontology.MouseHumanOMDataset()

# Confirm the task initialization by printing its details
print("Test Task:", task)


# Step 2: Collect the ontology dataset
# The dataset includes paths to the source ontology, target ontology, and reference matching files.
dataset = task.collect(
source_ontology_path="../assets/mouse-human/source.xml",
target_ontology_path="../assets/mouse-human/target.xml",
reference_matching_path="../assets/mouse-human/reference.xml",
)


# Step 3: Initialize the encoder model
# The encoder prepares concept representations from the source and target ontologies.
# Here, the 'ConceptParentLightweightEncoder' is used for lightweight encoding, which can be used here as well.
encoder_model = encoder.ConceptParentLightweightEncoder()

# Encode the source and target ontologies
# The encoder processes the concepts in both ontologies and returns embeddings for further alignment.
encoder_output = encoder_model(
source=dataset["source"],
target=dataset["target"],
)


# Step 4: Set up the retrieval model
# The retrieval model aligns the source and target ontologies using semantic similarity techniques.
# 'SBERTRetrieval' is selected with a pre-trained model ('all-MiniLM-L6-v2') for embedding retrieval.
model = SBERTRetrieval(
device="cpu",
top_k=1,
)

model.load(
path="all-MiniLM-L6-v2",
)

# Generate ontology matchings
# The retrieval model compares encoded embeddings from the source and target datasets to predict matchings.
matchings = model.generate(
input_data=encoder_output,
)


# Step 5: Post-process the matchings
# Apply the 'retriever_postprocessor' function to refine the predicted matchings.
# Postprocessing helps filter or adjust the matchings for improved alignment quality.
threshold = 0.2

matchings = retriever_postprocessor(
predicts=matchings,
threshold=threshold,
)


# Step 6: Evaluate the matchings
# The evaluation report compares the predicted matchings against the reference matchings
# provided in the dataset using metrics such as precision, recall, and F1-score.
evaluation = metrics.evaluation_report(
predicts=matchings,
references=dataset["reference"],
)

# Print the evaluation report in a human-readable JSON format
print(
"Evaluation Report:",
json.dumps(evaluation, indent=4),
)


# Step 7: Export matchings in SSSOM format
# Convert the generated matchings into an SSSOM TSV alignment file using
# the 'sssom_alignment_generator' utility.
sssom_str = sssom_alignment_generator(
matchings=matchings,
source=dataset["source"],
target=dataset["target"],
predicate_id="owl:equivalentClass",
mapping_set_metadata={
"mapping_set_id": "https://example.org/mappings/mouse-human-sbert",
"license": "https://creativecommons.org/licenses/by/4.0/",
"subject_type": "owl:Class",
"object_type": "owl:Class",
},
# Explicit CURIE maps must include all used prefixes; if omitted, Bioregistry is used as fallback.
curie_map={
"mouse": "http://mouse.owl#",
"human": "http://human.owl#",
"owl": "http://www.w3.org/2002/07/owl#",
"semapv": "https://w3id.org/semapv/vocab/",
},
aligner=model,
postprocessor=retriever_postprocessor,
postprocessor_params={
"threshold": threshold,
},
# If you don't want per-matching aligner/postprocessor metadata (e.g. similarity
# scores or mapping_justification inferred from the aligner), set
# include_aligner_metadata=False to produce a minimal SSSOM output.
include_aligner_metadata=False,
)


# Save the SSSOM alignment to a file for further use or analysis
output_file_path = "mouse-human-sbert.sssom.tsv"

with open(output_file_path,"w",encoding="utf-8",newline="",) as sssom_file:
sssom_file.write(sssom_str)

print(
f"Matchings in SSSOM format have been successfully written to "
f"'{output_file_path}'."
)
2 changes: 2 additions & 0 deletions ontoaligner/aligner/ensemble/voting/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ def _select(self, fused: List[Dict]) -> List[Dict]:
Returns:
List[Dict]: The filtered/selected predictions.
"""
if self.selection == "none":
return fused
if self.selection == "top1_source":
return self._select_top1_per_source(fused=fused)
if self.selection == "bijective":
Expand Down
4 changes: 2 additions & 2 deletions ontoaligner/aligner/ensemble/voting/reciprocal_rank_fusion.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ def __str__(self):
Returns a string representation of the voting method.

Returns:
dict: A dictionary with the class name as key and voting configuration as value.
str: A simple string representation of the class ("ReciprocalRankFusionVoting").
"""
return {"ReciprocalRankFusion": {"k": self.k}}
return "ReciprocalRankFusionVoting"

def fuse(self, aligner_outputs: List[Tuple[List[Dict], float]]) -> List[Dict]:
"""
Expand Down
9 changes: 2 additions & 7 deletions ontoaligner/aligner/ensemble/voting/weighted.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,9 @@ def __str__(self):
Returns a string representation of the voting method.

Returns:
dict: A dictionary with the class name as key and voting configuration as value.
str: A simple string representation of the class ("WeightedVoting").
"""
return {
"WeightedVoting": {
"min_votes": self.min_votes,
"score_threshold": self.score_threshold,
}
}
return "WeightedVoting"

def fuse(self, aligner_outputs: List[Tuple[List[Dict], float]]) -> List[Dict]:
"""
Expand Down
6 changes: 5 additions & 1 deletion ontoaligner/aligner/fewshot/fewshot.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,11 @@ def generate(self, input_data: List[Dict]) -> List:
"""
# IR generation
ir_output = self.ir_generate(input_data=input_data)
ir_output_cleaned = process.retriever_postprocessor(predicts=ir_output)
if 'threshold' in self.kwargs['retriever_config']:
threshold = self.kwargs['retriever_config']['threshold']
else:
threshold = 0.0
ir_output_cleaned = process.retriever_postprocessor(predicts=ir_output, threshold=threshold)
examples = self.build_fewshots(input_data=input_data)
input_data['examples'] = examples
# LLm generation
Expand Down
2 changes: 1 addition & 1 deletion ontoaligner/aligner/flora/flora.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ def __init__(
string_identity: bool = False,
relinit: float = 0.1,
ngrams: Optional[List[int]] = None,
model_id: Optional[str] = None,
model_id: Optional[str] = "Lihuchen/pearl_small",
emb_path: Optional[str] = None,
training_data: Optional[str] = None,
device: Optional[str] = None,
Expand Down
3 changes: 1 addition & 2 deletions ontoaligner/aligner/flora/literals.py
Original file line number Diff line number Diff line change
Expand Up @@ -406,8 +406,7 @@ def __init__(
if not identity:
if emb_path is not None:
try:
self.kg1_pretrained = self.load_embeddings(emb_path)
self.kg2_pretrained = self.load_embeddings(emb_path)
self.kg1_pretrained, self.kg2_pretrained = self.load_embeddings(emb_path)
except Exception as e:
raise RuntimeError(f"Error loading embeddings from {emb_path}: {e} \n "
f"Please ensure the embedding files exist and are in the correct format. ")
Expand Down
Loading
Loading