Skip to content
New issue

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

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

Already on GitHub? # to your account

Refactor ring methods in Molecule class #855

Merged
merged 27 commits into from
Feb 10, 2022
Merged

Refactor ring methods in Molecule class #855

merged 27 commits into from
Feb 10, 2022

Conversation

mattwthompson
Copy link
Member

@mattwthompson mattwthompson commented Feb 26, 2021

Fixes #823

This PR tries to implement solutions to #823. The major change is that several properties Molecule.rings, .n_rings, Atom.is_in_ring, Bond.is_in_ring, have been converted to methods, which breaks the existing API. The ways that membership in rings was being checked wasn't necessarily the best, since RDKit exposes a more direct way to do this (I assume OEChem does as well).

The main problem with the earlier implementation is that storing rings in Molecule._rings loses the provenance of which toolkit determined the number of rings (RDKit, OpenEye, and other toolkits are not guaranteed to agree). So these methods now generate rings on the fly as needed instead of storing them as private attributes and exposing getters. This should work around edge cases resulting from toolkit differences (unclear how we can test these without OpenEye functionality added). There an obvious downside of this change is wasteful re-computing the rings. I don't know if this is an important performance hit or not.

  • Refactor Bond.is_in_ring to use direct cheminformatics toolkit calls
  • Deprecate Molecule.rings and Molecule.n_rings
  • Tag issue being addressed
  • Add tests
  • Update docstrings/documentation, if applicable
  • Lint codebase
  • Update changelog

@codecov
Copy link

codecov bot commented Feb 26, 2021

Codecov Report

Merging #855 (137139c) into master (f9d8ee7) will decrease coverage by 0.33%.
The diff coverage is 95.00%.

@mattwthompson
Copy link
Member Author

mattwthompson commented Jan 28, 2022

The toolkit wrappers are disagreeing on the number of rings in naphthalene:

In [35]: molecule = Molecule.from_smiles("c1ccc2ccccc2c1")

In [36]: oechem.OEDetermineRingSystems(molecule.to_openeye())
Out[36]: (1, [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0])

In [37]: rdmol = molecule.to_rdkit(); rdmol.GetRingInfo().AtomRings()
Out[37]: ((0, 1, 2, 3, 8, 9), (4, 5, 6, 7, 8, 3))

In [38]: molecule.get_n_rings(toolkit_registry=OpenEyeToolkitWrapper())
Out[38]: 1

In [39]: molecule.get_n_rings(toolkit_registry=RDKitToolkitWrapper())
Out[39]: 2

but the other methods are behaving well in some simple tests.

@mattwthompson mattwthompson marked this pull request as ready for review January 31, 2022 23:23
@mattwthompson
Copy link
Member Author

Looks like a test is failing due to a toolkit disagreement in how many rings a molecule has. I'll look into that tomorrow, probably just removing it since it's a deprecated API point - otherwise this is ready for review @j-wags

@mattwthompson mattwthompson requested a review from j-wags January 31, 2022 23:24
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.

