# `seroverse.core`

Core Structure-of-Arrays (SoA) protocols, genomic intervals, sequence &amp; alphabet engines, k-mer/randstrobe indices, banded Smith-Waterman-Gotoh alignment, clustering, and graph models.

---

## Container Protocols (`seroverse.core.collections`)

## collections

Base classes, 1D NumPy array type aliases, and Numba kernels for Structure-of-Arrays (SoA) containers.

This module defines the concrete base classes (`ScalarView`, `BatchedContainer`, `RaggedArrayContainer`, `Spec`, `SpecContainer`, and `SpecEnum`) and 1D NumPy array type aliases that govern high-performance, vectorized containers and compiled ontology registries across SeroVerse.

Upon class definition (`__init_subclass__`), `BatchedContainer` and `RaggedArrayContainer` inspect `@dataclass` field annotations, verify that all stored container fields are NumPy arrays, register their `np.dtype`s, and automatically provide `__len__`, `__getitem__`, `__eq__`, `filter`, `empty`, `concat`, and `from_list`.

Classes:

| Name | Description |
| --- | --- |
| `ScalarView` | Concrete base class for immutable scalar views extracted from a `BatchedContainer`. |
| `BatchedContainer` | Concrete generic base class for Structure-of-Arrays (SoA) batch containers. |
| `RaggedArrayContainer` | Concrete generic base class for ragged Structure-of-Arrays (SoA) containers. |
| `Spec` | Immutable scalar specification for an ontology or reference database record. |
| `SpecContainer` | Immutable, read-only Structure-of-Arrays (SoA) database container for `Spec` records. |
| `SpecEnum` | Base `IntEnum` for 0-based contiguous ontology registries backed by a singleton `SpecContainer`. |

Functions:

| Name | Description |
| --- | --- |
| `lengths_to_offsets` | Compute 0-based exclusive prefix-sum offsets from a 1D array of element lengths. |
| `normalize_indices` | Normalize a slice, boolean mask, or integer index sequence into a 1D `int32` index array. |

### ScalarView

Concrete base class for immutable scalar views extracted from a `BatchedContainer`.

All scalar views are `@dataclass(frozen=True, slots=True)` records representing a single element of a Structure-of-Arrays (SoA) batch container. Inheriting from `ScalarView` automatically provides: - NumPy-safe structural equality (`__eq__`) using `np.array_equal` for any `np.ndarray` fields while preserving `@dataclass`-generated `__hash__` on scalar-only views. - Functional copy-update via `.replace(**changes)`. - Shallow dictionary serialization via `.to_dict()`.

Methods:

| Name | Description |
| --- | --- |
| `replace` | Return a new scalar view instance with specified fields replaced. |
| `to_dict` | Return a shallow dictionary mapping field names to their values. |

#### replace

```python
replace(**changes: Any) -> Self
```

Return a new scalar view instance with specified fields replaced.

#### to\_dict

```python
to_dict() -> dict[str, Any]
```

Return a shallow dictionary mapping field names to their values.

### BatchedContainer

Concrete generic base class for Structure-of-Arrays (SoA) batch containers.

Subclasses must be `@dataclass(frozen=True, slots=True)` classes whose stored fields are all annotated as 1D NumPy arrays (e.g. `Int32Array`, `UInt32Array`, `Float64Array`). Upon class creation, `BatchedContainer.__init_subclass__` validates and registers each field's `np.dtype` into `_field_dtypes` and automatically provides: - `__len__`, `__iter__`, and NumPy-safe `__eq__` - `__getitem__` with `@overload` typing, negative-index bounds checking, and automatic dispatch to `_get_scalar(idx)` (for integer indices) and `_get_slice(item)` (for slices/masks/index arrays) - `filter(mask)`, `replace(**changes)`, `empty()`, `concat(batches)`, and `from_list(items)`

Class Type Parameters:

| Name | Bound or Constraints | Description | Default |
| --- | --- | --- | --- |
| `T` | `ScalarView` | The `ScalarView` dataclass returned when indexing a single element. | *required* |
| `S` | `BatchedContainer[Any, Any]` | The batched container type returned when slicing or filtering. | *required* |

Methods:

| Name | Description |
| --- | --- |
| `filter` | Return a filtered container containing only records where `mask` is True. |
| `replace` | Return a new container instance with specified array fields replaced. |
| `to_dict` | Return a shallow dictionary mapping container field names to their underlying NumPy arrays. |
| `chunks` | Yield contiguous \\(O(1)\\) zero-copy mini-batch slices of at most `size` records. |
| `argsort` | Compute the stable 0-based `int32` permutation indices that sort this container by `*by`. |
| `sort_by` | Return a new container sorted stably by one or more 1D array fields or properties. |
| `empty` | Create an empty 0-length container with registered `np.dtype` arrays. |
| `concat` | Concatenate multiple containers of the same type into a single batch. |
| `from_list` | Pack a sequence of `ScalarView` instances into a batch container. |

#### filter

```python
filter(mask: BoolArray | list[bool]) -> S
```

Return a filtered container containing only records where `mask` is True.

#### replace

```python
replace(**changes: Any) -> Self
```

Return a new container instance with specified array fields replaced.

#### to\_dict

```python
to_dict() -> dict[str, Any]
```

Return a shallow dictionary mapping container field names to their underlying NumPy arrays.

#### chunks

```python
chunks(size: int) -> Iterator[S]
```

Yield contiguous \\(O(1)\\) zero-copy mini-batch slices of at most `size` records.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `size` | `int` | Maximum number of records per chunk (must be `> 0`). | *required* |

Yields:

| Name | Type | Description |
| --- | --- | --- |
| `S` | `S` | Contiguous mini-batch container slice. |

Raises:

| Type | Description |
| --- | --- |
| `ValueError` | If `size <= 0`. |

#### argsort

```python
argsort(
    *by: str, descending: bool | Sequence[bool] = False
) -> Int32Array
```

Compute the stable 0-based `int32` permutation indices that sort this container by `*by`.

Supports sorting by one or more registered 1D array columns or computed 1D array properties (in primary-to-secondary priority order), with either a single `descending` boolean or a per-key sequence of booleans.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `*by` | `str` | Field or property names to sort by (defaults to the primary container field). | `()` |
| `descending` | `bool \| Sequence[bool]` | Sort direction (`bool` applied to all keys, or a `Sequence[bool]` per key). | `False` |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `Int32Array` | `Int32Array` | 1D `int32` index permutation of length `len(self)`. |

Raises:

| Type | Description |
| --- | --- |
| `ValueError` | If a key does not resolve to a 1D NumPy array of length `len(self)` or if `descending` length does not match `len(by)`. |

#### sort\_by

```python
sort_by(
    *by: str, descending: bool | Sequence[bool] = False
) -> S
```

Return a new container sorted stably by one or more 1D array fields or properties.

#### empty

```python
empty() -> Self
```

Create an empty 0-length container with registered `np.dtype` arrays.

#### concat

```python
concat(batches: Iterable[Self]) -> Self
```

Concatenate multiple containers of the same type into a single batch.

#### from\_list

```python
from_list(items: Sequence[T]) -> Self
```

Pack a sequence of `ScalarView` instances into a batch container.

### RaggedArrayContainer

Bases: `BatchedContainer[T, S]`

Concrete generic base class for ragged Structure-of-Arrays (SoA) containers.

Ragged containers store variable-length per-record arrays (declared in `_ragged_fields`) in flat, contiguous 1D NumPy buffers indexed by `offsets` and `lengths` (`Int32Array`), alongside any fixed-length per-record 1D arrays (`_record_fields`).

Subclasses only need to declare `_ragged_fields: ClassVar[tuple[str, ...]]` (e.g. `("seqs",)` or `("members",)`), and inherit `__len__`, `__getitem__`, `_get_scalar`, `_get_slice`, `empty`, `concat`, `from_list`, `filter`, and `indptr` automatically.

Methods:

| Name | Description |
| --- | --- |
| `lengths_to_offsets` | Compute 0-based starting offsets from a 1D `lengths` array. |
| `concat` | Concatenate multiple ragged containers into a single contiguous batch. |
| `from_list` | Pack a sequence of `ScalarView` instances into a ragged container. |
| `pad` | Pack a ragged 1D field into a dense 2D `(N, max_len)` NumPy matrix. |

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `indptr` | `Int32Array` | CSR-compatible \\((N + 1)\\)-length index pointer array (`[0, *cumsum(lengths)]`). |

#### indptr

```python
indptr: Int32Array
```

CSR-compatible \\((N + 1)\\)-length index pointer array (`[0, *cumsum(lengths)]`).

#### lengths\_to\_offsets

```python
lengths_to_offsets(lengths: Int32Array) -> Int32Array
```

Compute 0-based starting offsets from a 1D `lengths` array.

#### concat

```python
concat(batches: Iterable[Self]) -> Self
```

Concatenate multiple ragged containers into a single contiguous batch.

#### from\_list

```python
from_list(items: Sequence[T]) -> Self
```

Pack a sequence of `ScalarView` instances into a ragged container.

#### pad

```python
pad(
    field_name: str | None = None,
    *,
    max_len: int | None = None,
    fill_value: Any = 0,
) -> ndarray[tuple[int, int], Any]
```

Pack a ragged 1D field into a dense 2D `(N, max_len)` NumPy matrix.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `field_name` | `str \| None` | Name of the ragged field in `_ragged_fields` to pad. Defaults to the sole ragged field when `len(_ragged_fields) == 1`. | `None` |
| `max_len` | `int \| None` | Target column width \\(L\\) of the output 2D matrix. Defaults to `max(self.lengths)` (or `0` when the container is empty); rows longer than `max_len` are truncated. | `None` |
| `fill_value` | `Any` | Padding value used to fill positions `[lengths[i] : max_len]`. | `0` |

Returns:

| Type | Description |
| --- | --- |
| `ndarray[tuple[int, int], Any]` | np.ndarray\[tuple\[int, int\], Any\]: Dense 2D array of shape `(len(self), max_len)`. |

Raises:

| Type | Description |
| --- | --- |
| `ValueError` | If `field_name` is omitted on a multi-field ragged container, is not in `_ragged_fields`, or `max_len < 0`. |

### Spec

Bases: `ScalarView`

Immutable scalar specification for an ontology or reference database record.

Serves as the scalar element view `T` for `SpecContainer` and `SpecEnum`. Every `Spec` defines a canonical ASCII/UTF-8 `name: bytes` attribute. Subclasses may add domain-specific fields (e.g. abbreviations, category enums, bitmasks, or numerical priors) and optionally override `lookup_keys` to register secondary lookup keys.

Methods:

| Name | Description |
| --- | --- |
| `lookup_keys` | Return normalized lowercase `bytes` keys used to index this spec in a `SpecContainer`. |

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `name_str` | `str` | Canonical specification name decoded as a UTF-8 `str`. |

#### name\_str

```python
name_str: str
```

Canonical specification name decoded as a UTF-8 `str`.

#### lookup\_keys

```python
lookup_keys() -> tuple[bytes, ...]
```

Return normalized lowercase `bytes` keys used to index this spec in a `SpecContainer`.

### SpecContainer

Bases: `BatchedContainer[T, S]`

Immutable, read-only Structure-of-Arrays (SoA) database container for `Spec` records.

Extends `BatchedContainer` with: - A canonical `names: BytesArray` column. - Automatic read-only array freezing (`arr.setflags(write=False)`) across all registered NumPy arrays upon construction (`__post_init__`). - Lazy \\(O(1)\\) case-insensitive name/key lookup via `.index(key)`, `.resolve_index(key)`, `key in container`, and `container[key]` (`str | bytes` indexing).

Methods:

| Name | Description |
| --- | --- |
| `index` | Resolve a `Spec` name, lookup key, or integer index to its 0-based integer index. |
| `resolve_index` | Resolve a `Spec` name, lookup key, or integer index, returning `default` if not found. |

#### index

```python
index(key: str | bytes | int | integer[Any]) -> int
```

Resolve a `Spec` name, lookup key, or integer index to its 0-based integer index.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `key` | `str \| bytes \| int \| integer[Any]` | Canonical name (`str` or `bytes`, case-insensitive), secondary lookup key, or integer index. | *required* |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `int` | `int` | Normalized 0-based index in `0..len(self) - 1`. |

Raises:

| Type | Description |
| --- | --- |
| `IndexError` | If `key` is an out-of-range integer. |
| `KeyError` | If `key` is a `str` or `bytes` not found in the container. |

#### resolve\_index

```python
resolve_index(
    key: str | bytes | int | integer[Any], default: int = -1
) -> int
```

Resolve a `Spec` name, lookup key, or integer index, returning `default` if not found.

### SpecEnum

Bases: `IntEnum`

Base `IntEnum` for 0-based contiguous ontology registries backed by a singleton `SpecContainer`.

Subclasses declare standard 0-based integer enum members (`MEMBER = 0..N-1`) and optionally override `_compile_specs` to return a domain-specific `SpecContainer` (if not overridden, a default `SpecContainer[Spec, SpecContainer]` is compiled from the lowercase enum member names).

Provides out-of-the-box: - `cls.specs()`: Cached singleton `SpecContainer` validated to have 1-to-1 contiguous correspondence (`0..N-1`) with `cls`. - `self.spec`: O(1) scalar `Spec` view for the enum member. - `self.name_bytes` and `self.name_str`: Canonical `Spec` name accessors. - `cls.from_name(key)` and `cls.resolve(key, default=...)`: O(1) case-insensitive resolution across enum instances, integer IDs, enum member names (`_`, `-`, or space-separated), canonical `Spec.name`, and any secondary `Spec.lookup_keys`.

Methods:

| Name | Description |
| --- | --- |
| `specs` | Return the cached, validated singleton `SpecContainer` for this enum. |
| `from_name` | Resolve an enum member by instance, integer value, member name, or `Spec` name/key. |
| `resolve` | Resolve an enum identifier, falling back to `default` (or `cls.UNKNOWN` if defined). |

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `spec` | `Any` | Return the scalar `Spec` view for this enum member. |
| `name_bytes` | `bytes` | Canonical `Spec.name` as raw ASCII/UTF-8 `bytes`. |
| `name_str` | `str` | Canonical `Spec.name` decoded as a UTF-8 `str`. |

#### spec

```python
spec: Any
```

Return the scalar `Spec` view for this enum member.

#### name\_bytes

```python
name_bytes: bytes
```

Canonical `Spec.name` as raw ASCII/UTF-8 `bytes`.

#### name\_str

```python
name_str: str
```

Canonical `Spec.name` decoded as a UTF-8 `str`.

#### specs

```python
specs() -> SpecContainer[Any, Any]
```

Return the cached, validated singleton `SpecContainer` for this enum.

#### from\_name

```python
from_name(
    key: str | bytes | int | integer[Any] | Self,
) -> Self
```

Resolve an enum member by instance, integer value, member name, or `Spec` name/key.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `key` | `str \| bytes \| int \| integer[Any] \| Self` | Enum member, 0-based integer value, or string/bytes identifier (case-insensitive). | *required* |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `Self` | `Self` | Resolved enum member. |

Raises:

| Type | Description |
| --- | --- |
| `ValueError` | If `key` is an integer not corresponding to a valid enum member. |
| `KeyError` | If `key` is a `str` or `bytes` not found in the lookup table. |

#### resolve

```python
resolve(
    key: str | bytes | int | integer[Any] | Self,
    default: Self | None = None,
) -> Self
```

Resolve an enum identifier, falling back to `default` (or `cls.UNKNOWN` if defined).

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `key` | `str \| bytes \| int \| integer[Any] \| Self` | Enum member, 0-based integer value, or string/bytes identifier. | *required* |
| `default` | `Self \| None` | Explicit fallback member if `key` cannot be resolved. If `None`, falls back to `cls.UNKNOWN` when defined on `cls`. | `None` |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `Self` | `Self` | Resolved enum member or fallback. |

Raises:

| Type | Description |
| --- | --- |
| `KeyError` | If `key` cannot be resolved and neither `default` nor `cls.UNKNOWN` is available. |

### lengths\_to\_offsets

```python
lengths_to_offsets(lengths: Int32Array) -> Int32Array
```

Compute 0-based exclusive prefix-sum offsets from a 1D array of element lengths.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `lengths` | `Int32Array` | 1D array of non-negative record lengths (`int32`). | *required* |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `Int32Array` | `Int32Array` | 1D `int32` array of starting offsets. |

### normalize\_indices

```python
normalize_indices(
    item: slice | ndarray[Any, Any] | list[Any], n: int
) -> Int32Array
```

Normalize a slice, boolean mask, or integer index sequence into a 1D `int32` index array.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `item` | `slice \| ndarray[Any, Any] \| list[Any]` | Slice, boolean mask array, or integer index sequence/array. | *required* |
| `n` | `int` | Total number of records in the target container. | *required* |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `Int32Array` | `Int32Array` | Resolved 0-based `int32` indices. |

---

## Genomic Intervals (`seroverse.core.interval`)

## interval

Genomic interval representation, strand orientations, and vectorized Structure-of-Arrays operations.

This module provides discrete coordinate intervals via `Interval`, strand representations via `Strand`, and high-performance, vectorized interval collections via `Intervals`.

Classes:

| Name | Description |
| --- | --- |
| `Strand` | Integer representation of genomic strand orientation. |
| `Interval` | A single 0-based, half-open genomic interval with strand orientation. |
| `Intervals` | A high-performance Structure-of-Arrays (SoA) collection of genomic intervals. |

