Skip to content

Commit 6ca7a10

Browse files
authored
Merge pull request #167 from ReactionMechanismGenerator/readme3
Various repo-wide fixes
2 parents 069d4d2 + 435b633 commit 6ca7a10

21 files changed

Lines changed: 121 additions & 61 deletions

.github/workflows/ci.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,18 @@ name: T3 CI
22

33
on:
44
workflow_dispatch:
5+
push:
6+
branches: [main]
57
pull_request:
68
branches: [main]
79
types: [opened, synchronize, reopened]
810
schedule:
911
- cron: '0 0 * * *'
1012

13+
concurrency:
14+
group: ${{ github.workflow }}-${{ github.ref }}
15+
cancel-in-progress: true
16+
1117
jobs:
1218
lint:
1319
name: Lint (ruff)

.vscode/launch.json

Lines changed: 0 additions & 17 deletions
This file was deleted.

.vscode/settings.json

Lines changed: 0 additions & 7 deletions
This file was deleted.

CODE_OF_CONDUCT.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# The RMG-ARC Tandem Tool (T3) Code of Conduct
1+
# T3 Code of Conduct
22

33
## Our Pledge
44

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ test:
1010
pytest tests/ --cov -ra -vv
1111

1212
test-main:
13-
pytest tests/test_main.py -ra -vv
13+
pytest tests/test_main.py --cov -ra -vv
1414

1515
test-functional:
16-
pytest tests/test_functional.py -ra -vv
16+
pytest tests/test_functional.py --cov -ra -vv

README.md

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
<p align="center">
2-
<a href="https://reactionmechanismgenerator.github.io/T3/"><img src="https://github.com/ReactionMechanismGenerator/T3/blob/main/grf/T3_logo_small.gif" alt="T3"></a>
3-
</p>
4-
5-
# The Tandem Tool (T3) for automated chemical kinetic model development
61

