relag.kernels¶
Kernel variant selector¶
- class relag.kernels.KernelVariant¶
Bases:
object- AlignmentGlobal = KernelVariant.AlignmentGlobal¶
- AlignmentLocal = KernelVariant.AlignmentLocal¶
- Cosine = KernelVariant.Cosine¶
- L1 = KernelVariant.L1¶
- L2 = KernelVariant.L2¶
- ProtSpam = KernelVariant.ProtSpam¶
- Structure = KernelVariant.Structure¶
- TanimotoBit = KernelVariant.TanimotoBit¶
- TanimotoReal = KernelVariant.TanimotoReal¶
- relag.kernels.zip_kernel(variant: KernelVariant, data1: Any, data2: Any, n_threads: int = 0, progress: bool = True, *args: Any, **kwargs: Any) list[float]¶
Compute pairwise kernel scores between two equal-length sequences of data items in parallel.
Evaluates
kernel(data1[i], data2[i])for each indexiand returns the scores as a flatlist[float]of lengthlen(data1).Extra positional and keyword arguments are forwarded to the kernel constructor.
- Parameters:
variant – Which kernel to use.
data1 – First sequence of items.
data2 – Second sequence of items. Must have the same length as
data1.n_threads – Number of parallel threads.
0uses all available cores.progress – Show a progress bar. Defaults to
True.
- Returns:
A
list[float]of lengthlen(data1)whereresult[i] = kernel(data1[i], data2[i]).- Raises:
ValueError – If
data1anddata2have different lengths.
Example:
from relag import KernelVariant from relag.kernels import zip_kernel seqs1 = ["MKTAYIAK", "ACDEFGHIKLM"] seqs2 = ["MKTAYIAKQR", "ACDEF"] scores = zip_kernel(KernelVariant.AlignmentGlobal, seqs1, seqs2) # scores[i] == kernel(seqs1[i], seqs2[i])
relag.kernels.alignments¶
Protein or Nucleotide sequence aligners and their configuration enums.
- class relag.kernels.alignments.GlobalAligner(gap_open: int = 11, gap_extend: int = 1, matrix: ScoringMatrix = ScoringMatrix.Blosum62, identity_mode: GlobalIdentityMode = GlobalIdentityMode.MaxLength, vectorization: VectorizationStrategy = VectorizationStrategy.Scan, width: DatatypeWidth = DatatypeWidth.Sat)¶
Bases:
objectNeedleman–Wunsch global sequence aligner returning a normalised identity score.
Wraps the parasail SIMD alignment library. The identity score is computed as the number of identical aligned positions divided by the denominator selected by
identity_mode.GlobalAligneris used as a kernel inHNSWState,exact_edges, andexact_nearest_neighborsviaKernelVariant.AlignmentGlobal.- Parameters:
gap_open – Affine gap-open penalty (positive integer, subtracted). Default
11.gap_extend – Affine gap-extend penalty (positive integer, subtracted). Default
1.matrix – Amino-acid substitution matrix. Default
ScoringMatrix.Blosum62.identity_mode – Normalisation denominator. Default
GlobalIdentityMode.MaxLength.vectorization – SIMD layout. Default
VectorizationStrategy.Scan.width – Integer precision. Default
DatatypeWidth.Sat.
Example:
from relag.kernels.alignments import GlobalAligner aligner = GlobalAligner(gap_open=11, gap_extend=1) score = aligner.call("MKTAYIAK", "MKTAYIAKQR") score = aligner("MKTAYIAK", "MKTAYIAKQR") # Alternative # score in [0.0, 1.0]
- call(ref_sample: str, query: str) float¶
Compute the global alignment identity between two sequences.
- Parameters:
ref_sample – Reference sequence (single-letter amino acid codes or nucleotides).
query – Query sequence.
- Returns:
Identity score in
[0.0, 1.0].
- class relag.kernels.alignments.LocalAligner(gap_open: int = 11, gap_extend: int = 1, min_coverage: float = 0.800000011920929, cov_mode: CoverageMode = CoverageMode.BothQueryTarget, matrix: ScoringMatrix = ScoringMatrix.Blosum62, identity_mode: LocalIdentityMode = LocalIdentityMode.AlignmentLength, vectorization: VectorizationStrategy = VectorizationStrategy.Striped, width: DatatypeWidth = DatatypeWidth.Sat)¶
Bases:
objectSmith–Waterman local sequence aligner returning a normalised identity score.
Like
GlobalAlignerbut aligns only the most similar sub-region of each sequence. Pairs that do not meet themin_coveragecriterion after alignment receive a score of0.0.LocalAligneris used as a kernel viaKernelVariant.AlignmentLocal.- Parameters:
gap_open – Affine gap-open penalty. Default
11.gap_extend – Affine gap-extend penalty. Default
1.min_coverage – Minimum fraction of sequence covered by the local alignment (per
cov_mode) for the pair to be accepted. Default0.8.cov_mode – Which sequence(s) must meet
min_coverage. DefaultCoverageMode.BothQueryTarget.matrix – Substitution matrix. Default
ScoringMatrix.Blosum62.identity_mode – Normalisation denominator. Default
LocalIdentityMode.AlignmentLength.vectorization – SIMD layout. Default
VectorizationStrategy.Striped.width – Integer precision. Default
DatatypeWidth.Sat.
Example:
from relag.kernels.alignments import LocalAligner, CoverageMode aligner = LocalAligner(min_coverage=0.5, cov_mode=CoverageMode.Query) score = aligner.call("ACDEFGHIKLM", "CDEFGHI") score = aligner("ACDEFGHIKLM", "CDEFGHI") # Alternative
- call(ref_sample: str, query: str) float¶
Compute the local alignment identity between two sequences.
- Parameters:
ref_sample – Reference alignments sequence (single-letter amino acid codes).
query – Query alignments sequence.
- Returns:
Identity score in
[0.0, 1.0], or1.0if the coverage filter fails.
- class relag.kernels.alignments.ScoringMatrix¶
Bases:
object- Blosum100 = ScoringMatrix.Blosum100¶
- Blosum30 = ScoringMatrix.Blosum30¶
- Blosum35 = ScoringMatrix.Blosum35¶
- Blosum40 = ScoringMatrix.Blosum40¶
- Blosum45 = ScoringMatrix.Blosum45¶
- Blosum50 = ScoringMatrix.Blosum50¶
- Blosum55 = ScoringMatrix.Blosum55¶
- Blosum60 = ScoringMatrix.Blosum60¶
- Blosum62 = ScoringMatrix.Blosum62¶
- Blosum65 = ScoringMatrix.Blosum65¶
- Blosum70 = ScoringMatrix.Blosum70¶
- Blosum75 = ScoringMatrix.Blosum75¶
- Blosum80 = ScoringMatrix.Blosum80¶
- Blosum85 = ScoringMatrix.Blosum85¶
- Blosum90 = ScoringMatrix.Blosum90¶
- Blosum95 = ScoringMatrix.Blosum95¶
- Dnafull = ScoringMatrix.Dnafull¶
- Identity = ScoringMatrix.Identity¶
- Nuc44 = ScoringMatrix.Nuc44¶
- Pam10 = ScoringMatrix.Pam10¶
- Pam100 = ScoringMatrix.Pam100¶
- Pam110 = ScoringMatrix.Pam110¶
- Pam120 = ScoringMatrix.Pam120¶
- Pam130 = ScoringMatrix.Pam130¶
- Pam140 = ScoringMatrix.Pam140¶
- Pam150 = ScoringMatrix.Pam150¶
- Pam160 = ScoringMatrix.Pam160¶
- Pam170 = ScoringMatrix.Pam170¶
- Pam180 = ScoringMatrix.Pam180¶
- Pam190 = ScoringMatrix.Pam190¶
- Pam20 = ScoringMatrix.Pam20¶
- Pam200 = ScoringMatrix.Pam200¶
- Pam210 = ScoringMatrix.Pam210¶
- Pam220 = ScoringMatrix.Pam220¶
- Pam230 = ScoringMatrix.Pam230¶
- Pam240 = ScoringMatrix.Pam240¶
- Pam250 = ScoringMatrix.Pam250¶
- Pam260 = ScoringMatrix.Pam260¶
- Pam270 = ScoringMatrix.Pam270¶
- Pam280 = ScoringMatrix.Pam280¶
- Pam290 = ScoringMatrix.Pam290¶
- Pam30 = ScoringMatrix.Pam30¶
- Pam300 = ScoringMatrix.Pam300¶
- Pam310 = ScoringMatrix.Pam310¶
- Pam320 = ScoringMatrix.Pam320¶
- Pam330 = ScoringMatrix.Pam330¶
- Pam340 = ScoringMatrix.Pam340¶
- Pam350 = ScoringMatrix.Pam350¶
- Pam360 = ScoringMatrix.Pam360¶
- Pam370 = ScoringMatrix.Pam370¶
- Pam380 = ScoringMatrix.Pam380¶
- Pam390 = ScoringMatrix.Pam390¶
- Pam40 = ScoringMatrix.Pam40¶
- Pam400 = ScoringMatrix.Pam400¶
- Pam410 = ScoringMatrix.Pam410¶
- Pam420 = ScoringMatrix.Pam420¶
- Pam430 = ScoringMatrix.Pam430¶
- Pam440 = ScoringMatrix.Pam440¶
- Pam450 = ScoringMatrix.Pam450¶
- Pam460 = ScoringMatrix.Pam460¶
- Pam470 = ScoringMatrix.Pam470¶
- Pam480 = ScoringMatrix.Pam480¶
- Pam490 = ScoringMatrix.Pam490¶
- Pam50 = ScoringMatrix.Pam50¶
- Pam500 = ScoringMatrix.Pam500¶
- Pam60 = ScoringMatrix.Pam60¶
- Pam70 = ScoringMatrix.Pam70¶
- Pam80 = ScoringMatrix.Pam80¶
- Pam90 = ScoringMatrix.Pam90¶
- class relag.kernels.alignments.GlobalIdentityMode¶
Bases:
objectDenominator used to normalise a global-alignments identity score.
After counting identical aligned positions the raw count is divided by:
AlignmentLength: the total length of the alignment (including gaps).MaxSeqLength: the length of the longer of the two sequences.MinSeqLength: the length of the shorter of the two sequences.MaxLength(default): same asMaxSeqLength— recommended for RGP datasets.
- AlignmentLength = GlobalIdentityMode.AlignmentLength¶
- MaxLength = GlobalIdentityMode.MaxLength¶
- MaxSeqLength = GlobalIdentityMode.MaxSeqLength¶
- MinSeqLength = GlobalIdentityMode.MinSeqLength¶
- class relag.kernels.alignments.VectorizationStrategy¶
Bases:
objectSIMD vectorization layout used by the parasail alignment engine.
Striped(default for local): interleaved layout, best for short sequences.Scan: sequential scan layout, often faster for long sequences or global alignment.Diag: diagonal layout; niche use-case, rarely needed.
In practice the default per-aligner is a good choice; change only if profiling shows a bottleneck.
- Diag = VectorizationStrategy.Diag¶
- Scan = VectorizationStrategy.Scan¶
- Striped = VectorizationStrategy.Striped¶
- class relag.kernels.alignments.DatatypeWidth¶
Bases:
objectInteger precision used for alignment score accumulation.
Short(8-bit),Half(16-bit),Full(32-bit),Long(64-bit): fixed-width integers — lower width is faster but can overflow on long sequences.Sat(default): 8-bit saturating arithmetic; If it saturates, silently restart with 16-bit.
- Full = DatatypeWidth.Full¶
- Half = DatatypeWidth.Half¶
- Long = DatatypeWidth.Long¶
- Sat = DatatypeWidth.Sat¶
- Short = DatatypeWidth.Short¶
- class relag.kernels.alignments.CoverageMode¶
Bases:
objectCoverage filter applied before accepting a local alignment as valid.
A pair is scored only when the alignment covers enough of the sequences as specified by the mode and
min_coveragethreshold:BothQueryTarget(default): both query and target must meetmin_coverage.Target: only the target must meetmin_coverage.Query: only the query must meetmin_coverage.LengthRatio: the shorter / longer length ratio must meetmin_coverage.ShorterSeq: coverage computed relative to the shorter sequence.
- BothQueryTarget = CoverageMode.BothQueryTarget¶
- LengthRatio = CoverageMode.LengthRatio¶
- Query = CoverageMode.Query¶
- ShorterSeq = CoverageMode.ShorterSeq¶
- Target = CoverageMode.Target¶
- class relag.kernels.alignments.LocalIdentityMode¶
Bases:
objectDenominator used to normalise a local-alignment identity score.
AlignmentLength(default): divide by the length of the local alignment.MinSeqLength: divide by the shorter sequence length.
- AlignmentLength = LocalIdentityMode.AlignmentLength¶
- MinSeqLength = LocalIdentityMode.MinSeqLength¶
relag.kernels.molecules¶
Molecules Tanimoto kernels.
- class relag.kernels.molecules.TanimotoBit¶
Bases:
objectTanimoto distance kernel for binary (bit) molecular fingerprints.
Measures structural dissimilarity between two molecules as the complement of the Jaccard index over their feature sets. A distance of 0 means the two fingerprints are identical; 1 means they share no features at all.
Formula:
1 - |A ∩ B| / |A ∪ B|This kernel is the standard choice when working with
ExplicitBitVectfingerprints such as Morgan, RDKit, or MACCS keys.Example:
from rdkit.Chem import MolFromSmiles, rdFingerprintGenerator from relag.utils import BitFingerprint from relag.kernels.molecules import TanimotoBit mfpgen = rdFingerprintGenerator.GetMorganGenerator(fpSize=1024, radius=2) benzene = BitFingerprint(mfpgen.GetFingerprint(MolFromSmiles("c1ccccc1"))) naphthalene = BitFingerprint(mfpgen.GetFingerprint(MolFromSmiles("c1ccc2ccccc2c1"))) acetic_acid = BitFingerprint(mfpgen.GetFingerprint(MolFromSmiles("CC(=O)O"))) k = TanimotoBit() print(k(benzene, naphthalene)) # low — structurally similar print(k(benzene, acetic_acid)) # high — structurally dissimilar
- call(a: utils.BitFingerprint, b: utils.BitFingerprint) float¶
Compute the Tanimoto distance between two
BitFingerprintobjects.- Parameters:
a – First fingerprint.
b – Second fingerprint.
- Returns:
Distance in
[0.0, 1.0].0.0means identical feature sets,1.0means fully disjoint.
Example:
from relag.utils import BitFingerprint from relag.kernels.molecules import TanimotoBit fp1 = BitFingerprint.from_list([True, False, True, True]) fp2 = BitFingerprint.from_list([True, True, True, False]) k = TanimotoBit() assert k.call(fp1, fp2) == k(fp1, fp2) # both forms are equivalent # intersection={0,2}=2, union={0,1,2,3}=4 → distance = 0.5
- class relag.kernels.molecules.TanimotoReal¶
Bases:
objectTanimoto distance kernel for real-valued (count) molecular fingerprints.
Generalises the binary Tanimoto to continuous feature vectors using the dot-product formulation. A distance of 0 means the two fingerprints are proportional; values approach 1 as the vectors become orthogonal.
Formula:
1 - dot(a, b) / (||a||² + ||b||² - dot(a, b))This kernel is the standard choice when working with count fingerprints such as those returned by
GetCountFingerprint(Morgan counts, etc.).Example:
from rdkit.Chem import MolFromSmiles, rdFingerprintGenerator from relag.utils import RealFingerprint from relag.kernels.molecules import TanimotoReal mfpgen = rdFingerprintGenerator.GetMorganGenerator(fpSize=1024, radius=2) benzene = RealFingerprint(mfpgen.GetCountFingerprint(MolFromSmiles("c1ccccc1"))) naphthalene = RealFingerprint(mfpgen.GetCountFingerprint(MolFromSmiles("c1ccc2ccccc2c1"))) acetic_acid = RealFingerprint(mfpgen.GetCountFingerprint(MolFromSmiles("CC(=O)O"))) k = TanimotoReal() print(k(benzene, naphthalene)) # low — structurally similar print(k(benzene, acetic_acid)) # high — structurally dissimilar
- call(a: utils.RealFingerprint, b: utils.RealFingerprint) float¶
Compute the Tanimoto distance between two
RealFingerprintobjects.- Parameters:
a – First fingerprint.
b – Second fingerprint.
- Returns:
Distance in
[0.0, 1.0].0.0means identical (proportional) feature vectors,1.0means fully orthogonal.
Example:
from relag.utils import RealFingerprint from relag.kernels.molecules import TanimotoReal fp1 = RealFingerprint.from_list([1.0, 0.0, 1.0]) fp2 = RealFingerprint.from_list([0.0, 1.0, 1.0]) k = TanimotoReal() assert k.call(fp1, fp2) == k(fp1, fp2) # both forms are equivalent # dot=1, ||fp1||²=2, ||fp2||²=2 → distance = 1 - 1/(2+2-1) ≈ 0.667
relag.kernels.structures¶
Protein structure kernels (USalign TM-score).
- class relag.kernels.structures.USAlignKernel(norm_mode: NormMode = NormMode.Min, fast: bool = True)¶
Bases:
objectProtein structure comparison kernel using USalign TM-score.
Operates on pre-loaded
PdbStructureobjects (fromrelag.utils). Returns1.0 - TM-scoreso that identical structures have distance 0 and unrelated structures have distance approaching 1.Example:
from relag.utils import PdbStructure from relag.kernels.structures import USAlignKernel, NormMode s1 = PdbStructure("1abc.pdb") s2 = PdbStructure("1xyz.pdb") k = USAlignKernel() # default: NormMode.Min d = k(s1, s2) # float in [0, 1]
- call(a: utils.PdbStructure, b: utils.PdbStructure) float¶
Compute the structure distance between two
PdbStructureobjects.- Parameters:
a – First structure.
b – Second structure.
- Returns:
Distance in
[0.0, 1.0].0.0means structurally identical, values near1.0indicate unrelated folds.
- class relag.kernels.structures.NormMode¶
Bases:
objectTM-score normalization strategy.
USalign returns two scores per alignment:
TM1: normalized by the length of the first structure (query).TM2: normalized by the length of the second structure (target).Min(default):min(TM1, TM2)— conservative, symmetric.Query: useTM1only.Target: useTM2only.
- Min = NormMode.Min¶
- Query = NormMode.Query¶
- Target = NormMode.Target¶
relag.kernels.protspam¶
ProtSpaM-style spaced-word kernel for protein sequences.
- class relag.kernels.protspam.ProtSpamKernel(patterns: utils.SWPatternSet, significance_threshold: int = 0, distance: ProtSpamDistance = ProtSpamDistance.Evolutionary)¶
Bases:
objectDistance between two
SWSequence, ProtSpaM-style: for each pattern in a sharedSWPatternSet, match spaced words by key (grouping ties into “blocks”), score the best-aligned spaced word pair within each matching block against BLOSUM62, and pool mismatches at don’t-care positions into a mismatch rate. Reports either that raw rate or a Kimura-corrected evolutionary distance, perdistance.Every
SWSequencepassed tocallmust have been built from the sameSWPatternSetas this kernel’spatterns()(or an equal copy of it).Example:
from relag.kernels.protspam import ProtSpamKernel, ProtSpamDistance from relag.utils import SWPatternSet, SWSequence sequences = [ "MKTAYIAKQRQISFVKSHFSRQLEERLGLIEVQAPILSRVGDGTQDNLSGAEK", "MKTAYIAKQRQISFVKSHFSRQLEERLGLIEVQAPILSRVGDGTQDNLSGAEA", ] # A RasBhari-optimized pattern set, shared by every SWSequence and the kernel. patterns = SWPatternSet(5, 6, 20) swseqs = [SWSequence(s, patterns) for s in sequences] kernel = ProtSpamKernel(patterns, distance=ProtSpamDistance.Evolutionary) distance = kernel.call(swseqs[0], swseqs[1]) distance = kernel(swseqs[0], swseqs[1]) # equivalent -- kernel(a, b) syntax assert distance >= 0.0
- call(ref_sample: utils.SWSequence, query: utils.SWSequence) float¶
Compute the distance between
ref_sampleandquery, per this kernel’sdistance()mode.- Parameters:
ref_sample – Reference sequence. Must have been built from the same
SWPatternSetas this kernel’spatterns().query – Query sequence. Same requirement.
- Returns:
The distance – see
ProtSpamDistance.
- Panics:
ref_sample/querymust have been built from the sameSWPatternSetas this kernel’spatterns(). If they weren’t, this can panic (index out of range, if the mismatched set has fewer patterns) or – more insidiously – silently compare the wrong patterns’ spaced words against each other with no panic at all, if the mismatched set merely has a different pattern at the same index.
- distance() ProtSpamDistance¶
Which value
callreports.
- patterns() utils.SWPatternSet¶
The shared pattern set spaced words are matched against.
- significance_threshold() int¶
Minimum BLOSUM62 score for a spaced-word match to be considered homologous.
- class relag.kernels.protspam.ProtSpamDistance¶
Bases:
objectWhich distance
ProtSpamKernel.callreports.MismatchRate: the raw mismatch rate itself (fraction of don’t-care positions that mismatch, pooled across every pattern’s accepted spaced-word matches) – always in[0, 1].1.0if no spaced word matched at all, or if every accepted match’s don’t-care positions mismatched outright.Evolutionary: the mismatch rate corrected into a distance via the Kimura two-parameter formula – in[0, inf].infif the mismatch rate is undefined (no match at all) or high enough (> ~0.8541) that the correction’s log argument is non-positive.
- Evolutionary = ProtSpamDistance.Evolutionary¶
- MismatchRate = ProtSpamDistance.MismatchRate¶
relag.kernels.vectors¶
Vector distance kernels.
- class relag.kernels.vectors.Cosine¶
Bases:
objectCosine distance:
1 - dot(a, b) / (||a|| * ||b||).0.0if either vector is the zero vector.Example:
import numpy as np from relag.kernels.vectors import Cosine a = np.array([1.0, 0.0], dtype=np.float32) b = np.array([0.0, 1.0], dtype=np.float32) k = Cosine() assert k.call(a, b) == k(a, b) == 1.0
- call(a: numpy.typing.NDArray[numpy.float32], b: numpy.typing.NDArray[numpy.float32]) float¶
Compute the cosine distance between two 1D
float32numpy arrays.Reads directly from each array’s buffer – no copy.
- Parameters:
a – First vector.
b – Second vector.
- Returns:
Distance in
[0.0, 2.0].0.0means the same direction,2.0means exactly opposite directions.
- class relag.kernels.vectors.L1¶
Bases:
objectManhattan (L1) distance:
sum(|a_i - b_i|).Example:
import numpy as np from relag.kernels.vectors import L1 a = np.array([1.0, 2.0, 3.0], dtype=np.float32) b = np.array([4.0, 0.0, 3.0], dtype=np.float32) k = L1() assert k.call(a, b) == k(a, b) == 5.0
- call(a: numpy.typing.NDArray[numpy.float32], b: numpy.typing.NDArray[numpy.float32]) float¶
Compute the L1 distance between two 1D
float32numpy arrays.Reads directly from each array’s buffer – no copy.
- Parameters:
a – First vector.
b – Second vector.
- Returns:
Distance in
[0.0, inf].0.0means identical vectors.
- class relag.kernels.vectors.L2¶
Bases:
objectEuclidean (L2) distance:
sqrt(sum((a_i - b_i)²)).Example:
import numpy as np from relag.kernels.vectors import L2 a = np.array([0.0, 0.0], dtype=np.float32) b = np.array([3.0, 4.0], dtype=np.float32) k = L2() assert k.call(a, b) == k(a, b) == 5.0
- call(a: numpy.typing.NDArray[numpy.float32], b: numpy.typing.NDArray[numpy.float32]) float¶
Compute the L2 distance between two 1D
float32numpy arrays.Reads directly from each array’s buffer – no copy.
- Parameters:
a – First vector.
b – Second vector.
- Returns:
Distance in
[0.0, inf].0.0means identical vectors.