References¶
A reference contains labeled single-cell representations projected into ALHENA's shared cell space. During annotation, image-derived cells are compared with these reference cells and receive one of the classes represented by the selected annotation axis.
This page explains how references are constructed, what the prebuilt references contain, how reference composition affects annotation, and how to build a custom reference.
For the practical workflow, see Inputs → References. For the retrieval procedure and confidence values, see Cell typing.
If you are using a prebuilt reference, the sections through Reference compatibility cover the information needed to choose, inspect, and interpret it. If you are creating your own reference, you can then continue directly to Building a custom reference.
What a reference file contains¶
ALHENA reference files use the .safetensors format. A prebuilt reference contains the projected
single-cell embeddings together with the class code assigned to each atlas cell on the supported
annotation axes.
| Tensor | Shape | Type | What it is |
|---|---|---|---|
embeddings |
(n_cells, 512) |
float16 | one projection per atlas cell, in the row order of the source atlas |
lineage_v1 |
(n_cells,) |
int8 | the class code of each cell on that axis, -1 for a cell with none |
compartment_v1 |
(n_cells,) |
int8 | the class code of each cell on that axis, -1 for a cell with none |
The reference does not contain the original gene-expression matrix, gene identifiers, cell barcodes, or complete source-atlas annotations.
Its metadata records information needed for compatibility and interpretation, including the
reference name, cell count, cell_space_id, and class support.
A reference is loaded on one annotation axis at a time. Atlas cells without a class on that axis are excluded from the retrieval pool.
Where a reference comes from¶
Reference construction starts from a labeled single-cell atlas. The atlas is embedded with the
single-cell model, then st_node_proj maps those representations into the same shared cell space
used by projected H&E-derived cells.
Class labels remain attached to the corresponding atlas cells. Annotation does not fit or fine-tune this reference; it only retrieves nearby reference cells and aggregates their labels.
flowchart LR
subgraph BUILD [Built once, before you run anything]
A[Labeled<br/>single-cell atlas] --> E[scConcept<br/>embeddings<br/>512 wide]
A --> L[Class labels:<br/>the atlas taxonomy]
E --> P[st_node_proj<br/>fixed linear map]
P --> R[Reference file:<br/>labeled cells]
L --> R
end
subgraph RUN [At annotation time, nothing is fitted]
H[H&E tile] --> K[Pre-projection cell embedding:<br/>tokens pooled by nucleus]
K --> Q[img_tok_proj<br/>fixed linear map]
Q --> C[Shared cell-space<br/>embedding]
end
R --> S[Shared cell space<br/>512 wide]
C --> S
S --> V[30 nearest<br/>reference cells vote]
V --> O[Cell-type annotation<br/>+ confidence]
Both sides must be projected into the same learned cell space, which is why encoder outputs and
references are checked through cell_space_id.
The available annotation classes are determined by the reference and annotation axis. If no reference cell represents a class, that class cannot be predicted.
Prebuilt references¶
ALHENA provides fourteen prebuilt reference files covering fifteen human tissue names;
LymphNode and Tonsil use the same reference.
References are downloaded independently, so selecting one tissue does not load the other tissue references.
All prebuilt references are derived from human single-cell atlases. See Can I use ALHENA on tissue from another species? for the implications of using these references outside human tissue.
| Reference | Tissue names | Cells | Size | Source |
|---|---|---|---|---|
bone_marrow |
BoneMarrow | 421,775 | 433 MB | DISCO |
breast |
Breast | 174,638 | 179 MB | DISCO |
cervix |
Cervix | 77,518 | 80 MB | Gene Expression Omnibus, accession GSE208653 |
heart |
Heart | 624,358 | 641 MB | DISCO |
intestine |
Colon | 414,406 | 425 MB | DISCO |
kidney |
Kidney | 103,547 | 106 MB | DISCO |
liver_cell |
Liver | 367,596 | 377 MB | DISCO |
lung |
Lung | 221,012 | 227 MB | DISCO |
ovary |
Ovary | 124,128 | 127 MB | DISCO |
pancreas_cell |
Pancreas | 188,369 | 193 MB | DISCO |
prostate |
Prostate | 21,030 | 22 MB | Tabula Sapiens, via CELLxGENE |
skin |
Skin | 394,594 | 405 MB | DISCO |
tonsil |
LymphNode, Tonsil | 273,755 | 281 MB | DISCO |
uterus |
Uterus | 22,029 | 23 MB | Tabula Sapiens, via CELLxGENE |
import alhena
print(alhena.available_tissues())
print(alhena.available_shards())
print(alhena.shard_for_tissue("LymphNode")) # tonsil
print(alhena.shard_for_tissue("Pancreatic")) # pancreas_cell
A prebuilt reference is fetched by tissue name, or by any alias below, with
alhena download.
Tissue aliases¶
TISSUE_ALIASES defines additional names accepted for several canonical tissues. Matching ignores
case, spacing, and separators, and every alias resolves to exactly one prebuilt reference.
| Tissue | Also accepted as |
|---|---|
| Breast | Mammary |
| Cervix | Cervix uteri, Uterine cervix |
| Colon | Bowel, Colonic, Colorectal, Large intestine, Rectum, Small intestine |
| Kidney | Renal |
| Liver | Hepatic |
| Lung | Pulmonary |
| Ovary | Ovarian |
| Pancreas | Pancreatic |
| Prostate | Prostate gland, Prostatic |
| Skin | Cutaneous |
| Tonsil | Tonsillar |
| Uterus | Corpus uteri, Endometrium, Myometrium, Uterine |
Aliases include alternative names for the same organ and anatomical regions explicitly represented by the underlying atlas.
They should not be interpreted as an automatic mapping between anatomically related tissues. A region that is not represented by the atlas is not accepted simply because it is nearby or biologically related.
alhena reference list shows the canonical tissue names together with all accepted aliases.
The intestine atlas holds esophageal cells as well
The intestine atlas also contains esophageal cells, but Esophagus is not exposed as a
tissue alias because it is a distinct organ rather than a region of the intestine.
Terms¶
Source attribution and license information for the prebuilt atlases are listed on the Cite page.
Class support¶
Reference classes are not equally represented. The tables below report, for each prebuilt reference, the number and proportion of cells available for retrieval on each annotation axis.
A value of 0 means that the corresponding class cannot be predicted with that reference. Very small classes are also highlighted because they provide fewer potential neighbors during retrieval.
On lineage_v1, the default axis:
| Reference | B_Plasma | Epithelial_Melanocyte | Myeloid | Stromal_Vascular | T_NK |
|---|---|---|---|---|---|
bone_marrow |
64,431 (17.9%) | 0 | 120,233 (33.4%) | 3,214 (0.9%) | 172,132 (47.8%) |
breast |
523 (0.3%) | 116,220 (67.2%) | 2,735 (1.6%) | 49,160 (28.4%) | 4,193 (2.4%) |
cervix |
4,596 (6.0%) | 18,890 (24.8%) | 14,871 (19.5%) | 7,208 (9.5%) | 30,608 (40.2%) |
heart |
872 (0.2%) | 1,331 (0.3%) | 49,337 (12.5%) | 332,736 (84.5%) | 9,265 (2.4%) |
intestine |
123,625 (30.0%) | 29,870 (7.2%) | 26,988 (6.5%) | 50,371 (12.2%) | 181,258 (44.0%) |
kidney |
1,470 (1.4%) | 58,851 (57.3%) | 13,466 (13.1%) | 17,218 (16.8%) | 11,719 (11.4%) |
liver_cell |
22,852 (6.3%) | 19,471 (5.4%) | 105,336 (29.0%) | 26,510 (7.3%) | 188,639 (52.0%) |
lung |
3,160 (1.4%) | 26,540 (12.0%) | 78,447 (35.6%) | 47,003 (21.3%) | 65,119 (29.6%) |
ovary |
182 (0.2%) | 10,283 (12.7%) | 2,734 (3.4%) | 63,530 (78.6%) | 4,049 (5.0%) |
pancreas_cell |
3,535 (3.0%) | 60,571 (52.2%) | 8,620 (7.4%) | 30,294 (26.1%) | 13,104 (11.3%) |
prostate |
101 (0.5%) | 14,147 (67.7%) | 1,309 (6.3%) | 2,201 (10.5%) | 3,133 (15.0%) |
skin |
10,800 (2.7%) | 143,201 (36.4%) | 38,128 (9.7%) | 118,017 (30.0%) | 83,731 (21.3%) |
tonsil |
201,142 (73.5%) | 247 (0.1%) | 5,785 (2.1%) | 0 | 66,581 (24.3%) |
uterus |
69 (0.3%) | 1,739 (7.9%) | 1,126 (5.1%) | 16,946 (77.0%) | 2,131 (9.7%) |
Percentages are calculated within the retrieval pool for the selected axis, after atlas cells without a class on that axis have been excluded.
Two different support checks are relevant here:
- Reference coverage: italic values contain fewer than 200 reference cells, the threshold
used by
ReferenceCoverageWarning. Bold zeroes indicate classes that are absent entirely. - Retrieval envelope: the thinnest expressed class should contain at least
10 × kreference cells. With the defaultk=30neighbors, this second threshold is 300 cells. It is not marked typographically in the table. It flags the three references containing an italic value and alsotonsil: its thinnest expressed class,Epithelial_Melanocyte, contains 247 cells, which is above the 200-cell coverage threshold but below the 300-cell retrieval-envelope threshold.
On compartment_v1, B_Plasma, Myeloid, and T_NK merge into the single Immune class. The
absent Epithelial_Melanocyte class in bone_marrow and absent Stromal_Vascular class in
tonsil remain absent. The same atlas rows carry a class on both built-in axes, so the total
retrieval-pool size is unchanged; the counts and percentages of Epithelial_Melanocyte and
Stromal_Vascular therefore remain unchanged as well.
| Reference | Epithelial_Melanocyte | Immune | Stromal_Vascular |
|---|---|---|---|
bone_marrow |
0 | 356,796 (99.1%) | 3,214 (0.9%) |
breast |
116,220 (67.2%) | 7,451 (4.3%) | 49,160 (28.4%) |
cervix |
18,890 (24.8%) | 50,075 (65.7%) | 7,208 (9.5%) |
heart |
1,331 (0.3%) | 59,474 (15.1%) | 332,736 (84.5%) |
intestine |
29,870 (7.2%) | 331,871 (80.5%) | 50,371 (12.2%) |
kidney |
58,851 (57.3%) | 26,655 (25.9%) | 17,218 (16.8%) |
liver_cell |
19,471 (5.4%) | 316,827 (87.3%) | 26,510 (7.3%) |
lung |
26,540 (12.0%) | 146,726 (66.6%) | 47,003 (21.3%) |
ovary |
10,283 (12.7%) | 6,965 (8.6%) | 63,530 (78.6%) |
pancreas_cell |
60,571 (52.2%) | 25,259 (21.8%) | 30,294 (26.1%) |
prostate |
14,147 (67.7%) | 4,543 (21.7%) | 2,201 (10.5%) |
skin |
143,201 (36.4%) | 132,659 (33.7%) | 118,017 (30.0%) |
tonsil |
247 (0.1%) | 273,508 (99.9%) | 0 |
uterus |
1,739 (7.9%) | 3,326 (15.1%) | 16,946 (77.0%) |
alhena reference describe prints these counts and shares for one reference on either axis. An
annotation run stores the counts used for retrieval in result.meta["reference_class_support"].
alhena annotate then prints each class's share of the retrieval pool alongside that class's share
of the resulting annotations.
How reference composition affects annotation¶
Annotation uses the k nearest reference cells to each query, not the global class proportions of
the reference.
Reference composition can nevertheless influence predictions through local density in the shared cell space. If two classes occupy overlapping regions but one is much more densely represented there, it can contribute more of the retrieved neighbors.
Confidence summarizes agreement among those retrieved neighbors. It does not correct for reference class imbalance or estimate whether the atlas composition matches the tissue being analyzed.
For this reason, interpret predicted cell-type composition together with the class support of the selected reference.
Classes absent from a prebuilt reference¶
Some prebuilt references cannot represent every class
On both built-in axes, the tonsil reference contains no Stromal_Vascular cells and the
bone_marrow reference contains no Epithelial_Melanocyte cells. Cells belonging biologically
to an absent class can still receive another available annotation because ALHENA does not
introduce an automatic Unknown class.
These limitations should be reported when interpreting composition or evaluating predictions.
These are properties of the atlases, not defects of the package, and no setting removes them.
Scoring a section whose known labels include an absent class is a further choice, with no default answer. Ground-truth classes absent from the reference describes the two evaluation populations.
Categories not represented by an axis¶
The built-in annotation axes describe broad cell classes. They do not attempt to represent every biological property of a cell.
For example, Epithelial_Melanocyte is a broad cell class and does not distinguish
malignant from non-malignant epithelial cells. Likewise, activation states or fine subtypes not
present in the selected taxonomy are not detected as special unknown categories.
A cell outside the taxonomy still receives the label favored by its retrieved reference neighbors. Confidence is not a novelty detector.
To annotate another biological category, build a custom reference whose labels explicitly represent that category and evaluate it on appropriate labeled H&E cells.
Thinly supported classes¶
Some prebuilt references contain only a small number of cells for particular classes. For example,
B_Plasma contains fewer than 200 reference cells in the prostate, ovary, and uterus references.
Predictions of thinly supported classes have fewer possible supporting reference neighbors and should therefore be interpreted with additional caution.
Reference coverage and retrieval warnings¶
ALHENA reports two types of warning when the selected reference or retrieval configuration has limited support.
ReferenceCoverageWarning reports classes that are absent or represented by fewer than
MIN_REFERENCE_CELLS_PER_CLASS (200) cells.
EnvelopeWarning reports when the chosen retrieval configuration lies outside the support
ratios expected by the package. Two ratios bound it:
| Ratio | Floor | Constant |
|---|---|---|
support of the thinnest expressed class, divided by k |
10 to 1 | MIN_SUPPORT_TO_K_RATIO |
k, divided by the number of classes |
3 to 1 | MIN_K_TO_CLASSES_RATIO |
At the default k = 30, the second ratio is 6 on lineage_v1 and 10 on compartment_v1. Only the
first fires on a prebuilt reference: on lineage_v1 for prostate, ovary, uterus and
tonsil, and on compartment_v1 for tonsil alone. Lowering k brings the second into play.
load_reference checks the first at the default k, and annotate_cells checks both at the k an
annotation run actually uses. Both coverage facts also travel on the result, as
meta["unexpressed_classes"] and meta["thinly_supported_classes"].
These thresholds are conservative operating bounds defined by ALHENA rather than empirically calibrated failure points. A warning identifies a condition that deserves attention; it does not by itself invalidate the result.
Inspecting a reference before you use it¶
Inspect class support before performing a large annotation run. describe_shard() reads the
reference metadata and class labels without loading the full embedding matrix:
import alhena
info = alhena.describe_shard(tissue="Prostate", axis="lineage_v1")
print(info.name, info.axis)
print(info.n_cells, "cells,", info.n_scored_cells, "in the retrieval pool")
print(info.class_support)
pool = sum(info.class_support.values())
print({name: round(count / pool, 3) for name, count in info.class_support.items()})
print("cannot express:", info.missing_classes)
print("thinly supported:", info.thin_classes)
print(info.cell_space_id)
missing_classes lists classes with no reference cells and thin_classes lists classes below the
support threshold. describe_shard() reports these conditions without emitting coverage warnings;
loading the reference performs the corresponding runtime checks.
Loading a reference also reads the embeddings:
reference = alhena.load_reference(tissue="Prostate", axis="lineage_v1")
print(len(reference), "cells,", reference.n_classes, "classes")
print(reference.class_order)
alhena reference describe gives the same description from the command line. The tissue is
positional, and --path takes a reference file on disk instead:
The command line has the whole of alhena reference, with the
output of each subcommand.
Interpreting reference counts¶
n_cells is the total number of rows stored in the reference, while n_scored_cells is the number
of cells that remain in the retrieval pool for the selected axis. class_support counts these
retrieval-pool cells by class.
Changing the annotation axis can merge classes and therefore change class support even when the underlying reference cells are unchanged.
Reference self-check¶
Reference.self_check() performs leave-one-out retrieval within the reference itself. Failure to
recover the atlas labels indicates a problem with the reference or taxonomy.
Successful self-retrieval is necessary but does not establish performance on H&E-derived cells. The self-check compares reference cells with other reference cells, whereas deployment compares image-derived cells with reference cells.
The cost grows with the cells scored times the size of the reference. A reference larger than
max_cells is scored on a subsample, drawn without replacement under a seed, and the number scored
is reported. The reference retrieved against is never subsampled. alhena reference check runs the
same check from the command line.
The coverage warnings and the check answer different questions. Thin support says how a prediction of that class should be read. It does not say that the reference cannot recover that class.
Reference compatibility¶
Image-derived cells and reference cells must belong to the same learned shared cell space. ALHENA
identifies this space through cell_space_id.
CellTyper checks compatibility between the encoder, previously computed CellEmbeddings, and the
selected reference. Incompatible combinations raise CellSpaceMismatchError.
Embedding width alone is not a valid compatibility check: different releases may use the same 512-dimensional representation while defining different learned spaces.
Building a custom reference¶
A custom reference allows ALHENA to annotate cells using a labeled single-cell atlas and taxonomy of your own.
Construction has two stages:
- embed the single-cell atlas with the dedicated atlas-embedding environment;
- use ALHENA to project those embeddings into the shared cell space and build the reference file.
Tutorial 5 provides the complete executable workflow. This section explains the important data and compatibility requirements.
Step 1 needs the repository
The atlas-embedding script and its dedicated environment are distributed in the source repository rather than in the installed Python package. Clone the repository before running the atlas-embedding step.
Step 1: embed the single-cell atlas¶
The provided atlas-embedding script uses
scConcept to embed the single-cell atlas. It reads an
.h5ad atlas and writes an HDF5 file containing cls_emb, of shape (n_cells, 512) at half
precision, in the row order of the atlas, together with the cell names for provenance.
The script reads the scConcept model files from ~/.cache/sc-concept/corpus40M-model30M/, or
from corpus40M-model30M/ inside the directory given to --model-cache. Download them once, in
the atlas-embedding environment:
python -c "from concept import scConcept; scConcept(cache_dir='$HOME/.cache/sc-concept').load_config_and_model(model_name='corpus40M-model30M')"
Provide the expression values expected by the atlas model
The atlas-embedding script expects raw expression counts rather than normalized or
log-transformed values. If raw counts are stored in an AnnData layer, select that layer
explicitly with --layer. If they are stored in adata.raw, as in CELLxGENE files, pass
--use-raw; those files keep their Ensembl identifiers in the gene index, read with
--gene-id-column var_names.
--gene-id-column names the column of adata.var holding the gene identifiers, or of
adata.raw.var with --use-raw; var_names uses the gene index instead. An atlas keyed on
gene symbols is read with --gene-id-type symbol.
--device and --batch-size control the forward pass, --overwrite replaces an existing output,
and --json writes a one-line JSON summary to standard output; progress messages are written
separately to standard error.
python scripts/alhena_atlas_embed.py \
--atlas atlas.h5ad \
--output atlas_cls_emb.h5 \
--gene-id-column var_names \
--gene-id-type symbol
Advanced: gene identifiers
Prefer Ensembl identifiers when the atlas provides them. They match the model vocabulary directly and avoid ambiguities that can occur with gene symbols.
The model vocabulary uses Ensembl identifiers without version suffixes. For example,
ENSG00000141510.17 is read as ENSG00000141510. If two atlas columns normalize to the same
Ensembl identifier, the run stops and reports the conflicting columns rather than merging them.
GENCODE-style _PAR_Y identifiers are handled separately. The _PAR_Y tag is preserved so
the X and Y columns do not collapse onto the same identifier. The model vocabulary contains
the X-copy identifier but not the tagged Y form, so the X copy is read and the tagged Y copy
is ignored.
Use --gene-id-type symbol only when the atlas is keyed by gene symbols rather than Ensembl
identifiers. Each symbol is matched exactly, including case, against
gene_mappings/hsapiens.csv in the model directory under --model-cache.
Some symbols map to more than one Ensembl identifier. In that situation, the symbol alone does
not identify which gene produced the counts, so the column is left unread and a warning names
the ambiguous symbol. In the table distributed with corpus40M-model30M, 1,501 of 19,477
symbols are ambiguous in this way, including HLA-A, TNF and PTPRC. If the atlas also contains
an Ensembl-ID column, prefer that column through --gene-id-column.
The output records how identifiers were interpreted: gene_id_type,
gene_ids_normalized, n_gene_ids_normalized, n_gene_ids_par_y,
n_gene_symbols_mapped, n_gene_symbols_ambiguous, and
n_gene_symbols_unmatched.
Keep the atlas-embedding configuration compatible with the released cell space
The released reference workflow assumes the default atlas model, species, token budget, and gene-sampling configuration. Changing these settings changes the single-cell representation being projected and may make the resulting reference incompatible with the intended ALHENA cell space. The script warns when a setting differs from its default, but no later step detects the difference: the reference records the encoder that projected it, not the model that embedded the atlas.
Keep the provided defaults unless you are intentionally building and validating a different representation pipeline.
Atlas embedding requires sufficient overlap with the single-cell model vocabulary. If too few genes can be matched, the script stops and reports the expected identifier format.
Step 2: build the reference¶
build_reference() projects the atlas embeddings through the single-cell-side projection head,
writes the reference file, and performs a reference self-check before returning.
import alhena
encoder = alhena.load_encoder()
report = alhena.build_reference(
"breast_cls_emb.h5",
"breast_labels.csv",
encoder,
"breast_own.safetensors",
axis="lineage_v1",
source="my breast atlas",
license="CC BY 4.0",
)
print(report.path, report.name)
print(report.n_rows, "rows,", report.n_labeled["lineage_v1"], "labeled")
print(report.class_support["lineage_v1"])
for note in report.self_check.warnings:
print(note)
Preserve atlas row order
Labels are matched to atlas embeddings by row position. Do not reorder, remove, or independently filter cells between atlas embedding and reference construction.
Labels come as an array, a DataFrame, or the path of a .csv, .tsv or .parquet file. A
table with one column is read as it stands; pass label_column when it has more. Pass a mapping
from axis name to labels to code several axes into one reference file.
ShardBuildReport records the number of atlas rows, labeled cells, class support, annotation axes,
and the results of the reference self-check. See the Building a reference API
page for the complete report schema.
A custom taxonomy requires a unique axis name together with an explicit class_order. The order
defines the stored class codes and deterministic tie-breaking behavior.
report = alhena.build_reference(
"gut_cls_emb.h5",
{"gut_v1": "gut_labels.csv"},
encoder,
"gut_own.safetensors",
axis="gut_v1",
class_order=["Enterocyte", "Goblet", "Paneth", "Tuft", "Stromal", "Immune"],
)
What your class order may hold
The built-in names lineage_v1 and compartment_v1 are reserved for their predefined class
sets. Use another axis name for a custom taxonomy.
Rows with no class are encoded as unlabeled and excluded from the retrieval pool when the
reference is loaded. A reference supports at most MAX_CLASSES classes on one axis, including
the Unknown class the build appends; see the reference-building API for
the exact storage limits.
A class name cannot contain /, because the .h5ad and zarr files that store annotations
cannot hold it in a key. A name such as T/NK is refused. Write it T_NK instead.
A reference built on a custom axis is read back through load_reference, which takes the class
order from the reference file itself:
reference = alhena.load_reference(path="gut_own.safetensors", axis="gut_v1")
typer = alhena.load_celltyper(reference=reference, encoder=encoder)
print(typer.axis, typer.class_order)
A loaded reference carries its axis, so load_celltyper does not need it again. load_celltyper
also reads the reference from the path of its file:
alhena.load_celltyper(reference="gut_own.safetensors", axis="gut_v1"). A tissue name selects a
prebuilt reference. A custom reference is selected by its file path together with its axis. On
the command line, alhena annotate takes the reference file through --reference and its axis
through --axis; alhena reference describe and alhena reference check take the file through
--path.
Annotating previously encoded cells¶
A custom reference can be used with previously computed CellEmbeddings as long as their
cell_space_id is compatible:
cells = alhena.io.read_cells("cells.h5ad")
typer = alhena.load_celltyper(reference="gut_own.safetensors", axis="gut_v1")
result = typer.annotate(cells)
print(result.axis, result.class_order)
No H&E tiles are re-encoded in this workflow. A mismatch between the saved cells and reference
raises CellSpaceMismatchError.
What a build guarantees, and what it does not¶
Reference construction checks internal consistency of the atlas labels and performs leave-one-out self-retrieval before returning.
Passing this self-check shows that the reference can recover its own atlas labels under the chosen taxonomy and retrieval operator. It does not establish annotation accuracy for H&E-derived cells, which must be evaluated separately when appropriate labeled data are available.
A label that matches no class
A label that is neither part of class_order nor declared in unlabeled raises an error.
Unknown and the empty string are always read as unlabeled. This prevents unrecognized labels
from being silently excluded from the reference.
Custom references keep the same retrieval defaults
Custom references use the same default
retrieval operator as the prebuilt references. A build on
a custom taxonomy therefore always raises EnvelopeWarning, and a taxonomy with substantially
different class support or class count may trigger it again when the reference is loaded or
used for annotation. This warning indicates that the reference lies outside the package's
declared retrieval-support envelope; it does not automatically invalidate the reference.
Use one reference for each annotation run¶
ALHENA does not concatenate several references into one retrieval pool. Different references may represent different atlas populations, class distributions, and taxonomies; pooling them would make retrieval depend on how those references were combined.
Select one biologically appropriate reference for each annotation run.
Advanced: reference storage¶
Rows are stored at half precision, and are converted to float32 and normalized once, at load. Half precision resolves about three decimal digits, which would tie neighbors in a top-k taken over millions of cosines.
Rows with no class on the loaded axis leave the retrieval pool at load, rather than being masked
out of the vote. All k places of a neighborhood then hold a cell that can vote.
Next: Installation