72
[![CI](https://github.com/ReactionMechanismGenerator/T3/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/ReactionMechanismGenerator/T3/actions/workflows/ci.yml)
83
[![Docs](https://github.com/ReactionMechanismGenerator/T3/actions/workflows/gh-pages.yml/badge.svg)](https://reactionmechanismgenerator.github.io/T3/)
@@ -11,6 +6,8 @@
116
[![MIT license](http://img.shields.io/badge/license-MIT-brightgreen.svg)](http://opensource.org/licenses/MIT)
127
![python](https://img.shields.io/badge/Python-3.12+-blue.svg)
138

9+
# The Tandem Tool (T3) for automated chemical kinetic model development
10+
1411
**T3** automates the development of detailed chemical kinetic models.
1512
Given a set of initial species and conditions, it produces a validated model with
1613
high-fidelity thermochemistry and rate parameters by iteratively combining

pyproject.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ ignore = [
3838
"W291", # trailing whitespace
3939
]
4040

41+
[tool.pytest.ini_options]
42+
filterwarnings = [
43+
"ignore::DeprecationWarning",
44+
"ignore::PendingDeprecationWarning",
45+
]
46+
4147
[tool.ruff.lint.per-file-ignores]
4248
"__init__.py" = ["F401"] # unused imports in __init__.py are re-exports
4349
"t3/runners/rmg_incore_sa.py" = ["E701"] # subprocess script, compact one-liners are fine

pytest.ini

Lines changed: 0 additions & 4 deletions
This file was deleted.

t3/main.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,7 @@ def run_rmg(self, restart_rmg: bool = False):
582582
t3_project_name=self.project,
583583
rmg_execution_type=self.rmg['rmg_execution_type'],
584584
restart_rmg=restart_rmg,
585+
walltime=self.t3['options']['max_RMG_walltime'],
585586
)
586587
if rmg_exception_encountered:
587588
self.rmg_exceptions_counter += 1
@@ -1151,13 +1152,13 @@ def get_reaction_key(self,
11511152
try:
11521153
if label == t3_reaction.get_reaction_smiles_label():
11531154
return key
1154-
except Exception:
1155+
except (AttributeError, ValueError):
11551156
pass
11561157
elif label_type == 'Chemkin':
11571158
try:
11581159
if label == t3_reaction.to_chemkin():
11591160
return key
1160-
except Exception:
1161+
except (AttributeError, ValueError):
11611162
pass
11621163
return None
11631164

t3/runners/rmg_runner.py

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44
"""
55

66
import datetime
7+
import logging
78
import os
89
import shlex
910
import shutil
11+
import subprocess
1012
import time
1113
from typing import TYPE_CHECKING, List, Optional, Tuple
1214

@@ -161,9 +163,27 @@ def rmg_job_converged(project_directory: str) -> Tuple[bool, Optional[str]]:
161163
return rmg_converged, error
162164

163165

166+
_DEFAULT_RMG_TIMEOUT_S = 6 * 3600 # 6 hours
167+
168+
logger = logging.getLogger(__name__)
169+
170+
171+
def _parse_walltime_to_seconds(walltime: str) -> int:
172+
"""Parse a 'DD:HH:MM:SS' walltime string to total seconds. Returns 0 for '00:00:00:00'."""
173+
parts = walltime.split(':')
174+
if len(parts) != 4:
175+
return 0
176+
try:
177+
days, hours, minutes, seconds = (int(p) for p in parts)
178+
except ValueError:
179+
return 0
180+
return days * 86400 + hours * 3600 + minutes * 60 + seconds
181+
182+
164183
def run_rmg_incore(rmg_input_file_path: str,
165184
verbose: Optional[int] = None,
166185
max_iterations: Optional[int] = None,
186+
walltime: Optional[str] = None,
167187
) -> bool:
168188
"""
169189
Run RMG incore under the rmg_env.
@@ -172,10 +192,14 @@ def run_rmg_incore(rmg_input_file_path: str,
172192
rmg_input_file_path (str): The path to the RMG input file.
173193
max_iterations (int, optional): Max RMG iterations.
174194
verbose (int, optional): Level of verbosity.
195+
walltime (str, optional): Max walltime in 'DD:HH:MM:SS' format. Defaults to 6 hours.
175196
176197
Returns:
177198
bool: Whether an exception was raised.
178199
"""
200+
timeout_s = _parse_walltime_to_seconds(walltime) if walltime else 0
201+
if timeout_s <= 0:
202+
timeout_s = _DEFAULT_RMG_TIMEOUT_S
179203
project_directory = os.path.abspath(os.path.dirname(rmg_input_file_path))
180204
verbose = f' -v {verbose}' if verbose is not None else ''
181205
max_iterations = f' -m {max_iterations}' if max_iterations is not None else ''
@@ -192,8 +216,16 @@ def run_rmg_incore(rmg_input_file_path: str,
192216
echo "Micromamba/Mamba/Conda required" >&2
193217
exit 1
194218
fi' '''
195-
stdout, stderr = execute_command(shell_script, shell=True, no_fail=True, executable='/bin/bash')
196-
stderr_text = ''.join(stderr) if isinstance(stderr, list) else (stderr or '')
219+
try:
220+
result = subprocess.run(shell_script, shell=True, executable='/bin/bash',
221+
capture_output=True, text=True, timeout=timeout_s)
222+
stderr_text = result.stderr or ''
223+
except subprocess.TimeoutExpired:
224+
logger.error(f'RMG incore timed out after {timeout_s}s')
225+
return True
226+
if result.returncode != 0:
227+
logger.error(f'RMG incore exited with code {result.returncode}')
228+
return True
197229
if 'RMG threw an exception and did not converge.' in stderr_text:
198230
return True
199231
return False
@@ -271,6 +303,7 @@ def rmg_runner(rmg_input_file_path: str,
271303
t3_project_name: Optional[str] = None,
272304
rmg_execution_type: Optional[str] = None,
273305
restart_rmg: bool = False,
306+
walltime: Optional[str] = None,
274307
) -> bool:
275308
"""
276309
Run an RMG job as a subprocess under the rmg_env.
@@ -286,6 +319,7 @@ def rmg_runner(rmg_input_file_path: str,
286319
t3_project_name (str, optional): The T3 project name, used for setting a job name on the server for the RMG run.
287320
rmg_execution_type (str, optional): The RMG execution type (incore or local). Also set via settings.py.
288321
restart_rmg (bool, optional): Whether to restart RMG from seed.
322+
walltime (str, optional): Max walltime in 'DD:HH:MM:SS' format. Defaults to 6 hours.
289323
290324
Returns:
291325
bool: Whether an exception was raised.
@@ -299,6 +333,7 @@ def rmg_runner(rmg_input_file_path: str,
299333
rmg_exception_encountered = run_rmg_incore(rmg_input_file_path=rmg_input_file_path,
300334
verbose=verbose,
301335
max_iterations=max_iterations,
336+
walltime=walltime,
302337
)
303338
return rmg_exception_encountered
304339
elif rmg_execution_type == 'local':

0 commit comments

Comments
 (0)