Skip to content

CREST Adapter#807

Open
calvinp0 wants to merge 157 commits into
mainfrom
crest_adapter
Open

CREST Adapter#807
calvinp0 wants to merge 157 commits into
mainfrom
crest_adapter

Conversation

@calvinp0

@calvinp0 calvinp0 commented Nov 27, 2025

Copy link
Copy Markdown
Member

Addition of CREST Adapter that complements the heuristic adapter.

This pull request adds support for the CREST conformer and transition state (TS) search method to the ARC project, along with several related improvements and code cleanups. The most important changes include integrating CREST as a TS search adapter, updating configuration and constants, and enhancing the heuristics TS search logic for better provenance tracking and code clarity.

CREST Integration:

  • Added CREST as a supported TS search method: updated JobEnum (arc/job/adapter.py), included CREST in the list of adapters and RMG family mapping, and registered it as a default incore adapter (arc/job/adapters/common.py, arc/job/adapters/ts/__init__.py). [1] [2] [3] [4]
  • Implemented a new test suite for CREST input generation (arc/job/adapters/ts/crest_test.py).
  • Added a Makefile target and installation script for CREST (Makefile). [1] [2]

Constants and Configuration:

  • Added the angstrom_to_bohr conversion constant to both Cython and Python constants modules (arc/constants.pxd, arc/constants.py). [1] [2] [3]

Heuristics TS Search Enhancements and Refactoring:

  • Refactored heuristics TS search logic to track and combine method provenance for TS guesses, allowing for more precise attribution when multiple methods contribute to a guess (arc/job/adapters/ts/heuristics.py). [1] [2] [3] [4]
  • Improved code readability and maintainability by reformatting imports and function calls, and clarifying data structures and comments in heuristics TS search (arc/job/adapters/ts/heuristics.py). [1] [2] [3] [4] [5] [6] [7]
    .

Comment thread arc/job/adapters/ts/crest.py Fixed
Comment thread arc/job/adapters/ts/crest.py Fixed
Comment thread arc/job/adapters/ts/crest.py Fixed
Comment thread arc/settings/settings.py Fixed
Comment thread arc/settings/settings.py Fixed
Comment thread arc/job/adapters/ts/autotst_ts.py Fixed
Comment thread arc/job/adapters/ts/crest.py Fixed
Comment thread arc/job/adapters/ts/heuristics.py Fixed
Comment thread arc/job/adapters/ts/heuristics.py Fixed
Comment thread arc/job/adapters/ts/heuristics.py Fixed
Comment thread arc/job/adapters/ts/crest.py Fixed

This comment was marked as resolved.

Comment thread arc/job/adapters/ts/crest.py Fixed

This comment was marked as resolved.

Comment thread arc/job/adapters/ts/heuristics.py Fixed
Comment thread arc/settings/settings.py Fixed
Comment thread arc/settings/settings.py Fixed
@calvinp0 calvinp0 force-pushed the crest_adapter branch 2 times, most recently from 3e88c36 to 7674f5f Compare February 2, 2026 09:49
@calvinp0 calvinp0 requested a review from Copilot February 2, 2026 12:10

This comment was marked as resolved.

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 encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

This comment was marked as resolved.

@calvinp0 calvinp0 force-pushed the crest_adapter branch 2 times, most recently from 9be935e to eab7647 Compare February 4, 2026 20:14
@calvinp0 calvinp0 requested a review from alongd February 4, 2026 21:30
@codecov

codecov Bot commented Jul 6, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 64.71%. Comparing base (e7f2c98) to head (8661c5c).
⚠️ Report is 3 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #807      +/-   ##
==========================================
+ Coverage   63.15%   64.71%   +1.55%     
==========================================
  Files         114      127      +13     
  Lines       38178    42499    +4321     
  Branches     9990    10909     +919     
==========================================
+ Hits        24113    27502    +3389     
- Misses      11183    11791     +608     
- Partials     2882     3206     +324     
Flag Coverage Δ
functionaltests 64.71% <ø> (+1.55%) ⬆️
unittests 64.71% <ø> (+1.55%) ⬆️

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.

Comment thread arc/settings/settings.py
# adapters support (see ts_adapters_by_rmg_family) but that RMG does not list as recommended
# (e.g. Intra_RH_Add_Endocyclic, XY_Addition_MultipleBond). Useful when running specific
# reactions across many families (e.g. a benchmark) rather than generating a mechanism.
rmg_family_set = 'default'

Check notice

Code scanning / CodeQL

Unused global variable Note

The global variable 'rmg_family_set' is not used.

Copilot Autofix

AI 1 day ago

