Skip to content

Fix mapping reverse discovery - #935

Open
calvinp0 wants to merge 3 commits into
mainfrom
fix_mapping_reverse_discovery
Open

Fix mapping reverse discovery#935
calvinp0 wants to merge 3 commits into
mainfrom
fix_mapping_reverse_discovery

Conversation

@calvinp0

Copy link
Copy Markdown
Member

This pull request makes several improvements to the atom mapping logic in the arc.mapping module, particularly for reactions involving XH₃ (e.g., CH₃) groups and for reactions discovered in the reverse direction. The changes focus on making the mapping more robust for linear molecules, ensuring that recoverable mapping failures do not log errors unnecessarily, and improving test coverage for these scenarios.

Mapping logic improvements

  • Enhanced _select_ch3_anchors in engine.py to robustly select non-colinear anchors for XH₃ groups, handling linear molecules by falling back to hydrogens and ensuring a valid plane can always be defined. Introduced _anchors_define_a_plane to encapsulate the colinearity check.
  • Updated _map_xh3_group to return None if a local frame cannot be constructed, and made map_hydrogens fall back to assigning hydrogens in order when geometric refinement fails, ensuring a complete atom map is always produced. [1] [2] [3]

Improved error handling and logging

  • Changed logging in map_rxn so that recoverable failures (e.g., due to orientation issues in reactions discovered in reverse) are logged at DEBUG level instead of ERROR, preventing false alarms for benign failures.
  • Added a logic branch in try_mapping to immediately attempt the flip fallback for reactions discovered in reverse, improving efficiency and clarity.

Test enhancements

  • Added new test cases in engine_test.py to verify anchor selection for linear molecules, ensure that mapping gracefully handles undefined planes, and confirm robust mapping for Retroene and other challenging reactions.
  • Added tests in driver_test.py to check that recoverable failures do not log errors and that retro-Diels-Alder reactions are mapped correctly in the discovered direction.
  • Introduced additional XYZ test data for relevant species in engine_test.py.

These changes collectively make the atom mapping more robust, especially for edge cases involving linear molecules and reactions with reverse-discovered families, while also improving test coverage and reducing noise from unnecessary error logs.

@codecov

codecov Bot commented Jul 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 63.43%. Comparing base (9787770) to head (ba734b2).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #935      +/-   ##
==========================================
- Coverage   63.45%   63.43%   -0.03%     
==========================================
  Files         114      114              
  Lines       38325    38363      +38     
  Branches    10030    10040      +10     
==========================================
+ Hits        24319    24335      +16     
- Misses      11089    11114      +25     
+ Partials     2917     2914       -3     
Flag Coverage Δ
functionaltests 63.43% <ø> (-0.03%) ⬇️
unittests 63.43% <ø> (-0.03%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@calvinp0
calvinp0 marked this pull request as ready for review August 2, 2026 20:22
Copilot AI review requested due to automatic review settings August 2, 2026 20:22

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

For a reaction whose family was discovered in the reverse direction, the
first-orientation map_rxn attempt fails on get_template_product_order (or on a
missing template map) and returns None, after which map_reaction routinely
recovers via its existing flip fallback and returns a valid map. The two
intermediate logger.error calls in map_rxn therefore fired as false alarms on
reactions that mapped successfully.

Downgrade both to logger.debug. Control flow is unchanged (both branches still
return None as before), so the returned atom map is identical for every
reaction. A genuine total-mapping failure (both orientations exhausted) is
still surfaced at error level by ARCReaction.atom_map ("could not be atom
mapped").

Add a focused test that drives the first-orientation failure via map_rxn and
asserts no ERROR is logged, while map_reaction still returns a valid map.
_select_ch3_anchors() promised a second anchor B forming a non-linear B-X-A
angle, but never tested for colinearity and never fell back to hydrogens.
For a linear heavy-atom skeleton (e.g., propyne, CH3-C#CH) every heavy
candidate is colinear with the X->A axis, so _construct_local_axes() raised
'Anchors are colinear; cannot define unique plane.', map_rxn() returned None,
and the whole reaction could not be atom mapped (surfaced by a Retroene
benchmark reaction, C=C=CCC <=> C#CC + C=C, once the species carried
optimized geometries).

Now anchor selection walks candidates in priority order (heavy neighbor of A,
any other neighbor of A, the XH3 hydrogens, any remaining atom) and returns
the first that passes the same non-colinearity criterion _construct_local_axes()
enforces, so selection can never hand it anchors it will reject.
_construct_local_axes() itself remains strict.

Also, _map_xh3_group() now rejects a (None, None) anchor tuple (a non-empty
tuple is truthy, so the previous guard missed it) and returns None instead of
propagating a ValueError, and map_hydrogens() falls back to an in-order
assignment of the three equivalent XH3 hydrogens when the geometric refinement
fails, so the resulting map stays a complete permutation.
@calvinp0
calvinp0 force-pushed the fix_mapping_reverse_discovery branch from ba734b2 to 44a2d9e Compare August 2, 2026 20:22
@calvinp0
calvinp0 requested a review from Copilot August 2, 2026 20:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants