Skip to content

Preserve chirality when merging explicit Hs in MergeQueryHs - #9676

Open
barlowa124 wants to merge 2 commits into
rdkit:masterfrom
barlowa124:mergehs-chirality-9675
Open

barlowa124 wants to merge 2 commits into
rdkit:masterfrom
barlowa124:mergehs-chirality-9675

Conversation

@barlowa124

Copy link
Copy Markdown
Contributor

Reference Issue

Fixes #9675

What does this implement/fix? Explain your changes.

MolOps::mergeQueryHs dropped chirality when an explicit H neighbor of a tetrahedral stereo center was merged into the parent's query. Two things combine here.

When the parent atom was not already a query atom, it was replaced by a QueryAtom via updateProps(). That call copies the property dictionary but not d_chiralTag, so the tag was lost outright.
And removing the H bonds changes the order of the remaining bonds about the center, which can flip the parity the tag encodes. removeHs() already compensates for this per removal (getPerturbationOrder + invertChirality). The merge path did not.

The change carries the tag across the replacement and applies the same parity fixup, computed over the kept bonds plus the removed bonds appended in original order.

The reported L-alanine case now keeps a chiral tag on the merged atom, and with useChirality on the query matches C[C@@H](N)C(=O)O while rejecting C[C@H](N)C(=O)O. A regression test covers both assertions.

Any other comments?

graphmolMolOpsTest passes all 116 test cases and molopsTestsCatch passes 16/16, run with RDBASE set. The Python-side check from the issue was not run (no py312 bindings on this machine). The C++ test asserts the same behavior.

Merging an explicit H neighbor into a chiral atom's query dropped the
chiral tag entirely: updateProps() copies the property dictionary but
not d_chiralTag, so the tag was lost when the atom was replaced by a
QueryAtom. The merged query then matched both enantiomers.

Carry the chiral tag across the replacement, and flip the tag when
removing the H bonds changes the parity of the remaining bond order --
the same fixup removeHs() already performs per removal.

Fixes rdkit#9675

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@greptile-apps

greptile-apps Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

[Medium risk] Fixes chirality handling when merging explicit hydrogens.

The PR appears safe to merge based on the reviewed changes.

Summary

The PR preserves a chiral tag when an explicit H is merged into its neighbor’s query and adjusts the tag for changes in bond order.

  • The latest changes add tests for an H-last ordering and a center that is already a query atom.
  • The earlier test-coverage thread is resolved.
Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart LR
  A[Chiral atom with explicit H] --> B[Identify H bonds to remove]
  B --> C[Compute bond-order parity]
  C --> D[Preserve tag on replacement, if needed]
  D --> E[Invert tag when parity is odd]
  E --> F[Merge H query and remove H atoms]
Loading

Reviews (2) · Last reviewed commit: "Cover even-parity and existing-QueryAtom..."

Comment thread Code/GraphMol/molopstest.cpp Resolved
Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Merging explicit hydrogens loses or inverts tetrahedral chirality

1 participant