Skip to content

Commit

Permalink
Merge branch 'devel' into OBC_for_OPLS
Browse files Browse the repository at this point in the history
  • Loading branch information
martimunicoy committed Nov 16, 2020
2 parents 314c072 + 2b89be6 commit 4d639a4
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 5 deletions.
2 changes: 2 additions & 0 deletions docs/releasehistory.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ New features
- `PR #88 <https://github.com/martimunicoy/peleffy/pull/88>`_: New method to retrieve atom degrees with RDKit.
- `PR #86 <https://github.com/martimunicoy/peleffy/pull/86>`_: New method to check the input PDB prior building the molecule.
- `PR #94 <https://github.com/martimunicoy/peleffy/pull/94>`_: New method for the OPLS OBC parameters.
- `PR #92 <https://github.com/martimunicoy/peleffy/pull/92>`_: New parameter to skip the stereochemistry assignment (and the checking from the OpenFF toolkit).

Tests added
"""""""""""
- `PR #88 <https://github.com/martimunicoy/peleffy/pull/88>`_: Adds tests to validate the atom degrees getter.
- `PR #86 <https://github.com/martimunicoy/peleffy/pull/86>`_: Adds tests to validate the PDB check up.
- `PR #94 <https://github.com/martimunicoy/peleffy/pull/94>`_: Adds tests to validate the OPLS OBC parameters generator.
- `PR #92 <https://github.com/martimunicoy/peleffy/pull/92>`_: New test to check the behaviour of the allow_undefined_stereo parameter.


1.0.0 - Full compatibility for OPLS2005 and OpenFF dihedrals and rotamer library improvements
Expand Down
21 changes: 21 additions & 0 deletions peleffy/forcefield/parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,27 @@ def name(self):
"""
return self._name

@staticmethod
def from_impact_template(molecule, impact_template_path):
"""
It returns a parameter wrapper out of an impact template.
Parameters
----------
molecule : a peleffy.topology.Molecule
The peleffy's Molecule object
impact_template_path : str
The path to the impact template from where the parameters
will be fetched
Returns
-------
parameters : a BaseParameterWrapper object
The resulting parameters wrapper
"""

raise NotImplementedError()


class OpenForceFieldParameterWrapper(BaseParameterWrapper):
"""
Expand Down
24 changes: 24 additions & 0 deletions peleffy/tests/test_molecule.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,3 +287,27 @@ def test_PDB_checkup(self):
assert output == "Input PDB has no information about the " \
+ "connectivity and this could result in an unexpected " \
+ "bond assignment\n"

def test_undefined_stereo(self):
"""
It checks the behaviour when ignoring the stereochemistry
in the Molecule initialization.
"""
from openforcefield.utils.toolkits import UndefinedStereochemistryError

# This should crash due to an undefined stereochemistry error
with pytest.raises(UndefinedStereochemistryError):
mol = Molecule(smiles='CN(C)CCC=C1c2ccccc2CCc3c1cccc3')

# This now should work
mol = Molecule(smiles='CN(C)CCC=C1c2ccccc2CCc3c1cccc3',
allow_undefined_stereo=True)

# And we can parameterize it
mol.parameterize('openff_unconstrained-1.2.1.offxml',
charge_method='gasteiger')

# Save it
with tempfile.TemporaryDirectory() as tmpdir:
with temporary_cd(tmpdir):
mol.to_pdb_file('molecule.pdb')
30 changes: 26 additions & 4 deletions peleffy/topology/molecule.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,8 @@ class Molecule(object):

def __init__(self, path=None, smiles=None, rotamer_resolution=30,
exclude_terminal_rotamers=True, name='', tag='UNK',
connectivity_template=None, core_constraints=[]):
connectivity_template=None, core_constraints=[],
allow_undefined_stereo=False):
"""
It initializes a Molecule object through a PDB file or a SMILES
tag.
Expand Down Expand Up @@ -477,6 +478,10 @@ def __init__(self, path=None, smiles=None, rotamer_resolution=30,
the core will be forced to contain them. Atoms can be specified
through integers that match the atom index or strings that
match with the atom PDB name
allow_undefined_stereo : bool
Whether to allow a molecule with undefined stereochemistry
to be defined or try to assign the stereochemistry and
raise a complaint if not possible. Default is False
Examples
--------
Expand Down Expand Up @@ -535,6 +540,7 @@ def __init__(self, path=None, smiles=None, rotamer_resolution=30,
self._exclude_terminal_rotamers = exclude_terminal_rotamers
self._connectivity_template = connectivity_template
self._core_constraints = core_constraints
self._allow_undefined_stereo = allow_undefined_stereo

if isinstance(path, str):
from pathlib import Path
Expand Down Expand Up @@ -636,9 +642,10 @@ def _initialize_from_pdb(self, path):
logger.info(' - Assigning connectivity from template')
rdkit_toolkit.assign_connectivity_from_template(self)

# RDKit must generate stereochemistry specifically from 3D coords
logger.info(' - Assigning stereochemistry from 3D coordinates')
rdkit_toolkit.assign_stereochemistry_from_3D(self)
if not self.allow_undefined_stereo:
# RDKit must generate stereochemistry specifically from 3D coords
logger.info(' - Assigning stereochemistry from 3D coordinates')
rdkit_toolkit.assign_stereochemistry_from_3D(self)

# Set molecule name according to PDB name
if self.name == '':
Expand Down Expand Up @@ -1202,6 +1209,21 @@ def connectivity_template(self):
"""
return self._connectivity_template

@property
def allow_undefined_stereo(self):
"""
Whether to allow a molecule with undefined stereochemistry
to be defined or try to assign the stereochemistry and
raise a complaint if not possible
Returns
-------
allow_undefined_stereo : bool
The current configuration towards the stereochemistry
behaviour of this molecule
"""
return self._allow_undefined_stereo

@property
def core_constraints(self):
"""
Expand Down
6 changes: 6 additions & 0 deletions peleffy/utils/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,12 @@ def get_impact_template_path(self, create_missing_folders=True):
else:
path = os.path.join(self.output_path,
self.OPLS_IMPACT_TEMPLATE_PATH)
else:
raise Exception('DataLocal output path for the impact '
+ 'template cannot be inferred because '
+ 'the forcefield for molecule '
+ '\'{}\' '.format(self.molecule)
+ 'has not been set yet')
else:
path = self.output_path

Expand Down
4 changes: 3 additions & 1 deletion peleffy/utils/toolkits.py
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,9 @@ def from_rdkit(self, molecule):
from openforcefield.topology.molecule import Molecule

rdkit_molecule = molecule.rdkit_molecule
return Molecule.from_rdkit(rdkit_molecule)
return Molecule.from_rdkit(
rdkit_molecule,
allow_undefined_stereo=molecule.allow_undefined_stereo)

def get_forcefield(self, forcefield_name):
"""
Expand Down

0 comments on commit 4d639a4

Please sign in to comment.