utils.FeatureEncoding#

Hand-crafted sequence feature encoders.

This module implements a collection of classical, hand-engineered feature encodings for RNA/DNA sequences, producing a fixed-length per-position feature matrix. It is mainly used to generate the 99-channel biochemical/k-mer feature tensor consumed by BRIDGE (the biochem input branch) and related baselines.

The encodings here are deterministic and do not require model parameters.

Who this is for#

  • Users who need to convert raw nucleotide sequences into BRIDGE-compatible biochemical/k-mer features.

  • Pipelines that prepare biochem tensors for training/inference.

  • Researchers who want to reproduce or inspect the exact feature definitions used in the project.

This module is not a general FASTA parser and does not perform padding/truncation checks beyond the fixed-size arrays it allocates.

Key outputs#

The main outputs are produced by:

  • dealwithdata(protein): Reads paired dataset files and returns a batch tensor.

  • dealwithdata2(seq): Encodes a single sequence and returns a batch of size 1.

Both return a NumPy array of shape (N, 101, 99) (or (1, 101, 99) for single input).

Feature definition (per position)#

All features are aligned to the same position axis of length 101. The final feature vector dimension is 99, constructed as:

  1. Base encoding + padding indicator (3 dims) via processFastaFile:
    • A → [1, 1, 1]

    • U → [0, 0, 1]

    • C → [0, 1, 0]

    • G → [1, 0, 0]

    • padded positions (i >= seq_length) set the last channel to 1 (padding flag)

    Shape: (101, 3)

  2. Nucleotide density (ND, 1 dim) via nd: Running frequency of the nucleotide observed at each position.

    Shape: (101,) (later combined to (101, 1) during stacking)

  3. Dinucleotide physicochemical properties (DPCP, 11 dims) via dpcp: A fixed 11-dimensional vector per dinucleotide at position i (for seq[i:i+2]). The implementation fills positions 0..len(seq)-2 and leaves the last position(s) as zeros. In dealwithdata / dealwithdata2, DPCP is normalized by dividing by 101.

    Shape: (101, 11)

  4. Positional k-mer frequency tensors via coden for k=1,2,3:
    • k=1 vocabulary size 4

    • k=2 vocabulary size 16

    • k=3 vocabulary size 64

    IMPORTANT: coden assigns the global count of the k-mer (across the entire sequence) to the row corresponding to its start position, not a one-hot indicator. Counts are normalized by dividing by 100.

    Shapes:
    • k=1: (101, 4)

    • k=2: (101, 16)

    • k=3: (101, 64)

    Concatenated: (101, 84)

Final concatenation#

The final per-sequence matrix is:

  • [base(3) + ND(1) + DPCP(11)](101, 15)

  • concatenate k-mers (101, 84)

  • total: (101, 99)

Input conventions and normalization#

Alphabet normalization

Most functions expect an RNA alphabet {A, U, C, G}. When encoding:

  • DNA T is converted to RNA U (T U).

Fixed length assumption

Many arrays are allocated with a fixed first dimension of 101. This module assumes sequences are at most 101 nt (or that upstream code ensures this). If sequences are longer than 101, encoders that index by position (e.g., nd) may fail.

Dataset file assumption (for dealwithdata)#

dealwithdata(protein) reads:

  • ./dataset/{protein}_pos.fa

  • ./dataset/{protein}_neg.fa

and assumes a simple FASTA-like layout where each record spans 3 lines:

  • line i : header (ignored)

  • line i+1 : sequence (used)

  • line i+2 : extra line (ignored; may be blank/structure/etc.)

If your FASTA uses the standard 2-line format, you must adapt this reader.

How to use#

Encode a single sequence (inference / interactive):

from features import dealwithdata2
x = dealwithdata2("ACGTACGTACGT")   # returns shape (1, 101, 99)

Encode a dataset by protein id:

from features import dealwithdata
X = dealwithdata("RBFOX2")          # reads ./dataset/RBFOX2_pos.fa and _neg.fa
# X has shape (N, 101, 99)

Notes and caveats#

  • Fixed length 101: The encoders allocate arrays of length 101 and do not truncate explicitly. If len(seq) > 101, functions like nd will index out of range. Ensure upstream padding/truncation to 101.

  • coden semantics: The positional k-mer matrices encode global counts at each position (scaled by /100), not one-hot presence. This is intentional but easy to misinterpret.

  • DPCP lookup: dpcp expects only valid dinucleotides over A/U/C/G. After normalization, ensure no other characters remain or dictionary lookup will fail.

Functions

coden(seq, kmer, tris)

Construct a position-wise k-mer feature tensor of shape (101, |V|).

dealwithdata(protein)

Batch-encode biochemical and k-mer features from paired FASTA files.

dealwithdata2(seq)

Encode a single sequence into the same feature representation as dealwithdata.

dpcp(seq)

Encode dinucleotide physicochemical properties (DPCP) into an 11-dimensional feature vector.

frequency(seq, kmer, coden_dict)

Count occurrences of each k-mer along a sequence and return as an index→count dictionary.

get_1_trids()

Build an index mapping for all possible 1-mers over RNA alphabet {A, C, G, U}.

get_2_trids()

Build an index mapping for all possible 2-mers over RNA alphabet {A, C, G, U}.

get_3_trids()

Build an index mapping for all possible 3-mers over RNA alphabet {A, C, G, U}.

nd(seq, seq_length)

Compute cumulative nucleotide density (ND) per position.

processFastaFile(seq)

Encode a nucleotide sequence into a 3-channel representation with padding up to length 101.

utils.FeatureEncoding.get_1_trids()[source]#

Build an index mapping for all possible 1-mers over RNA alphabet {A, C, G, U}.

