Skip to content

fix(statmech): declare reaction species in the Arkane kinetics input regardless of compute_thermo - #1022

Merged
calvinp0 merged 1 commit into
mainfrom
i017-kinetics-species
Aug 25, 2026
Merged

fix(statmech): declare reaction species in the Arkane kinetics input regardless of compute_thermo#1022
calvinp0 merged 1 commit into
mainfrom
i017-kinetics-species

Conversation

@alongd

@alongd alongd commented Aug 23, 2026

Copy link
Copy Markdown
Member

What this fixes

An Arkane kinetics input generated by ARC can reference species it never declares, so Arkane dies before computing anything:

File "arkane/input.py", line 297, in reaction
    reactants = sorted([species_dict[spec] for spec in reactants])
KeyError: '[O]C=O[1]'

This was found on a run where everything else went right: two species and a transition state all optimised and frequency-checked on a cluster, and then no rate coefficient at all.

Cause

ArkaneAdapter.render_arkane_input_template builds species_list under if e0_only or spc.compute_thermo:. A caller that sets compute_thermo=False — as an orchestrator does when it wants kinetics but does not want a full thermodynamics job queued — gets:

  • the E0 render (e0_only=True) → gate passes → all species declared;
  • the kinetics render (e0_only=False) → gate fails → none declared, while reaction(...) still names them by label.

generate_species_files writes the per-species statmech files either way, so ARC writes statmech/kinetics/species/<label>.py to disk and then writes a main input that references that species without declaring it. compute_thermo should govern whether a thermo job runs — not whether a species may be declared in an input that names it.

The existing test_generate_arkane_input never caught this because ARCSpecies.compute_thermo defaults to not is_ts, i.e. True for ordinary species; the defect only surfaces when a caller sets it to False explicitly.

The change

Collect the labels named by any reaction in the render's reaction list, and let a species through the gate if it is one of them:

if e0_only or spc.compute_thermo or spc.label in reaction_species_labels:

Deliberately narrow rather than dropping the gate: dropping it would push species into thermo inputs that exclude them on purpose. For a thermo render self.reactions is None, so the new set is empty and the gate is unchanged — thermo inputs are unaffected.

Testing

  • New unit test: a reactant with compute_thermo=False now renders as a species('R', ...) line in a kinetics input.
  • Mutation: restoring the old gate turns it red, with the rendered text showing reaction(reactants=['R'], products=['P']) above zero species( lines.
  • arc/statmech/: 50 passed.
  • End to end on real converged output. Taking the failing run's own kinetics input and adding only the two species(...) declarations this fix emits, Arkane exits 0 and writes the rate coefficient it previously could not produce:
    kinetics(label = '[O]C=O(1) <=> O=[C]O(8)',
        kinetics = Arrhenius(A=(36.3562,'s^-1'), n=3.33173, Ea=(61.8336,'kJ/mol'),
                             T0=(1,'K'), Tmin=(300,'K'), Tmax=(3000,'K')))
    
    No new quantum chemistry — the converged logs were already on disk. (Those numbers come from an RMG-Py checkout that is behind main in arkane/, so treat them as a plumbing result, not a physical one.)

Note for anyone running these tests: arc/statmech/ needs -n0. Under the default xdist config test_generate_arkane_input flakes, because sibling workers share the on-disk arc/testing/arkane_input_tests_delete directory. Pre-existing and unrelated to this change.


Separately: an unrelated bug found on the same run

arc/job/ssh.py:42-43 unpacked self.connect(), which returns None. Not fixed here, and no longer needs to be: @calvinp0 pointed out it is already fixed in #1001 (self._sftp, self._ssh = self.connect()self.connect(), with a regression test). Tracked there.

@codecov

codecov Bot commented Aug 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 64.63%. Comparing base (735de21) to head (4fbafa6).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1022      +/-   ##
==========================================
+ Coverage   64.61%   64.63%   +0.01%     
==========================================
  Files         119      119              
  Lines       39830    39831       +1     
  Branches    10313    10312       -1     
==========================================
+ Hits        25736    25743       +7     
+ Misses      11116    11104      -12     
- Partials     2978     2984       +6     
Flag Coverage Δ
functionaltests 64.63% <ø> (+0.01%) ⬆️
unittests 64.63% <ø> (+0.01%) ⬆️

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.

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.

Pull request overview

Fixes ARC-generated Arkane kinetics inputs that referenced reactant/product labels in reaction(...) blocks without declaring the corresponding species(...) entries when ARCSpecies.compute_thermo=False, which could cause Arkane to fail early with a KeyError and produce no kinetics output.

Changes:

  • Ensure any species named by reactions is included in the Arkane input species_list regardless of compute_thermo (while preserving the existing gate for non-reaction species).
  • Add a unit test covering kinetics-input rendering when reactants/products have compute_thermo=False.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
arc/statmech/arkane.py Expands the species-declaration gate so kinetics renders always declare reaction participants, preventing Arkane KeyError on undeclared species labels.
arc/statmech/arkane_test.py Adds regression test asserting reaction species are declared in kinetics inputs even when compute_thermo=False.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@alongd
alongd force-pushed the i017-kinetics-species branch from 442682d to 45ca6e1 Compare August 25, 2026 05:38
alongd added a commit to alongd/ARC that referenced this pull request Aug 25, 2026
…tion species in the Arkane kinetics input regardless of compute_thermo
@alongd
alongd requested a review from calvinp0 August 25, 2026 06:22
Comment thread arc/statmech/arkane.py Outdated
Comment thread arc/statmech/arkane_test.py
@calvinp0

calvinp0 commented Aug 25, 2026

Copy link
Copy Markdown
Member

Separately: an unrelated bug found on the same run, reported not fixed here

arc/job/ssh.py:42-43 does

self._sftp, self._ssh = self.connect()

but connect() (arc/job/ssh.py:346-368) returns None, so this raises TypeError: cannot unpack non-sequence NoneType. It only bites a fresh SSHClient used outside a with block, which is why it has survived: there is exactly one production call site, arc/job/trsh.py:1488, on the troubleshoot-by-changing-node recovery path. Not touched here to keep this PR to one change — flagging it so it is not lost.

Should be fixed in #1001

…rdless of compute_thermo

render_arkane_input_template gated species(...) declarations on
'e0_only or spc.compute_thermo'. A kinetics render (e0_only=False) whose
caller sets compute_thermo=False on reactants/products then emitted a
reaction(...) that named species it never declared, so Arkane raised
KeyError on the reactant label and produced no rate coefficient, despite
all QM jobs having converged.

Also declare any species named by a reaction in the render's reaction
list. Thermo inputs (no reactions) are unchanged; compute_thermo still
governs whether a thermo job runs, not whether a species may be declared
in an input that references it.
@alongd
alongd force-pushed the i017-kinetics-species branch from 45ca6e1 to 4fbafa6 Compare August 25, 2026 09:54
@alongd

alongd commented Aug 25, 2026

Copy link
Copy Markdown
Member Author

You're right — checked #1001 and it fixes exactly this: self._sftp, self._ssh = self.connect()self.connect(), with a regression test for it. Dropping the note from this PR's description so the fix is tracked in one place.

@alongd
alongd requested a review from calvinp0 August 25, 2026 09:55
@calvinp0
calvinp0 merged commit 005f19d into main Aug 25, 2026
8 checks passed
@calvinp0
calvinp0 deleted the i017-kinetics-species branch August 25, 2026 10:52
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.

3 participants