### Strand

Bases: `IntEnum`

Integer representation of genomic strand orientation.

Supports conversion from common string formats (`'+'`, `'-'`, `'1'`, `'-1'`).

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `FORWARD` | `int` | Forward strand (`+1`). |
| `REVERSE` | `int` | Reverse strand (`-1`). |
| `UNSTRANDED` | `int` | Unstranded or unknown orientation (`0`). |

### Interval

Bases: `ScalarView`

A single 0-based, half-open genomic interval with strand orientation.

Represents a discrete sequence segment defined by `start` (inclusive), `end` (exclusive), and `strand` orientation.

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `start` | `int` | 0-based starting position (inclusive). |
| `end` | `int` | 0-based ending position (exclusive). |
| `strand` | `Strand` | Strand orientation `Strand`. |

### Intervals

Bases: `BatchedContainer[Interval, 'Intervals']`

A high-performance Structure-of-Arrays (SoA) collection of genomic intervals.

Stores starts, ends, and strands as parallel 1D NumPy arrays for memory-efficient vectorized operations and Numba spatial algorithms.

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `starts` | `Int32Array` | 1D array of 0-based start coordinates. |
| `ends` | `Int32Array` | 1D array of 0-based end coordinates. |
| `strands` | `Int8Array` | 1D array of strand values (+1, -1, 0). |

#### lengths

```python
lengths: Int32Array
```

Compute the lengths of all intervals in base pairs (`ends - starts`).

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `Int32Array` | `Int32Array` | 1D array of interval lengths. |

---

## Genome Assemblies &amp; FASTA I/O (`seroverse.core.genome`, `seroverse.core.io`)

## genome

Classes:

| Name | Description |
| --- | --- |
| `GenomeAssembly` | Container for a genome assembly with support for transparent decompression. |

### GenomeAssembly

Bases: `Sequences`

Container for a genome assembly with support for transparent decompression.

Stores contig sequence data as a contiguous memory block using `Sequences` and supports thread-safe, lazy-cached index creation for high-performance sequence alignment.

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `id` | `bytes` | Unique genome assembly identifier. |

Methods:

| Name | Description |
| --- | --- |
| `ensure` | Ensure the input object is coerced into a `GenomeAssembly`. |
| `from_fasta` | Construct a GenomeAssembly directly from raw binary FASTA data. |
| `from_file` | Load a genome assembly from a FASTA file path. |
| `from_stream` | Load a genome assembly from an open binary stream. |
| `from_records` | Construct a `GenomeAssembly` from sequence records. |

#### ensure

```python
ensure(genome: Self | str | Path | IO[bytes]) -> Self
```

Ensure the input object is coerced into a `GenomeAssembly`.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `genome` | `Self \| str \| Path \| IO[bytes]` | Existing assembly object, file path, or binary FASTA stream. | *required* |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `GenomeAssembly` | `Self` | Validated or loaded `GenomeAssembly` instance. |

#### from\_fasta

```python
from_fasta(
    data: bytes | bytearray | memoryview,
    id_: bytes = b"unknown",
    *,
    truncate_id: bool = True,
    uppercase: bool = True,
) -> Self
```

Construct a GenomeAssembly directly from raw binary FASTA data.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `data` | `bytes \| bytearray \| memoryview` | Raw binary FASTA contents. | *required* |
| `id_` | `bytes` | Genome assembly identifier. | `b'unknown'` |
| `truncate_id` | `bool` | If `True`, truncates header IDs at first whitespace. | `True` |
| `uppercase` | `bool` | If `True`, normalizes sequence bytes to uppercase ASCII. | `True` |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `GenomeAssembly` | `Self` | Constructed `GenomeAssembly` instance. |

#### from\_file

```python
from_file(filepath: str | Path) -> Self
```

Load a genome assembly from a FASTA file path.

Supports plain `.fasta` / `.fa` / `.fna` files as well as compressed `.gz`, `.bz2`, and `.xz` files.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `filepath` | `str \| Path` | Path to the target FASTA file. | *required* |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `GenomeAssembly` | `Self` | Loaded `GenomeAssembly` instance. |

Raises:

| Type | Description |
| --- | --- |
| `NotImplementedError` | If the file format or compression extension is unsupported. |

#### from\_stream

```python
from_stream(
    handle: IO[bytes], id_: bytes | None = None
) -> Self
```

Load a genome assembly from an open binary stream.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `handle` | `IO[bytes]` | Open binary FASTA stream handle. | *required* |
| `id_` | `bytes \| None` | Custom assembly identifier. If None, derived from handle name or defaults to `b'unknown'`. | `None` |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `GenomeAssembly` | `Self` | Loaded `GenomeAssembly` instance. |

#### from\_records

```python
from_records(
    records: list[Sequence]
    | tuple[Sequence, ...]
    | Iterable[Sequence],
    id_: bytes = b"unknown",
) -> Self
```

Construct a `GenomeAssembly` from sequence records.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `records` | `Iterable[Sequence]` | Iterable of `Sequence` objects. | *required* |
| `id_` | `bytes` | Genome assembly identifier. | `b'unknown'` |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `GenomeAssembly` | `Self` | Constructed `GenomeAssembly` instance. |

## fasta

High-performance C-level and zero-copy NumPy FASTA I/O.

Classes:

| Name | Description |
| --- | --- |
| `FastaReader` | High-performance stateful FASTA stream iterator and vectorized batch loader. |

### FastaReader

Bases: `Iterator[Sequence]`

High-performance stateful FASTA stream iterator and vectorized batch loader.

Streams binary FASTA handles in chunks, splitting on `\n>` boundaries and applying C-level `bytes.translate` to yield `Sequence` instances with \\(O(1)\\) memory overhead, or loads an entire stream at once into a contiguous `Sequences` Structure-of-Arrays container via `load`.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `handle` | `IO[bytes] \| BufferedIOBase \| RawIOBase` | Open binary stream (`IO[bytes]`) containing FASTA sequence data. | *required* |
| `truncate_id` | `bool` | If `True`, truncates header IDs at the first whitespace character. | `True` |
| `uppercase` | `bool` | If `True`, normalizes sequence bytes to uppercase ASCII. | `True` |
| `chunk_size` | `int` | Read buffer size in bytes for streaming iteration (default 4 MiB). | `4 * 1024 * 1024` |

Methods:

| Name | Description |
| --- | --- |
| `from_bytes` | Construct a `FastaReader` from an in-memory binary buffer. |
| `close` | Close the underlying binary stream. |
| `load` | Load the FASTA stream into memory as a contiguous `Sequences` batch. |

#### from\_bytes

```python
from_bytes(
    data: bytes | bytearray | memoryview,
    truncate_id: bool = True,
    uppercase: bool = True,
    chunk_size: int = 4 * 1024 * 1024,
) -> Self
```

Construct a `FastaReader` from an in-memory binary buffer.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `data` | `bytes \| bytearray \| memoryview` | Raw binary FASTA buffer (`bytes`, `bytearray`, or `memoryview`). | *required* |
| `truncate_id` | `bool` | If `True`, truncates header IDs at the first whitespace character. | `True` |
| `uppercase` | `bool` | If `True`, normalizes sequence bytes to uppercase ASCII. | `True` |
| `chunk_size` | `int` | Read buffer size in bytes for streaming iteration. | `4 * 1024 * 1024` |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `FastaReader` | `Self` | Reader wrapping the binary buffer. |

#### close

```python
close() -> None
```

Close the underlying binary stream.

#### load

```python
load() -> Sequences
```

Load the FASTA stream into memory as a contiguous `Sequences` batch.

Uses C-level `bytes.split`, `bytes.partition`, and 256-byte lookup table `bytes.translate` combined with a single `bytearray.join` allocation and zero-copy `np.frombuffer` view.

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `Sequences` | `Sequences` | Packed Structure-of-Arrays container of all parsed sequences. |

---

## Alphabets &amp; Genetic Codes (`seroverse.core.seq.alphabet`)

## alphabet

ASCII-based biological alphabets, translation tables, and genetic codes.

This module provides high-performance ASCII alphabet definitions (`Alphabet`) with pre-computed 256-byte lookup tables for instant \\(O(1)\\) k-mer bit-packing and reduced alphabet transformations, alongside translation tables (`GeneticCode`) for vectorised parallel protein translation.

Classes:

| Name | Description |
| --- | --- |
| ``[`Alphabet`][seroverse.core.seq.alphabet.Alphabet]`` | ASCII biological alphabet representation with dual LUTs. |
| ``[`GeneticCode`][seroverse.core.seq.alphabet.GeneticCode]`` | Translation table and genetic code representation. |
| ``[`AlphabetError`][seroverse.core.seq.alphabet.AlphabetError]`` | Base exception for alphabet operations. |

### AlphabetError

Bases: `ValueError`

Raised when an alphabet definition is invalid or an operation is incompatible.

### Alphabet

ASCII biological alphabet with pre-computed lookup tables and dynamic singleton caching.

Provides pre-computed 256-byte lookup tables: - `kmer_lut`: Maps ASCII characters to dense \\(\[0 \\dots K-1\]\\) integers (with unknown characters mapped to \\(K\\)) for on-the-fly rolling k-mer and syncmer bit-packing in L1 cache. - `ascii_lut`: Maps ASCII characters to canonical uppercase / reduced group representative ASCII bytes. - `complement_lut`: 256-element byte translation table for nucleotide complementation.

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `symbols` | `bytes` | Canonical uppercase ASCII symbols representing distinct alphabet states. |
| `complement` | `bytes \| None` | Complemented symbols corresponding to `symbols` (for nucleotide alphabets). |
| `bits_per_char` | `int` | Exact bit width required to represent characters (\\((\\text{len}-1).\\text{bit\\\_length}()\\)). |
| `default_k` | `int` | Recommended default k-mer size for indexing. |
| `supports_canonical` | `bool` | Whether reverse-complement canonicalization is valid. |
| `kmer_lut` | `ndarray` | Read-only 256-byte array for \\(O(1)\\) dense integer mapping. |
| `ascii_lut` | `ndarray` | Read-only 256-byte array for \\(O(1)\\) ASCII normalization / reduction. |
| `complement_lut` | `ndarray \| None` | Read-only 256-byte array for nucleotide complementation. |

Methods:

| Name | Description |
| --- | --- |
| `masker` | Calculate k-mer bit-shift parameters and word mask for sequence hashing. |
| `encode` | Encode ASCII sequence bytes into dense integer values \[0..K-1\]. |
| `reduce` | Perform vectorized reduction of ASCII sequence bytes into reduced representative ASCII characters. |

#### masker

```python
masker(k: int) -> tuple[int, int, type[uint32 | uint64]]
```

Calculate k-mer bit-shift parameters and word mask for sequence hashing.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `k` | `int` | K-mer length. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `tuple[int, int, type[uint32 \| uint64]]` | tuple\[int, int, type\[np.uint32 \| np.uint64\]\]: Tuple of (bits\_per\_char, bitmask, integer\_dtype). |

#### encode

```python
encode(
    seq: bytes
    | bytearray
    | memoryview
    | ndarray[tuple[int], dtype[uint8]],
) -> ndarray[tuple[int], dtype[uint8]]
```

Encode ASCII sequence bytes into dense integer values \[0..K-1\].

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `seq` | `bytes \| bytearray \| memoryview \| ndarray` | Input sequence bytes or 1D array. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `ndarray[tuple[int], dtype[uint8]]` | np.ndarray\[tuple\[int\], np.dtype\[np.uint8\]\]: Array of dense integer indices. |

#### reduce

```python
reduce(
    seq: bytes
    | bytearray
    | memoryview
    | ndarray[tuple[int], dtype[uint8]],
) -> bytes | ndarray[tuple[int], dtype[uint8]]
```

Perform vectorized reduction of ASCII sequence bytes into reduced representative ASCII characters.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `seq` | `bytes \| bytearray \| memoryview \| ndarray` | Input sequence bytes or 1D array. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `bytes \| ndarray[tuple[int], dtype[uint8]]` | bytes \| np.ndarray\[tuple\[int\], np.dtype\[np.uint8\]\]: Reduced sequence(s) in ASCII format. |

### GeneticCode

NCBI Translation Table representation for codon translation and complementation.

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `table_id` | `int` | NCBI translation table integer identifier. |
| `name` | `bytes` | Descriptive byte-string name of the genetic code. |
| `start_codons` | `frozenset[bytes]` | Valid 3-base start codon byte triplets. |
| `stop_codons` | `frozenset[bytes]` | Valid 3-base stop codon byte triplets. |

Methods:

| Name | Description |
| --- | --- |
| `from_table` | Resolve a `GeneticCode` instance by NCBI translation table ID (`1, 11`) or byte-string name. |
| `is_coding` | Check if a nucleotide sequence starts with a valid start codon and ends with a stop codon. |
| `translate` | Translate a single nucleotide sequence into an ASCII protein sequence. |
| `translate_ragged` | Translate a ragged batch of nucleotide sequences in parallel. |

#### from\_table

```python
from_table(table: int | bytes | GeneticCode) -> GeneticCode
```

Resolve a `GeneticCode` instance by NCBI translation table ID (`1, 11`) or byte-string name.

#### is\_coding

```python
is_coding(seq: bytes) -> bool
```

Check if a nucleotide sequence starts with a valid start codon and ends with a stop codon.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `seq` | `bytes` | Nucleotide sequence to check. | *required* |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `bool` | `bool` | True if length \>= 3 and starts with a valid start codon and ends with a stop codon. |

#### translate

```python
translate(
    seq: bytes
    | bytearray
    | memoryview
    | ndarray[tuple[int], dtype[uint8]],
    frame: int = 0,
    to_stop: bool = False,
) -> ndarray[tuple[int], dtype[uint8]]
```

Translate a single nucleotide sequence into an ASCII protein sequence.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `seq` | `bytes \| bytearray \| memoryview \| ndarray` | Input nucleotide sequence. | *required* |
| `frame` | `int` | Reading frame offset (0, 1, or 2). Defaults to 0. | `0` |
| `to_stop` | `bool` | If True, truncates translation at the first stop codon (\*). Defaults to False. | `False` |

Returns:

| Type | Description |
| --- | --- |
| `ndarray[tuple[int], dtype[uint8]]` | np.ndarray\[tuple\[int\], np.dtype\[np.uint8\]\]: Translated protein sequence in ASCII format. |

#### translate\_ragged

```python
translate_ragged(
    seqs: ndarray[tuple[int], dtype[uint8]],
    offsets: ndarray[tuple[int], dtype[int32]],
    lengths: ndarray[tuple[int], dtype[int32]],
    frames: ndarray[tuple[int], dtype[int8]] | None = None,
    to_stop: bool = False,
) -> tuple[
    ndarray[tuple[int], dtype[uint8]],
    ndarray[tuple[int], dtype[int32]],
    ndarray[tuple[int], dtype[int32]],
]
```

Translate a ragged batch of nucleotide sequences in parallel.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `seqs` | `ndarray[tuple[int], dtype[uint8]]` | Concatenated nucleotide sequence bytes. | *required* |
| `offsets` | `ndarray[tuple[int], dtype[int32]]` | Start offsets per sequence. | *required* |
| `lengths` | `ndarray[tuple[int], dtype[int32]]` | Sequence lengths. | *required* |
| `frames` | `ndarray[tuple[int], dtype[int8]] \| None` | Reading frame offsets (0, 1, or 2) per sequence. | `None` |
| `to_stop` | `bool` | If True, truncates translation at the first stop codon (\*). Defaults to False. | `False` |

Returns:

| Type | Description |
| --- | --- |
| `tuple[ndarray[tuple[int], dtype[uint8]], ndarray[tuple[int], dtype[int32]], ndarray[tuple[int], dtype[int32]]]` | tuple\[np.ndarray, np.ndarray, np.ndarray\]: Tuple of (out\_seqs, out\_offsets, out\_lengths) arrays. |

---

## Sequence Containers (`seroverse.core.seq.seq`)

## seq

Biological sequence data structures, SoA containers, and translation utilities.

This module provides high-performance data structures for storing, manipulating, and translating biological sequences (DNA, RNA, protein). Sequences are stored either as individual immutable `Sequence` instances or as contiguous, flat arrays in `Sequences` Structure-of-Arrays (SoA) containers.

**Key Classes**

- `Sequence`: Immutable container for a single sequence record.
- `Sequences`: Memory-efficient, Numba-accelerated SoA container.
- `GeneticCode`: NCBI genetic code translator.

Classes:

| Name | Description |
| --- | --- |
| `Sequence` | A simple, immutable container for a single biological sequence. |
| `Sequences` | A high-performance SoA container for biological sequences. |

### Sequence

Bases: `ScalarView`

A simple, immutable container for a single biological sequence.

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `id` | `bytes` | Unique identifier or name of the sequence. |
| `seq` | `bytes` | Raw sequence data (e.g. DNA, RNA, or protein). |

Methods:

| Name | Description |
| --- | --- |
| `to_fasta` | Format the sequence record as a standard FASTA byte string. |
| `translate` | Translate a nucleotide sequence into a protein sequence using the specified genetic code. |

#### to\_fasta

```python
to_fasta() -> bytes
```

Format the sequence record as a standard FASTA byte string.

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `bytes` | `bytes` | FASTA formatted byte representation of the record. |

#### translate

