schrodinger / pymol-open-source

Open-source foundation of the user-sponsored PyMOL molecular visualization system.
https://pymol.org/
Other
1.15k stars 275 forks source link

iterate: Add explicit_valence and explicit_degree #227

Closed speleo3 closed 2 years ago

speleo3 commented 2 years ago

Add explicit_valence (sum of bond orders) and explicit_degree (number of directly-bonded neighbors) to cmd.iterate. These properties should be equivalent to OBAtom::GetExplicitValence(), OBAtom::GetExplicitDegree() and RDKit::Atom::getDegree().

Example:

from pymol import cmd

def test_explicit_degree():
    cmd.reinitialize()
    cmd.fragment("ala")
    result = []
    cmd.iterate("all", "result.append(explicit_degree)", space=locals())
    assert result == [2, 4, 2, 1, 4, 1, 1, 1, 1, 1]

def test_explicit_valence():
    cmd.reinitialize()
    cmd.fragment("ala")
    result = []
    cmd.iterate("all", "result.append(explicit_valence)", space=locals())
    assert result == [2, 4, 3, 2, 4, 1, 1, 1, 1, 1]

def test_explicit_valence__aromatic():
    cmd.reinitialize()
    cmd.fragment("benzene")
    cmd.valence("aromatic", "elem C", "elem C")
    result = []
    cmd.iterate("all", "result.append(explicit_valence)", space=locals())
    assert result == [4, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1]

test_explicit_degree()
test_explicit_valence()
test_explicit_valence__aromatic()
JarrettSJohnson commented 2 years ago

Thanks as always, Thomas! The method from RDKit is slightly unclear to me when I read; I assume that one implies only explicit bonds being used?

speleo3 commented 2 years ago

Thanks for merging, Jarrett! I agree that the documentation of RDKit::Atom::getDegree() could be more clear. I had a look at their code to confirm that it counts the number of explicit bonds (It's the "out degree" on the molecular graph). What's a bit confusing is that in RDKit, the number of explicit hydrogens is also a stored property and they add that when computing getTotalDegree().

This is how I understand the equivalence of the different methods:

Number of explicit bonds Number of explicit + implicit bonds Sum of explicit bond orders Sum of explicit + implicit bond orders
PyMOL explicit_degree valence explicit_valence
OpenBabel GetExplicitDegree() GetTotalDegree() GetExplicitValence() GetTotalValence()
RDKit GetDegree() GetTotalDegree() GetExplicitValence() GetTotalValence()