moleculekit.tools.residue_titration module#
Prepare non-standard residues for pKa titration and fold the result back into per-residue build templates.
The public entry points are capNonstandardResiduesForTitration() and
templatesFromTitration(), both dict-in / dict-out ({key: smiles}).
The caller runs its own pKa tool (e.g. AcePka) over the titration SMILES and
hands the protonated result back; moleculekit never reads the tool’s file
formats.
Each residue is built from its full base SMILES (an RCSB ligand descriptor or a caller override), so it carries the complete chemistry even when the deposited structure has a trimmed sidechain. Every outgoing inter-residue bond is then capped with an inert stand-in for its real partner, so the pKa tool sees a chemically sane molecule that titrates the residue’s own groups in a faithful environment. Most caps are neutral (an amide, a methyl); a phosphodiester partner is kept as a phosphate, so an internal nucleotide carries the real, charged backbone environment a terminal one would not:
a backbone peptide bond gets an amide cap - acetyl on the
Nside, N-methyl on the carbonylCside (the ACE / NME that keep a mid-chain backbone neutral);a sidechain / scaffold crosslink gets an inert cap chosen to keep the junction atom non-titratable: acetyl on a severed nitrogen, N-methyl on an amide carbonyl carbon, and for any other junction a cap reflecting the real partner element (a nitrogen partner gives an amide, an oxygen partner a hydroxyl, a phosphorus partner a phosphate, everything else a methyl). When a condensation crosslink (glycosidic, phosphoester, …) left the junction atom fully valent in the free-form SMILES, the displaced leaving group (the base-SMILES atom absent from the deposited residue) is stripped first;
a genuine free terminus or free-ligand end is left uncapped, so the pKa tool assigns its charge (a real C-terminus deprotonates, an N-terminus protonates).
The backbone atoms are located by their structure names (N / C) mapped
onto the SMILES; crosslink atoms are found by walking mol.bonds and mapped
the same way. Coordinates never affect the returned SMILES - only connectivity
does. After titration, templatesFromTitration() strips the caps back off
(the residue is a subgraph of its capped molecule) to yield one template SMILES
per residue for the builder.
- moleculekit.tools.residue_titration.capNonstandardResiduesForTitration(mol, specs, smiles=None, _logger=True)#
Build per-context pKa-titration input SMILES for the non-standard residues, keyed by
new_resname or resname.Each chain-resident NCAA is capped for its chain context, and every scaffold / covalent-ligand residue has its non-peptide crosslink(s) inert- capped the same way (see
_cap_residue_smiles()); a genuinely free ligand is passed through uncapped, as is any residue whose backbone or crosslink cannot be capped (a warning is logged and it is titrated whole). Entries are deduplicated by key so an NCAA appearing in several places is titrated once per unique (chemistry, context).The result is a plain
{key: smiles}dict. The caller runs its own pKa tool over the values (e.g. AcePka) and passes the protonated result back totemplatesFromTitration()as a dict of the same keys; moleculekit does not read or write any pKa tool’s file format.- Parameters:
mol (
Molecule) – The molecule the specs were detected in.specs (
list) – The specs returned bymoleculekit.tools.nonstandard_residues.detectNonStandardResidues().smiles (
dict|None) – Optional{resname: smiles}overrides; resnames absent here are fetched from RCSB by their CCD code.
- Returns:
titration –
{key: smiles}to titrate, one entry per unique template-requiring residue.- Return type:
- Raises:
RuntimeError – If a residue needing a template has neither an override in
smilesnor a fetchable RCSB SMILES.
- moleculekit.tools.residue_titration.templatesFromTitration(mol, specs, protonated, smiles=None)#
Strip the caps off pKa-titrated SMILES back into per-residue templates.
Inverse of
capNonstandardResiduesForTitration(), driven by the samemolandspecsso no intermediate state has to be carried between the two calls. For each template-requiring chain, scaffold, or covalent- ligand residue, its uncapped anchor is re-derived (_uncapped_residue_smiles()) and used as a relaxed substructure query (_relaxed_query()) to locate that residue’s own atoms inside its protonated, capped SMILES; the matched atoms are extracted (_submol_from_atoms()), dropping the ACE / NME / crosslink caps that fall outside the match. A pKa tool only ever changes protonation state, never the heavy-atom skeleton, so the anchor is guaranteed to be a subgraph of the protonated molecule. Residues titrated whole (genuinely free ligands, or residues whose backbone or crosslink could not be capped) are returned unchanged.- Parameters:
mol (
Molecule) – The molecule the specs were detected in (the same one passed tocapNonstandardResiduesForTitration()).specs (
list) – The specs frommoleculekit.tools.nonstandard_residues.detectNonStandardResidues().protonated (
dict) –{key: smiles}of the pKa-tool-protonated titration output, keyed exactly ascapNonstandardResiduesForTitration()returned.smiles (
dict|None) – The same{resname: smiles}overrides passed tocapNonstandardResiduesForTitration(), so anchors are re-derived from identical base SMILES.
- Returns:
templates –
{key: smiles}, one entry per key, with caps removed and the pKa tool’s protonation applied.- Return type:
- Raises:
RuntimeError – If
protonatedis missing a key, a protonated SMILES cannot be parsed, or a residue’s anchor cannot be located inside its protonated SMILES.