```python
translate(
    code: GeneticCode = bacterial,
    frame: int = 0,
    to_stop: bool = False,
) -> Sequence
```

Translate a nucleotide sequence into a protein sequence using the specified genetic code.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `code` | `GeneticCode` | Genetic code translation table to use. Defaults to `GeneticCode.bacterial`. | `bacterial` |
| `frame` | `int` | Reading frame offset (0, 1, or 2). Defaults to 0. | `0` |
| `to_stop` | `bool` | If True, truncates translation at the first stop codon (\*). Defaults to False. | `False` |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `Sequence` | `Sequence` | New sequence record containing the translated protein sequence. |

### Sequences

Bases: `RaggedArrayContainer[Sequence, 'Sequences']`

A high-performance SoA container for biological sequences.

Stores multiple sequences in a flat, contiguous memory layout using a 1D NumPy array of unsigned 8-bit integers (`np.uint8`). Individual sequences are accessed via parallel arrays of offsets and lengths.

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `ids` | `BytesArray` | 1D byte string array of identifiers for each sequence. |
| `seqs` | `UInt8Array` | Single flat 1D array containing all sequence byte data concatenated. |
| `offsets` | `Int32Array` | 1D array of start indices in `seqs`. |
| `lengths` | `Int32Array` | 1D array of sequence lengths. |

Methods:

| Name | Description |
| --- | --- |
| `to_fasta` | Format the entire batch as a single FASTA byte string. |
| `unique` | Return a new Sequences container containing only unique sequences. |
| `index_of` | Return the integer index or 1D index array corresponding to the given identifier(s). |
| `by_ids` | Fetch sequence record(s) matching the specified identifier(s). |
| `from_bytes` | Construct Sequences from a collection of raw sequence byte strings. |
| `from_records` | Construct Sequences from a collection of Sequence objects. |
| `extract` | Vectorized sub-sequence extraction from the batch. |
| `encode` | Encode sequence bytes into dense integer values \[0..K-1\] according to the given Alphabet. |
| `reduce` | Vectorized reduction of sequence characters using a reduced Alphabet. |
| `translate` | Vectorized translation of nucleotide sequences into protein sequences. |
| `random` | Generate a batch of random sequences sampled uniformly from an `Alphabet`. |

#### internal\_stops

```python
internal_stops: BoolArray
```

Vectorized check for internal stop codons in protein sequences.

Scans each sequence for the stop codon character ('\*') before the final position using a Numba kernel.

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `BoolArray` | `BoolArray` | A 1D boolean array where True indicates presence of an internal stop. |

#### to\_fasta

```python
to_fasta(use_indices: bool = False) -> bytes
```

Format the entire batch as a single FASTA byte string.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `use_indices` | `bool` | If True, uses 0-based integer index as FASTA header (`>0`, `>1`, ...) instead of byte string `ids`. Defaults to False. | `False` |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `bytes` | `bytes` | Complete FASTA-formatted byte string containing all sequences. |

#### unique

```python
unique() -> Sequences
```

Return a new Sequences container containing only unique sequences.

Uses a Numba-accelerated 64-bit FNV-1a hash to identify unique sequences while preserving first-occurrence order.

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `Sequences` | `Sequences` | A new container with duplicate sequences removed. |

#### index\_of

```python
index_of(
    query_ids: ndarray[tuple[int], dtype[bytes_]]
    | bytes
    | bytes_
    | Iterable[bytes],
) -> ndarray[tuple[int], dtype[int32]] | int
```

Return the integer index or 1D index array corresponding to the given identifier(s).

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `query_ids` | `ndarray[bytes_] \| bytes \| bytes_ \| Iterable[bytes]` | Single sequence ID or array/iterable of IDs. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `ndarray[tuple[int], dtype[int32]] \| int` | np.ndarray \| int: Integer index for scalar queries or 1D array of indices for batch queries. |

Raises:

| Type | Description |
| --- | --- |
| `KeyError` | If any requested sequence identifier is not found. |

#### by\_ids

```python
by_ids(
    query_ids: ndarray[tuple[int], dtype[bytes_]]
    | bytes
    | bytes_
    | Iterable[bytes],
) -> Sequence | Sequences
```

Fetch sequence record(s) matching the specified identifier(s).

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `query_ids` | `ndarray[bytes_] \| bytes \| bytes_ \| Iterable[bytes]` | Single sequence ID or 1D array/iterable of IDs. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `Sequence \| Sequences` | Sequence \| Sequences: A scalar `Sequence` if a single byte identifier is passed, or a sub-`Sequences` batch matching the query IDs in order. |

Raises:

| Type | Description |
| --- | --- |
| `KeyError` | If any requested sequence identifier is not found in the container. |

#### from\_bytes

```python
from_bytes(
    seqs: list[bytes] | tuple[bytes, ...] | Iterable[bytes],
    ids: tuple[bytes, ...]
    | ndarray[tuple[int], dtype[bytes_]]
    | list[bytes]
    | None = None,
) -> Sequences
```

Construct Sequences from a collection of raw sequence byte strings.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `seqs` | `Iterable[bytes]` | Sequence byte strings. | *required* |
| `ids` | `tuple[bytes, ...] \| ndarray[bytes_] \| list[bytes] \| None` | Sequence identifiers. Defaults to integer byte strings (b"0", b"1", ...). | `None` |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `Sequences` | `Sequences` | Newly constructed sequences container. |

#### from\_records

```python
from_records(
    records: list[Sequence]
    | tuple[Sequence, ...]
    | Iterable[Sequence],
) -> Sequences
```

Construct Sequences from a collection of Sequence objects.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `records` | `Iterable[Sequence]` | Sequence objects. | *required* |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `Sequences` | `Sequences` | Newly constructed sequences container. |

#### extract

```python
extract(
    indices: ndarray[tuple[int], dtype[int32]],
    starts: ndarray[tuple[int], dtype[int32]],
    ends: ndarray[tuple[int], dtype[int32]],
    strands: ndarray[tuple[int], dtype[int8]],
    new_ids: tuple[bytes, ...]
    | ndarray[tuple[int], dtype[bytes_]]
    | list[bytes]
    | None = None,
) -> Sequences
```

Vectorized sub-sequence extraction from the batch.

Handles coordinates and reverse-complementation across multiple sequences in parallel using Numba.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `indices` | `ndarray` | 1D array specifying parent sequence index for each extraction. | *required* |
| `starts` | `ndarray` | 0-based start coordinates relative to parent sequence. | *required* |
| `ends` | `ndarray` | 0-based end coordinates relative to parent sequence. | *required* |
| `strands` | `ndarray` | Strand orientations (1 for forward, -1 for reverse-complement). | *required* |
| `new_ids` | `tuple[bytes, ...] \| ndarray \| list[bytes] \| None` | Identifiers for extracted sequences. If None, auto-generates names. | `None` |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `Sequences` | `Sequences` | New collection of extracted sub-sequences. |

#### encode

```python
encode(
    alphabet: Alphabet,
) -> ndarray[tuple[int], dtype[uint8]]
```

Encode sequence bytes into dense integer values \[0..K-1\] according to the given Alphabet.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `alphabet` | `Alphabet` | Alphabet containing precomputed kmer lookup table. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `ndarray[tuple[int], dtype[uint8]]` | np.ndarray\[tuple\[int\], np.dtype\[np.uint8\]\]: Array of dense integer indices. |

#### reduce

```python
reduce(alphabet: Alphabet) -> Sequences
```

Vectorized reduction of sequence characters using a reduced Alphabet.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `alphabet` | `Alphabet` | Reduced alphabet containing precomputed lookup tables (e.g. `Alphabet.MMSEQS12`). | *required* |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `Sequences` | `Sequences` | New collection containing reduced ASCII sequence bytes. |

#### translate

```python
translate(
    code: GeneticCode = bacterial,
    frames: ndarray[tuple[int], dtype[int8]] | None = None,
    to_stop: bool = False,
) -> Sequences
```

Vectorized translation of nucleotide sequences into protein sequences.

Translates sequences according to the provided `GeneticCode` (defaults to NCBI Translation Table 11: `GeneticCode.bacterial`).

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `code` | `GeneticCode` | Genetic code translation table to use. Defaults to `GeneticCode.bacterial`. | `bacterial` |
| `frames` | `ndarray[tuple[int], dtype[int8]] \| None` | Reading frame offsets (0, 1, or 2) per sequence. Defaults to frame 0 for all. | `None` |
| `to_stop` | `bool` | If True, truncates translation at the first stop codon (\*). Defaults to False. | `False` |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `Sequences` | `Sequences` | New collection containing translated protein sequences. |

#### random

```python
random(
    alphabet: Alphabet = DNA,
    n_seqs: int = 10,
    length: int | tuple[int, int] = (50, 250),
    rng: Generator | int | None = None,
) -> Self
```

Generate a batch of random sequences sampled uniformly from an `Alphabet`.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `alphabet` | `Alphabet` | Alphabet whose primary symbols are sampled uniformly. Defaults to `Alphabet.DNA`. | `DNA` |
| `n_seqs` | `int` | Number of sequences to generate (`n_seqs >= 0`). Defaults to `10`. | `10` |
| `length` | `int \| tuple[int, int]` | Either a fixed integer sequence length or an inclusive `(min_len, max_len)` 2-tuple sampled uniformly per sequence. Defaults to `(50, 250)`. | `(50, 250)` |
| `rng` | `Generator \| int \| None` | Optional random generator, integer seed, or `None` passed to `np.random.default_rng`. | `None` |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `Self` | `Self` | A newly generated `Sequences` container. |

---

## K-mer &amp; Randstrobe Indices (`seroverse.core.seq.kmers`)

## kmers

K-mer indexing, FracMinHash, and Randstrobe sketch construction and search.

This module provides sequence sketch indices (`BaseKmerIndex`, `FracMinHashIndex`, `RandstrobeIndex`) and Numba JIT parallel search kernels emitting `Seeds`.

Classes:

| Name | Description |
| --- | --- |
| `BaseKmerIndex` | Data-Oriented Structure-of-Arrays (SoA) container for sequence k-mer sketches. |
| `FracMinHashIndex` | Specialized index for fast sequence comparisons using FracMinHash. |
| `RandstrobeIndex` | Specialized index for fast sequence comparisons using syncmer-linked randstrobes. |

### BaseKmerIndex

Data-Oriented Structure-of-Arrays (SoA) container for sequence k-mer sketches.

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `hashes` | `ndarray[tuple[int], dtype[uint64]]` | 1D array of 64-bit sketch hashes. |
| `seq_indices` | `ndarray[tuple[int], dtype[uint32]]` | 1D array of source sequence indices. |
| `positions` | `ndarray[tuple[int], dtype[uint32]]` | 1D array of start positions in sequences. |
| `offsets` | `ndarray[tuple[int], dtype[int32]]` | 1D array of sequence record start offsets. |
| `lengths` | `ndarray[tuple[int], dtype[int32]]` | 1D array of record counts per sequence. |
| `n_seqs` | `int` | Total number of indexed sequences. |
| `is_sorted` | `bool` | True if records are sorted by hash. |
| `k` | `int` | K-mer length parameter. |
| `alphabet` | `Alphabet` | Alphabet used for sequence encoding. |
| `reduce` | `bool` | True if using a reduced alphabet mapping. |
| `lut` | `ndarray[tuple[int], dtype[uint8]] \| None` | Optional custom lookup table. |

Methods:

| Name | Description |
| --- | --- |
| `empty` | Create an empty index instance using subclass field defaults. |
| `to_sorted` | Return a copy of the index with records sorted by hash. |
| `top_hits` | Find the single best-matching target sequence for each query sequence. |
| `hits` | Find all matching target sequences or individual anchors for each query sequence. |

#### total\_records

```python
total_records: int
```

Total number of k-mer / sketch records across all sequences.

#### indptr

```python
indptr: ndarray[tuple[int], dtype[uint32]]
```

CSR-compatible \\((N + 1)\\)-length index pointer array (`[0, *cumsum(lengths)]`).

#### empty

```python
empty() -> Self
```

Create an empty index instance using subclass field defaults.

#### to\_sorted

```python
to_sorted() -> Self
```

Return a copy of the index with records sorted by hash.

#### top\_hits

```python
top_hits(
    queries: BaseKmerIndex | Sequences | None = None,
    min_score: int = 1,
    *,
    query_seqs: Sequences | None = None,
    target_seqs: Sequences | None = None,
    matrix: SubstitutionMatrix | None = None,
) -> Seeds
```

Find the single best-matching target sequence for each query sequence.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `queries` | `BaseKmerIndex \| Sequences \| None` | Query sequences or index. If None, queries itself. | `None` |
| `min_score` | `int` | Minimum match score threshold. Defaults to 1. | `1` |
| `query_seqs` | `Sequences \| None` | Optional query sequences for ungapped diagonal tie-breaking. | `None` |
| `target_seqs` | `Sequences \| None` | Optional target sequences for ungapped diagonal tie-breaking. | `None` |
| `matrix` | `SubstitutionMatrix \| None` | Substitution matrix for ungapped diagonal scoring. | `None` |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `Seeds` | `Seeds` | Matched `Seeds` collection. |

#### hits

```python
hits(
    queries: BaseKmerIndex | Sequences | None = None,
    min_score: int = 1,
    *,
    aggregate: bool = True,
    query_seqs: Sequences | None = None,
    target_seqs: Sequences | None = None,
    matrix: SubstitutionMatrix | None = None,
) -> Seeds
```

Find all matching target sequences or individual anchors for each query sequence.

When `aggregate=True` (default), uses single-pass binary search over `self.hashes` followed by per-query sorted run-length grouping and modal/consensus diagonal voting to return one consensus `Seed` per qualifying `(query, target)` pair. When `aggregate=False`, emits every individual k-mer / strobe anchor hit for qualifying `(query, target)` pairs sorted by `(query_index, target_index, t_pos, q_pos)` for direct consumption by `Chainer`.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `queries` | `BaseKmerIndex \| Sequences \| None` | Query sequence index or raw sequences. If None, queries itself. | `None` |
| `min_score` | `int` | Minimum shared k-mer count required for a `(query, target)` pair. Defaults to 1. | `1` |
| `aggregate` | `bool` | If True, aggregate hits per `(query, target)` pair into a consensus diagonal seed. If False, return all individual `(q_pos, t_pos, span)` anchor occurrences sorted for collinear chaining. Defaults to True. | `True` |
| `query_seqs` | `Sequences \| None` | Optional query sequences for ungapped diagonal tie-breaking. | `None` |
| `target_seqs` | `Sequences \| None` | Optional target sequences for ungapped diagonal tie-breaking. | `None` |
| `matrix` | `SubstitutionMatrix \| None` | Substitution matrix for ungapped diagonal scoring. | `None` |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `Seeds` | `Seeds` | Matched `Seeds` collection. |

### FracMinHashIndex

Bases: `BaseKmerIndex`

Specialized index for fast sequence comparisons using FracMinHash.

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `k` | `int` | K-mer length parameter. Defaults to 21. |
| `scaled` | `int` | FracMinHash scale factor (e.g. 100). |
| `canonical` | `bool` | True if canonical k-mers (min of fwd/rev) are hashed. |
| `bits_per_char` | `int` | Alphabet bits per character. |

Methods:

| Name | Description |
| --- | --- |
| `build` | Build a FracMinHashIndex from sequence batch. |

#### build

```python
build(
    batch: Sequences,
    k: int | None = None,
    alphabet: Alphabet = DNA,
    scaled: int = 100,
    canonical: bool | None = None,
    seed: int = 42,
    sort_by_hash: bool = False,
    lut: ndarray[tuple[int], dtype[uint8]] | None = None,
    bits_per_char: int | None = None,
    reduce: bool | None = None,
    **kwargs: object,
) -> FracMinHashIndex
```

Build a FracMinHashIndex from sequence batch.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `batch` | `Sequences` | Input sequence collection. | *required* |
| `k` | `int \| None` | K-mer length. Defaults to alphabet default\_k. | `None` |
| `alphabet` | `Alphabet` | Alphabet instance. Defaults to `Alphabet.DNA`. | `DNA` |
| `scaled` | `int` | Sampling scale factor. Defaults to 100. | `100` |
| `canonical` | `bool \| None` | True if using canonical k-mers. Defaults to alphabet.supports\_canonical. | `None` |
| `seed` | `int` | Seed for hashing. Defaults to 42. | `42` |
| `sort_by_hash` | `bool` | True to sort output records by hash. Defaults to False. | `False` |
| `lut` | `ndarray \| None` | Optional custom lookup table. | `None` |
| `bits_per_char` | `int \| None` | Bits per character. Defaults to alphabet.bits\_per\_char. | `None` |
| `reduce` | `bool \| None` | True to reduce alphabet. | `None` |
| `**kwargs` | `object` | Additional parameters. | `{}` |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `FracMinHashIndex` | `FracMinHashIndex` | Built `FracMinHashIndex` instance. |

### RandstrobeIndex

Bases: `BaseKmerIndex`

Specialized index for fast sequence comparisons using syncmer-linked randstrobes.

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `alphabet` | `Alphabet` | Alphabet used for encoding. Defaults to `Alphabet.MMSEQS12`. |
| `s` | `int` | Sub-k-mer size for open syncmer evaluation. Defaults to 5. |
| `w_min` | `int` | Minimum syncmer offset window bound. Defaults to 1. |
| `w_max` | `int` | Maximum syncmer offset window bound. Defaults to 5. |
| `reduce` | `bool` | True if using a reduced alphabet mapping. Defaults to True. |

