Openff-toolkit: Cannot create an OpenMM system of T4-protein.mol2

Created on 9 Feb 2020  路  4Comments  路  Source: openforcefield/openff-toolkit

Describe the bug
After converting T4-protein.pdb -> mol2 using ambertools (tleap) and applying create_openmm_system, an error from OpenMM says the formal charge is -55, which does not match the sum of mol2 partial charges of 8.

To Reproduce
Pull/switch to branch fix-491 (#509) and run pytest -k test_parameterize_protein test_forcefield.py from the tests directory,
or, from the tests directory and downloading the mol2 T4-protein.mol2.zip:

import openforcefield
from openforcefield.topology import Molecule, Topology
from openforcefield.typing.engines.smirnoff import ForceField
mol_path = 'T4-protein.mol2'
molecule = Molecule.from_file(mol_path, allow_undefined_stereo=True)
topology = Topology.from_molecules(molecule)
forcefield = ForceField('test_forcefields/smirnoff99Frosst.offxml')
omm_system = forcefield.create_openmm_system(topology, charge_from_molecules=[molecule], allow_nonintegral_charges=False)

Output

openforcefield/tests/test_forcefield.py:1886: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
openforcefield/typing/engines/smirnoff/forcefield.py:1142: in create_openmm_system
    parameter_handler.postprocess_system(system, topology, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <openforcefield.typing.engines.smirnoff.parameters.ElectrostaticsHandler object at 0x7f1b6cb46320>
system = <simtk.openmm.openmm.System; proxy of <Swig Object of type 'OpenMM::System *' at 0x7f1b8ebcb7b0> >
topology = <openforcefield.topology.topology.Topology object at 0x7f1b6e128eb8>
kwargs = {'charge_from_molecules': [Molecule with name 'default_name' and SMILES '[H+].[H][C@-]1[C-]([C-]([C-]([C-]([C-]1[H])C(...])[O-])[O-])[O-])[O-])[H])[H])[H]'], 'toolkit_registry': <class 'openforcefield.utils.toolkits.OpenEyeToolkitWrapper'>}
force = <simtk.openmm.openmm.NonbondedForce; proxy of <Swig Object of type 'OpenMM::NonbondedForce *' at 0x7f1b60f473c0> >
uncharged_mols = []
ref_mol = Molecule with name 'default_name' and SMILES '[H+].[H][C@-]1[C-]([C-]([C-]([C-]([C-]1[H])C([H])([H])[C@@]([H])([C+](N(...])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[H])[H])[H]'
msg = "Partial charge sum (8.000000746455044 e) for molecule 'default_name' (SMILES [H+].[H][C@-]1[C-]([C-]([C-]([C-]([C-]1[...(-55). To override this error, provide the 'allow_nonintegral_charges=True' keyword to ForceField.create_openmm_system"
allow_nonintegral_charges = False, top_mol = <openforcefield.topology.topology.TopologyMolecule object at 0x7f1b60704550>
formal_charge_sum = -55

    def postprocess_system(self, system, topology, **kwargs):
        force = super().create_force(system, topology, **kwargs)
        # Check to ensure all molecules have had charges assigned
        uncharged_mols = []
        for ref_mol in topology.reference_molecules:
            if not self.check_charges_assigned(ref_mol, topology):
                uncharged_mols.append(ref_mol)

        if len(uncharged_mols) != 0:
            msg = "The following molecules did not have charges assigned by any ParameterHandler in the ForceField:\n"
            for ref_mol in uncharged_mols:
                msg += f"{ref_mol.to_smiles()}\n"
            raise UnassignedMoleculeChargeException(msg)


        # Unless check is disabled, ensure that the sum of partial charges on a molecule
        # add up to approximately its formal charge
        allow_nonintegral_charges = kwargs.get('allow_nonintegral_charges', False)
        for top_mol in topology.topology_molecules:
            # Skip check if user manually disables it.
            if allow_nonintegral_charges:
                continue
            formal_charge_sum = top_mol.reference_molecule.total_charge
            partial_charge_sum = 0. * unit.elementary_charge
            for top_particle in top_mol.particles:
                q, _, _ = force.getParticleParameters(top_particle.topology_particle_index)
                partial_charge_sum += q
            if abs(float(formal_charge_sum) - (partial_charge_sum/unit.elementary_charge)) > 0.01:
                msg = f"Partial charge sum ({partial_charge_sum}) " \
                      f"for molecule '{top_mol.reference_molecule.name}' (SMILES " \
                      f"{top_mol.reference_molecule.to_smiles()} does not equal formal charge sum " \
                      f"({formal_charge_sum}). To override this error, provide the " \
                      f"'allow_nonintegral_charges=True' keyword to ForceField.create_openmm_system"
>               raise NonintegralMoleculeChargeException(msg)
E               openforcefield.typing.engines.smirnoff.parameters.NonintegralMoleculeChargeException: Partial charge sum (8.000000746455044 e) for molecule 'default_name' (SMILES [H+].[H][C@-]1[C-]([C-]([C-]([C-]([C-]1[H])C([H])([H])[C@@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])C([H])([H])[C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N2[C@](C(C(C2([H])[H])([H])[H])([H])[H])([H])[C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])C([H])([H])[C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])C([H])([H])[C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])C([H])([H])[C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N3[C@](C(C(C3([H])[H])([H])[H])([H])[H])([H])[C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])C([H])([H])[C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+](N([H])[C@]([H])([C+]([O-])[O-])C([H])([H])C([H])(C([H])([H])[H])C([H])([H])[H])[O-])C([H])([H])[C+](N([H])[H])[O-])[O-])C([H])([H])C([H])([H])C([H])([H])C([H])([H])[N+]([H])([H])[H])[O-])C([H])([H])[C-]4[C-]([C-]([C+]([C-]([C-]4[H])[H])O[H])[H])[H])[O-])C([H])([H])[H])[O-])C([H])([H])[C+]([O-])[O-])[O-])C([H])([H])[C-]5[C-]6[C-]([C-]([C-]([C-]([C+]6N([C+]5[H])[H])[H])[H])[H])[H])[O-])[C@@]([H])(C([H])([H])[H])O[H])[O-])[O-])[C@@]([H])(C([H])([H])[H])O[H])[O-])C([H])([H])C([H])([H])C([H])([H])N([H])[C+](N([H])[H])N([H])[H])[O-])C([H])([H])[C-]7[C-]([C-]([C-]([C-]([C-]7[H])[H])[H])[H])[H])[O-])[C@@]([H])(C([H])([H])[H])O[H])[O-])[C@@]([H])(C([H])([H])[H])O[H])[O-])[C@@]([H])(C([H])([H])[H])C([H])([H])C([H])([H])[H])[O-])C([H])(C([H])([H])[H])C([H])([H])[H])[O-])C([H])([H])C([H])([H])C([H])([H])N([H])[C+](N([H])[H])N([H])[H])[O-])C([H])([H])C([H])([H])C([H])([H])C([H])([H])[N+]([H])([H])[H])[O-])C([H])([H])[H])[O-])C([H])([H])C([H])([H])C([H])([H])N([H])[C+](N([H])[H])N([H])[H])[O-])C([H])([H])[C+](N([H])[H])[O-])[O-])[O-])[C@@]([H])(C([H])([H])[H])O[H])[O-])C([H])([H])C([H])([H])[C+](N([H])[H])[O-])[O-])C([H])([H])[C+](N([H])[H])[O-])[O-])C([H])([H])[C-]8[C-]([C@-]([C+]([C@-]([C-]8[H])[H])O[H])[H])[H])[O-])C([H])([H])[C-]9[C-]1[C-]([C-]([C-]([C-]([C+]1N([C+]9[H])[H])[H])[H])[H])[H])[O-])C([H])([H])C([H])([H])C([H])([H])N([H])[C+](N([H])[H])N([H])[H])[O-])C([H])([H])O[H])[O-])C([H])([H])C([H])([H])C([H])([H])C([H])([H])[N+]([H])([H])[H])[O-])C([H])([H])[H])[O-])C([H])([H])C([H])(C([H])([H])[H])C([H])([H])[H])[O-])C([H])([H])[C+](N([H])[H])[O-])[O-])C([H])(C([H])([H])[H])C([H])([H])[H])[O-])C([H])([H])[H])[O-])C([H])([H])[H])[O-])C([H])([H])C([H])([H])[C+]([O-])[O-])[O-])C([H])([H])[C+]([O-])[O-])[O-])C([H])([H])[C-]1[C-]2[C@@-]([C-]([C-]([C-]([C+]2N([C+]1[H])[H])[H])[H])[H])[H])[O-])C([H])([H])C([H])([H])C([H])([H])N([H])[C+](N([H])[H])N([H])[H])[O-])C([H])([H])C([H])([H])C([H])([H])C([H])([H])[N+]([H])([H])[H])[O-])C([H])([H])C([H])([H])[C+](N([H])[H])[O-])[O-])C([H])([H])C([H])([H])[C+](N([H])[H])[O-])[O-])C([H])([H])C([H])(C([H])([H])[H])C([H])([H])[H])[O-])C([H])([H])C([H])([H])SC([H])([H])[H])[O-])C([H])([H])C([H])([H])C([H])([H])N([H])[C+](N([H])[H])N([H])[H])[O-])C([H])([H])C([H])(C([H])([H])[H])C([H])([H])[H])[O-])C([H])([H])O[H])[O-])C([H])([H])[C+](N([H])[H])[O-])[O-])[C@@]([H])(C([H])([H])[H])O[H])[O-])C([H])([H])[C-]1[C-]([C-]([C-]([C-]([C-]1[H])[H])[H])[H])[H])[O-])[O-])C([H])([H])[H])[O-])C([H])(C([H])([H])[H])C([H])([H])[H])[O-])[O-])[C@@]([H])(C([H])([H])[H])O[H])[O-])C([H])([H])C([H])([H])[C+]([O-])[O-])[O-])[O-])C([H])([H])C([H])([H])SC([H])([H])[H])[O-])C([H])([H])C([H])([H])[C+](N([H])[H])[O-])[O-])C([H])([H])[C-]1[C-]([C-]([C-]([C-]([C-]1[H])[H])[H])[H])[H])[O-])C([H])(C([H])([H])[H])C([H])([H])[H])[O-])C([H])([H])C([H])([H])SC([H])([H])[H])[O-])C([H])([H])[C+](N([H])[H])[O-])[O-])[C@@]([H])(C([H])([H])[H])C([H])([H])C([H])([H])[H])[O-])C([H])([H])[H])[O-])C([H])([H])[H])[O-])C([H])([H])S[H])[O-])C([H])([H])C([H])([H])C([H])([H])N([H])[C+](N([H])[H])N([H])[H])[O-])C([H])([H])C([H])([H])C([H])([H])N([H])[C+](N([H])[H])N([H])[H])[O-])C([H])(C([H])([H])[H])C([H])([H])[H])[O-])C([H])([H])[H])[O-])C([H])([H])[C+]([O-])[O-])[O-])C([H])([H])C([H])(C([H])([H])[H])C([H])([H])[H])[O-])C([H])([H])O[H])[O-])C([H])([H])[C+]([O-])[O-])[O-])C([H])([H])[C-]1[C-]([C-]([C+]([C-]([C-]1[H])[H])O[H])[H])[H])[O-])C([H])(C([H])([H])[H])C([H])([H])[H])[O-])[O-])C([H])([H])C([H])([H])C([H])([H])C([H])([H])[N+]([H])([H])[H])[O-])C([H])([H])C([H])(C([H])([H])[H])C([H])([H])[H])[O-])C([H])([H])C([H])([H])C([H])([H])C([H])([H])[N+]([H])([H])[H])[O-])C([H])([H])[H])[O-])C([H])([H])[C+](N([H])[H])[O-])[O-])C([H])([H])C([H])([H])C([H])([H])N([H])[C+](N([H])[H])N([H])[H])[O-])C([H])([H])C([H])(C([H])([H])[H])C([H])([H])[H])[O-])[C@@]([H])(C([H])([H])[H])C([H])([H])C([H])([H])[H])[O-])[O-])C([H])([H])C([H])([H])C([H])([H])N([H])[C+](N([H])[H])N([H])[H])[O-])C([H])(C([H])([H])[H])C([H])([H])[H])[O-])C([H])([H])[H])[O-])C([H])([H])[H])[O-])C([H])([H])[C+]([O-])[O-])[O-])C([H])(C([H])([H])[H])C([H])([H])[H])[O-])C([H])([H])[C+]([O-])[O-])[O-])C([H])([H])C([H])([H])[C+](N([H])[H])[O-])[O-])C([H])([H])[C+](N([H])[H])[O-])[O-])N([H])[C+]([C@]([H])(C([H])([H])C([H])(C([H])([H])[H])C([H])([H])[H])N([H])[C+]([C@]([H])(C([H])([H])C([H])([H])C([H])([H])C([H])([H])[N+]([H])([H])[H])N([H])[C+]([C@]([H])(C([H])([H])C([H])([H])[C+]([O-])[O-])N([H])[C+]([C@]([H])(C([H])([H])[H])N([H])[C+]([C@]([H])(C([H])([H])C([H])([H])[C+]([O-])[O-])N([H])[C+]([C@]([H])(C([H])([H])[C+]([O-])[O-])N([H])[C+]([C@]([H])(C([H])([H])C([H])([H])C([H])([H])C([H])([H])[N+]([H])([H])[H])N([H])[C+]([C@]([H])([C@@]([H])(C([H])([H])[H])O[H])N([H])[C+]([C@]([H])([C@@]([H])(C([H])([H])[H])C([H])([H])C([H])([H])[H])N([H])[C+]([C@]([H])(C([H])(C([H])([H])[H])C([H])([H])[H])N([H])[C+](C([H])([H])N([H])[C+]([C@]([H])(C([H])([H])[C+](N([H])[H])[O-])N([H])[C+]([C@]([H])(C([H])([H])S[H])N([H])[C+]([C@]([H])(C([H])([H])[C+](N([H])[H])[O-])N([H])[C+]([C@]([H])(C([H])([H])C([H])([H])C([H])([H])N([H])[C+](N([H])[H])N([H])[H])N([H])[C+](C([H])([H])N([H])[C+]([C@]([H])([C@@]([H])(C([H])([H])[H])C([H])([H])C([H])([H])[H])N([H])[C+]([C@]([H])(C([H])([H])[H])N([H])[C+]([C@]([H])(C([H])([H])C([H])([H])C([H])([H])C([H])([H])[N+]([H])([H])[H])N([H])[C+]([C@]([H])(C([H])([H])[C+]([O-])[O-])N([H])[C+]([C@]([H])(C([H])([H])C([H])(C([H])([H])[H])C([H])([H])[H])N([H])[C+]([C@]([H])(C([H])([H])C([H])([H])[C+]([O-])[O-])N([H])[C+]([C@]([H])(C([H])([H])O[H])N([H])[C+]([C@]([H])(C([H])([H])C([H])([H])C([H])([H])C([H])([H])[N+]([H])([H])[H])N([H])[C+]([C@]([H])(C([H])([H])[H])N([H])[C+]([C@]([H])(C([H])([H])[H])N([H])[C+]([C@]([H])(C([H])([H])[C+](N([H])[H])[O-])N([H])[C+]([C@]([H])(C([H])([H])C([H])(C([H])([H])[H])C([H])([H])[H])N([H])[C+]([C@]([H])(C([H])([H])O[H])N([H])[C+]([C@@]1(C(C(C(N1[C+]([C@]([H])(C([H])([H])O[H])N([H])[C+]([C@]([H])(C([H])([H])C([H])([H])C([H])([H])C([H])([H])[N+]([H])([H])[H])N([H])[C+]([C@]([H])([C@@]([H])(C([H])([H])[H])O[H])N([H])[C+]([C@]([H])(C([H])([H])C([H])(C([H])([H])[H])C([H])([H])[H])N([H])[C+]([C@]([H])(C([H])([H])C([H])(C([H])([H])[H])C([H])([H])[H])N([H])[C+]([C@]([H])(C([H])([H])[C+]1[C+](N([C+]([N-]1)[H])[H])[H])N([H])[C+](C([H])([H])N([H])[C+]([C@]([H])([C@@]([H])(C([H])([H])[H])C([H])([H])C([H])([H])[H])N([H])[C+](C([H])([H])N([H])[C+]([C@]([H])([C@@]([H])(C([H])([H])[H])C([H])([H])C([H])([H])[H])N([H])[C+]([C@]([H])([C@@]([H])(C([H])([H])[H])O[H])N([H])[C+]([C@]([H])(C([H])([H])[C-]1[C-]([C-]([C+]([C-]([C-]1[H])[H])O[H])[H])[H])N([H])[C+]([C@]([H])(C([H])([H])[C-]1[C-]([C-]([C+]([C-]([C-]1[H])[H])O[H])[H])[H])N([H])[C+](C([H])([H])N([H])[C+]([C@]([H])(C([H])([H])C([H])([H])[C+]([O-])[O-])N([H])[C+]([C@]([H])([C@@]([H])(C([H])([H])[H])O[H])N([H])[C+]([C@]([H])(C([H])([H])[C+]([O-])[O-])N([H])[C+]([C@]([H])(C([H])([H])C([H])([H])C([H])([H])C([H])([H])[N+]([H])([H])[H])N([H])[C+]([C@]([H])(C([H])([H])[C-]1[C-]([C-]([C+]([C-]([C-]1[H])[H])O[H])[H])[H])N([H])[C+]([C@]([H])([C@@]([H])(C([H])([H])[H])C([H])([H])C([H])([H])[H])N([H])[C+]([C@]([H])(C([H])([H])C([H])([H])C([H])([H])C([H])([H])[N+]([H])([H])[H])N([H])[C+]([C@]([H])(C([H])([H])C([H])(C([H])([H])[H])C([H])([H])[H])N([H])[C+]([C@]([H])(C([H])([H])C([H])([H])C([H])([H])N([H])[C+](N([H])[H])N([H])[H])N([H])[C+]([C@]([H])(C([H])([H])C([H])(C([H])([H])[H])C([H])([H])[H])N([H])[C+](C([H])([H])N([H])[C+]([C@]([H])(C([H])([H])C([H])([H])[C+]([O-])[O-])N([H])[C+]([C@]([H])(C([H])([H])[C+]([O-])[O-])N([H])[C+]([C@]([H])([C@@]([H])(C([H])([H])[H])C([H])([H])C([H])([H])[H])N([H])[C+]([C@]([H])(C([H])([H])C([H])([H])C([H])([H])N([H])[C+](N([H])[H])N([H])[H])N([H])[C+]([C@]([H])(C([H])([H])C([H])(C([H])([H])[H])C([H])([H])[H])N([H])[C+]([C@]([H])(C([H])([H])C([H])([H])SC([H])([H])[H])N([H])[C+]([C@]([H])(C([H])([H])C([H])([H])[C+]([O-])[O-])N([H])[C+]([C@]([H])(C([H])([H])[C-]1[C@-]([C-]([C-]([C-]([C-]1[H])[H])[H])[H])[H])N([H])[C+]([C@]([H])([C@@]([H])(C([H])([H])[H])C([H])([H])C([H])([H])[H])N([H])[C+]([C@]([H])(C([H])([H])[C+](N([H])[H])[O-])N([H])[C+]([C@]([H])(C([H])([H])C([H])([H])SC([H])([H])[H])[N+]([H])([H])[H])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])([H])[H])([H])[H])([H])[H])[H])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[O-])[H])[H])[H] does not equal formal charge sum (-55). To override this error, provide the 'allow_nonintegral_charges=True' keyword to ForceField.create_openmm_system

Additional context
Found this while working on #491 (see PR #509). In the mol2 file, I did change the terminal residues to name NME (from MET) and CLE (from LEU). Not sure where all those O- are coming from.

low enhancement medium reliability

Most helpful comment

This is likely also the origin of the "bug". The sum of the partial charges correctly reports the net charge as +8:

>>> m = Molecule.from_file('T4-protein.mol2', allow_undefined_stereo=True)
>>> m.partial_charges.sum()
Quantity(value=8.000000746455044, unit=elementary charge)

but to avoid issues with limited precision in reporting the true integral charge of the molecule, the .total_charge property sums up formal charges, which will be incorrect because the bond orders are all incorrect, leading to incorrect valences for most atoms:

>>> m.total_charge
-55

This leads to an idea for a simple sanity check: If the sum of the partial charges and the formal charges differ by a significant fraction of an integer, there is something wrong with the valences, and we should throw an exception on molecule validation. Perhaps we could suggest this in a new issue?

Tagging @j-wags for further input.

All 4 comments

@trevorgokey : How did you generate this mol2 file? It seems to have significant issues.

I was wondering why you needed to allow_undefined_stereo=True. If you don't,

molecule = Molecule.from_file(mol_path, allow_undefined_stereo=False)

it gives tons of problematic atoms

openforcefield.utils.toolkits.UndefinedStereochemistryError: Unable to make OFFMol from OEMol: OEMol has unspecified stereochemistry. oemol.GetTitle(): default_name
Problematic atoms are:
Atom atomic num: 6, name: CD1, idx: 61, aromatic: False, chiral: True with bonds:
bond order: 1, chiral: False to atom atomic num: 1, name: HD1, idx: 62, aromatic: False, chiral: False
bond order: 1, chiral: False to atom atomic num: 6, name: CE1, idx: 63, aromatic: False, chiral: True
bond order: 1, chiral: False to atom atomic num: 6, name: CG, idx: 60, aromatic: False, chiral: False
Atom atomic num: 6, name: CE1, idx: 63, aromatic: False, chiral: True with bonds:
bond order: 1, chiral: False to atom atomic num: 1, name: HE1, idx: 64, aromatic: False, chiral: False
bond order: 1, chiral: False to atom atomic num: 6, name: CZ, idx: 65, aromatic: False, chiral: False
bond order: 1, chiral: False to atom atomic num: 6, name: CD1, idx: 61, aromatic: False, chiral: True
...

These are ring atoms in a phenylalanine, which _should_ be aromatic. This suggests something is likely wrong in the bonds section.

Sure enough, all the bonds in the bonds section of the mol2 file are single bonds:
@<TRIPOS>BOND 1 18 19 1 2 18 21 1 3 14 15 1 4 14 16 1 5 14 17 1 6 13 14 1 7 10 11 1 8 10 12 1 9 10 13 1 10 7 8 1 11 7 9 1 12 7 10 1 13 5 6 1 14 5 7 1 15 5 18 1 16 1 2 1 17 1 3 1 18 1 4 1 19 1 5 1 20 33 34 1 21 33 35 1 22 30 31 1 23 30 32 1 24 28 29 1 25 28 30 1 ...
Can we replace this file with a corrected mol2 file?

This is likely also the origin of the "bug". The sum of the partial charges correctly reports the net charge as +8:

>>> m = Molecule.from_file('T4-protein.mol2', allow_undefined_stereo=True)
>>> m.partial_charges.sum()
Quantity(value=8.000000746455044, unit=elementary charge)

but to avoid issues with limited precision in reporting the true integral charge of the molecule, the .total_charge property sums up formal charges, which will be incorrect because the bond orders are all incorrect, leading to incorrect valences for most atoms:

>>> m.total_charge
-55

This leads to an idea for a simple sanity check: If the sum of the partial charges and the formal charges differ by a significant fraction of an integer, there is something wrong with the valences, and we should throw an exception on molecule validation. Perhaps we could suggest this in a new issue?

Tagging @j-wags for further input.

Yes, thanks for the catch. I commented/fixed this in #509. OpenMM is raising an exception because the two are different. I think we can close this one, but the main issue now is what happens when we supply a bogus mol2 file (like I did), and need to figure out what is wrong. I think somehow validating mol2 bond orders can be done, just not sure at the moment how to do so.

Was this page helpful?
0 / 5 - 0 ratings