CyteOnto class#
CyteOnto compares cell type labels in Cell Ontology space. from_config() creates it
and makes sure that the descriptions and embeddings of the Cell Ontology terms are on
disk. compare() scores author labels against the labels of one or more algorithms and
returns a DataFrame, and compare_anndata() reads the algorithm labels from
adata.obs. cache_stats(), clear_run() and purge_stale() manage the caches of
comparison runs.
from cyteonto import CyteOnto
cyto = await CyteOnto.from_config(agent=agent, embedding=embedding, llm=llm)
df = await cyto.compare(
author_labels=["alveolar macrophage", "regulatory T cell"],
algorithms={"method_a": ["lung macrophage", "Treg"]},
run_id="lung_v1",
)
from_config(), compare() and compare_anndata() are coroutines: await them in a
notebook, or run them with asyncio.run() in a script. The
Python quickstart runs these steps,
Read the results describes the DataFrame, and
Caching and runs describes what each call saves on disk.
- class cyteonto.CyteOnto(agent, embedding, llm, data_dir=None, user_dir=None, max_description_concurrency=100, use_pubmed_tool=True, reasoning=False, fallback_agent=None, fallback_embedding=None, fallback_llm=None)#
Compare two sets of cell type annotations against the Cell Ontology.
Typical use:
cyto = await CyteOnto.from_config(agent=agent, embedding=embd_cfg, llm=llm_cfg) results = await cyto.compare( run_id="sample_run", author_labels=[...], algorithms={"algo1": [...], "algo2": [...]}, )
Set up paths and cache keys without loading the ontology or calling a model.
- Parameters:
agent (
Agent) – pydantic-ai agent whose model describes cell types and splits compound labels.embedding (
EmbdConfig) – Embedding provider and model. Whenembedding.apiKeyisNone, the key is read from the provider’s environment variable, such asNEBIUS_API_KEY, or else fromEMBEDDING_MODEL_API_KEY.llm (
LlmConfig) – Provider and model ofagent, which name the description caches.llm.modelmust equalagent.model.model_name.data_dir (
str|Path|None, default:None) – Directory with the Cell Ontology files and the ontology caches. Defaults to thedatadirectory inside the installed package.user_dir (
str|Path|None, default:None) – Directory for the caches of comparison runs. Defaults to<data_dir>/user_files.max_description_concurrency (
int, default:100) – Maximum number of LLM requests that run at the same time.use_pubmed_tool (
bool, default:True) – Let the agent search PubMed abstracts while it describes a label.reasoning (
bool, default:False) – Leave the model’s reasoning mode as the provider sets it. WhenFalse, the requests ask the provider to turn reasoning off.fallback_agent (
Agent|None, default:None) – Agent that describes the labels whose description is still blank after the primary agent’s retries.fallback_embedding (
EmbdConfig|None, default:None) – Embedding configuration to use when the primary embedding provider fails, unless it equalsembedding. The instance first loads the ontology embeddings of this model, or makes them from the ontology descriptions, and then keeps embedding with it. If that step fails, the call raises and the instance keeps the primary model.fallback_llm (
LlmConfig|None, default:None) – Provider and model offallback_agent. It is reported inmodel_pair_usage; descriptions from the fallback agent are cached underllm.
- Raises:
ValueError – If no embedding API key is found for a provider other than
ollama, or ifllm.modeldiffers from the agent’s model name.
- usage: cyteonto.AgentUsage#
The requests and tokens of the successful LLM calls of this instance, to describe and to split labels, including those of
from_config(). Failed attempts and embedding requests are not counted.
- model_pair_usage: cyteonto.ModelPairUsage#
Whether the primary or the fallback LLM and embedding models were used.
- async classmethod from_config(agent, embedding, llm, data_dir=None, user_dir=None, force_regenerate=False, max_description_concurrency=100, use_pubmed_tool=True, reasoning=False, fallback_agent=None, fallback_embedding=None, fallback_llm=None)#
Create a
CyteOntoand make sure the ontology embeddings are on disk.Takes the arguments of
CyteOntoandforce_regenerate. Loads the descriptions of the Cell Ontology terms forllmfromdata_dirand checks that the term embeddings forllmandembeddingexist. Terms without a description are described withagent, andfallback_agentif given, and then every term is embedded again. When every term has a description and the embeddings file was made after the descriptions last changed, no model is called. Ifembeddingfails to embed the terms, the instance checks thatfallback_embeddingworks and switches to it and its ontology embeddings, which are made if they are missing.- Parameters:
force_regenerate (
bool, default:False) – Delete the ontology descriptions ofllm, which all model pairs with this LLM share, and their embeddings withembeddingandfallback_embeddingfirst. The descriptions and the embeddings withembeddingare then made again for every term, and those withfallback_embeddingat the next failover.- Raises:
ValueError – For the same reasons as the constructor.
FileNotFoundError – If
cell_to_cell_ontology.csv,cell_to_cell_ontology_enriched.csvorcl.owlis missing from<data_dir>/cell_ontology.RuntimeError – If the ontology CSV cannot be read, or the term embeddings cannot be made or saved.
- Return type:
- async compare(author_labels, algorithms, *, run_id=None, metric='cosine_kernel', metric_params=None, min_match_similarity=0.1, use_cache=True, compound_scoring='max')#
Compare author labels with the labels of one or more algorithms.
Labels are lowercased, compound labels are split into cell types, and each label or part is described, embedded and matched to its closest Cell Ontology term. Each author label is then scored against the algorithm label at the same position.
- Parameters:
author_labels (
list[str]) – Reference labels, one per item, such as a cell or a cluster.algorithms (
dict[str,list[str]] |Sequence[tuple[str,list[str]]]) – Mapping{algo_name: labels}(or sequence of pairs). Each label list must be the same length asauthor_labels. Algorithm names must be unique, and"author"is reserved.run_id (
str|None, default:None) – Unique identifier for this comparison. Used to namespace user caches on disk and to tag each result row. Reuse the samerun_idacross calls to benefit from caching; pass it toclear_runto delete the descriptions and embeddings. IfNone, an id of the formrun-<uuid4>is generated and logged.metric (
str, default:'cosine_kernel') – Similarity metric for each pair of matched terms:cosine_kernel,cosine_direct,path,set:jaccard,set:cosine,set:weighted_jaccard,weighted:num_ancestors,weighted:specificity,weighted:embedding_cosineorsimple. Other names fall back tosimple.metric_params (
dict[str,Any] |None, default:None) – Parameters ofcosine_kernel: thecenter,widthandamplitudeof its Gaussian. Other metrics ignore them.min_match_similarity (
float, default:0.1) – Lowest cosine similarity between a label and its closest Cell Ontology term at which the label counts as matched.use_cache (
bool, default:True) – WhenTrue, reuse the label decompositions, descriptions and embeddings saved forrun_id. WhenFalse, generate them again.compound_scoring (
Literal['max','hungarian_mean'], default:'max') – How to reduce the m×n part score matrix for compound pairs."max"takes the maximum entry;"hungarian_mean"uses Hungarian assignment mean with a coverage penalty when m != n.
- Return type:
DataFrame- Returns:
DataFrame with one row per (algorithm, pair_index) combination. The
run_idcolumn is populated with the id used for this call (the caller-provided value or the auto-generated UUID).- Raises:
ValueError – If
compound_scoringis invalid,algorithmsis empty, an algorithm name is repeated or is"author", or a label list differs in length fromauthor_labels.RuntimeError – If labels cannot be embedded, or, at an embedding failover, the ontology embeddings of the fallback model cannot be made or saved; the instance then keeps the primary model.
FileNotFoundError – If the ontology embeddings of the model pair are missing, or, at an embedding failover, both those of the fallback model and the ontology descriptions to make them from. Run
from_configfirst.
- async compare_anndata(author_labels, anndata_objects, target_columns, author_column, *, run_id=None, algorithm_names=None, metric='cosine_kernel', metric_params=None, min_match_similarity=0.1, use_cache=True, compound_scoring='max')#
Pull algorithm labels out of
adata.obsand delegate tocompare.Each column in
target_columnsbecomes one algorithm. Its values are converted to strings, so missing values become labels such as"nan".- Parameters:
author_labels (
list[str]) – Reference labels, one per row ofadata.obs.anndata_objects (
Sequence[Any]) – AnnData objects to read the columns from, each with one row per author label. An object withoutauthor_columninobsis skipped with a warning. With several objects, each algorithm name ends with the position of its object, such aspred_0andpred_1.target_columns (
list[str]) – Columns ofadata.obswith the algorithm labels. A missing column is skipped with a warning.author_column (
str) – Column that each object must have inobs. Only its presence is checked; the author labels come fromauthor_labels.run_id (
str|None, default:None) – As incompare: pass one to reuse caches, orNoneto let the call generate and log one.algorithm_names (
list[str] |None, default:None) – Names of the algorithms in the results, one per target column. Defaults to the column names.metric (
str, default:'cosine_kernel') – As incompare.metric_params (
dict[str,Any] |None, default:None) – As incompare.min_match_similarity (
float, default:0.1) – As incompare.use_cache (
bool, default:True) – As incompare.compound_scoring (
Literal['max','hungarian_mean'], default:'max') – As incompare.
- Return type:
DataFrame- Returns:
The DataFrame that
comparereturns.- Raises:
ValueError – If
algorithm_namesandtarget_columnsdiffer in length, or for the reasons thatcompareraises it, such as an object whose number of rows differs fromauthor_labels.
- cache_stats(run_id=None)#
Summarise on-disk user embedding caches.
- Parameters:
run_id (
str|None, default:None) – If given, restrict stats to that run. Otherwise aggregates across all runs underuser_dir/embeddings.- Return type:
dict[str,Any]- Returns:
A dict with
root(the directory searched),total_files(the number of NPZ files),total_size_mbandstale_files(NPZ files that cannot be loaded, such as files without inline labels).
- clear_run(run_id, kind=None, identifier=None)#
Delete user embeddings and descriptions for a run.
The label decompositions of the run are kept.
- Parameters:
run_id (
str) – The run identifier used incompare(...).kind (
str|None, default:None) –"author"or"algorithm". If omitted, all kinds underrun_idare removed.identifier (
str|None, default:None) – Whenkindis given, restrict to a single identifier (e.g. one algorithm name) and to the files of the current model pair. Ignored ifkindisNone.
- Return type:
int- Returns:
Number of files removed.
- Raises:
ValueError – If
kindis not"author","algorithm"orNone.
- purge_stale(run_id=None)#
Delete user NPZ files that cannot be loaded (such as the stale format).
Files in the stale format lack the inline labels.
- Parameters:
run_id (
str|None, default:None) – If given, only delete files of that run.- Return type:
int- Returns:
Number of files removed.