Methods:

| Name | Description |
| --- | --- |
| `build` | Build a RandstrobeIndex from sequence batch. |

#### build

```python
build(
    batch: Sequences,
    k: int = 10,
    s: int = 5,
    w_min: int = 1,
    w_max: int = 5,
    alphabet: Alphabet = MMSEQS12,
    seed: int = 42,
    sort_by_hash: bool = False,
    lut: ndarray[tuple[int], dtype[uint8]] | None = None,
    reduce: bool | None = None,
    **kwargs: object,
) -> RandstrobeIndex
```

Build a RandstrobeIndex from sequence batch.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `batch` | `Sequences` | Input sequence collection. | *required* |
| `k` | `int` | K-mer length. Defaults to 10. | `10` |
| `s` | `int` | Sub-k-mer size. Defaults to 5. | `5` |
| `w_min` | `int` | Min syncmer window bound. Defaults to 1. | `1` |
| `w_max` | `int` | Max syncmer window bound. Defaults to 5. | `5` |
| `alphabet` | `Alphabet` | Alphabet instance. Defaults to `Alphabet.MMSEQS12`. | `MMSEQS12` |
| `seed` | `int` | Random seed. Defaults to 42. | `42` |
| `sort_by_hash` | `bool` | True to sort records by hash. Defaults to False. | `False` |
| `lut` | `ndarray \| None` | Optional alphabet lookup table. | `None` |
| `reduce` | `bool \| None` | True to reduce alphabet. | `None` |
| `**kwargs` | `object` | Additional parameters. | `{}` |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `RandstrobeIndex` | `RandstrobeIndex` | Constructed `RandstrobeIndex`. |

Raises:

| Type | Description |
| --- | --- |
| `ValueError` | If `s >= k`. |

---

## Substitution Matrices, Seeds, Pairwise Alignment &amp; Collinear Chaining (`seroverse.core.align`)

## score

Biological sequence substitution matrices and Numba-accelerated ungapped scoring kernels.

Provides `SubstitutionMatrix` with singleton caching, read-only \\(256 \\times 256\\) ASCII lookup tables (`int8`), Karlin-Altschul statistical parameters (\\(\\lambda, K\\)), and parallel Numba kernels for ungapped diagonal scoring and pair prefiltering.

Classes:

| Name | Description |
| --- | --- |
| `SubstitutionMatrix` | Immutable biological substitution matrix with a precomputed \\(256 \\times 256\\) `int8` ASCII lookup table. |

### SubstitutionMatrix

Immutable biological substitution matrix with a precomputed \\(256 \\times 256\\) `int8` ASCII lookup table.

Maps any pair of ASCII sequence bytes `(a, b)` (including lowercase bytes, alphabet aliases, stop codons `*`, and unknown characters) to an `int8` substitution score in \\(O(1)\\) time.

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `alphabet` | `Alphabet` | Underlying biological `Alphabet`. |
| `lut` | `ndarray` | Read-only `(256, 256)` `int8` substitution score lookup table. |
| `lambda_` | `float` | Karlin-Altschul ungapped/gapped scale parameter \\(\\lambda\\). |
| `k` | `float` | Karlin-Altschul parameter \\(K\\). |
| `ln_k` | `float` | Precomputed natural logarithm \\(\\ln(K)\\). |
| `name` | `bytes \| None` | Canonical byte-string identifier (e.g. `b"BLOSUM62"`). |

Methods:

| Name | Description |
| --- | --- |
| `from_match_mismatch` | Construct a `SubstitutionMatrix` from uniform match and mismatch scores over `alphabet`. |
| `bitscore` | Compute Karlin-Altschul bitscore(s) \\(B = (\\lambda S - \\ln K) / \\ln 2\\). |

#### from\_match\_mismatch

```python
from_match_mismatch(
    alphabet: Alphabet = DNA,
    match: int = 2,
    mismatch: int = -3,
    *,
    unknown_score: int = -1,
    default_score: int = -128,
    lambda_: float = 0.625,
    k: float = 0.41,
    name: bytes | None = None,
) -> Self
```

Construct a `SubstitutionMatrix` from uniform match and mismatch scores over `alphabet`.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `alphabet` | `Alphabet` | Target biological alphabet. Defaults to `Alphabet.DNA`. | `DNA` |
| `match` | `int` | Score for identical characters (`a == b`). Defaults to `2`. | `2` |
| `mismatch` | `int` | Score for distinct characters (`a != b`). Defaults to `-3`. | `-3` |
| `unknown_score` | `int` | Score for ambiguous/wildcard characters (`N` or `X`). Defaults to `-1`. | `-1` |
| `default_score` | `int` | Score for out-of-alphabet characters. Defaults to `-128`. | `-128` |
| `lambda_` | `float` | Karlin-Altschul \\(\\lambda\\) parameter. Defaults to `0.625`. | `0.625` |
| `k` | `float` | Karlin-Altschul \\(K\\) parameter. Defaults to `0.41`. | `0.41` |
| `name` | `bytes \| None` | Optional byte-string name. | `None` |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `Self` | `Self` | Cached `SubstitutionMatrix` instance. |

#### bitscore

```python
bitscore(scores: float) -> float
```

```python
bitscore(
    scores: ndarray[tuple[int], dtype[Any]],
) -> ndarray[tuple[int], dtype[float32]]
```

```python
bitscore(
    scores: float | ndarray[tuple[int], dtype[Any]],
) -> float | ndarray[tuple[int], dtype[float32]]
```

Compute Karlin-Altschul bitscore(s) \\(B = (\\lambda S - \\ln K) / \\ln 2\\).

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `scores` | `float \| ndarray` | Raw alignment score(s). | *required* |

Returns:

| Type | Description |
| --- | --- |
| `float \| ndarray[tuple[int], dtype[float32]]` | float \| np.ndarray\[tuple\[int\], np.dtype\[np.float32\]\]: Non-negative bitscore(s). |

## seeds

Alignment seed and chaining anchor Structure-of-Arrays (SoA) batch containers.

This module provides `Seed` and `Seeds` for representing both pair-level consensus diagonal seeds and unaggregated multi-anchor hits, along with Numba-accelerated local ungapped diagonal refinement.

Classes:

| Name | Description |
| --- | --- |
| `Seed` | Alignment seed / anchor representing a matching region between query and target. |
| `Seeds` | Structure-of-Arrays (SoA) batch container for alignment seeds and chaining anchors. |

### Seed

Bases: `ScalarView`

Alignment seed / anchor representing a matching region between query and target.

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `query_index` | `int` | Index of the query sequence. |
| `target_index` | `int` | Index of the target sequence. |
| `score` | `int` | Match score (shared k-mer count when aggregated, or anchor weight `k` when unaggregated). |
| `offset` | `int` | Diagonal offset calculated as `q_pos - t_pos`. |
| `q_pos` | `int` | 0-based start coordinate on the query sequence. Defaults to `0`. |
| `t_pos` | `int` | 0-based start coordinate on the target sequence. Defaults to `0`. |
| `span` | `int` | Anchor match span in residues/bases. Defaults to `1`. |

### Seeds

Bases: `BatchedContainer[Seed, 'Seeds']`

Structure-of-Arrays (SoA) batch container for alignment seeds and chaining anchors.

Unifies aggregated pair-level seeds (1 consensus diagonal per `(query, target)` pair) and unaggregated multi-anchor hits (all `(q_pos, t_pos, span)` seed occurrences per pair) in a single container without redundancy.

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `query_indices` | `UInt32Array` | 1D array of query sequence indices. |
| `target_indices` | `UInt32Array` | 1D array of target sequence indices. |
| `scores` | `UInt32Array` | 1D array of seed/anchor scores. |
| `offsets` | `Int32Array` | 1D array of diagonal offsets (`q_pos - t_pos`). |
| `q_pos` | `Int32Array` | 1D array of 0-based query start positions. |
| `t_pos` | `Int32Array` | 1D array of 0-based target start positions. |
| `spans` | `UInt16Array` | 1D array of anchor match lengths (`k`). |

Methods:

| Name | Description |
| --- | --- |
| `top_hits` | Reduce the batch to only the highest-scoring seed for each query. |
| `extract_sequences` | Extract parallel batches of query and target sequences mapped by this seed batch. |
| `rescore_diagonals` | Refine diagonal `offsets` by scoring local ungapped homology within `[offset - window, offset + window]`. |

#### top\_hits

```python
top_hits(min_score: int = 1) -> Seeds
```

Reduce the batch to only the highest-scoring seed for each query.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `min_score` | `int` | Minimum match score threshold. Defaults to 1. | `1` |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `Seeds` | `Seeds` | Filtered `Seeds` collection containing top hit per query. |

#### extract\_sequences

```python
extract_sequences(
    queries: Sequences, targets: Sequences
) -> tuple[Sequences, Sequences]
```

Extract parallel batches of query and target sequences mapped by this seed batch.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `queries` | `Sequences` | Source collection of query sequences. | *required* |
| `targets` | `Sequences` | Source collection of target sequences. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `tuple[Sequences, Sequences]` | tuple\[Sequences, Sequences\]: Paired query and target sequence collections. |

#### rescore\_diagonals

```python
rescore_diagonals(
    queries: Sequences,
    targets: Sequences,
    matrix: SubstitutionMatrix = BLOSUM62,
    window: int = 16,
) -> Seeds
```

Refine diagonal `offsets` by scoring local ungapped homology within `[offset - window, offset + window]`.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `queries` | `Sequences` | Query sequences collection. | *required* |
| `targets` | `Sequences` | Target sequences collection. | *required* |
| `matrix` | `SubstitutionMatrix` | Substitution matrix for ungapped diagonal scoring. Defaults to `SubstitutionMatrix.BLOSUM62`. | `BLOSUM62` |
| `window` | `int` | Half-window search radius around each seed's initial diagonal offset. Defaults to 16. | `16` |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `Seeds` | `Seeds` | New `Seeds` batch with refined `offsets`. |

## pairwise

Pairwise sequence alignment algorithms, prefiltering engines, and SoA containers.

This module provides high-performance pairwise sequence alignment capabilities supporting three alignment engines: - `"block"` (default): Adaptive block-shifting Smith-Waterman-Gotoh (`block-aligner` style) with dynamic per-row window steering and X-drop termination. - `"wfa"`: Affine Wavefront Alignment (WFA2, Marco-Sola et al.) with greedy exact-match extension and adaptive wavefront pruning. - `"banded"`: Classic static-band Smith-Waterman-Gotoh with rolling-row bit-packed traceback.

It also provides MMseqs2-style reduced-alphabet 4-mer CSR + ungapped diagonal prefiltering and piecewise anchor-guided chain alignment.

**Key Classes**

- `PairwiseAlignment`: Immutable container for a single result.
- `PairwiseAlignments`: Batched SoA container for results.
- `PairwiseAligner`: Multi-mode pairwise alignment &amp; prefilter engine.

Classes:

| Name | Description |
| --- | --- |
| `PairwiseAlignment` | A lightweight, immutable container for the results of a single pairwise sequence alignment. |
| `PairwiseAlignments` | A high-performance SoA container for the results of multiple pairwise alignments. |
| `PairwiseAligner` | A high-performance, batched pairwise sequence aligner and MMseqs2-style prefilter engine. |

### PairwiseAlignment

Bases: `ScalarView`

A lightweight, immutable container for the results of a single pairwise sequence alignment.

This class holds summary statistics and coordinates for an alignment between a single query and target sequence. It is typically produced by indexing into a `PairwiseAlignments` collection.

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `score` | `int` | Final alignment score calculated using the substitution matrix and gap penalties. |
| `matches` | `int` | Total number of matching residues/bases. |
| `mismatches` | `int` | Total number of mismatched residues/bases. |
| `gaps` | `int` | Total number of gap characters (insertions or deletions). |
| `q_start` | `int` | 0-based start coordinate on query sequence (inclusive). |
| `q_end` | `int` | 0-based end coordinate on query sequence (exclusive). |
| `t_start` | `int` | 0-based start coordinate on target sequence (inclusive). |
| `t_end` | `int` | 0-based end coordinate on target sequence (exclusive). |

Methods:

| Name | Description |
| --- | --- |
| `bitscore` | Calculate the Karlin-Altschul bitscore of the alignment using `matrix`. |

#### pident

```python
pident: float
```

Calculate the percent identity of the aligned region.

Percent identity is defined as `(matches / (matches + mismatches + gaps)) * 100.0`.

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `float` | `float` | Percent identity value between 0.0 and 100.0, or 0.0 if alignment length is zero. |

#### bitscore

```python
bitscore(matrix: SubstitutionMatrix = BLOSUM62) -> float
```

Calculate the Karlin-Altschul bitscore of the alignment using `matrix`.

Uses the substitution matrix parameters (\\(\\lambda, K\\)): \\(B = (\\lambda S - \\ln K) / \\ln 2\\) for \\(S \> 0\\), else \\(0.0\\).

### PairwiseAlignments

Bases: `BatchedContainer[PairwiseAlignment, 'PairwiseAlignments']`

A high-performance SoA container for the results of multiple pairwise alignments.

This class stores alignment statistics in a Structure-of-Arrays (SoA) layout using 1D NumPy arrays.

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `scores` | `Int32Array` | 1D array of alignment scores. |
| `matches` | `Int32Array` | 1D array of match counts. |
| `mismatches` | `Int32Array` | 1D array of mismatch counts. |
| `gaps` | `Int32Array` | 1D array of gap counts. |
| `q_starts` | `Int32Array` | 1D array of query start coordinates. |
| `q_ends` | `Int32Array` | 1D array of query end coordinates. |
| `t_starts` | `Int32Array` | 1D array of target start coordinates. |
| `t_ends` | `Int32Array` | 1D array of target end coordinates. |

Methods:

| Name | Description |
| --- | --- |
| `bitscores` | Calculate Karlin-Altschul bitscores for all alignments in the batch using `matrix`. |

#### pidents

```python
pidents: Float32Array
```

Calculate percent identity for all alignments in the batch in a vectorized manner.

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `Float32Array` | `Float32Array` | 1D array of percent identity values. |

#### bitscores

```python
bitscores(
    matrix: SubstitutionMatrix = BLOSUM62,
) -> Float32Array
```

Calculate Karlin-Altschul bitscores for all alignments in the batch using `matrix`.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `matrix` | `SubstitutionMatrix` | Substitution matrix used for \\((\\lambda, K)\\) parameters. Defaults to `SubstitutionMatrix.BLOSUM62`. | `BLOSUM62` |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `Float32Array` | `Float32Array` | 1D array of bitscores (\\(\\ge 0.0\\)). |

### PairwiseAligner

A high-performance, batched pairwise sequence aligner and MMseqs2-style prefilter engine.

Supports three execution modes: - `"block"` (default): Adaptive block-shifting Smith-Waterman-Gotoh (`block-aligner` style) that dynamically shifts the active diagonal block per row to track arbitrary indels without falling out of a rigid static band, with `x_drop` early termination. - `"wfa"`: Affine Wavefront Alignment (WFA2, Marco-Sola et al.) with greedy exact-match slides and adaptive wavefront pruning in \\(O(N + s^2)\\) time. - `"banded"`: Classic static-band Smith-Waterman-Gotoh within a fixed `2*k + 1` diagonal band.

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `matrix` | `SubstitutionMatrix` | Substitution matrix for scoring. Defaults to `SubstitutionMatrix.BLOSUM62`. |
| `gap_open` | `int` | Penalty for opening a new gap. Defaults to 11. |
| `gap_extend` | `int` | Penalty for extending an existing gap. Defaults to 1. |
| `k` | `int` | Bandwidth parameter (`2*k+1` diagonals). Defaults to 20. |
| `mode` | `Literal['block', 'banded', 'wfa']` | Alignment algorithm mode. Defaults to `"block"`. |
| `block_size` | `int` | Half-block width parameter for `"block"` and `"wfa"` pruning. Defaults to 32. |
| `x_drop` | `int` | X-drop score threshold for early termination and block shifting. Defaults to 50. |

Methods:

| Name | Description |
| --- | --- |
| `align_seeds` | Convenience method to extract and align specific sequence pairs mapped by seeds. |
| `align_chains` | Perform piecewise anchor-guided base alignment for a batch of collinear `Chains`. |
| `prefilter` | Run MMseqs2-style 4-mer CSR + ungapped diagonal prefiltering to discover candidate homologous pairs. |
| `search` | Execute a two-stage MMseqs2-style prefilter followed by Smith-Waterman-Gotoh / WFA alignment. |

#### align\_seeds

```python
align_seeds(
    queries: Sequences, targets: Sequences, seeds: Seeds
) -> PairwiseAlignments
```

Convenience method to extract and align specific sequence pairs mapped by seeds.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `queries` | `Sequences` | Full collection of query sequences. | *required* |
| `targets` | `Sequences` | Full collection of target sequences. | *required* |
| `seeds` | `Seeds` | Seed collection mapping specific query sequences to target sequences. | *required* |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `PairwiseAlignments` | `PairwiseAlignments` | Alignment results parallel to the provided seeds. |

#### align\_chains

```python
align_chains(
    queries: Sequences, targets: Sequences, chains: Chains
) -> PairwiseAlignments
```

Perform piecewise anchor-guided base alignment for a batch of collinear `Chains`.