Sorry to be nitpicky here, but I can't meaningfully review this if we're planning to fully remove Molecule.rings and n_rings before merging (like I think we've decided to do, though maybe we understood different things from the discussion). Most of the lines in the test diffs will be substantially changed and so the review would be huge and it'd be hard to keep track of everything under discussion.

I think we should immediately remove those API points with no deprecation warning. It's bad, but we don't have a release planned where anyone would see a deprecation warning anyway, and 0.11.0 will hopefully be our only major API break this year, so this is probably the most realistic way forward.

@mattwthompson
Copy link
Member Author

My read of the discussion was that we'd deprecate those points in this release with the intention of removing them later - probably since that's what we would typically do. I will update this to remove them now, though.

@openforcefield openforcefield deleted a comment from lgtm-com bot Feb 4, 2022
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.

This is starting to come together really well. I think we can simplify the toolkitwrapper method signatures and avoid a lot of weird edge cases in the process -- See suggested code changes.

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.

Thanks for all the iteration on this. I'm approving this PR, pending changes in the comment before this post.

@lgtm-com
Copy link

lgtm-com bot commented Feb 10, 2022

This pull request introduces 1 alert when merging c413f35 into a7a9f18 - view on LGTM.com

new alerts:

  • 1 for Unused import

@lgtm-com
Copy link

lgtm-com bot commented Feb 10, 2022

This pull request introduces 1 alert when merging 475abc7 into a7a9f18 - view on LGTM.com

new alerts:

  • 1 for Unused import

@mattwthompson mattwthompson merged commit 9362b71 into master Feb 10, 2022
@mattwthompson mattwthompson deleted the toolkit-rings branch February 10, 2022 21:50
mattwthompson added a commit that referenced this pull request Apr 13, 2022
9362b71

Refactor ring methods in Molecule class (#855)

* Refactor Molecule._get_rings() to ToolkitWrapper.call()

* Refactor .n_rings, .is_in_ring to methods that call toolkit wrappers

* Add Molecule.n_rings and OpenEye implementations, tests

* Add bond_is_in_ring methods in cheminformatics toolkit wrappers

* Add back Molecule.rings with deprecation warning

* Add test for biphenyl's central bond not being "in a ring"

* Have Bond.is_in_ring route to wrapper methods

* Update release history

* Update pre-commit config, re-run black

* Fix mypy and tests

* Move is_in_ring tests to test_toolkits.py

* Fix tests, add back Molecule.n_rings as deprecated

* Update docs/releasehistory.md

Co-authored-by: Jeff Wagner <jwagnerjpl@gmail.com>

* Remove Molecule.rings and Molecule.n_rings

* Fix TestMolecule::test_is_in_ring

* Update biphenyl ring tests with mapped smiles

* Remove unused import

* Apply suggestions from code review

Co-authored-by: Jeff Wagner <jwagnerjpl@gmail.com>

* Rework ring checks to only take Atom or Bond

* Add test for error when Atom/Bond not attached to molecule

* Update docstring and changelog

* Fix test for unattached bond case

* Cleanup

Co-authored-by: Jeff Wagner <jwagnerjpl@gmail.com>
mattwthompson added a commit that referenced this pull request Apr 13, 2022
9362b71

Refactor ring methods in Molecule class (#855)

* Refactor Molecule._get_rings() to ToolkitWrapper.call()

* Refactor .n_rings, .is_in_ring to methods that call toolkit wrappers

* Add Molecule.n_rings and OpenEye implementations, tests

* Add bond_is_in_ring methods in cheminformatics toolkit wrappers

* Add back Molecule.rings with deprecation warning

* Add test for biphenyl's central bond not being "in a ring"

* Have Bond.is_in_ring route to wrapper methods

* Update release history

* Update pre-commit config, re-run black

* Fix mypy and tests

* Move is_in_ring tests to test_toolkits.py

* Fix tests, add back Molecule.n_rings as deprecated

* Update docs/releasehistory.md

Co-authored-by: Jeff Wagner <jwagnerjpl@gmail.com>

* Remove Molecule.rings and Molecule.n_rings

* Fix TestMolecule::test_is_in_ring

* Update biphenyl ring tests with mapped smiles

* Remove unused import

* Apply suggestions from code review

Co-authored-by: Jeff Wagner <jwagnerjpl@gmail.com>

* Rework ring checks to only take Atom or Bond

* Add test for error when Atom/Bond not attached to molecule

* Update docstring and changelog

* Fix test for unattached bond case

* Cleanup

Co-authored-by: Jeff Wagner <jwagnerjpl@gmail.com>
mattwthompson added a commit that referenced this pull request Apr 13, 2022
9362b71

Refactor ring methods in Molecule class (#855)

* Refactor Molecule._get_rings() to ToolkitWrapper.call()

* Refactor .n_rings, .is_in_ring to methods that call toolkit wrappers

* Add Molecule.n_rings and OpenEye implementations, tests

* Add bond_is_in_ring methods in cheminformatics toolkit wrappers

* Add back Molecule.rings with deprecation warning

* Add test for biphenyl's central bond not being "in a ring"

* Have Bond.is_in_ring route to wrapper methods

* Update release history

* Update pre-commit config, re-run black

* Fix mypy and tests

* Move is_in_ring tests to test_toolkits.py

* Fix tests, add back Molecule.n_rings as deprecated

* Update docs/releasehistory.md

Co-authored-by: Jeff Wagner <jwagnerjpl@gmail.com>

* Remove Molecule.rings and Molecule.n_rings

* Fix TestMolecule::test_is_in_ring

* Update biphenyl ring tests with mapped smiles

* Remove unused import

* Apply suggestions from code review

Co-authored-by: Jeff Wagner <jwagnerjpl@gmail.com>

* Rework ring checks to only take Atom or Bond

* Add test for error when Atom/Bond not attached to molecule

* Update docstring and changelog

* Fix test for unattached bond case

* Cleanup

Co-authored-by: Jeff Wagner <jwagnerjpl@gmail.com>

Co-authored-by: Jeff Wagner <jwagnerjpl@gmail.com>
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Refactor _get_rings to be a ToolkitWrapper call
3 participants