-
Notifications
You must be signed in to change notification settings - Fork 95
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
Improve visualization with RDKit backend #1001
Conversation
This looks really cool, and I'm glad we're closing that old issue. Based on our conversation in today's meeting, could you additionally:
Also, I think @mattwthompson is more familiar with the drawing code than me, so he may be a better reviewer (once you're ready for someone to take a look!) |
The drawing code looks fine to me. |
I'm far from an expert in these features (when I worked on #560 etc. I was pretty much learning it at the same time) but I'd be happy to review once this is ready. (It might be now?) |
Thanks @mattwthompson. I'm going to take over finishing this so that @Yoshanuikabundi can move on to learning Interchange in a week or two. I'll still need to thread the |
Rdkit has a complicated system for including Hydrogen atoms. It is discussed here: https://sourceforge.net/p/rdkit/mailman/message/36699970/ In brief, there are three levels of hydrogen inclusion: Explicit and in graph, explicit, and implicit. This is meant to model the difference between hydrogens that are explicit in a SMILES string, and those that are inferred by the toolkit, but it unfortunately goes even further than that. For instance, if hydrogens are removed from a molecule with the rdkit.Chem.rdmolops.RemoveHs() function, which is the recommended way to make explicit hydrogens implicit for visualization, RdKit can then imply the existence of hydrogens using its valence model. This can, for example, convert a radical to the stable species of equivalent charge, even if this means adding hydrogens. In fact, before this commit, simply calling the OFFTK Molecule.to_rdkit method could convert, for example, the hydroxyl radical to water: >>> from openff.toolkit.topology import Molecule >>> from rdkit import Chem >>> >>> radical = Molecule.from_smiles("[O][H]") >>> rd_radical = radical.to_rdkit() >>> Chem.MolToSmiles(rd_radical) '[H]O' Visualizing rd_radical clearly demonstrates that this is water; the oxygen atom has an implicit hydrogen. This can also be seen by building the radical up from individual atoms and bonds. OFFTK has a different philosophy: all the hydrogens are either provided or inferred when the Molecule is created, and then they are explicitly represented in the molecular graph forever. This commit sets the `NoImplicit` property for all atoms in a rdkit molecule created by to_rdkit to True. Since all the hydrogens in a Molecule are already explicitly represented, this more faithfully represents the desired molecule in the rdkit ecosystem. The molecular species is even now stable over sanitization: >>> radical = Molecule.from_smiles("[O][H]") >>> rd_hydroxyl_rad = radical.to_rdkit() >>> Chem.SanitizeMol(rd_hydroxyl_rad) # Modifies in place >>> Chem.MolToSmiles(rd_hydroxyl_rad) [H][O] Visualization even includes the radical dot!
1eb3d74
to
31be3c3
Compare
@j-wags I've implemented the changes we discussed. I think this is ready for review! @mattwthompson
|
@@ -1688,6 +1688,9 @@ def to_rdkit(cls, molecule, aromaticity_model=DEFAULT_AROMATICITY_MODEL): | |||
elif atom.stereochemistry == "R": | |||
rdatom.SetChiralTag(Chem.CHI_TETRAHEDRAL_CCW) | |||
|
|||
# Stop rdkit from adding implicit hydrogens | |||
rdatom.SetNoImplicit(True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Blocking: This seems like something that could potentially have downstream side effects since this code path is not restricted to visualization. I have a certain amount of confidence seeing that the tests still pass, but I'd like either @j-wags's blessing or another explanation as to why this won't accidentally break things. Maybe that's as simple as "well, we wouldn't want the result of .to_rdkit()` to have explicit hydrogens anyway" ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'd like @j-wags blessing too, but I give that explanation in the commit message to a0263f9. In short, we are already guaranteed to explicitly represent all our hydrogens, so its important to tell rdkit not to infer the existence of any other hydrogens. Without this change, converting a radical species to rdkit changes the molecule's identity. There are probably other related undiscovered bugs too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the detailed explanation in that commit. I'm on board with this solution given your explanation, the fact that the tests are passing, our general lack of support/interest in radical species, and the likelihood that there are bigger problems with handling radicals. Until they're a key part of our force fields, I don't think it's worth losing sleep over them.
Given that Jeff is somewhat priority paralyzed at the moment I think it would be best to merge this in its current state. Unlikely as it may be, we could still catch breaking behavior before a next release. But please add a note to the "Behavior changed" section summarizing this change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for looping me in. I think this is a good call -- On the surface this is exactly what we want (OFFMols ALWAYS have all atoms explicit), and I can't think of any cases where this would have unintended effects. So this looks good to me, thanks for catching it @Yoshanuikabundi!
I think this is good to go once the single blocking comment is resolved. I did make some changes myself; feel free to poke through the "resolved" conversations if anything is disagreeable. Below is the notebook I used while reviewing; everything looked good on this branch (including expected failures) and a couple of the RDKit cells looked weird using |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great to me. Thanks @Yoshanuikabundi!
Squashed commit of the following: commit 708a5c7 Author: Jeff Wagner <jwagnerjpl@gmail.com> Date: Tue Oct 26 13:13:04 2021 -0700 Update README.md commit 48a3e3f Author: Jeff Wagner <jwagnerjpl@gmail.com> Date: Tue Oct 26 13:11:07 2021 -0700 Update releasehistory.md commit 88b03bf Author: Jeff Wagner <jwagnerjpl@gmail.com> Date: Tue Oct 26 11:58:35 2021 -0700 Cleanup and releasenotes prep for 0.10.1 (#1112) * cleanup and releasenotes prep for 0.10.1 * Apply suggestions from code review Co-authored-by: Matt Thompson <mattwthompson@protonmail.com> * make CI run without mypy/typing-extensions * drop deps that are pulling in pydantic --> typing-extensions * revert changes to pre-release testing Co-authored-by: Matt Thompson <mattwthompson@protonmail.com> commit ac99d2e Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon Oct 18 05:39:02 2021 -0500 Bump actions/checkout from 2.3.4 to 2.3.5 (#1107) Bumps [actions/checkout](https://github.com/actions/checkout) from 2.3.4 to 2.3.5. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](actions/checkout@v2.3.4...v2.3.5) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit e8353ef Author: Matt Thompson <mattwthompson@protonmail.com> Date: Thu Oct 7 10:47:56 2021 -0500 Fall back to hill formula in Molecule.__repr__ if to_smiles() fails (#1087) * Fall back to hill formula in Molecule.__repr__ if to_smiles() fails * Update openff/toolkit/tests/test_molecule.py Co-authored-by: Jeff Wagner <jwagnerjpl@gmail.com> * Lint * Update openff/toolkit/tests/test_molecule.py * Lint * Update release history Co-authored-by: Jeff Wagner <jwagnerjpl@gmail.com> commit 893575a Merge: 36e4e30 a8472a7 Author: David Dotson <dotsdl@gmail.com> Date: Fri Oct 1 16:43:38 2021 -0700 Merge pull request #1101 from openforcefield/qcschema_fix `to_qcschema` fix with no bonds. commit a8472a7 Author: David Dotson <dotsdl@gmail.com> Date: Fri Oct 1 10:08:01 2021 -0700 Added changelog entry for #1101 commit bf10ad8 Author: Josh Horton <Josh.Horton@newcastle.ac.uk> Date: Fri Oct 1 16:49:58 2021 +0100 make sure connectivity is none when we have no bonds commit 36e4e30 Author: Matt Thompson <mattwthompson@protonmail.com> Date: Thu Sep 30 11:00:33 2021 -0500 Use Quantity.value_in_unit() instead of dividing quantities by units (#1088) * Use Quantity.value_in_unit() instead of dividing quantities by units * More fixes found by @lilyminium * Update openff/toolkit/topology/molecule.py Co-authored-by: trevorgokey <50244806+trevorgokey@users.noreply.github.com> * Fix atom positions unit logic Co-authored-by: trevorgokey <50244806+trevorgokey@users.noreply.github.com> commit 8a076ae Author: Matt Thompson <mattwthompson@protonmail.com> Date: Thu Sep 30 10:20:26 2021 -0500 Make atom names more unique (#1096) * Append 'x' to atom names to avoid downstream clashes * Update release notes, note TODO from review commit 7ab1636 Author: Matt Thompson <mattwthompson@protonmail.com> Date: Thu Sep 30 08:38:35 2021 -0500 Avoid ParseError deprecation warning when not imported (#1094) commit d39905b Author: Lily Wang <31115101+lilyminium@users.noreply.github.com> Date: Thu Sep 23 11:55:46 2021 -0700 Speed up rdkit distances (#1070) * replace rdkit distances * add branch to ci * small modifications * blacken and remove CI * add comments and change variable name Co-authored-by: Matt Thompson <mattwthompson@protonmail.com> commit fa18468 Author: Matt Thompson <mattwthompson@protonmail.com> Date: Thu Sep 23 12:12:27 2021 -0500 Preparations for supporting type annotations (#1059) * Gradual typing: Set up mypy without type annotations * Add mypy to CI * Add mypy to CI * Fix syntax in environment file * Update configuration, turn off no-redef globally * Prevent mypy from quitting CI runs early * Run mypy in CI only when RDKit and OpenEye backends are installed * Only run mypy on "true/true" parts of matrix * Update import skips for openmm commit 6cfad71 Author: Lily Wang <31115101+lilyminium@users.noreply.github.com> Date: Wed Sep 22 16:42:21 2021 -0700 Raise subclass of AttributeError in __getattr__ (#1052) * add new exception * black likes newlines * isort alphabetically * update releasehistory commit b9caeac Author: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed Sep 22 14:39:17 2021 -0700 [pre-commit.ci] pre-commit autoupdate (#1083) updates: - [github.com/psf/black: 21.8b0 → 21.9b0](psf/black@21.8b0...21.9b0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> commit c0f9ebe Author: Matt Thompson <mattwthompson@protonmail.com> Date: Wed Sep 22 16:27:34 2021 -0500 Assorted README fixes (#1082) * Update README: smirnoff.html links, latest -> stable, Sage changes * Add link to force field plugin entry point commit 9310765 Author: Josh A. Mitchell <yoshanuikabundi@gmail.com> Date: Thu Sep 23 00:40:06 2021 +1000 Updating install guide (#1062) * Update install guide * Reorganise installation.md to avoid repeating information * Describe installing from source * Add section describing WSL and platform support * Recommend WSL2 and mention hardware reqs * Mention the Jupyter WSL caveat * Update changelog Co-authored-by: Jeff Wagner <jwagnerjpl@gmail.com> commit b1c41ae Author: Josh A. Mitchell <yoshanuikabundi@gmail.com> Date: Thu Sep 16 10:02:20 2021 +1000 Disable HTML post processing to help RTD builds pass (#1080) commit be3079e Author: Jeff Wagner <jwagnerjpl@gmail.com> Date: Wed Sep 15 16:21:52 2021 -0700 fix binder links commit 6a85063 Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue Sep 14 09:35:58 2021 -0500 Bump codecov/codecov-action from 2.0.3 to 2.1.0 (#1078) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 2.0.3 to 2.1.0. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/master/CHANGELOG.md) - [Commits](codecov/codecov-action@v2.0.3...v2.1.0) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> commit 1440cf6 Author: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon Sep 13 14:41:46 2021 -0500 [pre-commit.ci] pre-commit autoupdate (#1077) updates: - [github.com/nbQA-dev/nbQA: 1.1.0 → 1.1.1](nbQA-dev/nbQA@1.1.0...1.1.1) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> commit 36f3c75 Author: Josh A. Mitchell <yoshanuikabundi@gmail.com> Date: Mon Sep 13 19:52:38 2021 +1000 Update Example notebooks to Sage force field (#1065) * Update check_parameter_coverage to Sage FF * Update conformer-energies to Sage FF * Update forcefield_modification to Sage FF * Update inspect_assigned_parameters to Sage FF * Update smirnoff_simulation to Sage FF * Update using_smirnoff_in_amber_or_gromacs to Sage FF * Update swap_amber_parameters to Sage FF * Update toolkit_showcase to Sage FF * Update using_smirnoff_with_amber_protein_forcefield to Sage FF * Update virtual_sites to Sage FF * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update changelog * Fix references to old force fields in comments * Update conformer_energies.py to use Sage and print out the used force field * Add pin for openff-forcefield >=2.0.0 to examples environment * Add example script behaviour change to changelog * Merge `master` into `update-example-ffs` Squashed commit of the following: commit b3bcc88 Author: Jeff Wagner <jwagnerjpl@gmail.com> Date: Fri Sep 10 13:42:37 2021 -0700 Update latest release tag to be 'stable' instead of 'latest' (#1068) * update use of latest tag to refer to 'stable' instead of 'latest' (since 'latest' clashes with the RTD builtin 'latest' keyword) * Update .github/workflows/release.yml Co-authored-by: Josh A. Mitchell <yoshanuikabundi@gmail.com> * Update notebook links from 'latest' to 'stable' tag * cosmetic commit to kick ci Co-authored-by: Josh A. Mitchell <yoshanuikabundi@gmail.com> commit 9d9f933 Author: Matt Thompson <mattwthompson@protonmail.com> Date: Thu Sep 9 18:24:25 2021 -0500 Safely import OpenMM (#1063) * Pin to OpenMM 7.5.x * Loosen OpenMM pin * Fix link to OpenMM ForceField API docs * Unpin everything * Cleanup * Gracefully import OpenMM in examples * Safely import OpenMM everywhere * Clean up an import * Run CI with openmm==7.5 pin * Run CI with openmm==7.6 pin * Unpin OpenMM, run slow tests * Revert addition of slow tests commit e4b56ab Author: Matt Thompson <mattwthompson@protonmail.com> Date: Thu Sep 9 17:12:30 2021 -0500 Catch/raise descriptive error on conformer generation failure (#1050) * Catch/raise descriptive error on conformer generation failure * Run slow tests in PR * Remove useless raise_exception_types, add test in Molecule API * Remove unused import * Update openff/toolkit/utils/exceptions.py Co-authored-by: Lily Wang <31115101+lilyminium@users.noreply.github.com> * Use uranium hexafluoride to test conformer generation failures * Make conformer generation try other toolkits * Explicitly test that both OpenEye and RDKit fail on UF6 * Update CHANGELOG * Fix change pushed to wrong branch Co-authored-by: Lily Wang <31115101+lilyminium@users.noreply.github.com> commit 7a3fad5 Author: Matt Thompson <mattwthompson@protonmail.com> Date: Wed Sep 8 16:01:00 2021 -0500 nbqa-black -> black (#1064) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> commit b3bcc88 Author: Jeff Wagner <jwagnerjpl@gmail.com> Date: Fri Sep 10 13:42:37 2021 -0700 Update latest release tag to be 'stable' instead of 'latest' (#1068) * update use of latest tag to refer to 'stable' instead of 'latest' (since 'latest' clashes with the RTD builtin 'latest' keyword) * Update .github/workflows/release.yml Co-authored-by: Josh A. Mitchell <yoshanuikabundi@gmail.com> * Update notebook links from 'latest' to 'stable' tag * cosmetic commit to kick ci Co-authored-by: Josh A. Mitchell <yoshanuikabundi@gmail.com> commit 9d9f933 Author: Matt Thompson <mattwthompson@protonmail.com> Date: Thu Sep 9 18:24:25 2021 -0500 Safely import OpenMM (#1063) * Pin to OpenMM 7.5.x * Loosen OpenMM pin * Fix link to OpenMM ForceField API docs * Unpin everything * Cleanup * Gracefully import OpenMM in examples * Safely import OpenMM everywhere * Clean up an import * Run CI with openmm==7.5 pin * Run CI with openmm==7.6 pin * Unpin OpenMM, run slow tests * Revert addition of slow tests commit e4b56ab Author: Matt Thompson <mattwthompson@protonmail.com> Date: Thu Sep 9 17:12:30 2021 -0500 Catch/raise descriptive error on conformer generation failure (#1050) * Catch/raise descriptive error on conformer generation failure * Run slow tests in PR * Remove useless raise_exception_types, add test in Molecule API * Remove unused import * Update openff/toolkit/utils/exceptions.py Co-authored-by: Lily Wang <31115101+lilyminium@users.noreply.github.com> * Use uranium hexafluoride to test conformer generation failures * Make conformer generation try other toolkits * Explicitly test that both OpenEye and RDKit fail on UF6 * Update CHANGELOG * Fix change pushed to wrong branch Co-authored-by: Lily Wang <31115101+lilyminium@users.noreply.github.com> commit 7a3fad5 Author: Matt Thompson <mattwthompson@protonmail.com> Date: Wed Sep 8 16:01:00 2021 -0500 nbqa-black -> black (#1064) commit 6463e8a Author: Matt Thompson <mattwthompson@protonmail.com> Date: Thu Sep 2 17:36:06 2021 -0500 Remove dormant API points (#1058) * Remove dead API points * Remove _networkx_to_hill_formula, replace _to_mdtraj, update release notes * Fix typo commit 881c29a Author: Matt Thompson <mattwthompson@protonmail.com> Date: Thu Sep 2 15:49:04 2021 -0500 Minor fixes for OpenMM 7.6 API changes (#1061) * Pin to OpenMM 7.5.x * Loosen OpenMM pin * Fix link to OpenMM ForceField API docs * Unpin everything * Cleanup * Gracefully import OpenMM in examples * Test on OpenMM 7.5 * Remove OpenMM 7.5 pin commit e0b632d Author: Josh A. Mitchell <yoshanuikabundi@gmail.com> Date: Thu Sep 2 09:11:23 2021 +1000 Enable new OpenFF theme (#979) * Enable openff theme * Typo * Convert headers in index to captions * Updates to work with main theme branch * Fix logo colours Co-authored-by: Jeff Wagner <jwagnerjpl@gmail.com> commit 7cb165a Author: Josh A. Mitchell <yoshanuikabundi@gmail.com> Date: Thu Sep 2 09:10:27 2021 +1000 Improve visualization with RDKit backend (#1001) * Improve usage of RDKit visualization backend * Compute 2d coordinates again every time * lint * Update changelog * Update visualize test for new return type * Implement show_hydrogens for openeye * Remove errant print * Fix incorrect rendering of radicals Rdkit has a complicated system for including Hydrogen atoms. It is discussed here: https://sourceforge.net/p/rdkit/mailman/message/36699970/ In brief, there are three levels of hydrogen inclusion: Explicit and in graph, explicit, and implicit. This is meant to model the difference between hydrogens that are explicit in a SMILES string, and those that are inferred by the toolkit, but it unfortunately goes even further than that. For instance, if hydrogens are removed from a molecule with the rdkit.Chem.rdmolops.RemoveHs() function, which is the recommended way to make explicit hydrogens implicit for visualization, RdKit can then imply the existence of hydrogens using its valence model. This can, for example, convert a radical to the stable species of equivalent charge, even if this means adding hydrogens. In fact, before this commit, simply calling the OFFTK Molecule.to_rdkit method could convert, for example, the hydroxyl radical to water: >>> from openff.toolkit.topology import Molecule >>> from rdkit import Chem >>> >>> radical = Molecule.from_smiles("[O][H]") >>> rd_radical = radical.to_rdkit() >>> Chem.MolToSmiles(rd_radical) '[H]O' Visualizing rd_radical clearly demonstrates that this is water; the oxygen atom has an implicit hydrogen. This can also be seen by building the radical up from individual atoms and bonds. OFFTK has a different philosophy: all the hydrogens are either provided or inferred when the Molecule is created, and then they are explicitly represented in the molecular graph forever. This commit sets the `NoImplicit` property for all atoms in a rdkit molecule created by to_rdkit to True. Since all the hydrogens in a Molecule are already explicitly represented, this more faithfully represents the desired molecule in the rdkit ecosystem. The molecular species is even now stable over sanitization: >>> radical = Molecule.from_smiles("[O][H]") >>> rd_hydroxyl_rad = radical.to_rdkit() >>> Chem.SanitizeMol(rd_hydroxyl_rad) # Modifies in place >>> Chem.MolToSmiles(rd_hydroxyl_rad) [H][O] Visualization even includes the radical dot! * Fix release history lost in previous merge conflict * ipython -> IPython * Apply suggestions from code review * Note TODOs * Default boolean argument to a boolean value * Update behaviour change in changelog Co-authored-by: Matthew W. Thompson <mattwthompson@protonmail.com> Co-authored-by: Jeff Wagner <jwagnerjpl@gmail.com> commit f5b5558 Author: Matt Thompson <mattwthompson@protonmail.com> Date: Wed Sep 1 15:58:26 2021 -0500 Add @requires_pkg on Interchange tests (#1054) commit da37f07 Author: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon Aug 30 16:43:57 2021 -0500 [pre-commit.ci] pre-commit autoupdate (#1060) updates: - [github.com/psf/black: 21.7b0 → 21.8b0](psf/black@21.7b0...21.8b0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> commit a837709 Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed Aug 25 11:14:29 2021 -0500 Bump codecov/codecov-action from 2.0.2 to 2.0.3 (#1055) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 2.0.2 to 2.0.3. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/master/CHANGELOG.md) - [Commits](codecov/codecov-action@v2.0.2...v2.0.3) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Previously, the
Molecule.visualize()
method with therdkit
backend was a little ugly. It rendered in low-resolution PNG and would use the conformer coordinates to position atoms. This caused results that were inconsistent depending on whether conformers existed in theMolecule
, and at worst could obscure complex molecules. Hydrogens were also always rendered explicitly, which is at least unconventional.This PR adds an
explicit_hydrogens
argument to theMolecule.visualize()
method that determines whether hydrogens should be rendered, forces a recalculation of 2D coordinates for visualization with every call, and draws in SVG format so that lines are crisp and clear at any scale. It also allows therdkit
backend to accept the existingwidth
andheight
arguments. Finally, it prefers the CoordGen library for 2d coordinate generation - it seems to provide nicer coordinates, especially with explicit hydrogens.I've had to screenshot the SVGs to get GitHub to like them, but you can see even from the screenshots how much crisper they are. On the notebook, they render as SVGs.
Before:
Before, with a conformer:
After, with implicit hydrogens (the new default):
After, with explicit hydrogens:
Closes #759, at least for the
rdkit
backend.