Aligns inter-anchor gaps using pinned Affine Wavefront Alignment (WFA2) and extends left and right chain ends using adaptive block X-drop Smith-Waterman-Gotoh.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `queries` | `Sequences` | Full collection of query sequences. | *required* |
| `targets` | `Sequences` | Full collection of target sequences. | *required* |
| `chains` | `Chains` | Collinear anchor chains mapping query sequences to target sequences. | *required* |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `PairwiseAlignments` | `PairwiseAlignments` | Base-level alignment results parallel to `chains`. |

#### prefilter

```python
prefilter(
    queries: Sequences,
    targets: Sequences | None = None,
    *,
    min_ungapped_score: int = 42,
    min_coverage: float = 0.0,
    upper_triangle: bool | None = None,
) -> Seeds
```

Run MMseqs2-style 4-mer CSR + ungapped diagonal prefiltering to discover candidate homologous pairs.

Builds a direct \\(12^4 = 20,736\\)-bucket CSR inverted index of 4-mers (`Alphabet.MMSEQS12` for proteins or `Alphabet.DNA` for nucleotides) on `targets` (or `queries` for self-search) and evaluates ungapped diagonal scores using `self.matrix` on shared 4-mer diagonals.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `queries` | `Sequences` | Query sequences. | *required* |
| `targets` | `Sequences \| None` | Target sequences. If `None`, performs self-search on `queries`. | `None` |
| `min_ungapped_score` | `int` | Minimum local ungapped diagonal score to retain a pair. Defaults to `42`. | `42` |
| `min_coverage` | `float` | Minimum length ratio \\(\\min(L\_q, L\_t) / \\max(L\_q, L\_t)\\). Defaults to `0.0`. | `0.0` |
| `upper_triangle` | `bool \| None` | If `True`, restricts output to pairs with `q_idx < t_idx`. Defaults to `True` when `targets is None` and `False` otherwise. | `None` |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `Seeds` | `Seeds` | Candidate `Seeds` containing `(query_indices, target_indices, scores, offsets, q_pos, t_pos, spans)`. |

#### search

```python
search(
    queries: Sequences,
    targets: Sequences | None = None,
    *,
    min_ungapped_score: int = 42,
    min_coverage: float = 0.0,
    upper_triangle: bool | None = None,
    banded: bool = True,
) -> tuple[Seeds, PairwiseAlignments]
```

Execute a two-stage MMseqs2-style prefilter followed by Smith-Waterman-Gotoh / WFA alignment.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `queries` | `Sequences` | Query sequences. | *required* |
| `targets` | `Sequences \| None` | Target sequences. If `None`, performs self-search on `queries`. | `None` |
| `min_ungapped_score` | `int` | Minimum ungapped diagonal score threshold for Stage 1. Defaults to `42`. | `42` |
| `min_coverage` | `float` | Minimum sequence length ratio filter. Defaults to `0.0`. | `0.0` |
| `upper_triangle` | `bool \| None` | Restrict to `q_idx < t_idx` (defaults to `True` when `targets is None`). | `None` |
| `banded` | `bool` | If `True` (default), seeds the aligner with the Stage 1 diagonal offsets. If `False`, runs unseeded alignment on the prefiltered pairs. | `True` |

Returns:

| Type | Description |
| --- | --- |
| `tuple[Seeds, PairwiseAlignments]` | tuple\[Seeds, PairwiseAlignments\]: Parallel `(seeds, alignments)` for all candidate pairs passing Stage 1. |

## chaining

Collinear anchor chaining (`minimap2`-style concave-gap DP) and ragged SoA containers.

This module provides an Object-Oriented and Data-Oriented Structure-of-Arrays (SoA) collinear anchor chaining system inspired by `minimap2` (Li, 2018): - `Chain`: Immutable scalar view of a single collinear chain. - `Chains`: Ragged SoA batch container (`RaggedArrayContainer`) storing variable-length anchor chains across sequence pairs. - `Chainer`: Parallel Numba JIT collinear chaining and piecewise WFA2 + adaptive block X-drop base-alignment engine.

Classes:

| Name | Description |
| --- | --- |
| `Chain` | Immutable scalar view of a single collinear anchor chain between a query and target sequence. |
| `Chains` | Ragged Structure-of-Arrays (SoA) batch container for collinear anchor chains. |
| `Chainer` | Collinear anchor chaining and piecewise alignment engine (`minimap2`-style concave-gap DP). |

### Chain

Bases: `ScalarView`

Immutable scalar view of a single collinear anchor chain between a query and target sequence.

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `query_index` | `int` | Index of the query sequence. |
| `target_index` | `int` | Index of the target sequence. |
| `score` | `int` | Collinear chaining dynamic programming score. |
| `q_start` | `int` | 0-based start coordinate of the first anchor on the query sequence. |
| `q_end` | `int` | 0-based exclusive end coordinate of the last anchor on the query sequence. |
| `t_start` | `int` | 0-based start coordinate of the first anchor on the target sequence. |
| `t_end` | `int` | 0-based exclusive end coordinate of the last anchor on the target sequence. |
| `is_primary` | `bool` | True if classified as a primary chain on the query sequence. |
| `q_pos` | `Int32Array` | 1D array of anchor query start coordinates. |
| `t_pos` | `Int32Array` | 1D array of anchor target start coordinates. |
| `spans` | `UInt16Array` | 1D array of anchor match spans (`k`). |

#### n\_anchors

```python
n_anchors: int
```

Return the number of anchors in this chain.

#### offset

```python
offset: int
```

Return the initial diagonal offset `q_start - t_start` of this chain.

#### seeds

```python
seeds: Seeds
```

Return the anchors belonging to this chain as a `Seeds` batch.

### Chains

Bases: `RaggedArrayContainer[Chain, 'Chains']`

Ragged Structure-of-Arrays (SoA) batch container for collinear anchor chains.

Stores per-chain summary arrays (`query_indices`, `target_indices`, `scores`, `q_starts`, `q_ends`, `t_starts`, `t_ends`, `is_primary`) alongside CSR-style `offsets` and `lengths` indexing into flat concatenated anchor arrays (`anchor_q_pos`, `anchor_t_pos`, `anchor_spans`).

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `query_indices` | `UInt32Array` | 1D array of query sequence indices. |
| `target_indices` | `UInt32Array` | 1D array of target sequence indices. |
| `scores` | `Int32Array` | 1D array of chaining DP scores. |
| `q_starts` | `Int32Array` | 1D array of chain query start coordinates. |
| `q_ends` | `Int32Array` | 1D array of chain query end coordinates. |
| `t_starts` | `Int32Array` | 1D array of chain target start coordinates. |
| `t_ends` | `Int32Array` | 1D array of chain target end coordinates. |
| `is_primary` | `BoolArray` | 1D boolean array of primary chain flags. |
| `offsets` | `Int32Array` | 1D array of start indices into anchor arrays. |
| `lengths` | `Int32Array` | 1D array of anchor counts per chain. |
| `anchor_q_pos` | `Int32Array` | Concatenated 1D array of anchor query positions. |
| `anchor_t_pos` | `Int32Array` | Concatenated 1D array of anchor target positions. |
| `anchor_spans` | `UInt16Array` | Concatenated 1D array of anchor spans. |

Methods:

| Name | Description |
| --- | --- |
| `primary` | Return only primary chains (`self[self.is_primary]`). |
| `top_chains` | Select the single highest-scoring chain for each unique query sequence. |
| `to_seeds` | Convert chains into pair-level consensus `Seeds`. |
| `extract_sequences` | Extract parallel batches of query and target sequences mapped by this `Chains` batch. |

#### total\_anchors

```python
total_anchors: int
```

Return the total number of anchors across all chains.

#### diagonal\_offsets

```python
diagonal_offsets: Int32Array
```

Return the 1D array of initial diagonal offsets `q_starts - t_starts` for each chain.

#### primary

```python
primary() -> Chains
```

Return only primary chains (`self[self.is_primary]`).

#### top\_chains

```python
top_chains() -> Chains
```

Select the single highest-scoring chain for each unique query sequence.

#### to\_seeds

```python
to_seeds() -> Seeds
```

Convert chains into pair-level consensus `Seeds`.

#### extract\_sequences

```python
extract_sequences(
    queries: Sequences, targets: Sequences
) -> tuple[Sequences, Sequences]
```

Extract parallel batches of query and target sequences mapped by this `Chains` batch.

### Chainer

Collinear anchor chaining and piecewise alignment engine (`minimap2`-style concave-gap DP).

Chains unaggregated `Seeds` (produced by `index.hits(queries, aggregate=False)`) into collinear `Chains` using a concave gap penalty function and `max_skip` predecessor pruning, classifies primary vs secondary chains, and performs piecewise base-level alignment via WFA2 + adaptive block X-drop.

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `max_dist_x` | `int` | Maximum target distance between consecutive anchors in a chain. Defaults to 5000. |
| `max_dist_y` | `int` | Maximum query distance between consecutive anchors in a chain. Defaults to 5000. |
| `max_band` | `int` | Maximum diagonal shift \\(\|(q\_i - q\_j) - (t\_i - t\_j)\|\\) between chained anchors. Defaults to 500. |
| `min_cnt` | `int` | Minimum number of anchors required to form a valid chain. Defaults to 2. |
| `min_score` | `int` | Minimum chaining DP score required to emit a chain. Defaults to 20. |
| `gap_scale` | `float` | Concave gap penalty scaling multiplier. Defaults to 1.0. |
| `max_skip` | `int` | Heuristic predecessor pruning threshold. Defaults to 25. |
| `mask_level` | `float` | Minimum query overlap ratio to mask a lower-scoring chain as secondary. Defaults to 0.5. |

Methods:

| Name | Description |
| --- | --- |
| `align` | Perform piecewise anchor-guided base alignment for each chain in `chains`. |
| `search` | Execute a full `minimap2`-style seed-chain-align search pipeline. |

#### align

```python
align(
    queries: Sequences,
    targets: Sequences,
    chains: Chains,
    aligner: PairwiseAligner | None = None,
) -> PairwiseAlignments
```

Perform piecewise anchor-guided base alignment for each chain in `chains`.

Uses WFA2 for inter-anchor gaps and adaptive block X-drop extension at chain ends.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `queries` | `Sequences` | Query sequences collection. | *required* |
| `targets` | `Sequences` | Target sequences collection. | *required* |
| `chains` | `Chains` | Collinear chains to align at the base/residue level. | *required* |
| `aligner` | `PairwiseAligner \| None` | Optional `PairwiseAligner` providing scoring matrix and gap penalties. | `None` |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `PairwiseAlignments` | `PairwiseAlignments` | Base-level alignment statistics parallel to `chains`. |

#### search

```python
search(
    queries: Sequences,
    index: BaseKmerIndex,
    targets: Sequences,
    aligner: PairwiseAligner | None = None,
    *,
    min_seed_score: int = 1,
    primary_only: bool = True,
) -> tuple[Chains, PairwiseAlignments]
```

Execute a full `minimap2`-style seed-chain-align search pipeline.

Extracts unaggregated anchors via `index.hits(queries, min_score=min_seed_score, aggregate=False)`, chains them with concave-gap DP, optionally filters to primary chains, and performs piecewise WFA2 + adaptive block X-drop base alignment.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `queries` | `Sequences` | Query sequences. | *required* |
| `index` | `BaseKmerIndex` | Sorted k-mer / syncmer / randstrobe index built on `targets`. | *required* |
| `targets` | `Sequences` | Target sequences. | *required* |
| `aligner` | `PairwiseAligner \| None` | Optional `PairwiseAligner` for scoring parameters. Defaults to `PairwiseAligner(matrix=index._default_matrix())`. | `None` |
| `min_seed_score` | `int` | Minimum anchor hits per `(query, target)` pair before chaining. Defaults to 1. | `1` |
| `primary_only` | `bool` | If True (default), restricts output to primary chains (`chains.primary()`). | `True` |

Returns:

| Type | Description |
| --- | --- |
| `tuple[Chains, PairwiseAlignments]` | tuple\[Chains, PairwiseAlignments\]: Parallel `(chains, alignments)` for all discovered homologous chains. |

---

## Sequence Clustering (`seroverse.core.seq.clustering`)

## clustering

Sequence clustering algorithms, ragged SoA data structures, and Numba kernels.

Provides high-performance sequence clustering (`Clusterer`) and ragged Structure-of-Arrays cluster containers (`Clusters`, `Cluster`) combining sparse syncmer-linked randstrobe pre-filtering, parallel banded Smith-Waterman-Gotoh alignment, and sub-millisecond Numba greedy set-cover / CD-HIT clustering.

Classes:

| Name | Description |
| --- | --- |
| `Cluster` | Scalar view of a single sequence cluster. |
| `Clusters` | Ragged Structure-of-Arrays (SoA) container for sequence clustering results. |
| `Clusterer` | High-performance sequence clustering engine. |

### Cluster

Bases: `ScalarView`

Scalar view of a single sequence cluster.

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `representative` | `int` | Sequence index of the cluster centroid in the source collection. |
| `members` | `Int32Array` | 1D array of sequence indices belonging to this cluster. |

### Clusters

Bases: `RaggedArrayContainer[Cluster, 'Clusters']`

Ragged Structure-of-Arrays (SoA) container for sequence clustering results.

Stores centroid representative indices (`representatives`) and variable-length member sequence indices in a flat contiguous array (`members`) indexed by `offsets` and `lengths` for \\(O(1)\\) cluster slicing and member lookup.

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `representatives` | `Int32Array` | 1D array of sequence indices representing the centroid of each cluster. |
| `members` | `Int32Array` | Flat 1D array of member sequence indices concatenated across all clusters. |
| `offsets` | `Int32Array` | Starting index into `members` for each cluster. |
| `lengths` | `Int32Array` | Number of member sequences in each cluster. |

Methods:

| Name | Description |
| --- | --- |
| `as_csr` | Return a zero-copy \\((C \\times N)\\) sparse CSR cluster-membership incidence matrix. |
| `get_members` | Return 1D array of original sequence indices assigned to the specified cluster ID. |
| `centroids` | Extract the representative centroid sequences from the source collection. |
| `from_assignments` | Construct a `Clusters` container from flat cluster ID assignments. |

#### n\_clusters

```python
n_clusters: int
```

Total number of clusters \\(C\\).

#### n\_seqs

```python
n_seqs: int
```

Total number of clustered sequences \\(N\\).

#### sizes

```python
sizes: Int32Array
```

1D array of member counts for each cluster (alias for `lengths`).

#### representative\_indices

```python
representative_indices: Int32Array
```

1D array of centroid sequence indices (alias for `representatives`).

#### cluster\_ids

```python
cluster_ids: Int32Array
```

1D array mapping each sequence index to its cluster ID \\(c \\in \[0, C-1\]\\).

#### as\_csr

```python
as_csr(n_seqs: int | None = None) -> CSR
```

Return a zero-copy \\((C \\times N)\\) sparse CSR cluster-membership incidence matrix.

Row \\(c\\) contains `1` at column \\(i\\) for each sequence \\(i \\in \\text{members}\_c\\).

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `n_seqs` | `int \| None` | Total number of sequences \\(N\\) (columns). If `None`, inferred from `max(members) + 1`. | `None` |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `CSR` | `CSR` | Sparse \\((C \\times N)\\) `uint8` membership matrix. |

#### get\_members

```python
get_members(cluster_id: int) -> Int32Array
```

Return 1D array of original sequence indices assigned to the specified cluster ID.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `cluster_id` | `int` | 0-based integer cluster identifier. | *required* |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `Int32Array` | `Int32Array` | Zero-copy slice of sequence indices belonging to this cluster. |

#### centroids

```python
centroids(seqs: Sequences) -> Sequences
```

Extract the representative centroid sequences from the source collection.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `seqs` | `Sequences` | Source `Sequences` collection. | *required* |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `Sequences` | `Sequences` | Sliced collection containing only cluster centroids. |

#### from\_assignments

```python
from_assignments(
    cluster_ids: Int32Array,
    representatives: Int32Array,
    sizes: Int32Array,
) -> Self
```

Construct a `Clusters` container from flat cluster ID assignments.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `cluster_ids` | `Int32Array` | 1D array mapping each sequence \\(i \\in \[0, N-1\]\\) to cluster ID \\(c \\in \[0, C-1\]\\). | *required* |
| `representatives` | `Int32Array` | 1D array of centroid sequence indices (length \\(C\\)). | *required* |
| `sizes` | `Int32Array` | 1D array of member counts per cluster (length \\(C\\)). | *required* |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `Clusters` | `Self` | Ragged SoA container with \\(O(1)\\) member indexing. |

### Clusterer

High-performance sequence clustering engine.

Combines sparse syncmer-linked randstrobe pre-filtering (`RandstrobeIndex`), SIMD-parallel banded Smith-Waterman-Gotoh alignment (`PairwiseAligner`), and compiled Numba clustering algorithms to group biological sequences.

**Modes**

