Skip to content

fix: honor explicit zero valence instead of hallucinating hydrogens#230

Open
fbaensch-beilstein wants to merge 2 commits into
devfrom
fix/zero-valence-hallucinated-hydrogens
Open

fix: honor explicit zero valence instead of hallucinating hydrogens#230
fbaensch-beilstein wants to merge 2 commits into
devfrom
fix/zero-valence-hallucinated-hydrogens

Conversation

@fbaensch-beilstein

Copy link
Copy Markdown
Collaborator

Summary

Fixes #105. An explicit zero valence — VAL=-1 in V3000, normalized to the V2000 valence-field value 15 — was only special-cased in get_num_H when the atom had no bonds. A zero-valence atom carrying a bond fell into the literal-valence branch and received num_H = 15 - chem_bonds_valence implicit hydrogens.

Concretely, ethane with VAL=-1 on both carbons produced:

InChI=1S/C2H28/c1-2/h1-2H14

(14 "hallucinated" hydrogens per terminal carbon = 15 - 1).

Fix

In get_num_H (INCHI_BASE/src/util.c), treat valence 15 as zero valence unconditionally — no implicit H regardless of whether bonds were drawn. The isolated-atom behavior is unchanged; only the bonded case is corrected:

InChI=1S/C2/c1-2

Test

New INCHI-1-TEST/tests/test_executable/test_github_105.py, parametrized over both V3000 (VAL=-1) and V2000 (valence field 15), asserting the zero-valence ethane gives InChI=1S/C2/c1-2. Written test-first: confirmed RED on the old binary (C2H28), GREEN after the fix.

Verification

  • New test: passes for both formats.
  • Full CLI suite (test_executable): no unexpected failures.
  • C++ unit tests (ctest): 15/15 pass.
  • test_meta: pass.
  • Library multithreading: no segfault; regression: 4 expected, 0 unexpected.
  • Invariance: the 3 non-expected failures (Arsine, phosphabicyclo, mcule 1609394746) were confirmed pre-existing by rebuilding libinchi from baseline and reproducing them identically — not introduced here.
  • No output drift: baseline vs fixed libinchi produce byte-identical InChIs across all 4190 records of both CI regression datasets. The new branch only fires for an explicit 15/VAL=-1 valence field, which real PubChem/mcule structures never carry.

Note

This implements the "honor the zero valence" resolution from the issue discussion. The stricter "reject contradictory input (bond + zero valence) as an error" option is intentionally not taken here — it would be a larger, behavior-changing diff better handled separately.

An explicit zero valence (V3000 VAL=-1, normalized to the V2000 valence
field value 15) was only special-cased in get_num_H when the atom had no
bonds. A zero-valence atom carrying a bond fell into the literal-valence
branch and got num_H = 15 - chem_bonds_valence implicit hydrogens, e.g.
ethane with VAL=-1 on both carbons yielded InChI=1S/C2H28/c1-2/h1-2H14.

Treat valence 15 as zero valence unconditionally: no implicit H regardless
of whether bonds were drawn (InChI=1S/C2/c1-2 for the example above).

Verified no output drift: baseline vs fixed libinchi produce identical
InChIs across all 4190 records of both CI regression datasets.

Closes #105
@github-actions

github-actions Bot commented Jun 24, 2026

Copy link
Copy Markdown

Unit Test Coverage Report

Coverage Regression Summary

Metric PR (%) Base (%) Difference (pp)
Lines 18.6 18.6 +0.00
Branches 12.3 12.3 +0.00

Find details on the base coverage at https://iupac-inchi.github.io/InChI/coverage/index.html

Find details on this PR's coverage by downloading coverage-reports-29074940986 and opening html/index.html

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes incorrect implicit-hydrogen assignment when an explicit zero valence is provided in molfile input (V3000 VAL=-1, normalized to V2000 valence-field 15). This aligns InChI output with the “honor zero valence” behavior discussed in issue #105 and prevents large, invalid “hallucinated hydrogen” counts for bonded atoms.

Changes:

  • Update get_num_H to treat input valence 15 as zero valence unconditionally (no implicit H added even if bonds are present).
  • Add a regression test covering both V3000 (VAL=-1) and V2000 (valence field 15) encodings using a minimal ethane example.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
INCHI-1-TEST/tests/test_executable/test_github_105.py Adds regression coverage for explicit zero-valence inputs to ensure no implicit H are added.
INCHI-1-SRC/INCHI_BASE/src/util.c Fixes implicit-H calculation to honor explicit zero valence (15) regardless of drawn bonds.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread INCHI-1-SRC/INCHI_BASE/src/util.c

@JanCBrammer JanCBrammer left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can confirm that the test is red pre-fix and green post-fix (ran test locally). Good to merge as far as I'm concerned.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

VAL=-1 not properly handled

3 participants