haddock.libs.libscan module

Shared helpers for the mutagenesis scan modules.

The alascan (alanine), rnascan (RNA base) and dnascan (DNA base pair) analysis modules share the same scoring, z-score, cluster-output, b-factor and TSV-writing machinery. The common, module-agnostic pieces live here; each module keeps only its own mutation logic (which residues/atoms are mutated, how the interface is scanned, and how mutation jobs are executed).

class haddock.libs.libscan.AddDeltaBFactor(model: PDBFile, path: Path, model_results: List[MutationResult])[source]

Bases: object

Add the (normalised) delta score into the b-factor column of a PDB.

Subclasses set module_name (used for the output filename suffix, <model>_<module_name>.pdb) and may override _residue_keys() to control which residues each mutation result is attributed to (e.g. both nucleotides of a base pair for dnascan).

module_name: str = 'scan'

filename suffix / module identifier; overridden by subclasses

normalize_score(score: float) → float[source]

Normalise the input score based on observed scores for this model

In case normalisation cannot be performed, returns 50.0

Parameters:

score (float) – Input score to be normalized

Returns:

norm100 (float) – Normalized score between 0 and 100

reorder_results() → None[source]

Aggregate mutation results into a per-residue delta score map.

Organise mutation results into a dictionary with chain-resid keys and, as values, the mean delta score over all mutations attributed to that residue (e.g. {"A-115": 5.2}), and determine the min and max score within the model to normalise the data.

run() → PDBFile[source]

Perform the addition of delta scores as bfactor in pdb file.

write_delta_score_to_pdb(output_path: Path) → Path[source]

Add delta scores as b-factors in PDB file.

Parameters:

output_path (Path) – Path to the pdb file.

Returns:

output_path (Path) – Path to the pdb file with the b-factors added.

class haddock.libs.libscan.BaseInterfaceScanner(model: str | Path | Any, params: Dict[str, Any] | None = None)[source]

Bases: object

Common state shared by every module’s InterfaceScanner.

Subclasses add their own mutation target (e.g. mutation_res for alascan or scan_bases for the nucleic-acid modules) and implement run(), which detects the interface and builds the module-specific mutation jobs.

haddock.libs.libscan.CLUSTER_STAT_COLUMNS = ['delta_score', 'delta_score_std', 'delta_vdw', 'delta_vdw_std', 'delta_elec', 'delta_elec_std', 'delta_desolv', 'delta_desolv_std', 'delta_bsa', 'delta_bsa_std', 'frac_pres']

statistics columns appended after the per-module identity columns in the cluster TSV output (mean/std of each energy term plus the population fraction)

class haddock.libs.libscan.ClusterOutputer(cluster_scan_data: Dict[str, Dict[str, float | int]], clt_id: str, clt_population: int, scan_residue: str | None = None, generate_plot: bool = False, offline: bool = False, splitplot: bool = False)[source]

Bases: object

Base class writing the per-cluster scan TSV (and optional plot).

Subclasses provide the module-specific identity columns/rows (which depend on whether a mutation is a single residue or a base pair) via _identity_columns() and _identity_row(), and set the class attributes module_name, sort_columns, zscore_reference and default_scan_residue. The averaging, z-scoring, sorting, file writing and (harmonised) plot handling are shared.

default_scan_residue: str = 'residue'
gen_plot(df_scan_clt: DataFrame) → None[source]

Generate the scan plot based on provided data.

Parameters:

df_scan_clt (pd.DataFrame) – The data frame containing the data to be plotted.

module_name: str = 'scan'
plot_xaxis_title: str = 'Residue Name'

x-axis label of the cluster plot; mutational scans override it

run() → str[source]

Write cluster scan output to a scan_clt_X.tsv file (and plot).

Returns:

scan_clt_filename (str) – Name of the tsv file written

sort_columns = ['chain', 'resid']
zscore_reference: str = 'residues'
class haddock.libs.libscan.ModelPointMutation(model_path: Path, model_id: str, chain: str, resid: int, ori_resname: str, target_resname: str, native_scores: Tuple[float, float, float, float, float], output_mutants: bool = False, ligand_param_fname: Path | str = '', ligand_top_fname: Path | str = '')[source]

Bases: object

Execute a single point mutation and score it against the native model.

Shared by the alascan and rnascan modules, whose per-model scoring flow is identical; only the mutate primitive differs (protein residue vs RNA base). Each module keeps a thin run() that forwards its own module-level mutate and calc_score to _run() (so both stay patchable in the module namespace for tests).

class haddock.libs.libscan.MutationResult(model_id: str, chain: str, resid: int, ori_resname: str, target_resname: str, mutant_scores: Tuple[float, float, float, float, float], delta_scores: Tuple[float, float, float, float, float], success: bool, error_msg: str | None = None, partner_chain: str | None = None, partner_resid: int | None = None, partner_ori_resname: str | None = None, partner_target_resname: str | None = None)[source]

