StructurePreprocessor.encode

StructurePreprocessor.encode(df_seq, *, features, pdb_folder=None, pae_folder=None, domain_folder=None, ss_mode='ss3', gap_handling='pad', plddt_disorder_threshold=70.0, local_window=5, pae_band_edges=(5, 15), on_failure='nan', return_df=False)[source]

Encode a mixed feature list, routing each key to the right backend.

One entry point that hides the encode_dssp / encode_pdb / encode_pae / encode_domains split: each requested feature key is dispatched to its owning encoder via the feature registry, and the per-backend outputs are merged into a single [0, 1]-normalized dict_num whose D-axis follows the requested features order (so it lines up with build_scales() / build_cat()). You no longer need to know which source a key comes from or call aaanalysis.combine_dict_nums() yourself.

Added in version 1.1.0.

Parameters:
  • df_seq (pd.DataFrame, shape (n_samples, n_seq_info)) – DataFrame containing an entry column with unique protein identifiers and a sequence column with full protein sequences.

  • features (list of str) – Any mix of feature keys from the StructurePreprocessor registry. Each key is routed to its owning encoder (DSSP / PDB / PAE / domains); keys from different sources may be freely interleaved.

  • pdb_folder (str or pathlib.Path, optional) – Directory of <entry>.pdb / .cif files. Required when the requested features include any DSSP or PDB key (DSSP may instead reuse pre-computed columns already on df_seq).

  • pae_folder (str or pathlib.Path, optional) – Directory of AlphaFold PAE sidecar JSONs. Required when the requested features include any PAE key.

  • domain_folder (str or pathlib.Path, optional) – Directory of per-entry chopping files. Required when the requested features include any domain key, unless df_seq already carries a chopping column.

  • ss_mode ({'ss3', 'ss8'}, default='ss3') – Forwarded to encode_dssp() when a DSSP key is requested.

  • gap_handling ({'pad', 'omit'}, default='pad') – Forwarded to encode_dssp() when a DSSP key is requested.

  • plddt_disorder_threshold (float, default=70.0) – Forwarded to encode_pdb() when the plddt_disorder key is requested.

  • local_window (int, default=5) – Forwarded to encode_pae() for the local / distal PAE means.

  • pae_band_edges (tuple of (int, int), default=(5, 15)) – Forwarded to encode_pae() for pae_band_means.

  • on_failure ({'nan', 'drop', 'raise'}, default='nan') – Passed through to every routed backend. 'nan' isolates failures (entry-level entries or single features are NaN-filled, everything else kept); 'drop' removes entries that any routed backend dropped (the merged output keeps only entries present in every source); 'raise' re-raises.

  • return_df (bool, default=False) – If True, also return an echo of df_seq (kept entries) plus a boolean encode_ok column that is the per-entry AND of every routed backend’s entry-level status.

Returns:

  • dict_num (dict[str, np.ndarray]) – {entry: (L_entry, D_total) ndarray} with the requested features concatenated along D in the given order. Values are in [0, 1] (NaN for unresolved positions or isolated features).

  • df_seq_out (pd.DataFrame) – Returned only when return_df=True. Echo of df_seq (kept entries) plus a boolean encode_ok column.

Raises:
  • ValueError – On invalid arguments, unknown feature keys, or a missing folder required by one of the routed backends.

  • RuntimeError – Propagated from a routed backend under on_failure='raise'.

See also

Examples

encode is the single feature/backend router: you pass one mixed features list and it dispatches each key to its owning encoder (encode_dssp / encode_pdb / encode_pae / encode_domains) via the feature registry, then merges the per-source tensors into one [0, 1]-normalized dict_num whose D-axis follows the requested feature order. You no longer need to know which source a key comes from or call combine_dict_nums yourself. Here we mix PDB ATOM features (bfactor, plddt) with an AlphaFold PAE summary (pae_row_mean) using the bundled AF_TINY fixture.

import warnings
import tempfile, shutil
from pathlib import Path
import numpy as np
import pandas as pd
import aaanalysis as aa
import aaanalysis.utils as ut
aa.options['verbose'] = False
warnings.filterwarnings('ignore')

