Get charge centers#
Identifying sparse formal-charge centers in one chemical state.
Use this experimental tool to prepare charged participants for molecular analysis. It recognizes carboxyl and guanidine motifs, combines directly bonded charged atoms, and omits groups whose charges sum to zero. Other nonzero formal charges remain labeled atomic centers. It computes chemical features; it does not detect interactions.
Added in version 1.0.0.
API documentation
See molsysmt.physchem.get_charge_centers() for arguments, fields and errors.
Basic usage#
Let’s show how the prerequisites work with bundled pentalanine. A force-field file need not contain formal-charge assignments or bond-order information suitable for this definition. Missing prerequisites raise an error instead of invoking parameterization or a residue-charge table.
import molsysmt as msm
import numpy as np
from molsysmt import pyunitwizard as puw
from molsysmt.native import Topology
molsys = msm.convert(msm.systems['pentalanine']['pentalanine.prmtop'],
to_form='molsysmt.Topology')
print('Atoms:', msm.get(molsys, n_atoms=True))
try:
centers = msm.physchem.get_charge_centers(molsys)
print('Centers:', len(centers['charges']))
except msm.StructuralInconsistencyError:
print('Formal-charge recognition prerequisites are missing.')
Atoms: 5207
Formal-charge recognition prerequisites are missing.
Declaring complete connectivity#
For a minimal system containing two isolated ions, specify elements and formal charges. If you know that no covalent bonds are missing, you can explicitly declare complete connectivity for this operation. The assumption is recorded; the source metadata and bonds remain unchanged. It must not be used to hide missing bonds.
molsys = Topology(n_atoms=2)
molsys.atoms['atom_type'] = ['Na', 'Cl']
msm.set(molsys, element='atom', formal_charge=[1, -1])
centers = msm.physchem.get_charge_centers(molsys, assume_complete_connectivity=True)
print(centers['atom_indices'], centers['atom_offsets'])
print(puw.get_value(centers['charges'], to_unit='e'))
print(centers['evidence'])
[0 1] [0 1 2]
[ 1. -1.]
{'kind': 'formal_charge', 'connectivity_completeness': 'unavailable', 'assume_complete_connectivity': True, 'chemical_state_provenance_index': None}
Recognizing compound centers#
The following small-molecule examples use the optional RDKit backend through SMILES conversion. The recognizer itself uses native chemistry without RDKit. Zwitterionic glycine has two local charged centers despite its zero total charge. Carboxylate membership contains C and both O atoms; its distance references are only the O atoms. Guanidinium similarly contains C and three N atoms, with N atoms as references. Every index belongs to the full input atom axis.
molsys = msm.convert('smiles:[NH3+]CC(=O)[O-]', to_form='molsysmt.Topology')
centers = msm.physchem.get_charge_centers(molsys)
print('Whole centers:', centers['atom_indices'], centers['atom_offsets'])
print('Distance references:', centers['geometry_atom_indices'], centers['geometry_atom_offsets'])
print('Rules:', centers['center_types'])
print('Charges:', puw.get_value(centers['charges'], to_unit='e'))
Whole centers: [0 2 3 4] [0 1 4]
Distance references: [0 3 4] [0 1 3]
Rules: ['formal_charge_atom' 'carboxylate']
Charges: [ 1. -1.]
molsys_A = msm.convert('smiles:NC(=[NH2+])N', to_form='molsysmt.Topology')
guanidinium = msm.physchem.get_charge_centers(molsys_A)
print(guanidinium['center_types'], guanidinium['geometry_atom_indices'])
['guanidinium'] [0 2 3]
Selecting whole centers#
A repeated or reordered selection returns each center once, in deterministic atom index order. Selecting a single member of a compound center cuts its chemical participant and raises an error. This differs from querying an already calculated Interactions result, where one member can select incident observations.
selected = msm.physchem.get_charge_centers(molsys, selection=[4, 2, 3, 4])
print(selected['atom_indices'])
try:
msm.physchem.get_charge_centers(molsys, selection=[3, 4])
except msm.ArgumentError:
print('The selection cuts a compound center.')
[2 3 4]
The selection cuts a compound center.
Preserving empty results#
Neutral nitro groups contain formal charge separation but have zero net group charge. The recognized directly bonded charges cancel. Membership remains a typed empty array with offsets [0], rather than an untyped list or missing result.
molsys_B = msm.convert('smiles:C[N+](=O)[O-]', to_form='molsysmt.Topology')
empty = msm.physchem.get_charge_centers(molsys_B)
print(empty['atom_indices'].shape, empty['atom_indices'].dtype)
print(empty['atom_offsets'])
print(puw.get_value(empty['charges'], to_unit='e').shape)
(0,) int64
[0]
(0,)
Choosing a chemical state#
A state index selects stored chemistry without changing the reference state. For isolated ions, an alternative state can be created and assigned independently. The ‘structure’ option follows basic queries: selected structures must all have one assigned state, and mixed assignments raise an error. Recognition runs once for that state; it produces no per-structure occurrences.
molsys = msm.convert('smiles:[Na+].[Cl-]', to_form='molsysmt.Topology')
molsys = msm.convert(molsys, to_form='molsysmt.MolSys')
state_index = molsys.chemical_states.append_state()
msm.set(molsys, element='atom', chemical_state=state_index, formal_charge=[0, 0])
neutral = msm.physchem.get_charge_centers(molsys, chemical_state=state_index,
assume_complete_connectivity=True)
print(neutral['chemical_state_index'], len(neutral['charges']))
print('Reference:', msm.get(molsys, reference_chemical_state_index=True))
1 0
Reference: 0
Understanding evidence and limits#
The payload separates charge source, recognition definition and rule version. It records the calculation-time MolSysMT version and the stored state provenance index when available. Unknown provenance remains unknown. The full state is examined before selection; a selection does not bypass missing chemistry elsewhere.
This version does not group phosphate, sulfate or aromatic ions. Those charges may appear as explicitly labeled atomic/cluster centers; that representation must not be mistaken for complete ionic functional-group classification. It also does not recognize all resonance forms. Whole-center membership and geometric references are different fields and must be used according to the chosen method.
The dictionary is a chemical-feature result, not an InteractionsDict analysis. Its unitful charges require a quantity-aware codec if you serialize the features. Ionic detection, cutoff choice, periodic images and Interactions output follow in a separate implementation step.
See also
Related Tools & References
molsysmt.basic.convert()— Load chemistry and native forms.molsysmt.basic.get()— Query source attributes and state inventory.molsysmt.physchem.get_charge_centers()— Recognize sparse charge centers.molsysmt.basic.set()— Assign explicit chemical-state attributes.