Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Find rotatable bonds #506

Merged
merged 5 commits into from Feb 13, 2020
Merged

[WIP] Find rotatable bonds #506

merged 5 commits into from Feb 13, 2020

Conversation

jthorton
Copy link
Collaborator

@jthorton jthorton commented Feb 6, 2020

… __str__ methods for the Bonds class.

Tests added for the new method.
@jthorton
Copy link
Collaborator Author

jthorton commented Feb 6, 2020

This is the my initial go at adding the ability to find rotatable bonds, which seems to work quite well. I have not added a new bond attribute is_rotatable yet as it was not clear if it was needed and how it would behave. For example would the attribute update after each query (similar to how the WBO is stored in the fractional_bond_order attribute) meaning the function would do something like

def find_rotatable_bonds(self, ignore_functional_groups=None, toolkit_registry=GLOBAL_TOOLKIT_REGISTRY):
    rotatable_bond_smarts = '[!$(*#*)&!D1:1]-&!@[!$(*#*)&!D1:2]'
    # get all of the general matches
    general_matches = self.chemical_environment_matches(query=rotatable_bond_smarts,
                                                        toolkit_registry=toolkit_registry)
    ignore_functional_groups = [list of SMARTS to ignore]
    ignore_bonds = toolkit_registryfind_smarts_matches to find matches for the items in 
    ignore_functional_groups
    Remove ignore_bonds from rotatable_bonds
    
    # now reset the is_rotatable attribute on each bond to match the search
    for bond in rotatbale_bonds:
        bond.is_rotatable = True

    return rotatable_bonds

Conflicts:
	openforcefield/tests/test_molecule.py
@jthorton jthorton requested a review from j-wags February 12, 2020 18:07
Copy link
Member

@j-wags j-wags left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks really nice. Mostly asked for changes around the tests, but otherwise this is in very good shape.

Comment on lines +1347 to +1352
def __repr__(self):
return f"Bond(atom1 index={self.atom1_index}, atom2 index={self.atom2_index})"

def __str__(self):
return f"<Bond atom1 index='{self.atom1_index}', atom2 index='{self.atom2_index}'>"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. Thanks for adding these.

Comment on lines +2235 to +2241
def condense_matches(matches):
condensed_matches = set()
for m in matches:
condensed_matches.add(tuple(sorted(m)))
return condensed_matches

general_bonds = condense_matches(general_matches)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good thinking!

Comment on lines 702 to 706
# now ignore the C-O bond
bonds = ethanol.find_rotatable_bonds('[#6:1]-[#8:2]')
assert len(bonds) == 1
assert ethanol.atoms[bonds[0].atom1_index].atomic_number == 6
assert ethanol.atoms[bonds[0].atom2_index].atomic_number == 6
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you copy this block and also run the check when the SMIRKS indices are reversed? The sorted line in the new function should handle it, but it's always good to be sure.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I have added that as well.

Comment on lines 2246 to 2247
if not isinstance(ignore_functional_groups, list):
ignore_functional_groups = [ignore_functional_groups]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since there are iterable objects other than lists, we try to follow a design pattern like this:

https://github.com/openforcefield/openforcefield/blob/ee0f715e094e6f1749bf60f3a3b48174a9e6a9b7/openforcefield/topology/topology.py#L1030-L1035)

Copy link
Collaborator Author

@jthorton jthorton Feb 13, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for catching that that only problem is if the user gives a single SMIRKS string this is iterable which would cause issues so maybe if I type check for a str first and then do this it would work?

Comment on lines 691 to 692
def test_find_rotatable_bonds(self):
"""Test finding rotatable bonds while ignoring some groups"""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you move this to test_toolkits, and run once with OETK and another time with RDKit? I know the different setups are technically covered in our Travis testing matrix, but weird things can happen when both toolkits are installed that hide sneaky problems.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No problem its best to be safe here, I have moved the tests.

@j-wags j-wags self-requested a review February 13, 2020 16:10
Copy link
Member

@j-wags j-wags left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome. Fix for #513 looks great. Thanks @jthorton

@jthorton jthorton merged commit 3e58ffb into master Feb 13, 2020
@j-wags j-wags added this to the 0.7.0 milestone Feb 14, 2020
@j-wags j-wags deleted the find_rotatables branch May 27, 2021 14:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

OFFMol.to_rdkit loses aromaticity info Include find rotatable bonds in OETKW and RDKTKW
2 participants