PDB_FIXTURES = Path(aa.__file__).resolve().parent / '_data' / 'pdb_test'
strp = aa.StructurePreprocessor(verbose=False)
df_seq = pd.DataFrame({'entry': ['AF_TINY'],
                       'sequence': ['ACDEFGHIKLMNPQRSTVWYACDEFGHIKL']})
# PAE sidecar under the <entry>.json name the resolver expects.
pae_dir = tempfile.mkdtemp()
shutil.copy(PDB_FIXTURES / 'AF_TINY_pae.json', Path(pae_dir) / 'AF_TINY.json')

# One call, keys from two different sources, interleaved in any order.
feats = ['bfactor', 'pae_row_mean', 'plddt']
dict_num, df_out = strp.encode(df_seq=df_seq, features=feats,
                              pdb_folder=str(PDB_FIXTURES), pae_folder=pae_dir,
                              return_df=True)
arr = dict_num['AF_TINY']
print('merged shape (L, D):', arr.shape, '-> D follows feats order', feats)
merged shape (L, D): (30, 3) -> D follows feats order ['bfactor', 'pae_row_mean', 'plddt']
# return_df=True echoes df_seq (kept entries) plus a combined 'encode_ok'
# column = AND of every routed backend's entry-level status.
aa.display_df(df_out, n_rows=10, show_shape=True)
DataFrame shape: (1, 3)
  entry sequence encode_ok
1 AF_TINY ACDEFGHIKLMNPQRSTVWYACDEFGHIKL True

Per-feature failure isolation. If one feature is unavailable (for example depth, which needs the external msms binary) or its encoder raises for an entry, only that feature’s column(s) are filled with NaN while every other feature is kept and the entry is retained; a single UserWarning names the isolated feature. This replaces the old behavior where one unavailable feature NaN-ed the whole entry. Below, depth is isolated (its column is all NaN) while bfactor and pae_row_mean come through intact.

feats2 = ['bfactor', 'depth', 'pae_row_mean']
dn = strp.encode(df_seq=df_seq, features=feats2,
                pdb_folder=str(PDB_FIXTURES), pae_folder=pae_dir)
v = dn['AF_TINY']
for j, key in enumerate(feats2):
    print(f'{key:>14}: all-NaN column? {bool(np.isnan(v[:, j]).all())}')
     bfactor: all-NaN column? False
       depth: all-NaN column? True
pae_row_mean: all-NaN column? False

Further parameters. StructurePreprocessor.encode also accepts: domain_folder — directory of per-entry chopping files, required when a domain key is requested unless df_seq already carries a chopping column; ss_mode / gap_handling — forwarded to encode_dssp when a DSSP key is requested; plddt_disorder_threshold — forwarded to encode_pdb for the plddt_disorder key; local_window / pae_band_edges — forwarded to encode_pae; on_failure'nan' isolates failures (default), 'drop' keeps only entries present in every routed source, 'raise' re-raises; return_df — also return the (dict_num, df_seq_out) pair.

encode() accepts every backend’s option in one call; the router applies each only to the features that need it.

# Every routing option, passed explicitly (unused ones are ignored per feature).
dict_num2 = strp.encode(
    df_seq=df_seq,
    features=['bfactor', 'plddt', 'pae_row_mean'],
    pdb_folder=str(PDB_FIXTURES),
    pae_folder=pae_dir,
    domain_folder=None,             # only used for domain-derived features
    ss_mode='ss3',                  # DSSP secondary-structure alphabet: 'ss3' | 'ss8'
    gap_handling='pad',             # missing residues: 'pad' (NaN) | 'omit'
    plddt_disorder_threshold=70.0,  # AF pLDDT cutoff for the disorder feature
    local_window=5,                 # residue window for local-window features
    pae_band_edges=(5, 15),         # PAE distance-band edges (near / mid / far)
    on_failure='nan',               # per-feature failure policy: 'nan' | 'drop' | 'raise'
)
print('all routing options applied:', dict_num2['AF_TINY'].shape)