ReactionMechanismGenerator / ReactionMechanismGenerator/ARC
LinearAdapter silently ignores a pre-set atom map, returning identical TS guesses for different maps
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 51
- Forks
- 25
- Avg merge
- 4d 5h
- Merged PRs (30d)
- 15
Description
Describe the bug
LinearAdapter recomputes the atom map internally, so an atom map set on the reaction beforehand has no effect on the transition-state guesses it returns. Calling the adapter with two different pre-set maps for the same reaction yields byte-identical guess geometries, with nothing in the log indicating that the supplied map was not used.
This may well be by design — the adapter is built to iterate over rxn.product_dicts and derive its own map for each. What makes it worth reporting is that there is no signal: execute_incore() reports guesses as successful either way, so a caller who supplies a map has no way to discover it was ignored.
The behavior is easy to read the other way, because the adapter snapshots and restores the attribute:
# arc/job/adapters/ts/linear.py, execute_incore()
atom_map_snapshot = rxn._atom_map
...
rxn._atom_map = atom_map_snapshot
That protects the caller's value, but the value is never consumed. The consumption point is instead:
# same file
atom_map = cached_map_rxn(rxn=rxn, product_dict_index=i, map_cache=map_cache) # -> map_rxn(...)
How to reproduce
On main @ a24e13b0:
import arc.job.adapters.ts.linear as linear
from arc.job.adapters.ts.linear import LinearAdapter
from arc.reaction import ARCReaction
from arc.species.species import ARCSpecies
def build():
return ARCReaction(r_species=[ARCSpecies(label='r', smiles='CC[CH]C')],
p_species=[ARCSpecies(label='p', smiles='CCC[CH2]')])
geometries = []
for forced in (map_a, map_b): # two different valid maps for this reaction
rxn = build()
rxn._atom_map = list(forced)
rxn.ts_species = None
LinearAdapter(project='p', project_directory='/tmp/p', job_type='tsg',
reactions=[rxn], testing=True).execute_incore()
good = [g for g in rxn.ts_species.ts_guesses if g.success and g.initial_xyz]
geometries.append(good[0].initial_xyz)
# every pairwise coordinate RMSD is 0.000 A
I ran this over several distinct maps of one intra_H_migration reaction: each call reported 8 successful guesses, and all of them were the same geometry.
Monkeypatching linear.map_rxn to return a chosen map does change the output, which confirms that is the consumption point. It is not a clean workaround though — with one of the forced maps the adapter then produced zero guesses, so the guess strategies appear to assume the map they derived themselves.
Expected behavior
Any one of these would resolve it, in decreasing order of usefulness:
- Honor
rxn.atom_mapwhen it is already set, and derive a map only when it is not. - Accept an explicit map (or a list of maps) as an adapter argument, so a caller can request a guess for a particular correspondence.
- If neither is wanted, log a warning when the adapter overwrites a pre-set map, and say in the docstring that guesses are generated per product dictionary rather than per supplied map.
The general point is that for a reaction with more than one valid correspondence, there is currently no supported way to ask for a transition-state guess for a specific one, and the attempt fails quietly rather than loudly.
Installation information
- ARC
main@a24e13b0 - Python 3.14, Linux
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in arc/job/adapters/ts/linear.py, especially execute_incore(), the atom-map snapshot/restore, and the cached_map_rxn() call that reaches map_rxn(). Reproduce the differing pre-set maps and inspect the existing adapter and transition-state guess tests; done means the project has an agreed supported behavior for supplied maps, with regression coverage and an explicit signal or documented limitation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100