Returns:

dict[str, int] Mapping from 1-mer string to integer index (size = 4). Example: {‘A’: 0, ‘C’: 1, ‘G’: 2, ‘U’: 3} (exact ordering depends on generation logic).

utils.FeatureEncoding.get_2_trids()[source]#

Build an index mapping for all possible 2-mers over RNA alphabet {A, C, G, U}.

Returns:

dict[str, int] Mapping from 2-mer string to integer index (size = 4^2 = 16).

utils.FeatureEncoding.get_3_trids()[source]#

Build an index mapping for all possible 3-mers over RNA alphabet {A, C, G, U}.

Returns:

dict[str, int] Mapping from 3-mer string to integer index (size = 4^3 = 64).

utils.FeatureEncoding.frequency(seq, kmer, coden_dict)[source]#

Count occurrences of each k-mer along a sequence and return as an index→count dictionary.

This helper converts DNA ‘T’ to RNA ‘U’ before looking up the k-mer index. The returned dictionary is sparse (only k-mers observed in the sequence appear).

Parameters:
  • seq (str) – Input nucleotide sequence. ‘T’ will be internally treated as ‘U’.

  • kmer (int) – k-mer size.

  • coden_dict (dict[str, int]) – Mapping from k-mer string to integer index (created by get_1_trids/get_2_trids/get_3_trids).

Returns:

dict[int, int] Dictionary mapping k-mer index to its occurrence count in the sequence.

utils.FeatureEncoding.coden(seq, kmer, tris)[source]#

Construct a position-wise k-mer feature tensor of shape (101, |V|).

For each position i (0-based), this tensor places the global frequency of the k-mer starting at i into the corresponding k-mer index column. This yields a sparse matrix where each row has at most one non-zero entry.

IMPORTANT DESIGN NOTE#

This implementation encodes global counts at each position (not a one-hot). The counts are normalized by 100 (consistent with the original feature scaling in the provided implementation).

Parameters:
  • seq (str) – Input nucleotide sequence (will treat ‘T’ as ‘U’).

  • kmer (int) – k-mer size (1, 2, or 3).

  • tris (dict[str, int]) – k-mer -> index mapping.

returns:

np.ndarray Array of shape (101, len(tris)) containing position-wise frequency features. Rows beyond the valid k-mer start positions remain all zeros.

utils.FeatureEncoding.processFastaFile(seq)[source]#

Encode a nucleotide sequence into a 3-channel representation with padding up to length 101.

Encoding scheme (phys_dic)#

A -> [1, 1, 1] U -> [0, 0, 1] C -> [0, 1, 0] G -> [1, 0, 0]

Padding rule#

For padded positions (i >= seqLength), the last channel is set to 1. This acts as an explicit padding indicator so the model can distinguish real residues from padded positions.

Parameters:

seq (str) – Input sequence consisting of {A, U, C, G} (after upstream normalization).

returns:

np.ndarray Array of shape (101, 3).

utils.FeatureEncoding.dpcp(seq)[source]#

Encode dinucleotide physicochemical properties (DPCP) into an 11-dimensional feature vector.

For each position i, this function assigns the property vector of the dinucleotide seq[i:i+2]. Positions near the end that do not have a full dinucleotide remain zeros.

Parameters:

seq (str) – Input RNA sequence (A/U/C/G).

Returns:

np.ndarray Array of shape (101, 11). Only positions 0..len(seq)-2 are filled.

utils.FeatureEncoding.nd(seq, seq_length)[source]#

Compute cumulative nucleotide density (ND) per position.

For each position j, ND is defined as:

count(seq[j] in seq[0:j+1]) / (j+1)

i.e., the running fraction of the nucleotide observed at position j.

Parameters:
  • seq (str) – Input RNA sequence.

  • seq_length (int) – Total length used for output (typically 101).

Returns:

np.ndarray Array of length seq_length containing per-position ND values.

utils.FeatureEncoding.dealwithdata(protein)[source]#

Batch-encode biochemical and k-mer features from paired FASTA files.

This function reads:
  • ./dataset/{protein}_pos.fa

  • ./dataset/{protein}_neg.fa

and encodes each sequence into a fixed-length feature tensor.

Notes

FASTA assumption The input FASTA is assumed to be organized in blocks of 3 lines per record:

  • line i : header

  • line i+1 : sequence

  • line i+2 : (optional/unused, e.g., structure or blank)

This function uses only the sequence line (i+1).

Output features (concatenated along the last axis; length = 101)
  • 3-dim base encoding with padding indicator (processFastaFile): (101, 3)

  • 1-dim nucleotide density ND (nd): (101, 1)

  • 11-dim dinucleotide physicochemical properties DPCP (dpcp): (101, 11)

  • k-mer frequency tensors for k=1,2,3 (coden): (101, 4 + 16 + 64)

Final per-sequence shape: (101, 99); batch output: (N, 101, 99).

Parameters:

protein (str) – Dataset identifier used to locate the FASTA files.

Returns:

np.ndarray Feature tensor of shape (N, 101, F) for all sequences from pos and neg files. The concatenation order is: [base+pad, ND, DPCP, kmer(1), kmer(2), kmer(3)].

utils.FeatureEncoding.dealwithdata2(seq)[source]#

Encode a single sequence into the same feature representation as dealwithdata.

This is a single-instance version intended for inference or interactive usage. It applies the same normalization steps and feature concatenation scheme.

Parameters:

seq (str) – Raw nucleotide sequence (DNA ‘T’ will be converted to RNA ‘U’; ambiguous ‘N’ will be replaced with ‘A’).

Returns:

np.ndarray Feature tensor of shape (1, 101, F) where F matches dealwithdata output.