In an SDF, bond type "4" (aromatic) is not legal but is widely used. OpenBabel seems to parse it correctly (e.g. it will produce a correct SMILES or SDF), but atom->ImplicitHydrogenCount() returns the wrong value. See the attached C++ program. Here is the output of the program; note that impH is different in the two molecules even though both are benzene.
atom 1: impH: 1, bond orders: 2 1
atom 2: impH: 1, bond orders: 2 1
atom 3: impH: 1, bond orders: 1 2
atom 4: impH: 1, bond orders: 2 1
atom 5: impH: 1, bond orders: 1 2
atom 6: impH: 1, bond orders: 2 1
atom 1: impH: 0, bond orders: 2 1
atom 2: impH: 0, bond orders: 2 1
atom 3: impH: 0, bond orders: 1 2
atom 4: impH: 0, bond orders: 2 1
atom 5: impH: 0, bond orders: 1 2
atom 6: impH: 0, bond orders: 2 1
My notes (https://gist.github.com/baoilleach/4232459) say that the actual valence of an atom is:
BOSum() + GetImplicitHydrogenCount()
Is this constant? (Looking at the BOSum, there is a special treatment of value 4)
When bond-type 4 is detected, it is changed to 5 for internal storage (see formats/mdlformat.cpp:500). I believe bond-type 5 is a sort of internal "this might be aromatic" flag. After parsing, kekulize.cpp changes these to single/double. My guess is that some "implicit-H-perceived" flag isn't getting set if the bond-type == 5 during kekulization.
It seems right that BOSum() + GetImplicitHydrogenCount() would be constant under normal valence situations ... but "constant" is tricky with S, P, N and so forth, e.g. with double-bonded oxygens.