Bases: object

Result from a single mutation.

The partner_* fields are only used by modules that perform paired (double) mutations, such as dnascan (base-pair mutations); they default to None for single-residue mutations (alascan, rnascan).

chain: str
delta_scores: Tuple[float, float, float, float, float]
error_msg: str | None = None
model_id: str
mutant_scores: Tuple[float, float, float, float, float]
ori_resname: str
partner_chain: str | None = None
partner_ori_resname: str | None = None
partner_resid: int | None = None
partner_target_resname: str | None = None
resid: int
success: bool
target_resname: str
haddock.libs.libscan.STANDARD_SCAN_COLUMNS = ['chain', 'res', 'ori_resname', 'end_resname', 'score', 'vdw', 'elec', 'desolv', 'bsa', 'delta_score', 'delta_vdw', 'delta_elec', 'delta_desolv', 'delta_bsa']

columns of the per-model scan TSV shared by single-residue scans

haddock.libs.libscan.add_zscores(df_scan_clt, column='delta_score')[source]

Add z-scores to the dataframe.

Parameters:
  • df_scan (pandas.DataFrame) – Dataframe with the scan results for the model.

  • colunm (str) – Column to calculate the z-score.

Returns:

df_scan (pandas.DataFrame) – Dataframe with the z-scores added.

haddock.libs.libscan.build_resname_dict(coords: Dict[Tuple, object]) → Dict[str, str][source]

Map "{chain}-{resid}" to its residue name from a coordinate dict.

Parameters:

coords (dict) – Coordinate dictionary keyed by (chain, resid, atom_name, resname) tuples, as returned by load_coords(..., add_resname=True).

Returns:

dict – Mapping of "{chain}-{resid}" to the residue name (first occurrence).

haddock.libs.libscan.calc_score(pdb_f: str, run_dir: str, outputpdb: bool = False, ligand_param_fname: Path | str = '', ligand_top_fname: Path | str = '') → Tuple[float, float, float, float, float][source]

Calculate the score of a model.

Parameters:
  • pdb_f (str) – Path to the pdb file.

  • run_dir (str) – Path to the run directory.

  • outputpdb (bool, optional) – If True, the output, energy-minimized pdb file will be written. Default is False.

  • ligand_param_fname (Union[Path, str]) – Path to additional parameter file used by CNS

  • ligand_top_fname (Union[Path, str]) – Path to additional topology file used by CNS

Returns:

  • Tuple[float, float, float, float, float] – All the scores

  • score (float) – Haddock score.

  • vdw (float) – Van der Waals energy.

  • elec (float) – Electrostatic energy.

  • desolv (float) – Desolvation energy.

  • bsa (float) – Buried surface area.

Raises:

FileNotFoundError – Error when the file could not be located.

haddock.libs.libscan.filter_interface(interface: Dict[str, List[int]], filter_resdic: Dict[str, List[int]], user_chains: List[str]) → Dict[str, List[int]][source]

Restrict the detected interface to the user-selected residues/chains.

If the user provided target residues (resdic_*), the interface is intersected with them. Otherwise, if the user provided target chains, the interface is restricted to those chains. With neither, the interface is returned unchanged.

Parameters:
  • interface (dict) – Mapping of chain id to its list of interface residue numbers.

  • filter_resdic (dict) – Mapping of chain id to user-requested residue numbers. The sentinel {"_": []} means “no residue restriction”.

  • user_chains (list of str) – User-requested chain ids (used only when no residue restriction is set).

Returns:

dict – The filtered interface.

haddock.libs.libscan.get_atoms_to_keep(ori_resname: str, target_resname: str, *, backbone_atoms: List[str], purines: Tuple[str, ...], pyrimidines: Tuple[str, ...]) → Dict[str, str][source]

Return the atoms to preserve when mutating one nucleic-acid base into another.

The result maps each atom name to keep (as found in the original residue) to the atom name it must be written with in the mutated residue. Backbone atoms and same-ring-type base atoms keep their name (mapped to themselves).

The sugar-phosphate backbone (backbone_atoms) is always kept. When the original and target bases are of the same ring type (both purines or both pyrimidines) the base ring atoms common to that type are kept as well, so that the base orientation is preserved and CNS only rebuilds the differing substituents. For cross-type mutations (purine <-> pyrimidine) the three glycosidic-region anchor atoms are kept and renamed to their counterpart in the target ring system.