To fix this without changing behavior, explicitly mark rmg_family_set as a public module variable by adding it to __all__ in arc/settings/settings.py. This matches the rule’s own guidance (“not explicitly made public by inclusion in __all__”), preserves existing config semantics, and avoids risky deletion/renaming of a likely externally used setting.

Best concrete change:

  • In arc/settings/settings.py, add a module-level __all__ definition that includes 'rmg_family_set'.
  • Place it near the rmg_family_set declaration for clarity.
  • No new imports, methods, or dependencies are required.
Suggested changeset 1
arc/settings/settings.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/arc/settings/settings.py b/arc/settings/settings.py
--- a/arc/settings/settings.py
+++ b/arc/settings/settings.py
@@ -366,6 +366,7 @@
 # (e.g. Intra_RH_Add_Endocyclic, XY_Addition_MultipleBond). Useful when running specific
 # reactions across many families (e.g. a benchmark) rather than generating a mechanism.
 rmg_family_set = 'default'
+__all__ = ['rmg_family_set']
 
 # Default environment names for sister repos
 TS_GCN_PYTHON, TANI_PYTHON, AUTOTST_PYTHON, KINBOT_PYTHON, ARC_PYTHON, XTB, XTB_PYTHON, OB_PYTHON, RMG_PYTHON, RMG_PATH, RMG_DB_PATH = \
EOF
@@ -366,6 +366,7 @@
# (e.g. Intra_RH_Add_Endocyclic, XY_Addition_MultipleBond). Useful when running specific
# reactions across many families (e.g. a benchmark) rather than generating a mechanism.
rmg_family_set = 'default'
__all__ = ['rmg_family_set']

# Default environment names for sister repos
TS_GCN_PYTHON, TANI_PYTHON, AUTOTST_PYTHON, KINBOT_PYTHON, ARC_PYTHON, XTB, XTB_PYTHON, OB_PYTHON, RMG_PYTHON, RMG_PATH, RMG_DB_PATH = \
Copilot is powered by AI and may make mistakes. Always verify output.
Comment thread arc/family/family_test.py
rxn = ARCReaction(r_species=[ARCSpecies(label='R', smiles='C=CCC', multiplicity=1)],
p_species=[ARCSpecies(label='P', smiles='C1CCC1', multiplicity=1)])
product_dicts = rxn.get_product_dicts(rmg_family_set=['Intra_RH_Add_Endocyclic'])
self.assertTrue(len(product_dicts) > 0)

Check notice

Code scanning / CodeQL

Imprecise assert Note

assertTrue(a > b) cannot provide an informative message. Using assertGreater(a, b) instead will give more informative messages.

Copilot Autofix

AI 1 day ago

Replace the imprecise boolean assertion with a specific unittest assertion:

  • In arc/family/family_test.py, inside test_apply_recipe_coerces_string_bond_order, change:
    • self.assertTrue(len(product_dicts) > 0)
    • to
    • self.assertGreater(len(product_dicts), 0)

This preserves behavior while improving failure diagnostics (it will report actual compared values). No imports, helper methods, or additional definitions are needed.

Suggested changeset 1
arc/family/family_test.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/arc/family/family_test.py b/arc/family/family_test.py
--- a/arc/family/family_test.py
+++ b/arc/family/family_test.py
@@ -751,7 +751,7 @@
         rxn = ARCReaction(r_species=[ARCSpecies(label='R', smiles='C=CCC', multiplicity=1)],
                           p_species=[ARCSpecies(label='P', smiles='C1CCC1', multiplicity=1)])
         product_dicts = rxn.get_product_dicts(rmg_family_set=['Intra_RH_Add_Endocyclic'])
-        self.assertTrue(len(product_dicts) > 0)
+        self.assertGreater(len(product_dicts), 0)
         self.assertEqual(product_dicts[0]['family'], 'Intra_RH_Add_Endocyclic')
 
     def test_get_rmg_recommended_family_sets(self):
EOF
@@ -751,7 +751,7 @@
rxn = ARCReaction(r_species=[ARCSpecies(label='R', smiles='C=CCC', multiplicity=1)],
p_species=[ARCSpecies(label='P', smiles='C1CCC1', multiplicity=1)])
product_dicts = rxn.get_product_dicts(rmg_family_set=['Intra_RH_Add_Endocyclic'])
self.assertTrue(len(product_dicts) > 0)
self.assertGreater(len(product_dicts), 0)
self.assertEqual(product_dicts[0]['family'], 'Intra_RH_Add_Endocyclic')

def test_get_rmg_recommended_family_sets(self):
Copilot is powered by AI and may make mistakes. Always verify output.
calvinp0 added 4 commits July 7, 2026 04:25
…library