- `"cdhit"` (default): Length-descending greedy incremental clustering (CD-HIT style). Guarantees that full-length proteins are selected as cluster representatives rather than fragments.
- `"mcl"`: Markov Cluster Algorithm (MCL) on BLOSUM62 alignment bitscores. Sensitive to divergent functional homologs (e.g., glycosyltransferases, polymerases, flippases) via random-walk expansion and inflation (\\(I\\)).
- `"greedy_cover"`: Iterative maximum-uncovered-degree greedy set cover.
- `"upgma"`: Hierarchical average-linkage (UPGMA) clustering.
- `"connected_components"`: Transitive closure core components.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `min_identity` | `float` | Minimum pairwise sequence percent identity threshold \\(\[0.0, 100.0\]\\). Defaults to 80.0 (automatically relaxed to 25.0 when `mode="mcl"` and left at default 80.0). | `80.0` |
| `min_coverage` | `float` | Minimum alignment coverage fraction \\(\[0.0, 1.0\]\\) on both query and target. Defaults to 0.0. | `0.0` |
| `min_bitscore` | `float` | Minimum Karlin-Altschul alignment bitscore threshold. Defaults to 0.0 (automatically set to 40.0 when `mode="mcl"` and left at 0.0). | `0.0` |
| `inflation` | `float` | MCL inflation parameter \\(I \> 1.0\\) controlling cluster granularity. Defaults to 2.0. | `2.0` |
| `min_score` | `int` | Minimum shared randstrobe hash hits for alignment candidate seed filtering. Defaults to 2. | `2` |
| `k` | `int` | Strobemer seed length. Defaults to 10. | `10` |
| `s` | `int` | Strobemer sampling stride. Defaults to 5. | `5` |
| `aligner_k` | `int` | Bandwidth parameter (\\(2k + 1\\) diagonals) for banded Gotoh alignment. Defaults to 20. | `20` |
| `matrix` | `SubstitutionMatrix` | Substitution matrix for scoring and prefiltering. Defaults to `SubstitutionMatrix.BLOSUM62`. | `BLOSUM62` |
| `mode` | `Literal['cdhit', 'mcl', 'greedy_cover', 'upgma', 'connected_components']` | Clustering algorithm mode. Defaults to `"cdhit"`. | `'cdhit'` |
| `embedding_weight` | `float` | Blend weight \\(\\alpha \\in \[0.0, 1.0\]\\) for active-site motif cosine similarity in MCL edge weighting and role-gated twilight-zone rescue. Defaults to 0.0 (automatically uses 0.25 when `embeddings` are explicitly supplied to `cluster()`). | `0.0` |
| `motif_rescue_threshold` | `float` | Minimum cosine similarity \\(\[0.0, 1.0\]\\) between active-site embeddings required to trigger role-gated twilight-zone identity relaxation. Defaults to 0.75. | `0.75` |

Methods:

| Name | Description |
| --- | --- |
| `cluster` | Cluster an input batch of sequences into non-redundant representative groups. |

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `aligner` | `PairwiseAligner` | Return a configured `PairwiseAligner` instance. |

#### aligner

```python
aligner: PairwiseAligner
```

Return a configured `PairwiseAligner` instance.

#### cluster

```python
cluster(
    seqs: Sequences,
    roles: ndarray[tuple[int], dtype[Any]]
    | Sequence[int]
    | None = None,
    embeddings: ndarray[tuple[int, int], dtype[Any]]
    | None = None,
) -> Clusters
```

Cluster an input batch of sequences into non-redundant representative groups.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `seqs` | `Sequences` | Input collection of sequences to cluster. | *required* |
| `roles` | `ndarray[tuple[int], dtype[Any]] \| Sequence[int] \| None` | Optional 1D array/sequence of integer `GeneRole` IDs (length \\(N\\)). When provided, prevents clustering across incompatible known roles (`role > 0`) and, in `"mcl"` mode (or when `min_identity < 60.0`), evaluates all intra-role pairs so divergent functional homologs sharing the same role are aligned even without shared exact k-mer seeds. | `None` |
| `embeddings` | `ndarray[tuple[int, int], dtype[Any]] \| None` | Optional 2D array `(N, D)` of sequence representations (e.g., active-site `conv_max` or `task_weighted` features from `GeneRoleClassifier.transform()`). When provided, enables role-gated twilight-zone homology rescue for pairs with cosine similarity `>= self.motif_rescue_threshold` and blends cosine similarity into MCL edge weights. | `None` |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `Clusters` | `Clusters` | Ragged SoA container of cluster assignments and centroid representatives. |

---

## Graph Models, CSR Matrices, Alignment &amp; Layout (`seroverse.core.graph`)

## csr

Compressed Sparse Row (`CSR`) and multi-relational CSR (`RelationalCSR`) graph matrices.

Provides zero-SciPy, Numba-accelerated sparse adjacency representations: - `CSR`: Base 2D Compressed Sparse Row matrix supporting fast COO/dense construction, transpose (`.T`), SpMV/SpMM (`@`), sparse addition (`+`), submatrix slicing, symmetric normalized Laplacian (`.laplacian`), and connected components (`.connected_components`). - `RelationalCSR`: Subclass of `CSR` storing per-edge relation type IDs (`rel_types`) and virtual pool node indices (`virtual_nodes`) for multi-relational message passing.

Classes:

| Name | Description |
| --- | --- |
| `CSR` | Immutable 2D Compressed Sparse Row (`CSR`) matrix backed by contiguous NumPy arrays and Numba kernels. |
| `RelationalCSR` | Immutable Compressed Sparse Row (`CSR`) incoming-edge representation of a multi-relational directed graph. |

### CSR

Immutable 2D Compressed Sparse Row (`CSR`) matrix backed by contiguous NumPy arrays and Numba kernels.

Supports direct attribute access (`indptr`, `indices`, `data`, `shape`) and standard sparse matrix operations (`@`, `+`, `.T`, `.sum()`, `.toarray()`, `.tocoo()`, `.laplacian()`, `.connected_components()`, `.with_diag()`, `.without_zeros()`, submatrix slicing) without requiring `scipy.sparse`.

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `indptr` | `ndarray[tuple[int], dtype[int32]]` | 1D `int32` row pointer array of shape `(n_rows + 1,)`. |
| `indices` | `ndarray[tuple[int], dtype[int32]]` | 1D `int32` column index array of shape `(nnz,)`. |
| `data` | `ndarray[tuple[int], Any]` | 1D non-zero value array of shape `(nnz,)`. |
| `shape` | `tuple[int, int]` | 2-tuple `(n_rows, n_cols)` giving matrix dimensions. |

Methods:

| Name | Description |
| --- | --- |
| `empty` | Create an empty `CSR` matrix of shape `(n_rows, n_cols)` with zero non-zeros. |
| `from_coo` | Construct a `CSR` matrix from coordinate `(rows, cols, data)` arrays. |
| `from_dense` | Construct a `CSR` matrix from a 2D dense NumPy array. |
| `copy` | Return a deep copy of this `CSR` matrix. |
| `astype` | Cast `self.data` to `dtype` and return a `CSR` matrix. |
| `tocsr` | Return `self` (compatibility with `scipy.sparse`). |
| `tocsc` | Return `self.T` whose `.indptr` indexes columns (compatibility with `scipy.sparse`). |
| `tocoo` | Return `self`, which exposes `.row`, `.col`, and `.data` directly. |
| `toarray` | Convert this sparse `CSR` matrix into a 2D dense NumPy array. |
| `with_diag` | Return a new `CSR` matrix with diagonal entries `(i, i)` set to `values` (or removed when `values == 0`). |
| `without_zeros` | Return a new `CSR` matrix with zero-valued entries removed from `indices` and `data`. |
| `sum` | Sum matrix elements over the given axis (`None`, `0`, or `1`). |
| `laplacian` | Compute the dense (normalized or unnormalized) graph Laplacian matrix \\(L\\) in a single Numba pass. |
| `connected_components` | Compute undirected connected components `(n_components, labels)` in \\(O(N + \\text{nnz})\\) time. |
| `connected_components_from_edges` | Compute undirected connected components `(n_components, labels)` directly from flat edge arrays in \\(O(N + E)\\) time. |
| `extract_undirected_edges` | Symmetrize (`A + A.T`) and extract unique upper-triangular undirected edges `(u < v, w)`. |

#### ndim

```python
ndim: int
```

Number of matrix dimensions (always `2`).

#### nnz

```python
nnz: int
```

Total number of stored elements.

#### dtype

```python
dtype: dtype[Any]
```

Data type of stored matrix values.

#### row

```python
row: ndarray[tuple[int], dtype[int32]]
```

1D `int32` array of row indices for each stored entry (COO compatibility).

#### col

```python
col: ndarray[tuple[int], dtype[int32]]
```

1D `int32` array of column indices for each stored entry (COO compatibility).

#### T

```python
T: CSR
```

Return the transpose \\((N\_{\\text{cols}} \\times N\_{\\text{rows}})\\) as a `CSR` matrix.

#### empty

```python
empty(shape: tuple[int, int], dtype: Any = float64) -> Self
```

Create an empty `CSR` matrix of shape `(n_rows, n_cols)` with zero non-zeros.

#### from\_coo

```python
from_coo(
    rows: Sequence[int] | ndarray,
    cols: Sequence[int] | ndarray,
    data: Sequence[Any] | ndarray | None = None,
    shape: tuple[int, int] | None = None,
    dtype: Any = None,
    *,
    sum_duplicates: bool = True,
) -> Self
```

Construct a `CSR` matrix from coordinate `(rows, cols, data)` arrays.

#### from\_dense

```python
from_dense(arr: ndarray) -> Self
```

Construct a `CSR` matrix from a 2D dense NumPy array.

#### copy

```python
copy() -> Self
```

Return a deep copy of this `CSR` matrix.

#### astype

```python
astype(dtype: Any, copy: bool = True) -> CSR
```

Cast `self.data` to `dtype` and return a `CSR` matrix.

#### tocsr

```python
tocsr() -> CSR
```

Return `self` (compatibility with `scipy.sparse`).

#### tocsc

```python
tocsc() -> CSR
```

Return `self.T` whose `.indptr` indexes columns (compatibility with `scipy.sparse`).

#### tocoo

```python
tocoo() -> CSR
```

Return `self`, which exposes `.row`, `.col`, and `.data` directly.

#### toarray

```python
toarray() -> ndarray
```

Convert this sparse `CSR` matrix into a 2D dense NumPy array.

#### with\_diag

```python
with_diag(values: float = 0) -> CSR
```

Return a new `CSR` matrix with diagonal entries `(i, i)` set to `values` (or removed when `values == 0`).

#### without\_zeros

```python
without_zeros() -> CSR
```

Return a new `CSR` matrix with zero-valued entries removed from `indices` and `data`.

#### sum

```python
sum(axis: int | None = None) -> ndarray | float | int
```

Sum matrix elements over the given axis (`None`, `0`, or `1`).

#### laplacian

```python
laplacian(
    *,
    normed: bool = True,
    symmetrize_unweighted: bool = False,
) -> ndarray[tuple[int, int], dtype[float64]]
```

Compute the dense (normalized or unnormalized) graph Laplacian matrix \\(L\\) in a single Numba pass.

#### connected\_components

```python
connected_components() -> tuple[
    int, ndarray[tuple[int], dtype[int32]]
]
```

Compute undirected connected components `(n_components, labels)` in \\(O(N + \\text{nnz})\\) time.

#### connected\_components\_from\_edges

```python
connected_components_from_edges(
    n_nodes: int, edge_u: ndarray, edge_v: ndarray
) -> tuple[int, ndarray[tuple[int], dtype[int32]]]
```

Compute undirected connected components `(n_components, labels)` directly from flat edge arrays in \\(O(N + E)\\) time.

#### extract\_undirected\_edges

```python
extract_undirected_edges(
    *, use_weights: bool = True
) -> tuple[
    ndarray[tuple[int], dtype[int32]],
    ndarray[tuple[int], dtype[int32]],
    ndarray[tuple[int], dtype[float64]],
]
```

Symmetrize (`A + A.T`) and extract unique upper-triangular undirected edges `(u < v, w)`.

### RelationalCSR

Bases: `CSR`

Immutable Compressed Sparse Row (`CSR`) incoming-edge representation of a multi-relational directed graph.

Inherits `indptr`, `indices` (incoming source vertex IDs), `data` (normalized `float32` edge aggregation weights), and `shape` from `CSR`, while adding per-edge relation type IDs (`rel_types`), total relation count (`n_relations`), and optional virtual pool node indices (`virtual_nodes`).

For each target vertex \\(v \\in \[0, N-1\]\\), the slice `k in range(indptr[v], indptr[v + 1])` enumerates incoming directed edges \\((u\_k \\xrightarrow{r\_k} v)\\) with source vertex `u_k = indices[k]` (also aliased as `.src_indices`), relation ID `r_k = rel_types[k]`, and normalized aggregation weight `data[k]` (also aliased as `.edge_weights`).

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `indptr` | `ndarray[tuple[int], dtype[int32]]` | 1D `int32` array of shape `(N + 1,)` indexing incoming edges per target vertex. |
| `indices` | `ndarray[tuple[int], dtype[int32]]` | 1D `int32` array of shape `(E,)` of source vertex indices. |
| `data` | `ndarray[tuple[int], Any]` | 1D `float32` array of shape `(E,)` of per-edge aggregation weights. |
| `shape` | `tuple[int, int]` | 2-tuple `(N, N)` giving total node dimensions. |
| `rel_types` | `ndarray[tuple[int], dtype[int32]]` | 1D `int32` array of shape `(E,)` of relation type IDs in `[0, R - 1]`. |
| `n_relations` | `int` | Total number of distinct relation types \\(R\\). |
| `virtual_nodes` | `ndarray[tuple[int], dtype[int32]]` | 1D `int32` array of virtual global pool vertex indices (empty if none). |

Methods:

| Name | Description |
| --- | --- |
| `from_edges` | Construct a `RelationalCSR` from flat directed edge arrays. |
| `from_multihop` | Build an 8-relation multi-hop `RelationalCSR` for a graph or ragged batch. |
| `from_batch` | Build a multi-hop `RelationalCSR` directly from a `Graphs` batch. |
| `from_graph` | Build a multi-hop `RelationalCSR` from a single `Graph`. |

#### n\_nodes

```python
n_nodes: int
```

Total number of vertices \\(N\\) (including any virtual pool vertices).

#### src\_indices

```python
src_indices: ndarray[tuple[int], dtype[int32]]
```

1D `int32` array of incoming source vertex indices (alias for `self.indices`).

#### edge\_weights

```python
edge_weights: ndarray[tuple[int], dtype[float32]]
```

1D `float32` array of per-edge aggregation weights (alias for `self.data`).

#### from\_edges

```python
from_edges(
    n_nodes: int,
    sources: Sequence[int] | ndarray,
    targets: Sequence[int] | ndarray,
    relations: Sequence[int] | ndarray | None = None,
    *,
    n_relations: int | None = None,
    add_self_loops: bool = True,
    normalize_by_degree: bool = True,
    virtual_nodes: ndarray | None = None,
) -> Self
```

Construct a `RelationalCSR` from flat directed edge arrays.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `n_nodes` | `int` | Total number of vertices \\(N\\). | *required* |
| `sources` | `Sequence[int] \| ndarray` | 1D array-like of source vertex indices `u`. | *required* |
| `targets` | `Sequence[int] \| ndarray` | 1D array-like of target vertex indices `v`. | *required* |
| `relations` | `Sequence[int] \| ndarray \| None` | Optional 1D array-like of integer relation IDs `r >= 0`. If `None`, all edges receive relation `1` (when `add_self_loops=True`, self-loops receive relation `0`). | `None` |
| `n_relations` | `int \| None` | Total number of relation types \\(R\\). Inferred if `None`. | `None` |
| `add_self_loops` | `bool` | If `True` (default), prepends a self-loop `(v -> v, r=0)` for every vertex. | `True` |
| `normalize_by_degree` | `bool` | If `True` (default), normalizes incoming weights per `(target, relation)` group so each relation's incoming messages average cleanly. | `True` |
| `virtual_nodes` | `ndarray \| None` | Optional 1D `int32` array of virtual global pool vertex indices. | `None` |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `RelationalCSR` | `Self` | Incoming-edge multi-relational CSR structure. |

#### from\_multihop

```python
from_multihop(
    node_offsets: Sequence[int] | ndarray,
    edge_sources: Sequence[int] | ndarray,
    edge_targets: Sequence[int] | ndarray,
    edge_orientations: Sequence[int]
    | ndarray
    | None = None,
    *,
    include_2hop: bool = True,
    add_virtual_pool: bool = True,
) -> Self
```

Build an 8-relation multi-hop `RelationalCSR` for a graph or ragged batch.

**Constructs up to 8 directed relation types**

- `0`: Self-loop (`v -> v`)
- `1`: 1-hop forward (`u -> v`, codirectional)
- `2`: 1-hop reverse (`v -> u`, codirectional)
- `3`: 1-hop convergent/divergent (`u <-> v` when `edge_orientations != 0`)
- `4`: 2-hop forward (`u -> w -> v`)
- `5`: 2-hop reverse (`v -> w -> u`)
- `6`: Real vertex to per-graph virtual global pool (`u -> pool_g`)
- `7`: Per-graph virtual global pool to real vertex (`pool_g -> u`)

#### from\_batch

```python
from_batch(
    batch: Graphs[Any, Any],
    edge_orientations: Sequence[int]
    | ndarray
    | None = None,
    *,
    include_2hop: bool = True,
    add_virtual_pool: bool = True,
) -> Self
```

Build a multi-hop `RelationalCSR` directly from a `Graphs` batch.

#### from\_graph