Parameters:
  • ori_resname (str) – Original (wild-type) residue name.

  • target_resname (str) – Target base residue name.

  • backbone_atoms (list of str) – Sugar-phosphate backbone atoms to always keep (RNA keeps O2', DNA does not).

  • purines, pyrimidines (tuple of str) – Residue names classified as purines / pyrimidines for this module.

Returns:

dict of str -> str – Mapping of original atom name -> atom name to write for the mutated nucleotide.

haddock.libs.libscan.get_score_string(pdb_f: str, run_dir: str, outputpdb: bool = False, ligand_param_fname: Path | str = '', ligand_top_fname: Path | str = '') → List[str][source]

Get score output from cli_score.main.

Parameters:
  • pdb_f (str) – Path to the pdb file.

  • run_dir (str) – Path to the run directory.

  • outputpdb (bool, optional) – If True, the output, energy-minimized pdb file will be written. Default is False.

  • ligand_param_fname (Union[Path, str]) – Path to additional parameter file used by CNS.

  • ligand_top_fname (Union[Path, str]) – Path to additional topology file used by CNS.

Returns:

out (list[str]) – List of strings with the score output.

haddock.libs.libscan.group_scan_by_cluster(models: List[PDBFile], results_by_model: Dict[str, List[MutationResult]], ident_builder, metadata_builder=None) → Tuple[Dict[str, Dict[str, Dict[str, float | int]]], Dict[str, int]][source]

Group per-model scan data per cluster.

Parameters:
  • models (List[PDBFile]) – List of input models.

  • results_by_model (dict) – Mutation results keyed by model id.

  • ident_builder (callable) – Function mapping a MutationResult to its unique string identifier.

  • metadata_builder (callable, optional) – Function mapping a MutationResult to a dict of static metadata stored alongside the accumulated delta lists (used by paired-mutation modules).

Returns:

  • clt_scan (dict) – Scan data for each cluster, grouped by mutation identifier.

  • clt_pops (dict) – Number of entries for each cluster.

haddock.libs.libscan.make_scan_plot(df: DataFrame, clt_id, scan_res: str = 'residue', offline: bool = False, splitplot: bool = False, xaxis_title: str = 'Residue Name') → str[source]

Generate a scan cluster plot (harmonised across scan modules).

Shared plotting entry point for the alascan, rnascan and dnascan modules. Depending on splitplot the energy components are either drawn as separate stacked panels (one panel per energy term) or overlaid in a single grouped-bar panel.

Parameters:
  • df (pandas.DataFrame) – Cluster scan data to plot.

  • clt_id (int or str) – Cluster identifier.

  • scan_res (str, optional) – Label used for the scan (e.g. "ALA", "RNA base").

  • offline (bool, optional) – Whether the plot must be functional offline, by default False.

  • splitplot (bool, optional) – If True draw one panel per energy component; if False (default) overlay all components in a single panel.

  • xaxis_title (str, optional) – Label of the x-axis, by default “Residue Name”. Mutational scans use “Mutation” instead.

Returns:

html_output_filename (str) – Name of the plot generated.

haddock.libs.libscan.norm_atom_name(atom_name: str) → str[source]

Normalise atom names so that primes are always written as ‘.

haddock.libs.libscan.standard_scan_row(result: MutationResult) → list[source]

Build a per-model TSV row for a single-residue mutation result.

haddock.libs.libscan.validate_scan_bases(scan_bases: List[str], allowed: Tuple[str, ...], *, base_kind: str, allowed_note: str) → List[str][source]

Validate and normalise a list of target nucleic-acid bases.

Entries are upper-cased and de-duplicated (keeping first-seen order) and must belong to allowed.

Parameters:
  • scan_bases (list of str) – Target bases requested by the user.

  • allowed (tuple of str) – Canonical residue names accepted by the calling module.

  • base_kind (str) – Human-readable base family (e.g. "RNA" or "DNA") used in the “empty list” error message.

  • allowed_note (str) – Sentence describing the accepted values (and why the other naming is rejected) used in the “invalid entry” error message.

Returns:

list of str – Normalised, de-duplicated list of canonical residue names, in the order first seen.

Raises:

ConfigurationError – If scan_bases is empty or contains an unrecognised base.

haddock.libs.libscan.write_scan_out(results: ~typing.List[~haddock.libs.libscan.MutationResult], model_id: str, module_name: str, sort_columns: ~typing.List[str], row_builder=<function standard_scan_row>, columns: ~typing.List[str] | None = None, zscore_reference: str = 'residues', extra_header_lines=()) → None[source]

Save mutation results for one model to scan_{model_id}.tsv.

Parameters:
  • results (List[MutationResult]) – List of mutation results from scanning.

  • model_id (str) – Identifier for the model used in the filename.

  • module_name (str) – Module label used in the file header (alascan/rnascan/…).

  • sort_columns (List[str]) – Column names used to sort the rows.

  • row_builder (callable) – Function mapping a successful MutationResult to a TSV row.

  • columns (List[str], optional) – Column names of the rows; defaults to STANDARD_SCAN_COLUMNS.

  • zscore_reference (str) – Wording used in the z-score header comment (residues/mutations).

  • extra_header_lines (iterable of str) – Extra comment lines added to the header (without the leading #).

Notes

If results is empty, no file is created.