Fix C: get_reactants_xyz/get_products_xyz now expand each species by get_species_count
so a repeated participant (e.g. OH + OH) contributes all its atoms and the combined
geometry matches the atom map, instead of failing with an atom-count mismatch.

Fix A: skip isomorphic, same-multiplicity duplicates when building the thermo library
so identical reactants don't abort it with an Arkane DatabaseError.
…t invalid

A submerged/negative barrier (e.g. barrierless radical-radical reactions like OH+OH)
raises a ValueError in Arkane's Eckart method and aborted the whole rate calculation.
tunneling is now a template parameter; on that specific failure ARC retries once with
tunneling disabled so a (tunneling-free) rate coefficient is still produced.
# Conflicts:
#	arc/statmech/arkane.py
Comment thread arc/statmech/arkane.py Fixed
calvinp0 added 4 commits July 7, 2026 04:56
1+2_Cycloaddition, Diels_alder_addition, Retroene, XY_elimination_hydroxyl, and
intra_halogen_migration only had linear (or kinbot+linear), which finds spurious
H-motion saddles that NMD correctly rejects. Adds the double-ended path finders so
the real heavy-atom TS can be located (same fix as XY_Addition).
# Conflicts:
#	arc/job/adapters/common.py
…t run_arkane's bool

run_arkane can wrongly return success when Arkane crashes on an invalid (submerged)
barrier: it writes a partial output.py and the error is missed in captured stderr
(async tee). So the previous 'if not success' guard never fired (reaction 05 stayed
NO_RATE). Now the retry keys off the actual outcome — no kinetics produced AND the
invalid-barrier signature present — and re-runs without tunneling. Detector reads both
stderr.log and stdout.log for robustness. Validated: a no-tunneling Arkane run produces
a rate for 05's -20.8 kJ/mol barrier.
Comment thread arc/statmech/arkane.py
for name in ('stderr.log', 'stdout.log'):
path = os.path.join(statmech_dir, name)
if os.path.isfile(path):
content += open(path, encoding='utf-8', errors='ignore').read()

Check warning

Code scanning / CodeQL

File is not always closed Warning

File is opened but is not closed.

Copilot Autofix

AI about 2 hours ago

Use a context manager when reading each log file in arkane_failed_on_invalid_barrier so each descriptor is always closed, even if reading fails.

Best fix (no behavior change): in arc/statmech/arkane.py, replace the inline open(...).read() at line 614 with:

  • with open(path, encoding='utf-8', errors='ignore') as f:
  • content += f.read()

This preserves existing logic and encoding/error handling while guaranteeing closure on all paths. No new imports or helper methods are needed.

Suggested changeset 1
arc/statmech/arkane.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/arc/statmech/arkane.py b/arc/statmech/arkane.py
--- a/arc/statmech/arkane.py
+++ b/arc/statmech/arkane.py
@@ -611,7 +611,8 @@
     for name in ('stderr.log', 'stdout.log'):
         path = os.path.join(statmech_dir, name)
         if os.path.isfile(path):
-            content += open(path, encoding='utf-8', errors='ignore').read()
+            with open(path, encoding='utf-8', errors='ignore') as f:
+                content += f.read()
     return 'Eckart method are invalid' in content \
         or ('barrier heights' in content and 'Eckart' in content)
 
EOF
@@ -611,7 +611,8 @@
for name in ('stderr.log', 'stdout.log'):
path = os.path.join(statmech_dir, name)
if os.path.isfile(path):
content += open(path, encoding='utf-8', errors='ignore').read()
with open(path, encoding='utf-8', errors='ignore') as f:
content += f.read()
return 'Eckart method are invalid' in content \
or ('barrier heights' in content and 'Eckart' in content)

Copilot is powered by AI and may make mistakes. Always verify output.
calvinp0 added 4 commits July 7, 2026 13:32
Continuation of the A+A dedup fix: remove_dup_species dedups rxn.reactants to a single
label, so AutoTST building the reverse from rxn.products/reactants produced the imbalanced
'P1 + P2 <=> R1' instead of 'P1 + P2 <=> R1 + R1'. Re-expand the reverse labels by
get_species_count so the reverse reaction stays atom-balanced.
SMILES cannot encode a lone-pair singlet (e.g. singlet carbene [CH2], mult 1, C u0 p1):
Arkane re-perceives SMILES('[CH2]') as a u2 biradical, and u2+multiplicity=1 violates
Hund's rule when save_thermo_lib writes/reloads the adjacency list, crashing the whole
thermo step (reaction 01). When a species' SMILES doesn't round-trip to the same
multiplicity, emit the lossless adjacency list instead. Validated: RMG parses the u0 p1
carbene adjlist cleanly (the call that crashed).
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.

4 participants