```python
from_graph(
    graph: Graph,
    *,
    include_2hop: bool = True,
    add_virtual_pool: bool = True,
) -> Self
```

Build a multi-hop `RelationalCSR` from a single `Graph`.

## models

Core graph representations, bitfield packing, and vectorized SoA containers.

Classes:

| Name | Description |
| --- | --- |
| `BitField` | Descriptor defining a bitfield slice (shift, width, mask). |
| `NodeBase` | Abstract base protocol for all core nodes. |
| `IntNode` | Base model for core nodes represented as bit-packed primitive integers. |
| `DirectedEdge` | Base class for all directed core edges. |
| `Graph` | Scalar view and topological model representing a single directed graph. |
| `Graphs` | Base Structure-of-Arrays (SoA) container for batched graph datasets. |

### BitField

Descriptor defining a bitfield slice (shift, width, mask). Provides safe packing, extraction, and bitmask computation.

Methods:

| Name | Description |
| --- | --- |
| `extract` | Extracts and right-shifts this bitfield's value from an integer. |
| `extract_array` | Extracts and right-shifts this bitfield's value across a numpy array. |
| `pack` | Validates and shifts field\_val into its bit position. |

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `mask` | `int` | Absolute bitmask positioned at field shift. |
| `max_val` | `int` | Maximum unsigned value that fits within this bitfield width. |

#### mask

```python
mask: int
```

Absolute bitmask positioned at field shift.

#### max\_val

```python
max_val: int
```

Maximum unsigned value that fits within this bitfield width.

#### extract

```python
extract(val: int) -> int
```

Extracts and right-shifts this bitfield's value from an integer.

#### extract\_array

```python
extract_array(arr: ndarray) -> ndarray
```

Extracts and right-shifts this bitfield's value across a numpy array.

#### pack

```python
pack(field_val: int) -> int
```

Validates and shifts field\_val into its bit position.

### NodeBase

Bases: `ABC`

Abstract base protocol for all core nodes.

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `type_id` | `int` | Semantic integer label used in core adjacency matrices and embeddings. |
| `is_edge_node` | `bool` | Returns True if this node represents an injected edge in a bipartite core. |

#### type\_id

```python
type_id: int
```

Semantic integer label used in core adjacency matrices and embeddings.

#### is\_edge\_node

```python
is_edge_node: bool
```

Returns True if this node represents an injected edge in a bipartite core.

### IntNode

Bases: `int`, `NodeBase`

Base model for core nodes represented as bit-packed primitive integers.

Inherits from Python's built-in `int` and `GraphNode`, enabling zero-allocation integer node semantics across NumPy arrays, SciPy CSR matrices, and core algorithms. Hosts BitField member descriptors that automatically extract bit values when accessed on instances, while providing bitmasking, range validation, and packing at the class level.

Methods:

| Name | Description |
| --- | --- |
| `mask` | Constructs an absolute bitmask covering the specified bitfield names. |
| `mask_excluding` | Constructs a bitmask excluding the specified bitfield names. |
| `pack` | Packs keyword field values into a composite integer. |

#### mask

```python
mask(*field_names: str) -> int
```

Constructs an absolute bitmask covering the specified bitfield names.

#### mask\_excluding

```python
mask_excluding(*field_names: str) -> int
```

Constructs a bitmask excluding the specified bitfield names.

#### pack

```python
pack(**kwargs: int) -> int
```

Packs keyword field values into a composite integer.

### DirectedEdge

Base class for all directed core edges.

### Graph

Bases: `ScalarView`

Scalar view and topological model representing a single directed graph. Provides sparse CSR conversion, multi-hop `RelationalCSR` construction, Laplacian spectrum calculation, and 1-Wasserstein spectral distance.

Methods:

| Name | Description |
| --- | --- |
| `as_graph` | Builds a sparse CSR adjacency matrix and node label array. |
| `as_relational_csr` | Build a multi-hop `RelationalCSR` for this graph. |
| `laplacian_spectrum` | Computes the continuous topological spectrum of the core. |
| `spectral_distance` | Computes the topological Wasserstein Distance (Earth Mover's Distance) |

#### as\_graph

```python
as_graph(
    as_bipartite: bool = False, symmetrize: bool = False
) -> tuple[CSR, ndarray[tuple[int], dtype[uint32]]]
```

Builds a sparse CSR adjacency matrix and node label array.

All biological and genomic models in KBank are strictly directed graphs. By default, returns the canonical directed representation. If a mathematical algorithm requires a symmetric input matrix (e.g. Laplacian spectrum calculation or bidirectional message passing), specify `symmetrize=True`.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `as_bipartite` | `bool` | If True, treats each directed edge as an intermediate node, forming a bipartite incidence core where edge weights are 1. If False, edges directly connect primary nodes with edge weights equal to the integer edge type. | `False` |
| `symmetrize` | `bool` | If True, produces a symmetrized (bidirectional) adjacency matrix projection. | `False` |

Returns:

| Type | Description |
| --- | --- |
| `tuple[CSR, ndarray[tuple[int], dtype[uint32]]]` | A tuple of: - adj: Sparse CSR adjacency matrix of shape (total\_nodes, total\_nodes). - labels: 1D NumPy array of node labels (`np.ndarray[tuple[int], np.dtype[np.uint32]]`). |

#### as\_relational\_csr

```python
as_relational_csr(
    *,
    include_2hop: bool = True,
    add_virtual_pool: bool = True,
) -> RelationalCSR
```

Build a multi-hop `RelationalCSR` for this graph.

#### laplacian\_spectrum

```python
laplacian_spectrum() -> ndarray[tuple[int], dtype[float64]]
```

Computes the continuous topological spectrum of the core.

Constructs the unweighted, symmetrized normalized core Laplacian via `CSR.laplacian` and solves for the sorted eigenvalues using :func:`numpy.linalg.eigvalsh`.

Returns:

| Type | Description |
| --- | --- |
| `ndarray[tuple[int], dtype[float64]]` | A 1D sorted NumPy array of eigenvalues (`np.ndarray[tuple[int], np.dtype[np.float64]]`). |

#### spectral\_distance

```python
spectral_distance(other: Graph) -> float
```

Computes the topological Wasserstein Distance (Earth Mover's Distance) between this core model and another, comparing skeletal shapes.

Extracts the Laplacian spectra from both graphs and computes their Wasserstein-1 distance via a compiled Numba 1D optimal transport kernel.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `other` | `Graph` | Another `Graph` instance to compare against. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `float` | Wasserstein distance between the two normalized Laplacian spectra as a float. |

### Graphs

Bases: `BatchedContainer[T, S]`

Base Structure-of-Arrays (SoA) container for batched graph datasets. Provides block-diagonal CSR adjacency, Wasserstein spectral distance matrices, pan-graph compression, and vectorized SoA array slicing and concatenation.

Methods:

| Name | Description |
| --- | --- |
| `empty` | Create an empty 0-length graph batch. |
| `concat` | Concatenate multiple graph batches into a single contiguous batch. |
| `from_list` | Pack a sequence of `Graph` instances into a `Graphs` batch. |
| `random` | Generate a random `Graphs` batch using the Erdős–Rényi \\(G(n, p)\\) model. |
| `get_block_diagonal_graph` | Returns a single disconnected CSR core representing the entire batch. |
| `as_relational_csr` | Build a multi-hop `RelationalCSR` for this batch. |
| `spectral_distance_matrix` | Computes the all-vs-all continuous topological distance matrix across the batch. |
| `as_pan_graph` | Compresses the SoA batch into a unified directed pan-core network. |

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `node_lengths` | `UInt32Array` | Number of nodes in each graph in the batch. |
| `edge_lengths` | `UInt32Array` | Number of edges in each graph in the batch. |

#### node\_lengths

```python
node_lengths: UInt32Array
```

Number of nodes in each graph in the batch.

#### edge\_lengths

```python
edge_lengths: UInt32Array
```

Number of edges in each graph in the batch.

#### empty

```python
empty() -> Self
```

Create an empty 0-length graph batch.

#### concat

```python
concat(batches: Iterable[Self]) -> Self
```

Concatenate multiple graph batches into a single contiguous batch.

#### from\_list

```python
from_list(items: Sequence[T]) -> Self
```

Pack a sequence of `Graph` instances into a `Graphs` batch.

#### random

```python
random(
    n_graphs: int = 10,
    n_nodes: int | tuple[int, int] = (5, 15),
    p: float = 0.25,
    *,
    n_node_types: int = 8,
    n_edge_types: int = 4,
    directed: bool = True,
    allow_self_loops: bool = False,
    rng: Generator | int | None = None,
) -> Self
```

Generate a random `Graphs` batch using the Erdős–Rényi \\(G(n, p)\\) model.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `n_graphs` | `int` | Number of graphs in the batch (`n_graphs >= 0`). Defaults to `10`. | `10` |
| `n_nodes` | `int \| tuple[int, int]` | Either a fixed integer node count per graph or an inclusive `(min_nodes, max_nodes)` 2-tuple sampled uniformly per graph. Defaults to `(5, 15)`. | `(5, 15)` |
| `p` | `float` | Edge inclusion probability \\(p \\in \[0, 1\]\\). Defaults to `0.25`. | `0.25` |
| `n_node_types` | `int` | Number of distinct integer node types sampled uniformly in `[1, n_node_types]`. Defaults to `8`. | `8` |
| `n_edge_types` | `int` | Number of distinct integer edge types sampled uniformly in `[1, n_edge_types]`. Defaults to `4`. | `4` |
| `directed` | `bool` | If `True` (default), generates independent directed edges \\((u \\to v)\\). If `False`, generates symmetric undirected edges \\((u \\leftrightarrow v)\\). | `True` |
| `allow_self_loops` | `bool` | If `True`, permits self-loops \\((u \\to u)\\). Defaults to `False`. | `False` |
| `rng` | `Generator \| int \| None` | Optional `np.random.Generator`, integer seed, or `None` passed to `np.random.default_rng`. | `None` |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `Self` | `Self` | A newly generated `Graphs` instance. |

#### get\_block\_diagonal\_graph

```python
get_block_diagonal_graph(unweighted: bool = False) -> CSR
```

Returns a single disconnected CSR core representing the entire batch.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `unweighted` | `bool` | If True, sets all non-zero edge weights to 1; otherwise retains the integer edge types. | `False` |

Returns:

| Type | Description |
| --- | --- |
| `CSR` | Block-diagonal sparse CSR adjacency matrix of shape (total\_nodes, total\_nodes). |

#### as\_relational\_csr

```python
as_relational_csr(
    edge_orientations: Sequence[int]
    | ndarray
    | None = None,
    *,
    include_2hop: bool = True,
    add_virtual_pool: bool = True,
) -> RelationalCSR
```

Build a multi-hop `RelationalCSR` for this batch.

#### spectral\_distance\_matrix

```python
spectral_distance_matrix() -> ndarray[
    tuple[int, int], dtype[float64]
]
```

Computes the all-vs-all continuous topological distance matrix across the batch.

Extracts per-core normalized Laplacian spectra and computes pairwise Wasserstein-1 distances in parallel using compiled Numba kernels.

Returns:

| Type | Description |
| --- | --- |
| `ndarray[tuple[int, int], dtype[float64]]` | A dense symmetric matrix (N x N) of Wasserstein distances (`np.ndarray[tuple[int, int], np.dtype[np.float64]]`). |

#### as\_pan\_graph

```python
as_pan_graph(
    node_mask: int | None = None,
) -> tuple[
    CSR,
    ndarray[tuple[int], dtype[uint32]],
    ndarray[tuple[int], dtype[uint32]],
]
```

Compresses the SoA batch into a unified directed pan-core network. Merges identical nodes, records node occurrence frequencies, and computes the exact occurrence frequency (count) of each directed transition.

Pan-graphs in KBank are strictly directed consensus networks representing synteny flow and biosynthetic transitions.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `node_mask` | `int \| None` | Optional bitmask to apply to node types before merging. | `None` |

Returns:

| Type | Description |
| --- | --- |
| `tuple[CSR, ndarray[tuple[int], dtype[uint32]], ndarray[tuple[int], dtype[uint32]]]` | A tuple of: - adj: Sparse CSR pan-core adjacency matrix of shape (num\_pan\_nodes, num\_pan\_nodes) where data values represent transition occurrence counts. - pan\_nodes: 1D array of pan-node integer labels (`np.ndarray[tuple[int], np.dtype[np.uint32]]`). - node\_counts: 1D array of frequencies indicating how many original nodes merged into each pan-node (`np.ndarray[tuple[int], np.dtype[np.uint32]]`). |

## align

Generic bipartite graph alignment framework with pluggable cost strategies and topological embeddings.

Classes:

| Name | Description |
| --- | --- |
| `AlignmentConfig` | Immutable configuration for bipartite graph alignment solvers. |
| `EmbeddingStrategy` | Abstract base strategy for computing continuous topological node embeddings. |
| `WeisfeilerLehmanEmbedding` | Computes generalized continuous Weisfeiler-Lehman topological smoothing. |
| `DegreeProfileEmbedding` | Computes in-degree, out-degree, and total degree profiles for each node. |
| `CostStrategy` | Abstract base strategy for computing semantic node compatibility cost matrices. |
| `ExactMatchCostStrategy` | Isomorphic cost model: 0.0 for identical node types, infinite penalty for mismatches. |
| `CallableCostStrategy` | Adapter wrapping custom user-defined cost functions. |
| `Alignment` | Outcome of bipartite graph alignment containing matched node pairs, costs, and unmatched nodes. |
| `GraphAligner` | Configurable bipartite graph alignment solver using Hungarian assignment. |
| `IsomorphicGraphAligner` | Specialized aligner pre-configured for same-domain structural isomorphism matching. |

### AlignmentConfig

Immutable configuration for bipartite graph alignment solvers.

Methods:

| Name | Description |
| --- | --- |
| `default` | Return default `AlignmentConfig`. |
| `rigid` | Strict alignment prioritizing rigid semantic constraints over topology. |
| `topological` | Relaxed alignment prioritizing topological graph flow smoothing. |

#### default

```python
default() -> Self
```

Return default `AlignmentConfig`.

#### rigid

```python
rigid() -> Self
```

Strict alignment prioritizing rigid semantic constraints over topology.

#### topological

```python
topological() -> Self
```

Relaxed alignment prioritizing topological graph flow smoothing.

### EmbeddingStrategy

Bases: `ABC`

Abstract base strategy for computing continuous topological node embeddings.

Methods:

| Name | Description |
| --- | --- |
| `compute` | Compute node embeddings from sparse adjacency and initial node features. |

#### compute

```python
compute(
    adj: CSR,
    features: ndarray[tuple[int, int], dtype[float64]],
) -> ndarray[tuple[int, int], dtype[float64]]
```

Compute node embeddings from sparse adjacency and initial node features.

### WeisfeilerLehmanEmbedding

Bases: `EmbeddingStrategy`

Computes generalized continuous Weisfeiler-Lehman topological smoothing.

Methods:

| Name | Description |
| --- | --- |
| `compute` | Smooth continuous features across sparse graph adjacency. |

#### compute

```python
compute(
    adj: CSR,
    features: ndarray[tuple[int, int], dtype[float64]],
) -> ndarray[tuple[int, int], dtype[float64]]
```

Smooth continuous features across sparse graph adjacency.

### DegreeProfileEmbedding

Bases: `EmbeddingStrategy`

Computes in-degree, out-degree, and total degree profiles for each node.

Methods:

| Name | Description |
| --- | --- |
| `compute` | Augment node features with in-degree and out-degree computed from sparse adjacency. |

#### compute

```python
compute(
    adj: CSR,
    features: ndarray[tuple[int, int], dtype[float64]],
) -> ndarray[tuple[int, int], dtype[float64]]
```

Augment node features with in-degree and out-degree computed from sparse adjacency.

### CostStrategy

Bases: `ABC`

Abstract base strategy for computing semantic node compatibility cost matrices.

Methods:

| Name | Description |
| --- | --- |
| `compute_cost` | Compute `(N, M)` pairwise node compatibility cost matrix. |

#### compute\_cost

```python
compute_cost(
    labels_a: ndarray[tuple[int], dtype[Any]],
    labels_b: ndarray[tuple[int], dtype[Any]],
    penalty: float = 1000000.0,
    graph_a: Graph | None = None,
    graph_b: Graph | None = None,
) -> ndarray[tuple[int, int], dtype[float64]]
```

Compute `(N, M)` pairwise node compatibility cost matrix.

### ExactMatchCostStrategy

Bases: `CostStrategy`

Isomorphic cost model: 0.0 for identical node types, infinite penalty for mismatches.

Methods:

| Name | Description |
| --- | --- |
| `compute_cost` | Compute exact equality cost matrix using vectorized broadcasting. |

#### compute\_cost

```python
compute_cost(
    labels_a: ndarray[tuple[int], dtype[Any]],
    labels_b: ndarray[tuple[int], dtype[Any]],
    penalty: float = 1000000.0,
    graph_a: Graph | None = None,
    graph_b: Graph | None = None,
) -> ndarray[tuple[int, int], dtype[float64]]
```

Compute exact equality cost matrix using vectorized broadcasting.

### CallableCostStrategy

Bases: `CostStrategy`

Adapter wrapping custom user-defined cost functions.

Methods:

| Name | Description |
| --- | --- |
| `compute_cost` | Delegate cost computation to wrapped callable. |

#### compute\_cost

```python
compute_cost(
    labels_a: ndarray[tuple[int], dtype[Any]],
    labels_b: ndarray[tuple[int], dtype[Any]],
    penalty: float = 1000000.0,
    graph_a: Graph | None = None,
    graph_b: Graph | None = None,
) -> ndarray[tuple[int, int], dtype[float64]]
```

Delegate cost computation to wrapped callable.

### Alignment

Outcome of bipartite graph alignment containing matched node pairs, costs, and unmatched nodes.

### GraphAligner

Configurable bipartite graph alignment solver using Hungarian assignment.

Methods:

| Name | Description |
| --- | --- |
| `align` | Execute bipartite graph alignment between two `Graph` instances. |

#### align

```python
align(graph_a: Graph, graph_b: Graph) -> Alignment
```

Execute bipartite graph alignment between two `Graph` instances.

### IsomorphicGraphAligner

Bases: `GraphAligner`

Specialized aligner pre-configured for same-domain structural isomorphism matching.

## layout

Force-directed and spectral graph layout algorithms with Numba-accelerated kernels.

Provides `LayoutEngine` for computing 2D and \\(D\\)-dimensional node coordinates for `Graph` instances, `Graphs` pan-graphs, and sparse adjacency matrices using the Fruchterman-Reingold spring-electrical algorithm.

Classes:

| Name | Description |
| --- | --- |
| `LayoutEngine` | Configurable graph layout engine with Numba-accelerated Fruchterman-Reingold physics. |

### LayoutEngine

Configurable graph layout engine with Numba-accelerated Fruchterman-Reingold physics.

Supports laying out single `Graph` instances, `Graphs` collections (via their unified `.as_pan_graph()` representation), or raw SciPy sparse / NumPy adjacency matrices.

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `mode` | `LayoutMode` | Layout algorithm (`"fruchterman_reingold"` or shorthand `"fr"`). |
| `dim` | `int` | Coordinate dimensionality (\\(D \\ge 1\\)). Defaults to `2`. |
| `iterations` | `int` | Number of simulated annealing iterations. Defaults to `50`. |
| `k` | `float \| None` | Optimal inter-node spring distance. If `None`, defaults to \\(1 / \\sqrt\[\\text{dim}\]{N}\\). |
| `scale` | `float \| None` | Bounding radius for output rescaling (`[-scale, +scale]`), or `None` to disable rescaling. |
| `center` | `Sequence[float] \| ndarray \| None` | Optional \\(D\\)-dimensional center offset. Defaults to origin. |
| `gravity` | `float` | Central gravity coefficient keeping disconnected components compact. Defaults to `0.05`. |
| `tol` | `float` | Early stopping threshold on maximum node displacement. Defaults to `1e-4`. |
| `init` | `InitMode` | Coordinate initialization strategy (`"random"`, `"circular"`, or `"spectral"`). |
| `use_weights` | `bool` | Whether edge weights scale attractive forces. Defaults to `True`. |
| `as_bipartite` | `bool` | Whether to expand edges as bipartite nodes when laying out a `Graph`. |
| `node_mask` | `int \| None` | Optional bitmask passed to `Graphs.as_pan_graph(node_mask=...)`. |
| `seed` | `int` | Deterministic random seed for coordinate initialization. Defaults to `42`. |

Methods:

| Name | Description |
| --- | --- |
| `rescale` | Rescale node coordinates so the largest centered coordinate magnitude equals `scale`. |
| `layout` | Compute `(N, dim)` layout coordinates for a graph, batch pan-graph, or adjacency matrix. |

#### rescale

```python
rescale(
    pos: ndarray[tuple[int, int], dtype[float64]],
) -> ndarray[tuple[int, int], dtype[float64]]
```

Rescale node coordinates so the largest centered coordinate magnitude equals `scale`.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `pos` | `ndarray[tuple[int, int], dtype[float64]]` | `(N, dim)` coordinate array. | *required* |

Returns:

| Type | Description |
| --- | --- |
| `ndarray[tuple[int, int], dtype[float64]]` | Rescaled `(N, dim)` coordinate array (`float64`). |

#### layout

```python
layout(
    graph: Graph | Graphs[Any, Any] | CSR | ndarray,
    *,
    pos: ndarray | None = None,
    fixed: Sequence[int] | ndarray | None = None,
) -> ndarray[tuple[int, int], dtype[float64]]
```

Compute `(N, dim)` layout coordinates for a graph, batch pan-graph, or adjacency matrix.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `graph` | `Graph \| Graphs[Any, Any] \| CSR \| ndarray` | Input `Graph`, `Graphs` (laid out via `.as_pan_graph()`), sparse `CSR`, or dense 2D adjacency array. | *required* |
| `pos` | `ndarray \| None` | Optional initial `(N, dim)` node coordinates for warm-starting or pinning. | `None` |
| `fixed` | `Sequence[int] \| ndarray \| None` | Optional sequence/array of node indices (or boolean mask of length `N`) whose positions should remain fixed during optimization. | `None` |

Returns:

| Type | Description |
| --- | --- |
| `ndarray[tuple[int, int], dtype[float64]]` | 2D NumPy array of shape `(N, dim)` with `float64` coordinates. |

## gnn

Numba-accelerated Relational Message-Passing Neural Network (`RelationalMPNN`).

Provides compiled `@njit(parallel=True, fastmath=True)` message-passing forward/backward kernels, factorized bilinear directed edge/slot scorers, and the `RelationalMPNN` model operating over `RelationalCSR` graphs.

Classes:

| Name | Description |
| --- | --- |
| `RelationalMPNN` | Numba-powered Relational Message-Passing Neural Network (R-MPNN) for node &amp; directed tree inference. |

### RelationalMPNN

Numba-powered Relational Message-Passing Neural Network (R-MPNN) for node &amp; directed tree inference.

**Architecture**

1. Input projection: \\(h^{(0)} = \\text{RMSNorm}(X W\_{\\text{in}} + b\_{\\text{in}})\\).
2. \\(L\\) Relational Message-Passing layers with residual connections, ReLU, RMSNorm, and optional clamped-node anchor injection (`clamped_mask`) so pre-existing annotations anchor contextual propagation without drifting.
3. Node readout head: \\(Z\_{\\text{node}} = h^{(L)} W\_{\\text{node}} + b\_{\\text{node}}\\) (`(N, num_node_classes)`).
4. Factorized bilinear multi-slot directed edge readout head: \\(S\[u, v, c\] = \\frac{1}{\\sqrt{K}} \\sum\_{k=1}^K (h\_u^{(L)} W\_{\\text{src}})\_k (h\_v^{(L)} W\_{\\text{dst}})\_k W\_{\\text{chan}}\[c, k\] + b\_{\\text{chan}}\[c\]\\) producing `(M, M, num_edge_channels)` logits suitable for decoding via `ArborescenceSolver` or `Arborescence.maximum`.

Methods:

| Name | Description |
| --- | --- |
| `encode` | Run the \\(L\\)-layer R-MPNN encoder and return final node embeddings `(N, hidden_dim)`. |
| `predict_node_logits` | Compute pre-softmax node class logits `(N, num_node_classes)`. |
| `predict_node_proba` | Compute softmax node class probabilities `(N, num_node_classes)`. |
| `score_edges` | Score all directed candidate edges `(u -> v, channel)` among `h_nodes` (or `h_nodes[node_indices]`). |
| `fit_step` | Execute one complete forward + backward + AdamW optimization step on a graph or batch. |
| `save` | Save model weights and hyperparameters to a compressed `.npz` archive (`allow_pickle=False`). |
| `load` | Load a `RelationalMPNN` from a compressed `.npz` archive. |

#### encode

```python
encode(
    x: ndarray,
    csr: RelationalCSR | Graph | Graphs[Any, Any],
    *,
    clamped_mask: ndarray | None = None,
) -> ndarray[tuple[int, int], dtype[float32]]
```

Run the \\(L\\)-layer R-MPNN encoder and return final node embeddings `(N, hidden_dim)`.

#### predict\_node\_logits

```python
predict_node_logits(
    x: ndarray,
    csr: RelationalCSR | Graph | Graphs[Any, Any],
    *,
    clamped_mask: ndarray | None = None,
) -> ndarray[tuple[int, int], dtype[float32]]
```

Compute pre-softmax node class logits `(N, num_node_classes)`.

#### predict\_node\_proba

```python
predict_node_proba(
    x: ndarray,
    csr: RelationalCSR | Graph | Graphs[Any, Any],
    *,
    clamped_mask: ndarray | None = None,
) -> ndarray[tuple[int, int], dtype[float32]]
```

Compute softmax node class probabilities `(N, num_node_classes)`.

#### score\_edges

```python
score_edges(
    h_nodes: ndarray,
    node_indices: Sequence[int] | ndarray | None = None,
) -> ndarray[tuple[int, int, int], dtype[float32]]
```

Score all directed candidate edges `(u -> v, channel)` among `h_nodes` (or `h_nodes[node_indices]`).

Returns:

| Type | Description |
| --- | --- |
| `ndarray[tuple[int, int, int], dtype[float32]]` | np.ndarray: 3D `float32` tensor of shape `(M, M, num_edge_channels)`. |

#### fit\_step

```python
fit_step(
    x: ndarray,
    csr: RelationalCSR | Graph | Graphs[Any, Any],
    *,
    node_targets: ndarray | None = None,
    node_weights: ndarray | None = None,
    edge_node_indices: ndarray | None = None,
    edge_parent_targets: ndarray | None = None,
    edge_slot_targets: ndarray | None = None,
    clamped_mask: ndarray | None = None,
    lr_scale: float = 1.0,
) -> float
```

Execute one complete forward + backward + AdamW optimization step on a graph or batch.

Parameters:

| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `x` | `ndarray` | Input node feature matrix `(N_real, in_dim)` or `(N_total, in_dim)`. | *required* |
| `csr` | `RelationalCSR \| Graph \| Graphs[Any, Any]` | `RelationalCSR`, `Graph`, or `Graphs` connectivity structure. | *required* |
| `node_targets` | `ndarray \| None` | Optional 1D `int32` array of ground-truth node class indices (`-1` = ignore). | `None` |
| `node_weights` | `ndarray \| None` | Optional 1D `float32` array of per-node loss weights. | `None` |
| `edge_node_indices` | `ndarray \| None` | Optional 1D `int32` array of active tree vertices `[v_0, ..., v_{M-1}]`. | `None` |
| `edge_parent_targets` | `ndarray \| None` | Optional 1D `int32` array of length `M` giving target parent index in `[0, M-1]` for each active tree vertex (`-1` for root or unsupervised vertices). | `None` |
| `edge_slot_targets` | `ndarray \| None` | Optional 1D `int32` array of length `M` giving target slot/channel in `[0, num_edge_channels - 1]` for each active tree vertex (`-1` = marginalize over slots). | `None` |
| `clamped_mask` | `ndarray \| None` | Optional 1D `uint8` / boolean mask of clamped vertices. | `None` |
| `lr_scale` | `float` | Cosine/schedule multiplier on `self.learning_rate`. | `1.0` |

Returns:

| Name | Type | Description |
| --- | --- | --- |
| `float` | `float` | Total scalar loss for this step. |

#### save

```python
save(path: Path | str) -> Path
```

Save model weights and hyperparameters to a compressed `.npz` archive (`allow_pickle=False`).

#### load

```python
load(path: Path | str) -> Self
```

Load a `RelationalMPNN` from a compressed `.npz` archive.

## arborescence

Directed spanning arborescence solvers and Structure-of-Arrays (SoA) containers.

Provides compiled Numba branch-and-bound algorithms encapsulated in an object-oriented solver and ragged SoA container hierarchy:

- `Arborescence`: Scalar view of a single directed spanning arborescence.
- `Arborescences`: Ragged Structure-of-Arrays container of arborescences.
- `ArborescenceSolver`: Configurable solver for maximum/minimum and \\(k\\)-best directed spanning arborescences.

Classes:

| Name | Description |
| --- | --- |
| `Arborescence` | Scalar view of a single directed spanning arborescence. |
| `Arborescences` | Ragged Structure-of-Arrays (SoA) container of `Arborescence` trees. |
| `ArborescenceSolver` | Configurable solver for directed spanning arborescences and \\(k\\)-best arborescence ensembles. |

### Arborescence

Bases: `ScalarView`

Scalar view of a single directed spanning arborescence.

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `parents` | `Int32Array` | 1D `int32` array of shape `(N,)` where `parents[v]` is the parent node \\(u\\) of \\(v\\) (`-1` for `root` or excluded nodes). |
| `score` | `float` | Total weight (or cost) of the selected arborescence edges. |
| `slots` | `Int32Array` | 1D `int32` array of shape `(N,)` giving the selected channel/slot index \\(s\\) on the incoming edge \\((u \\to v, s)\\) (`0` for 2D inputs, `-1` for `root`). |
| `root` | `int` | Root vertex index (`0 <= root < N`). Defaults to `0`. |

Methods:

| Name | Description |
| --- | --- |
| `maximum` | Find the maximum-weight directed spanning arborescence rooted at `root`. |
| `minimum` | Find the minimum-cost directed spanning arborescence rooted at `root`. |

#### n\_nodes

```python
n_nodes: int
```

Total number of vertices \\(N\\) in the parent array.

#### edges

```python
edges: ndarray[tuple[int, int], dtype[int32]]
```

2D `int32` array of shape `(M, 3)` containing `(parent_u, child_v, slot_s)` for each tree edge.

#### maximum

```python
maximum(
    weights: ndarray,
    root: int = 0,
    *,
    edge_groups: ndarray | None = None,
    required_nodes: ndarray | None = None,
    slot_exclusivity: bool = True,
    max_backtracks: int = 250000,
) -> Self
```

Find the maximum-weight directed spanning arborescence rooted at `root`.

#### minimum

```python
minimum(
    costs: ndarray,
    root: int = 0,
    *,
    edge_groups: ndarray | None = None,
    required_nodes: ndarray | None = None,
    slot_exclusivity: bool = True,
    max_backtracks: int = 250000,
) -> Self
```

Find the minimum-cost directed spanning arborescence rooted at `root`.

### Arborescences

Bases: `RaggedArrayContainer[Arborescence, 'Arborescences']`

Ragged Structure-of-Arrays (SoA) container of `Arborescence` trees.

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `parents` | `Int32Array` | Flat 1D `int32` array of concatenated parent pointers across all trees. |
| `scores` | `Float64Array` | 1D `float64` array of total tree scores/costs of shape `(B,)`. |
| `slots` | `Int32Array` | Flat 1D `int32` array of concatenated incoming edge slot indices across all trees. |
| `roots` | `Int32Array` | 1D `int32` array of root vertex indices of shape `(B,)`. |
| `offsets` | `Int32Array` | 1D `int32` array of starting indices into `parents` and `slots` per tree. |
| `lengths` | `Int32Array` | 1D `int32` array of vertex counts per tree. |

Methods:

| Name | Description |
| --- | --- |
| `k_best` | Enumerate the top-`k` optimal directed spanning arborescences rooted at `root`. |

#### k\_best

```python
k_best(
    weights: ndarray,
    root: int = 0,
    k: int = 5,
    *,
    mode: Literal["max", "min"] = "max",
    edge_groups: ndarray | None = None,
    required_nodes: ndarray | None = None,
    slot_exclusivity: bool = True,
    max_backtracks: int = 250000,
) -> Self
```

Enumerate the top-`k` optimal directed spanning arborescences rooted at `root`.

### ArborescenceSolver

Configurable solver for directed spanning arborescences and \\(k\\)-best arborescence ensembles.

Uses compiled Numba branch-and-bound with regret-ordered vertex branching and suffix upper-bound pruning. Supports 2D `(N, N)` and 3D `(N, N, S)` edge tensors, valence/slot exclusivity (`slot_exclusivity=True`), custom `edge_groups` constraints, and subset `required_nodes`.

Attributes:

| Name | Type | Description |
| --- | --- | --- |
| `mode` | `Literal['max', 'min']` | Optimization sense (`"max"` for maximum weight or `"min"` for minimum cost). Defaults to `"max"`. |
| `root` | `int` | Default root vertex index (`0 <= root < N`). Defaults to `0`. |
| `k` | `int` | Default number of top arborescences to enumerate (`k >= 1`). Defaults to `1`. |
| `slot_exclusivity` | `bool` | If `True` (default), enforces that at most one outgoing edge from parent \\(u\\) may occupy slot \\(s\\) on 3D `(N, N, S)` weight tensors when `edge_groups` is `None`. |
| `max_backtracks` | `int` | Maximum branch-and-bound backtracks before returning best found solutions. Defaults to `250_000`. |

Methods:

| Name | Description |
| --- | --- |
| `solve_k_best` | Enumerate the top-`k` optimal arborescences in a ragged `Arborescences` container. |
| `solve` | Solve for the single optimal `Arborescence`. |

#### solve\_k\_best

```python
solve_k_best(
    weights: ndarray,
    *,
    root: int | None = None,
    k: int | None = None,
    edge_groups: ndarray | None = None,
    required_nodes: ndarray | None = None,
) -> Arborescences
```

Enumerate the top-`k` optimal arborescences in a ragged `Arborescences` container.

#### solve

```python
solve(
    weights: ndarray,
    *,
    root: int | None = None,
    edge_groups: ndarray | None = None,
    required_nodes: ndarray | None = None,
) -> Arborescence
```

Solve for the single optimal `Arborescence`.
