Fix switch_ts to reset state & clean up IRC when switching TS guesses#866
Fix switch_ts to reset state & clean up IRC when switching TS guesses#866
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes Scheduler.switch_ts() to properly reset state when a TS guess is invalidated, preventing stale jobs/flags from affecting the next TS guess.
Changes:
- Clean up IRC species spawned from the invalidated TS guess (remove jobs, output, species entries, labels).
- Reset per-label
output[label]['job_types']flags andconvergenceso the next guess re-runs the pipeline. - Discard pending pipe-batch entries for the invalidated TS label/directions.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
arc/scheduler.py |
Adds TS-switch cleanup for IRC species, resets job state, and clears pending pipe batches. |
arc/scheduler_test.py |
Adds a unit test intended to validate the cleanup/reset behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
arc/scheduler_test.py
Outdated
| sched = self.sched1 | ||
| ts_label = 'methylamine' | ||
| sched.output = dict() | ||
| sched.initialize_output_dict() | ||
|
|
||
| # Simulate state after a TS guess completes: freq/sp/opt marked done. | ||
| sched.output[ts_label]['job_types']['opt'] = True | ||
| sched.output[ts_label]['job_types']['freq'] = True | ||
| sched.output[ts_label]['job_types']['sp'] = True | ||
| sched.output[ts_label]['convergence'] = True | ||
|
|
||
| # Simulate IRC species spawned from the TS guess. | ||
| irc_label_1 = 'IRC_methylamine_1' | ||
| irc_label_2 = 'IRC_methylamine_2' | ||
| irc_spc_1 = ARCSpecies(label=irc_label_1, smiles='CN', compute_thermo=False) | ||
| irc_spc_2 = ARCSpecies(label=irc_label_2, smiles='CN', compute_thermo=False) | ||
| sched.species_dict[ts_label].irc_label = f'{irc_label_1} {irc_label_2}' | ||
| sched.species_dict[irc_label_1] = irc_spc_1 |
There was a problem hiding this comment.
switch_ts() is TS-specific (it calls determine_most_likely_ts_conformer(), expects TS paths under output/rxns/..., and repopulates TS checks). This test uses ts_label = 'methylamine', which is initialized as a non-TS species in setUpClass, so the test setup doesn’t represent a real switch_ts scenario and can’t safely be converted to a true integration-style switch_ts() test without introducing a proper TS species fixture.
a6cc203 to
a160ef7
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
arc/scheduler_test.py
Outdated
| sched = Scheduler(project='test_switch_ts', ess_settings=self.ess_settings, | ||
| species_list=[ts_spc], | ||
| opt_level=Level(repr=default_levels_of_theory['opt']), | ||
| freq_level=Level(repr=default_levels_of_theory['freq']), | ||
| sp_level=Level(repr=default_levels_of_theory['sp']), | ||
| ts_guess_level=Level(repr=default_levels_of_theory['ts_guesses']), | ||
| project_directory=os.path.join(ARC_PATH, 'Projects', | ||
| 'arc_project_for_testing_delete_after_usage4'), |
There was a problem hiding this comment.
The test deletes the temporary project directory only at the very end. If an assertion fails earlier, the directory can be left behind and pollute subsequent test runs. Consider registering the cleanup via addCleanup()/try-finally (or using tempfile.TemporaryDirectory) so the directory is removed even on failure.
| sched = Scheduler(project='test_switch_ts', ess_settings=self.ess_settings, | |
| species_list=[ts_spc], | |
| opt_level=Level(repr=default_levels_of_theory['opt']), | |
| freq_level=Level(repr=default_levels_of_theory['freq']), | |
| sp_level=Level(repr=default_levels_of_theory['sp']), | |
| ts_guess_level=Level(repr=default_levels_of_theory['ts_guesses']), | |
| project_directory=os.path.join(ARC_PATH, 'Projects', | |
| 'arc_project_for_testing_delete_after_usage4'), | |
| project_directory = os.path.join(ARC_PATH, 'Projects', | |
| 'arc_project_for_testing_delete_after_usage4') | |
| self.addCleanup(shutil.rmtree, project_directory, ignore_errors=True) | |
| sched = Scheduler(project='test_switch_ts', ess_settings=self.ess_settings, | |
| species_list=[ts_spc], | |
| opt_level=Level(repr=default_levels_of_theory['opt']), | |
| freq_level=Level(repr=default_levels_of_theory['freq']), | |
| sp_level=Level(repr=default_levels_of_theory['sp']), | |
| ts_guess_level=Level(repr=default_levels_of_theory['ts_guesses']), | |
| project_directory=project_directory, |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #866 +/- ##
==========================================
+ Coverage 60.09% 60.29% +0.19%
==========================================
Files 102 102
Lines 31045 31075 +30
Branches 8087 8098 +11
==========================================
+ Hits 18658 18736 +78
+ Misses 10071 9999 -72
- Partials 2316 2340 +24
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
a160ef7 to
d66ba64
Compare
alongd
left a comment
There was a problem hiding this comment.
Looks good, but I think the addition should be inside delete_all_species_jobs()
d66ba64 to
ccbfb89
Compare
ccbfb89 to
a267fe7
Compare
|
When a TS guess fails validation (e.g., NMD check), switch_ts picks the next guess but previously left stale state behind:
1. IRC species from the invalidated guess were never cleaned up. delete_all_species_jobs('TS0') only deletes jobs under the TS0 label, but IRC species like IRC_TS0_1 are separate entries in running_jobs/species_dict/etc. These orphaned species
continued running in parallel with the new guess, potentially interfering with job processing.
2. job_types flags (freq, sp, opt) were never reset. After guess N's freq completed, job_types['freq'] = True carried over to guess N+1, causing the scheduler to skip re-running freq for the new geometry.
3. convergence was never reset to None.
4. The old line self.output[label]['geo'] = ... wrote to the wrong dict level (top-level keys instead of self.output[label]['paths']), making it dead code.
5. Pending pipe batches from the old guess were never discarded.
a267fe7 to
042494c
Compare
When a TS guess fails validation (e.g., NMD check), switch_ts picks the next guess but previously left stale state behind:
continued running in parallel with the new guess, potentially interfering with job processing.