Skip to content

Commit 43d7f6d

Browse files
authored
Merge pull request #179 from ReactionMechanismGenerator/pdep_qm
PDep→QM network selection and hybrid Arkane input generation (I-008)
2 parents 0f0737c + a2ad908 commit 43d7f6d

110 files changed

Lines changed: 53188 additions & 196 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.gitignore‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,3 +152,24 @@ htmlcov/*
152152

153153
# Local-only agent working files (never commit)
154154
docs/superpowers/
155+
docs/t3-pdep-qm-scope.md
156+
docs/t3-pdep-qm-impl-plan.md
157+
docs/t3-pdep-qm-next-session-prompt.md
158+
docs/t3-pdep-qm-explorer-design.md
159+
160+
# Vendored test fixtures are real Arkane output and must be tracked, despite the *.log rule
161+
# above which exists to keep run logs out of the repo.
162+
!tests/data/pdep_arkane_log/*.log
163+
# Narrowed to the exact file name, not just the depth: a `*/*.log` negation would also un-ignore
164+
# any other log that happened to land in a network's fixture directory (e.g. a stray debug.log
165+
# from a local run), which is the accidental-commit risk the *.log rule exists to prevent.
166+
!tests/data/pdep_real_networks/*/arkane.log
167+
168+
# Artifacts a test run writes into the tracked fixture trees. Some tests point a real T3 at a
169+
# fixture iteration directory, and T3 writes its per-iteration records where it always does. Named
170+
# exactly, and only under the two fixture directories that are actually written to, so this cannot
171+
# hide a record that was meant to be a fixture.
172+
tests/data/minimal_data/iteration_1/t3_pdep_qm_budget.yml
173+
tests/data/minimal_data/iteration_1/t3_pdep_network_assessments.yml
174+
tests/data/pdep_network/iteration_1/t3_pdep_qm_budget.yml
175+
tests/data/pdep_network/iteration_1/t3_pdep_network_assessments.yml

‎docs/input_reference.md‎

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,22 @@ t3:
8484
pdep_SA_threshold: 0.001 # optional, used to determine wells and reactions to calculate thermo
8585
# and rates for from a PES of a sensitive reaction, default: 0.001
8686
# Pass None to skip PES SA.
87+
pdep_min_delta_ln_k: 0.001 # optional, the smallest ln(k) response to a PES SA perturbation that
88+
# still counts as "sensitive", default: 0.001. Acts as an absolute
89+
# floor alongside the relative pdep_SA_threshold, so that denormal
90+
# near-zero sensitivity coefficients cannot pass on relative grounds.
91+
pdep_QM_max_transition_states: 10 # optional, per-iteration budget of uncertain transition
92+
# states admitted to QM across all selected PDep networks
93+
# (networks are admitted most-deserving-first, and a network
94+
# is admitted whole or not at all), default: None (unlimited).
95+
# Must be a positive integer when given; booleans are refused.
96+
pdep_QM_max_networks: 3 # optional, per-iteration cap on the number of PDep networks admitted
97+
# to QM, default: None (unlimited). Must be a positive integer when
98+
# given; booleans are refused.
8799
ME_methods: ['CSE', 'MSC'] # master equation methods for PES SA,
88-
# any combination of 'CSE', 'RS', 'MSC', default: ['CSE', 'MSC']
100+
# any combination of 'CSE', 'RS', 'MSC', default: ['CSE', 'MSC'].
101+
# Case-insensitive; entries are normalized to upper case, which is
102+
# the spelling used for the per-method output sub-directory.
89103
top_SA_species: 10 # optional, used per observable to determine thermo to calculate, default: 10
90104
top_SA_reactions: 10 # optional, used per observable to determine rates to calculate as well as
91105
# thermo of species participating in these reactions, default: 10

‎t3/common.py‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,17 @@
2222
PROJECTS_BASE_PATH = os.path.join(t3_path, 'Projects')
2323
VALID_CHARS = "-_=.,%s%s" % (string.ascii_letters, string.digits)
2424

25+
# The master-equation methods T3 knows how to ask Arkane for, mapping the shorthand a user writes
26+
# in ``T3.sensitivity.ME_methods`` to Arkane's own name for it. It lives here rather than beside
27+
# its main consumer in ``t3.utils.writer`` because ``t3.schema`` validates against it, and schema
28+
# validation must not drag in the writer's dependency stack (Mako, ARC species perception, the
29+
# thermo reader). ``t3.utils.writer`` re-exports it, so the many existing
30+
# ``from t3.utils.writer import METHOD_MAP`` call sites keep working.
31+
METHOD_MAP = {'CSE': 'chemically-significant eigenvalues',
32+
'RS': 'reservoir state',
33+
'MSC': 'modified strong collision',
34+
}
35+
2536

2637
def get_species_by_label(label: str,
2738
species_list: list[ARCSpecies],

‎t3/logger.py‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,34 @@ def log_species_summary(self,
213213
self.log(f'{key}: {species.qm_label}{smiles} '
214214
f'(status: {clean_t3_status(species)})')
215215

216+
def log_pdep_network_summary(self,
217+
selections: list,
218+
):
219+
"""
220+
Log a summary of the PDep network QM-selection decisions.
221+
222+
Args:
223+
selections (list): The ``PDepNetworkSelection`` decisions to summarize.
224+
"""
225+
self.log('\n\n\nPDep Network Summary:\n'
226+
'---------------------')
227+
qualifying = [selection for selection in selections if selection.qualified]
228+
if not qualifying:
229+
self.log('No PDep networks qualified for QM refinement.')
230+
return
231+
for selection in qualifying:
232+
strongest = max(selection.uncertain_path_reactions,
233+
key=lambda ts: ts.delta_ln_k,
234+
default=None)
235+
evidence = ''
236+
if strongest is not None:
237+
comment = strongest.kinetics_comment.splitlines()[0] if strongest.kinetics_comment else ''
238+
via = f' via {strongest.path_reaction_str}' if strongest.path_reaction_str else ''
239+
kinetics = f', kinetics: {comment}' if comment else ''
240+
evidence = (f' (strongest evidence: TS {strongest.ts_label}{via}, '
241+
f'delta_ln_k={strongest.delta_ln_k:.3g} at {strongest.condition}{kinetics})')
242+
self.log(f'{selection.network_id}: {selection.reason()}{evidence}')
243+
216244
def log_reactions_summary(self,
217245
reactions_dict: dict[int, T3Reaction],
218246
):

0 commit comments

Comments
 (0)