Closed thesketh closed 4 years ago
The valence electron count is designed to count all electrons in the valence shell. For nitrogen bound to three carbons, the count should be 2, for example.
This is to ensure that all molecular properties can be computed in a consistent way. For example, if you wanted to know whether a nitrogen was a lone pair donor, it would be difficult to do that if it had zero nonbonding electrons.
What you're getting at is worthwhile. Nitrogen with 5 hydrogens is weird. But it doesn't break any rules - other than regularly observed bonding behavior.
That said, a function called validate_hydrogens
could work. It would accept a Molecule
and for each atom check that the hydrogen count conformed to a particular view of bonding regularity.
It might not be universally applicable, however. Each research group may have a different idea of what represents bonding regularity.
The tradeoff I made in Molecule.rs was to allow anything up to and including consumption of all valence electrons. Past that, and you get an error.
That makes sense, it's a good idea to leave the valence electron counts alone, it was just the first solution that came to mind. I might emit a warning for these three in Python. A validation function could be useful, but you're right that deciding what is 'normal' might be difficult
As alternative solutions, I think enforcing the octet rule or checking the hybridisation state would work:
Atom::build
and Atom::add_bond
could check that the octet rule isn't violated. This won't work for the transition metals because of dative bonding, and would need to use electronegativity to assign which atom in a bond gains/loses the electron. Leads to different behaviour for negative charges (e.g. we can make Ti20-, but P20- is a violation)Both of these feel like heavy-handed solutions for only three exceptions, though. In line with 'be liberal in what you accept', the current behaviour is preferable. I'll close this for now, if hybridisation/VSEPR shape are implemented later and the code for this is in place it might be worth revisiting.
I've been thinking about corner cases because I've been putting together the unit tests for oxmol, and
atom::Atom::build
happily accepts NH5, OH6 and FH7 without returningHypervalentAtom
.I have a fix that works, but I'm not sure if it's the best way to handle it. This preserves the ability to represent PF5, SF6 and IF7.
in element:.rs, adjust the valence electron counts for the offending atoms:
in atom::Atom::build, re-add the missing electrons after adding hydrogens:
I don't know how neon is supposed to behave, but I think anyone representing noble gasses is likely to know their quirks anyway.