arc.scheduler

A module for scheduling ARC jobs Includes spawning, terminating, checking, and troubleshooting various jobs

arc.scheduler.SYMMETRY_BREAKING_ADAPTERS = {'gaussian', 'orca'}

The two sets above are statements about ARC’S ADAPTERS and not about what the ESSs can do.

STABILITY_ANALYSIS_ADAPTERS holds the adapters that compose a wavefunction stability analysis input and whose parser reads the verdict back. Whether an ESS absent from it offers the analysis at all is a separate question and is not what the set answers.

SYMMETRY_BREAKING_ADAPTERS holds the adapters that compose a reference an unrestricted SCF cannot collapse out of, which is an orbital guess taken from a broken-symmetry solution or a symmetry-breaking directive. An adapter absent from it composes one spin-symmetric determinant however its ESS is asked, so an unrestricted SCF it writes converges back to the restricted solution. Molpro is the case worth naming: Molpro itself has a {uhf} program and takes a ROTATE directive that mixes two starting orbitals, which is how a broken-symmetry singlet is requested of it, but ARC’s Molpro adapter writes {hf} in every input it composes and spends the unrestricted decision on the u prefix of the correlation method instead. Naming the orbitals a ROTATE would mix needs their index and irreducible representation, which that adapter has neither at the point it writes its input nor a nosym geometry to make unambiguous.

class arc.scheduler.Scheduler(project, ess_settings, species_list, project_directory, composite_method=None, conformer_opt_level=None, conformer_sp_level=None, opt_level=None, freq_level=None, sp_level=None, scan_level=None, ts_guess_level=None, irc_level=None, orbitals_level=None, adaptive_levels=None, job_types=None, rxn_list=None, bath_gas=None, restart_dict=None, max_job_time=None, allow_nonisomorphic_2d=False, memory=None, testing=False, dont_gen_confs=None, n_confs=10, e_confs=5, fine_only=False, trsh_ess_jobs=True, trsh_rotors=True, rotor_scan_resolution=None, kinetics_adapter='arkane', freq_scale_factor=1.0, ts_adapters=None, report_e_elect=False, skip_nmd=False, output=None)[source]

ARC’s Scheduler class. Creates jobs, submits, checks status, troubleshoots. Each species in species_list has to have a unique label.

Dictionary structures:

job_dict = {label_1: {'conf_opt':   {0: Job1,
                                     1: Job2, ...},
                      'conf_sp':    {0: Job1,
                                     1: Job2, ...},
                      'tsg':        {0: Job1,
                                     1: Job2, ...},  # TS guesses
                      'opt':        {job_name1: Job1,
                                     job_name2: Job2, ...},
                      'sp':         {job_name1: Job1,
                                     job_name2: Job2, ...},
                      'freq':       {job_name1: Job1,
                                     job_name2: Job2, ...},
                      'composite':  {job_name1: Job1,
                                     job_name2: Job2, ...},
                      'scan':       {job_name1: Job1,
                                     job_name2: Job2, ...},
                      <job_type>:   {job_name1: Job1,
                                     job_name2: Job2, ...},
                      ...
                      }
            label_2: {...},
            }

output = {label_1: {'job_types': {job_type1: <status1>,  # boolean
                                  job_type2: <status2>,
                                 },
                    'paths': {'geo': <path to geometry optimization output file>,
                              'freq': <path to freq output file>,
                              'sp': <path to sp output file>,
                              'composite': <path to composite output file>,
                              'irc': [list of two IRC paths],
                              'stability': <path to wavefunction stability analysis output file>,
                             },
                    'conformers': <comments>,
                    'isomorphism': <comments>,
                    'convergence': <status>,  # bool | None
                    'restart': <comments>,
                    'info': <comments>,
                    'warnings': <comments>,
                    'errors': <comments>,
                   },
         label_2: {...},
         }

Note

The rotor scan dicts are located under Species.rotors_dict

Parameters:
  • project (str) – The project’s name. Used for naming the working directory.

  • ess_settings (dict) – A dictionary of available ESS and a corresponding server list.

  • species_list (list) – Contains input ARCSpecies objects (both wells and TSs).

  • rxn_list (list) – Contains input ARCReaction objects.

  • project_directory (str) – Folder path for the project: the input file path or ARC/Projects/project-name.

  • composite_method (str, optional) – A composite method to use.

  • conformer_opt_level (str | dict, optional) – The level of theory to use for conformer comparisons.

  • conformer_sp_level (str | dict, optional) – The level of theory to use for conformer sp jobs.

  • opt_level (str | dict, optional) – The level of theory to use for geometry optimizations.

  • freq_level (str | dict, optional) – The level of theory to use for frequency calculations.

  • sp_level (str | dict, optional) – The level of theory to use for single point energy calculations.

  • scan_level (str | dict, optional) – The level of theory to use for torsion scans.

  • ts_guess_level (str | dict, optional) – The level of theory to use for TS guess comparisons.

  • irc_level (str | dict, optional) – The level of theory to use for IRC calculations.

  • orbitals_level (str | dict, optional) – The level of theory to use for calculating MOs (for plotting).

  • adaptive_levels (dict, optional) – A dictionary of levels of theory for ranges of the number of heavy atoms in the species. Keys are tuples of (min_num_atoms, max_num_atoms), values are dictionaries with job type tuples as keys and levels of theory as values. ‘inf’ is accepted in max_num_atoms

  • job_types (dict, optional) – A dictionary of job types to execute. Keys are job types, values are boolean.

  • bath_gas (str, optional) – A bath gas. Currently used in OneDMin to calc L-J parameters. Allowed values are He, Ne, Ar, Kr, H2, N2, O2.

  • restart_dict (dict, optional) – A restart dictionary parsed from a YAML restart file.

  • max_job_time (float, optional) – The maximal allowed job time on the server in hours (can be fractional).

  • allow_nonisomorphic_2d (bool, optional) – Whether to optimize species even if they do not have a 3D conformer that is isomorphic to the 2D graph representation.

  • memory (float, optional) – The total allocated job memory in GB (14 by default).

  • testing (bool, optional) – Used for internal ARC testing (generating the object w/o executing it).

  • dont_gen_confs (list, optional) – A list of species labels for which conformer jobs were loaded from a restart file, or user-requested. Additional conformer generation should be avoided.

  • n_confs (int, optional) – The number of lowest force field conformers to consider.

  • e_confs (float, optional) – The energy threshold in kJ/mol above the lowest energy conformer below which force field conformers are considered.

  • fine_only (bool) – If True ARC will not run optimization jobs without fine=True.

  • kinetics_adapter (str, optional) – The statmech software to use for kinetic rate coefficient calculations.

  • freq_scale_factor (float, optional) – The harmonic frequencies scaling factor.

  • trsh_ess_jobs (bool, optional) – Whether to attempt troubleshooting failed ESS jobs. Default is True.

  • trsh_rotors (bool, optional) – Whether to attempt troubleshooting failed rotor scan jobs. Default is True.

  • ts_adapters (list, optional) – Entries represent different TS adapters.

  • report_e_elect (bool, optional) – Whether to report electronic energy. Default is False.

  • skip_nmd (bool, optional) – Whether to skip normal mode displacement check. Default is False.

  • output (dict, optional) – Output dictionary with status per job type and final QM file paths for all species.

project

The project’s name. Used for naming the working directory.

Type:

str

servers

A list of servers used for the present project.

Type:

list

remote_project_paths

Keys are servers used for the present project, values are the respective remote paths of the project’s directory on that server.

Type:

dict

species_list

Contains input ARCSpecies objects (both species and TSs).

Type:

list

species_dict

Keys are labels, values are ARCSpecies objects.

Type:

dict

rxn_list

Contains input ARCReaction objects.

Type:

list

unique_species_labels

A list of species labels (checked for duplicates).

Type:

list

stability_unimplemented_ess

ESS names already reported as having no wavefunction stability analysis implemented in ARC, reported once per ESS per run.

Type:

set

unbreakable_reference_ess

Names of adapters already reported as writing no symmetry-broken reference, so that an adopted unrestricted reference collapses in the jobs they compose. Reported once per adapter per run.

Type:

set

job_dict

A dictionary of all scheduled jobs. Keys are species / TS labels, values are dictionaries where keys are job names (corresponding to ‘running_jobs’ if job is running) and values are the Job objects.

Type:

dict

running_jobs

A dictionary of currently running jobs (a subset of job_dict). Keys are species/TS label, values are lists of job names (e.g. ‘conformer3’, ‘opt_a123’).

Type:

dict

server_job_ids

A list of relevant job IDs currently running on the server.

Type:

list

output

Output dictionary with status per job type and final QM file paths for all species.

Type:

dict

output_multi_spc

Output dictionary with status per job type of multi-species clusters.

Type:

dict

ess_settings

A dictionary of available ESS and a corresponding server list.

Type:

dict

restart_dict

A restart dictionary parsed from a YAML restart file.

Type:

dict

project_directory

Folder path for the project: the input file path or ARC/Projects/project-name.

Type:

str

save_restart

Whether to start saving a restart file. True only after all species are loaded (otherwise saves a partial file and may cause loss of information).

Type:

bool

restart_path

Path to the restart.yml file to be saved.

Type:

str

max_job_time

The maximal allowed job time on the server in hours (can be fractional).

Type:

float

testing

Used for internal ARC testing (generating the object w/o executing it).

Type:

bool

allow_nonisomorphic_2d

Whether to optimize species even if they do not have a 3D conformer that is isomorphic to the 2D graph representation.

Type:

bool

dont_gen_confs

A list of species labels for which conformer jobs were loaded from a restart file, or user-requested. Additional conformer generation should be avoided for them.

Type:

list

memory

The total allocated job memory in GB (14 by default).

Type:

float

n_confs

The number of lowest force field conformers to consider.

Type:

int

e_confs

The energy threshold in kJ/mol above the lowest energy conformer below which force field conformers are considered.

Type:

float

job_types

A dictionary of job types to execute. Keys are job types, values are boolean.

Type:

dict

bath_gas

A bath gas. Currently used in OneDMin to calc L-J parameters. Allowed values are He, Ne, Ar, Kr, H2, N2, O2.

Type:

str

composite_method

A composite method to use.

Type:

str

conformer_opt_level

The level of theory to use for conformer comparisons.

Type:

dict

conformer_sp_level

The level of theory to use for conformer sp jobs.

Type:

dict

opt_level

The level of theory to use for geometry optimizations.

Type:

dict

freq_level

The level of theory to use for frequency calculations.

Type:

dict

sp_level

The level of theory to use for single point energy calculations.

Type:

dict

scan_level

The level of theory to use for torsion scans.

Type:

dict

ts_guess_level

The level of theory to use for TS guess comparisons.

Type:

dict

irc_level

The level of theory to use for IRC calculations.

Type:

dict

orbitals_level

The level of theory to use for calculating MOs (for plotting).

Type:

dict

adaptive_levels

A dictionary of levels of theory for ranges of the number of heavy atoms in the species. Keys are tuples of (min_num_atoms, max_num_atoms), values are dictionaries with job type tuples as keys and levels of theory as values. ‘inf’ is accepted in max_num_atoms

Type:

dict

fine_only

If True ARC will not run optimization jobs without fine=True.

Type:

bool

kinetics_adapter

The statmech software to use for kinetic rate coefficient calculations.

Type:

str

freq_scale_factor

The harmonic frequencies scaling factor.

Type:

float

trsh_ess_jobs

Whether to attempt troubleshooting failed ESS jobs. Default is True.

Type:

bool

trsh_rotors

Whether to attempt troubleshooting failed rotor scan jobs. Default is True.

Type:

bool

ts_adapters

Entries represent different TS adapters.

Type:

list

report_e_elect

Whether to report electronic energy.

Type:

bool

skip_nmd

Whether to skip normal mode displacement check.

Type:

bool

add_label_to_unique_species_labels(label)[source]

Adds a label to self.unique_species_labels. Modifies the label if it is not unique.

Parameters:

label (str) – A species label.

Returns:

The modified species label

Return type:

str

adopt_stability_orbitals(label)[source]

Hand a species the orbitals its wavefunction stability analysis relaxed into, or none.

A verdict reporting followed_to_stable was measured by an ESS that rotated the unstable orbitals, re-converged the SCF and reached a stable solution, and wrote that solution to the analysis job’s own orbitals file. That file is the broken-symmetry reference, so it becomes the species’ checkfile and seeds the SCF of the job that follows. Any other verdict was measured without relaxing anything, so the file the species holds describes the reference the analysis rejected and is dropped rather than passed on.

Parameters:

label (str) – The species label.

carry_stability_verdict_across_ts_switch(label)[source]

Reduce a TS’s stability verdict to what still holds once its geometry is abandoned.

An adopted external instability is kept, and it is kept because carrying it is cheap rather than because it is known to transfer. Distinct saddles of one reaction do NOT always agree: the campaign behind this feature found one reaction whose three lowest-energy saddles are unstable while its only stable one is the highest, and another whose unstable saddles sit 61 kcal/mol above its stable ones. What makes carrying it safe is that forcing an unrestricted reference on a guess that is in fact stable costs nothing but SCF effort: a stable restricted solution IS the unrestricted minimum, so E(UKS) = E(RKS) exactly there. What it buys is that the next guess is unrestricted from its very first optimization, which is the reference the discovering guess reached only by being optimized a second time: a carried verdict spares the next guess that second optimization and the analysis that would have prompted it. Every other verdict is dropped rather than carried: a ‘stable’, ‘unknown’ or internal-instability verdict has no consumer, and leaving it would attribute a bill of health to a geometry that was never tested. A verdict ARC would not act on is dropped too, so a TS whose user declared a number_of_radicals carries nothing: the declaration decides its reference, and carrying a verdict that will never be adopted would promise the next guess a reference change that is not coming.

DROPPING A VERDICT CLEARS stability_analysis_ran with it, so the surviving guess is measured in its turn. The dropped verdict describes a wavefunction that is gone, and the next guess comes from a different search and is a different saddle: leaving the flag set would have ARC publish that guess’ restricted energy with no verdict of its own and nothing to say whether it was measured stable or never measured at all.

The geometry-specific detail is dropped in either case. The negative-eigenvector labels and eigenvalues, and whether the analytic frequencies are invalidated, all describe the abandoned wavefunction and its Hessian, and no measurement of them exists for the new guess: a CARRIED verdict keeps stability_analysis_ran set, so no second analysis runs for the guess it is carried to and the carried verdict is never contradicted by a later one. Its reference is already decided, and a fresh analysis of the unrestricted reference the next guess runs on measures a different question than the one that was adopted. The guess the carried verdict was measured on is recorded alongside it.

THE RELAXED CONSTRAINTS ARE CARRIED, unlike the rest of the detail, because they name the CLASS of the instability rather than its size at one geometry, and that class is what the reference decision reads: a relaxation of the spin constraint calls for a symmetry-broken determinant, which derived_instability_breaks_spin_symmetry reports and the ORCA adapter acts on, while a relaxation of the reality of the orbitals calls for a reference ARC does not write. Dropping them would leave the surviving guess carrying a verdict whose class is unknown, which is read as no evidence of broken-symmetry character at all.

The per-job SCF reference records are cleared outright, and so is any mixed-reference warning they raised: opt, freq and sp all re-run for the new guess, so the references of the abandoned guess’ jobs describe nothing and a warning about them would outlive its subject in the species’ permanent output entry. The invalid-Hessian and spin-contamination warnings go with them, for the same reason and about the same jobs. The optimization job whose post-opt work an analysis was holding is released too, since switch_ts abandons that job along with the geometry it converged to.

The unreachable-reference warning is cleared with them, and it is always cleared. It is raised only on a verdict stamped REFERENCE_CHANGE_AVAILABLE_KEY False, which adopted_reference_is_unrestricted reads as well, so such a verdict is never one this method carries over: it is dropped here along with the geometry it was measured on, and the warning would otherwise name a reference change the surviving guess was never offered. The next guess is measured in its turn and raises the warning again where its own verdict cannot be honoured.

THE TWO RECORDS ARE REDUCED TOGETHER. The verdict summary the run summary prints, and the sentence it added to the species’ info, describe the abandoned geometry down to the stability-matrix root, so they are cleared alongside the detail this drops from the species object. delete_all_species_jobs resets the stability path the same switch, so leaving them would have output.yml report no verdict for the surviving geometry while the run summary printed the abandoned guess’ root against it. The log the carried verdict was read from stays with it, so a carried decision still names the analysis that made it.

Parameters:

label (str) – The TS species label.

Returns:

None

check_all_done(label)[source]

Check that we have all required data for the species/TS.

Parameters:

label (str) – The species label.

check_directed_scan(label, pivots, scan, energies)[source]

Checks (QA) whether the directed scan is relatively “smooth”, and whether the optimized geometry indeed represents the minimum energy conformer. Recommends whether or not to use this rotor using the ‘successful_rotors’ and ‘unsuccessful_rotors’ attributes. This method differs from check_directed_scan_job(), since here we consider the entire scan.

Parameters:
  • label (str) – The species label.

  • pivots (list[list[int]]) – The rotor pivots.

  • scan (list[int]) – The four atoms defining the dihedral.

  • energies (list[float]) – The rotor scan energies in kJ/mol.

check_directed_scan_job(label, job)[source]

Check that a directed scan job for a specific dihedral angle converged successfully, otherwise troubleshoot.

Parameters:
  • label (str) – The species label.

  • job (JobAdapter) – The rotor scan job object.

check_freq_job(label, job)[source]

Check that a freq job converged successfully. Also checks (QA) that no imaginary frequencies were assigned for stable species, and that exactly one imaginary frequency was assigned for a TS.

The SCF reference this job declared is recorded only if its geometry survives the check. A TS whose normal mode displacement fails is switched to a different guess inside post_freq_actions, which clears the per-job reference records of the abandoned guess along with everything else that described it; recording afterwards would write one of them straight back, and the next guess’ sp job would then be compared against the reference of a geometry that is gone.

Parameters:
  • label (str) – The species label.

  • job (JobAdapter) – The frequency job object instance.

check_irc_species(label)[source]

Check that the optimized geometry of the two species created from a TS IRC runs makes sense. A TS for which the IRC check positively failed is rejected, and a different TS guess is sought.

Parameters:

label (str) – The label of one of the optimized IRC-resulting species.

check_max_simultaneous_jobs_limit(server)[source]

Check if the number of running jobs on the server is not above the set server limit.

Parameters:

server (str) – The server name.

check_negative_freq(label, job, vibfreqs)[source]

A helper function for determining the number of negative frequencies. Also logs appropriate errors.

Parameters:
  • label (str) – The species label.

  • job (JobAdapter) – The optimization job object.

  • vibfreqs (list | np.ndarray | None) – The vibrational frequencies, or None if they could not be parsed.

Returns:

Whether the number of negative frequencies is as expected,

and whether a different TS guess was selected as a result.

Return type:

tuple[bool, bool]

check_rxn_e0_by_spc(label)[source]

Check the E0 (electronic energy + ZPE) of reactions related to a specific species. Requires all opt + freq computations to be converged for all species (and TS) participating in each reaction.

Parameters:

label (str) – A label representing a species.

check_scan_job(label, job)[source]

Check that a rotor scan job converged successfully. Also checks (QA) whether the scan is relatively “smooth”, and whether the optimized geometry indeed represents the minimum energy conformer. Recommends whether to use this rotor using the ‘successful_rotors’ and ‘unsuccessful_rotors’ attributes.

Parameters:
  • label (str) – The species label.

  • job (JobAdapter) – The rotor scan job object.

check_scf_reference_consistency(label)[source]

Warn when a species’ electronic energy and its ZPE were computed on different SCF references.

Its E0 is then the sum of an energy and a zero-point correction taken from two different potential energy surfaces, so it is not a point on either of them. ARC does not re-run the species, so the mismatch is reported in the log, in the species’ output warnings and in output.yml, and nothing is invalidated.

AN ADOPTED STABILITY VERDICT REACHES THIS CHECK THROUGH ITS SINGLE POINT. The verdict decides the reference of the levels a broken-symmetry one describes, which level_admits_a_broken_symmetry_reference defines, so a species whose freq is a DFT one and whose sp is a correlated wavefunction one takes the broken-symmetry reference for its ZPE and keeps the spin-adapted one for its electronic energy. That is the mismatch this reports, and the alternative it is chosen over is a correlated energy expanded about a symmetry-broken reference, which is a worse number reported by a quieter run. A species whose freq and sp are both at levels the verdict decides, and one whose sp is at its own DFT level, run on one reference throughout and are not reported.

What reaches this check besides is a pair of jobs composed on either side of some other change to the species’ state: an sp resubmitted by troubleshooting, an sp deferred past its freq, or a species restored from a restart.

Parameters:

label (str) – The species label.

check_sp_job(label, job)[source]

Check that a single point job converged successfully.

Parameters:
  • label (str) – The species label.

  • job (JobAdapter) – The single point job object.

check_spin_contamination(label, sp_path)[source]

Warn when the wavefunction the electronic energy came from is spin-contaminated.

The <S**2> of an unrestricted determinant exceeds the spin-pure S(S+1) of the state it is meant to describe by the weight of the higher multiplicities mixed into it, so the deviation between the two IS the contamination. An energy carrying it is not the energy of the state ARC reports it for, and it reaches the thermo and the rates unchanged: nothing here re-runs the job, changes its reference or projects the contamination out. The species’ output warnings and the log are where it is reported.

MAX_S_SQUARED_DEVIATION is the largest deviation reported without a warning. It is an absolute deviation rather than a fraction of the spin-pure value because a singlet’s spin-pure value is zero, and the broken-symmetry singlet is exactly the case that most needs reporting, so a fraction is undefined where it matters most. Its size follows from what a deviation means: the nearest contaminant of a state of spin S is the state of spin S+1, whose S(S+1) lies 2S+2, at least 2, above it, so a deviation of 0.1 is at most a five percent admixture of that state. Below it an unrestricted energy and the Hessian taken at it are customarily used as the state’s own.

A restricted reference prints no <S**2>, and an ESS with no reader for it reports none either, so both are passed over rather than reported uncontaminated.

Parameters:
  • label (str) – The species label.

  • sp_path (str | None) – The path to the log the electronic energy was read from.

Returns:

None

check_stability_job(label, job)[source]

Parse and record the verdict of a wavefunction stability analysis job.

Stores a summary of the verdict under the species’ output entry, where the run summary reads it, stores the structured verdict together with the path of the log it was read from on the species object, where the reference decision reads it, and logs it. A job that left no log, and a log holding no stability analysis, record nothing. Nothing here is troubleshooted or re-run: a job that died with its analysis already printed is read for the verdict it printed, since the analysis precedes whatever killed it and its blocks are complete or absent rather than truncated into a different verdict.

A verdict calling for an unrestricted reference is stamped with whether the ESSs this species runs in can be given one, which stability_verdict_can_be_honoured decides and adopted_reference_is_unrestricted reads. A verdict that cannot be honoured is recorded, logged and reported in the species’ output warnings as UNREACHABLE_REFERENCE_MESSAGE, and decides nothing.

A verdict that invalidates the analytic frequencies also writes INVALID_ANALYTIC_FREQ_MESSAGE into the species’ output warnings, which is what carries it into output.yml and into the run summary. Nothing is re-run on it: the frequencies, the ZPE they give and the E0 built from them are reported as they were computed, with the warning attached.

A verdict already on the species, which can only be one carried over from an abandoned TS guess, is replaced by the one parsed here: a measurement on the live geometry supersedes one carried from a geometry that is gone.

An instability is logged as a warning and a stable wavefunction as an info message, and a verdict carrying a negative stability-matrix root also reports that root’s label and eigenvalue, which name the perturbation the wavefunction broke along and how far.

Whether an instability bears on the validity of the analytic frequencies depends on the reference. Gaussian’s rule, which both ESS readers apply so that the same physical situation gets the same answer whichever ESS measured it, is that for a restricted wavefunction it suffices that no singlet (internal) instability exists, while for an unrestricted one any instability, internal or external, invalidates them. Neither ESS computes a spin-flip root for an unrestricted reference, so both readers report an undetermined external_instability there and the external half of that rule is never reached: a stable verdict on an unrestricted reference covers the spin-conserving sector alone, which is the sector the analytic Hessian is taken in. So the frequency-validity warning is raised for an internal instability of either reference, and additionally for an external instability of an unrestricted one. An instability whose sector the ESS did not report leaves the question undetermined rather than answered either way, and is warned about as such. An external instability of a restricted reference is reported without that warning: a lower symmetry-broken solution exists, which for a TS with stretched partial bonds is expected, and the analytic Hessian remains a correct second derivative of the surface that was computed. That surface is not the ground state, though. Near an RHF -> UHF instability onset the restricted surface is spuriously stiff along the bond-stretching coordinate, which for a TS is the reaction coordinate, so the imaginary frequency and the barrier curvature are wrong in a known direction, too large and too high.

Adopting the verdict replaces one biased number with another rather than with the right one. A broken-symmetry solution is not a spin eigenfunction: it is contaminated by the higher multiplicity it mixes in, so its energy lies ABOVE the spin-pure low-spin energy, and the restricted energy it replaces lies above the broken-symmetry one in turn. The ordering is E_projected < E_BS < E_restricted, so adoption is a step toward the spin-pure energy that stops short of it, and the residual error keeps the sign and direction it had before. ARC does not project the contamination out. arc/checks/spin.py holds the Yamaguchi approximate spin-projection arithmetic that estimates the projected energy from the broken-symmetry and high-spin energies and their S**2 values.

A spin contamination larger than MAX_S_SQUARED_DEVIATION is warned about where the electronic energy is read, in check_spin_contamination, and not here: the analysis log this verdict comes from describes the wavefunction that was tested, or for an ESS that follows an instability the solution it relaxed into, and neither is the wavefunction the published energy belongs to.

Parameters:
  • label (str) – The species label.

  • job (JobAdapter) – The stability analysis job object instance.

Returns:

None

deduce_job_adapter(level, job_type)[source]

Deduce the job adapter (the software) to be used for jobs other than TS searches.

Parameters:
  • level (Level) – The level of theory that will be used for the job.

  • job_type (str) – The job’s type.

Returns: str

The deduced job adapter.

delete_all_species_jobs(label)[source]

Delete all jobs of a species/TS.

Parameters:

label (str) – The species label.

determine_adaptive_level(original_level_of_theory, job_type, heavy_atoms)[source]

Determine the level of theory to be used according to the job type and number of heavy atoms. self.adaptive_levels is a dictionary of levels of theory for ranges of the number of heavy atoms in the species. Keys are tuples of (min_num_atoms, max_num_atoms), values are dictionaries with job type tuples as keys and levels of theory as values. The string ‘inf’ is accepted instead of an integer in max_num_atoms.

Parameters:
  • original_level_of_theory (Level) – The level of theory for non-sp/opt/freq job types.

  • job_type (str) – The job type for which the level of theory is determined.

  • heavy_atoms (int) – The number of heavy atoms in the species.

determine_most_likely_ts_conformer(label)[source]

Determine the most likely TS conformer. Save the resulting xyz as the .initial_xyz attribute of the TS Species.

Parameters:

label (str) – The TS species label.

determine_most_stable_conformer(label, sp_flag=False)[source]

Determine the most stable conformer for a species (which is not a TS). Also run an isomorphism check. Save the resulting xyz as initial_xyz.

Parameters:
  • label (str) – The species label.

  • sp_flag (bool) – Whether this is a single point calculation job.

end_job(job, label, job_name)[source]

A helper function for checking job status, saving in csv file, and downloading output files if needed.

A completed geometry job hands the species its converged orbitals, which the jobs that follow read as an initial guess. The file is ESS-specific, a check.chk for Gaussian and an input.gbw for ORCA, and is adopted under the name the job adapter declares. A zero-byte file is refused: paramiko creates the local file before it opens the remote one, so a download that failed leaves an empty file behind that os.path.isfile cannot tell from a real one, and adopting it would hand every subsequent job an unreadable guess.

Parameters:
  • job (JobAdapter) – The job object.

  • label (str) – The species label.

  • job_name (str) – The job name from the running_jobs dict.

Returns:

True if job terminated successfully on the server, False otherwise.

Return type:

bool

flush_pending_pipe_batches()[source]

Attempt to submit accumulated deferred pipe batches for SP, freq, IRC, and conf_sp.

For each family:
  1. Snapshot and clear the pending set.

  2. Ask the planner for the handled subset.

  3. Fall back to per-job submission for the unhandled remainder.

Called once per main-loop iteration, after all newly-ready work has been discovered and before the loop sleeps.

generate_final_ts_guess_report()[source]

Generate a TS report for this ARC project and saves it as a YAML file.

get_chosen_tsg(label)[source]

Get the TSGuess object of a TS species that is currently being optimized.

The chosen_ts attribute of an ARCSpecies object stores a TSGuess.index, which is an identity assigned to a TS guess when it is appended to the species. It is not a position in a list, and in particular it is not the TSGuess.conformer_index attribute, which is the index of the conformer optimization job spawned for the guess (i.e., a position in the list of successful TS guesses). If chosen_ts is None, no selection was made among several guesses. That happens when only a single TS guess was successful and was sent directly to a geometry optimization, in which case that guess is returned, and after a restart file with ambiguous TS guess identities was repaired, in which case there may be several successful guesses and None is returned.

Parameters:

label (str) – The TS species label.

Returns:

The chosen TSGuess object, or None if it could not be determined.

Return type:

TSGuess | None

get_completed_incore_jobs()[source]

Check job status of all incore jobs, get a list of relevant completed job IDs.

Todo: Add tests.

get_server_job_ids(specific_server=None)[source]

Check job status on a specific server or on all active servers, get a list of relevant running job IDs.

Parameters:

specific_server (str, optional) – The server to check. If None, check all active servers.

has_pending_pipe_work(label)[source]

Whether a species still has work queued for, or running in, a pipe run.

A species whose jobs were routed to pipe mode holds no entries in running_jobs, so an empty entry does not mean that species is finished. It must be kept until its pipe work terminates: dropping it leaves check_all_done() unreachable for that species, because the main loop only reaches it through running_jobs. The species would then never be marked as converged even once every one of its piped jobs had succeeded.

Parameters:

label (str) – The species label.

Returns:

True if any pending batch or active pipe run still holds this species.

Return type:

bool

initialize_output_dict(label=None)[source]

Initialize self.output. Do not initialize keys that will contain paths (‘geo’, ‘freq’, ‘sp’, ‘composite’), their existence indicate the job was terminated for restarting purposes. If label is not None, will initialize for a specific species, otherwise will initialize for all species.

Parameters:

label (str, optional) – A species label.

log_open_shell_character_sources(label, verdict, restricted)[source]

Log how a species’ declared open-shell character and its measured stability verdict stand to each other.

A user-declared number_of_radicals always decides the reference and is never overwritten here, so a conflict with the measured verdict is reported and nothing else. When the user declared nothing and the verdict calls for an unrestricted reference, that verdict is what subsequent jobs for a transition state will run on, and that adoption is logged as such; for any other species, and for a transition state whose verdict no ESS of the run can be given a symmetry-broken reference for, the verdict is reported as measured but not acted on, together with what would let it be acted on. Every branch logs; none raises.

Parameters:
  • label (str) – The species label.

  • verdict (str) – The stability verdict that was parsed.

  • restricted (bool | None) – Whether the tested wavefunction used a restricted reference.

Returns:

None

make_reaction_labels_info_file()[source]

A helper function for creating the reactions labels.info file.

parse_composite_geo(label, job)[source]

Check that a ‘composite’ job converged successfully, and parse the geometry into final_xyz. Also checks (QA) that no imaginary frequencies were assigned for stable species, and that exactly one imaginary frequency was assigned for a TS. Returns True if the job converged successfully, False otherwise and troubleshoots.

Parameters:
  • label (str) – The species label.

  • job (JobAdapter) – The composite job object.

Returns:

Whether the job converged successfully.

Return type:

bool

parse_conformer(job, label, i)[source]

Parse E0 (kJ/mol) from the conformer opt output file. For species, save it in the Species.conformer_energies attribute. Fot TSs, save it in the TSGuess.energy attribute, and also parse the geometry.

Parameters:
  • job (JobAdapter) – The conformer job object.

  • label (str) – The TS species label.

  • i (int) – The conformer index.

Returns:

Whether the conformer job is being troubleshooted by running a new job.

Return type:

bool

parse_opt_e_elect(label, job)[source]

Parse electronic energy for ‘opt’ or ‘optfreq’ job if it converged successfully.

Parameters:
  • label (str) – The species label.

  • job (JobAdapter) – The optimization job object.

parse_opt_geo(label, job)[source]

Check that an ‘opt’ or ‘optfreq’ job converged successfully, and parse the geometry into final_xyz. If the job is ‘optfreq’, also checks (QA) that no imaginary frequencies were assigned for stable species, and that exactly one imaginary frequency was assigned for a TS. Returns True if the job (or both jobs) converged successfully, False otherwise and troubleshoots opt.

Parameters:
  • label (str) – The species label.

  • job (JobAdapter) – The optimization job object.

Returns:

Whether the job converged successfully.

Return type:

bool

post_freq_actions(label, job, vibfreqs)[source]

Run the imaginary frequency QA and, if it passes, perform every action a converged freq job is expected to leave behind.

Pipe mode computes a batch of freq tasks outside the Scheduler’s job machinery and hands the results back to be checked, so it is a second caller of this method. Both routes share it so that a species cannot be reported as converged while missing the artifacts its consumers read: species.freqs, which carries the frequencies into the restart and output files, and the freq.out copy under the species output folder, whose absence makes compute_rxn_e0() give up on the reaction E0 check. For a TS this is also where the normal mode displacement check runs, so skipping it would leave the TS permanently un-validated.

Troubleshooting a failed check is deliberately not done here: it resubmits jobs and therefore needs a real job object, which only a Scheduler-submitted job has.

Parameters:
  • label (str) – The species label.

  • job (JobAdapter) – The frequency job object instance.

  • vibfreqs (list | np.ndarray | None) – The vibrational frequencies, or None if they could not be parsed.

Returns:

Whether the frequencies passed the check,

and whether a different TS guess was selected as a result.

Return type:

tuple[bool, bool]

post_opt_geo_work(spc_label, job)[source]

Few steps to finish after running the opt job.

Parameters:
  • spc_label (str) – The species label.

  • job (JobAdapter) – The optimization job object.

post_sp_actions(label, sp_path, level=None, job=None)[source]

Perform post-sp actions.

job is the job whose log the electronic energy is read from, which is the sp job where one ran and the optimization job where the sp level equals the opt level and no sp job was submitted. Its SCF reference is recorded here, under ‘sp’, because it is the job that supplied the energy whichever of the two it is. A caller that has no job to name, a species restored from a restart among them, records nothing.

THE ONE CALLER THAT NAMES NO JOB is run_sp_job’s path for a project restarted with no opt job left in its job dictionary, which reaches the optimization log through output[label]['paths']['geo'] and has no job object to hand over. It is reached only where the sp level equals the opt level, where one job supplied both the geometry and the energy and the two therefore share one SCF reference by construction, so the reference comparison that record feeds has nothing to find. What it costs is that output.yml reports a null reference_mismatch for such a project rather than false.

Parameters:
  • label (str) – The species label.

  • sp_path (str) – The path to ‘output.out’ for the single point job.

  • level (Level, optional) – The level of theory used for the sp job.

  • job (JobAdapter, optional) – The job whose log the electronic energy is read from.

process_conformers(label)[source]

Process the generated conformers and spawn DFT jobs at the conformer_opt_level. If more than one conformer is available, they will be optimized at the DFT conformer_opt_level.

Parameters:

label (str) – The species label.

process_directed_scans(label, pivots)[source]

Process all directed rotors for a species and check the quality of the scan.

Parameters:
  • label (str) – The species label.

  • pivots (list[int] | list[list[int]]) – The rotor pivots.

process_irc_verdict(ts_label, rxn)[source]

Act on the verdict of the IRC check of a TS species.

The verdict is three-valued: True means the optimized IRC endpoints correspond to the requested wells, False means they positively do not, and None means the check was not performed or its result could not be determined (e.g., IRC jobs were not requested). Only a False verdict rejects the TS, in which case a different TS guess is sought. Once every guess was tried, the TS is marked unconverged and the verdict is restored.

Parameters:
  • ts_label (str) – The label of the TS species the IRC check was performed for.

  • rxn (ARCReaction, optional) – The reaction the TS species belongs to.

record_scf_reference(label, job, reference_key=None)[source]

Record which SCF reference a completed job declared in the input it ran.

Only the two job types an E0 is built from are recorded, under the two keys SCF_REFERENCE_JOB_TYPES maps them to: ‘sp’, which supplies the electronic energy, and ‘freq’ or the combined ‘optfreq’, which supply the ZPE. Every other job type decides neither term, so recording it would compare references that are never summed.

reference_key names the term the job supplies where the job type does not say it. A species whose sp level equals its opt level runs no sp job at all and reads its electronic energy out of the optimization’s log, so it is the opt job that supplied the energy and its memo is recorded under ‘sp’. Without that the most common single-level configuration would record no energy reference at all, and the mixed-reference check would have nothing to compare for the whole run.

The value is read off the job adapter’s own memo of the decision it made while writing that input, not recomputed, so a species whose reference decision changed after the job ran still reports what the job did. Jobs whose level carries no reference prefix, the force field, composite and semiempirical methods, are not recorded: their ‘restricted’ flag is not a reference choice ARC made, and comparing it against a DFT job’s would report a mismatch that does not exist. Anything that is not a submitted ESS job, pipe tasks among them, carries no memo and is skipped.

Parameters:
  • label (str) – The species label.

  • job (JobAdapter) – The completed job object.

  • reference_key (str, optional) – The term the job supplied, ‘sp’ or ‘freq’. Taken from the job type when not given.

Returns:

None

record_tsg_job_error(label, job, output_error)[source]

Record an unrecoverable TS-search job error on the TS guesses that job produced.

A tsg<i> job name numbers the TS-search adapter that was dispatched for the reaction, it is not a position in species.ts_guesses: one adapter may contribute several guesses or none at all, and guesses from other adapters are interleaved. Using the job number as a list index therefore either annotates an unrelated guess or raises an IndexError when the adapter number exceeds the number of guesses generated so far. Match on the adapter that produced each guess instead.

Parameters:
  • label (str) – The TS species label.

  • job (JobAdapter) – The failed TS-search job.

  • output_error (str) – The error string to record.

release_held_stability_work(label=None)[source]

Release the post-optimization work of every species held for an analysis that is not running.

A species holds a stability_pending_opt_job from the moment its wavefunction stability analysis is spawned until spawn_post_stability_jobs releases it, and both of those are written to the restart file. A run resumed in between finds the record but not the job, since a finished job is not restored into running_jobs, so this is what reaches spawn_post_stability_jobs for it. A species whose analysis is still queued is left alone; the main loop reaches it when that job ends.

Parameters:

label (str, optional) – A single species label to release, or None for all of them.

report_running_jobs_snapshot()[source]

Overwrite <project>/running_jobs.yml with a timestamped snapshot of the currently running jobs and active pipes. If the payload is identical to the previous snapshot, the file is left untouched and only a one-line heartbeat is logged to ARC.log.

restore_running_jobs()[source]

Make Job objects for jobs which were running in the previous session. Important for the restart feature so long jobs won’t run twice.

Rebuilding a job adapter re-composes its input file, which recomputes the SCF reference from the species’ state as it is now. The reference the queued job actually ran with is therefore restored onto the rebuilt adapter from the restart file, so that a job which was submitted before a stability verdict was adopted still reports the reference it declared.

run_composite_job(label)[source]

Spawn a composite job (e.g., CBS-QB3) using ‘final_xyz’ for species ot TS ‘label’.

Parameters:

label (str) – The species label.

run_conformer_jobs(labels=None)[source]

Select the most stable conformer for each species using molecular dynamics (force fields) and subsequently spawning opt jobs at the conformer level of theory, usually a reasonable yet cheap DFT, e.g., b97d3/6-31+g(d,p). The resulting conformer is saved in a string format xyz in the Species initial_xyz attribute.

Parameters:

labels (list) – Labels of specific species to run conformer jobs for. If None, conformer jobs will be spawned for all species in self.species_list.

run_freq_job(label)[source]

Spawn a freq job using ‘final_xyz’ for species ot TS ‘label’. If this was originally a composite job, run an appropriate separate freq job outputting the Hessian.

Parameters:

label (str) – The species label.

run_irc_job(label, irc_direction='forward')[source]

Spawn an IRC job.

Parameters:
  • label (str) – The species label.

  • irc_direction (str) – The IRC job direction, either ‘forward’ or ‘reverse’.

run_job(job_type, conformer=None, cpu_cores=None, dihedral_increment=None, dihedrals=None, directed_scan_type=None, ess_trsh_methods=None, fine=False, irc_direction=None, job_adapter=None, label=None, level_of_theory=None, memory=None, max_job_time=None, rotor_index=None, reactions=None, queue=None, attempted_queues=None, scan_trsh='', shift='', trsh=None, torsions=None, times_rerun=0, tsg=None, xyz=None)[source]

A helper function for running (all) jobs.

Parameters:
  • job_type (str) – The type of job to run.

  • conformer (int, optional) – Conformer number if optimizing conformers.

  • cpu_cores (int, optional) – The total number of cpu cores requested for a job.

  • dihedral_increment (float, optional) – The degrees increment to use when scanning dihedrals of TS guesses.

  • dihedrals (list, optional) – The dihedral angles of a directed scan job corresponding to torsions.

  • directed_scan_type (str, optional) – The type of the directed scan.

  • ess_trsh_methods (list, optional) – A list of troubleshooting methods already tried out for ESS convergence.

  • fine (bool, optional) – Whether to run an optimization job with a fine grid. True to use fine.

  • irc_direction (str, optional) – The direction to run the IRC computation.

  • job_adapter (str, optional) – An ESS software to use.

  • label (str | list[str], optional) – The species label, or a list of labels in case of multispecies.

  • level_of_theory (Level, optional) – The level of theory to use.

  • memory (int, optional) – The total job allocated memory in GB.

  • max_job_time (int, optional) – The maximal allowed job time on the server in hours.

  • rotor_index (int, optional) – The 0-indexed rotor number (key) in the species.rotors_dict dictionary.

  • reactions (list[ARCReaction], optional) – Entries are ARCReaction instances, used for TS search methods.

  • scan_trsh (str, optional) – A troubleshooting method for rotor scans.

  • shift (str, optional) – A string representation alpha- and beta-spin orbitals shifts (molpro only).

  • times_rerun (int, optional) – Number of times this job was re-run with the same arguments (no trsh methods).

  • torsions (list[list[int]], optional) – The 0-indexed atom indices of the torsion(s).

  • trsh (str, optional) – A troubleshooting keyword to be used in input files.

  • tsg (int, optional) – TSGuess number if optimizing TS guesses.

  • xyz (dict | list[dict], optional) – The 3D coordinates for the species.

run_onedmin_job(label)[source]

Spawn a lennard-jones calculation using OneDMin.

Parameters:

label (str) – The species label.

run_opt_job(label, fine=False)[source]

Spawn a geometry optimization job. The initial guess is taken from the initial_xyz attribute.

Parameters:
  • label (str) – The species label.

  • fine (bool) – Whether a fine grid should be used during optimization.

run_orbitals_job(label)[source]

Spawn orbitals job used for molecular orbital visualization. Currently supporting QChem for printing the orbitals, the output could be visualized using IQMol.

Parameters:

label (str) – The species label.

run_scan_jobs(label)[source]

Spawn rotor scan jobs using ‘final_xyz’ for species (or TS).

Parameters:

label (str) – The species label.

run_sp_job(label, level=None, conformer=None)[source]

Spawn a single point job using ‘final_xyz’ for species or a TS represented by ‘label’. If the method is MRCI, first spawn a simple CCSD(T) job, and use orbital determination to run the MRCI job.

Parameters:
  • label (str) – The species label.

  • level (Level) – An alternative level of theory to run at. If None, self.sp_level will be used.

  • conformer (int) – The conformer number.

run_stability_job(label, opt_job)[source]

Spawn a wavefunction stability analysis job for a TS or for a species that optimized restricted.

The analysis is spawned from the optimization, before the frequency job, the single point and the IRC of that species, so the reference every one of them would be computed on is measured while it can still be changed. Its level comes from the optimization job, its geometry is the one that optimization converged to, and its orbitals are the ones that optimization wrote, so its SCF reproduces the wavefunction under test rather than whichever solution a fresh SCF reaches: without them Gaussian falls back to guess=mix, whose deliberately symmetry-broken SCF is a different wavefunction, and ORCA converges from its own initial guess.

It is spawned at most once per species, recorded on the species as stability_analysis_ran so a restart does not spawn a second one, and only where every one of the following holds: the species is a TS or its optimization declared a restricted reference, which is the only reference the analysis can inform, since a restricted solution gives the same energy as an unrestricted one if and only if it is stable; the optimization is a submitted ESS job, which a pipe task is not; that job’s ESS is in STABILITY_ANALYSIS_ADAPTERS; its level is DFT or Hartree-Fock, the only ones either of those ESSs offers the analysis for; and the species still holds the checkfile that optimization wrote, which is ESS-specific, a .chk for Gaussian and a .gbw for ORCA. Each refusal is logged and the caller runs the jobs that follow unchanged.

A job that ran in an ESS for which ARC has not implemented the analysis is reported as a warning once per ESS per run, rather than once per species: the condition holds for every species that ESS runs, so it is a statement about the run and not about the species that happened to reach it first.

WHAT THE ANALYSIS IS FOR ON A SPECIES THAT IS NOT A TS, given that it is expected to return ‘stable’ nearly every time: well under a few per cent of closed-shell equilibrium geometries are RHF -> UHF unstable, and a well is not where instabilities are looked for. Its value is what a ‘stable’ verdict licenses rather than what an unstable one reports. A well verified stable has identical restricted and unrestricted energies, so comparing it against a TS that ARC has made unrestricted is a comparison on one surface rather than across two; without the verdict that cannot be asserted. It also catches an undeclared singlet biradical, whose restricted energy is wrong and which nothing else in ARC detects.

Parameters:
  • label (str) – The species label.

  • opt_job (JobAdapter) – The optimization job whose wavefunction is tested.

Returns: bool

Whether a stability analysis job was spawned.

run_ts_conformer_jobs(label)[source]

Spawn opt jobs at the ts_guesses level of theory for the TS guesses.

When only a single guess succeeded, its geometry is optimized directly. The reported provenance (relative energy, chosen_ts_method, successful_methods and the guess log path) is taken from that same guess rather than from ts_guesses[0]: several TS adapters append success=False guesses, so the first entry of ts_guesses is not necessarily the guess whose coordinates are being optimized.

Parameters:

label (str) – The TS species label.

save_e_elect(label)[source]

Save the electronic energy of the corresponding species. It will append if the file already exists.

save_restart_dict()[source]

Update the restart_dict and save the restart.yml file.

schedule_jobs()[source]

The main job scheduling block

A species whose post-optimization work was held for a wavefunction stability verdict is released here when no analysis of its is still running, which is the state a run resumed after its analysis ended leaves behind: the job it was waiting on is gone, so nothing else would reach spawn_post_stability_jobs for it and the species would hold that work for the rest of the run. A verdict recorded before the interruption still decides what the release does, and one that never arrived releases the held jobs unchanged.

set_scan_resolution(args, job_type)[source]

Inject the run-level rotor scan resolution into a scan job’s troubleshooting args.

The value set via the rotor_scan_resolution input key is threaded through args['trsh']['scan_res'] (the same channel a per-job troubleshooting override uses), so a run may state its 1D rotor scan resolution once instead of relying on the launching host’s settings value. Only 'scan' jobs are affected, and a scan_res already present in args (e.g. from troubleshooting) is never overridden. When self.rotor_scan_resolution is None the args are returned unchanged, so behaviour is identical to today’s settings default.

Parameters:
  • args (dict) – The job arguments dictionary.

  • job_type (str) – The job type.

Returns: dict

The (possibly updated) job arguments dictionary.

spawn_directed_scan_jobs(label, rotor_index, xyz=None)[source]

Spawn directed scan jobs. Directed scan types could be one of the following: ‘brute_force_sp’, ‘brute_force_opt’, ‘cont_opt’, ‘brute_force_sp_diagonal’, ‘brute_force_opt_diagonal’, or ‘cont_opt_diagonal’. Here we treat cont and brute_force separately, and also consider the diagonal keyword. The differentiation between sp and opt is done in the Job module.

Parameters:
  • label (str) – The species label.

  • rotor_index (int) – The 0-indexed rotor number (key) in the species.rotors_dict dictionary.

  • xyz (str, optional) – The 3D coordinates for a continuous directed scan.

Raises:
  • InputError – If the species directed scan type has an unexpected value, or if xyz wasn’t given for a cont_opt job.

  • SchedulerError – If the rotor scan resolution as defined in settings.py is illegal.

spawn_post_irc_jobs(label, job)[source]

Spawn additional jobs after IRC has converged.

Parameters:
  • label (str) – The species label.

  • job (JobAdapter) – The IRC job object.

spawn_post_opt_jobs(label, job_name)[source]

Spawn additional jobs after opt has converged.

A wavefunction stability analysis, where run_stability_job finds the species eligible for one, is the single job spawned from here and everything else waits for its verdict: the frequency job, the single point, the IRC and the rotor scans all inherit the SCF reference and the geometry of the optimization, so computing them before the reference is measured spends them on a surface that may be about to change. The optimization job’s name is recorded on the species as stability_pending_opt_job before the analysis is spawned, so that a run interrupted between the two finds the record in its restart file, and spawn_post_stability_jobs re-enters this method with it once the verdict is in. The analysis runs at most once per species, so the re-entry spawns none and proceeds.

Parameters:
  • label (str) – The species label.

  • job_name (str) – The opt job name (used for differentiating between opt and optfreq jobs).

spawn_post_stability_jobs(label)[source]

Resume the work a wavefunction stability analysis was holding, once its verdict is in.

spawn_post_opt_jobs records the optimization job it was called for on the species as stability_pending_opt_job and returns without enqueueing anything whenever it spawns a stability analysis, so that no Hessian, energy or reaction path is computed on a reference that is still under test. This method is what releases that work, and it is reached for every stability job that leaves running_jobs, whether it converged, errored or was never parsed, so a species is not held by an analysis that produced no verdict.

A verdict ARC acts on, which adopted_reference_is_unrestricted defines, re-optimizes the species instead of releasing the held work. The re-optimization runs at the optimization level, starts from the geometry the first optimization converged to, and is unrestricted, because is_species_restricted reads the adopted verdict off the species. Re-optimizing is what makes an adoption correct: the restricted geometry is a stationary point of the restricted surface only, so a Hessian computed there on the broken-symmetry reference sits at a non-stationary point and can report imaginary modes that belong to the mismatch rather than to the molecule. Its own completion re-enters spawn_post_opt_jobs, which spawns no second analysis and releases the frequency, single point and IRC onto the geometry and the reference they belong with.

AT MOST ONE RE-OPTIMIZATION per species, recorded on the species as stability_reoptimized and written to the restart file, so a run resumed between the analysis and the re-optimization cannot spawn a second one.

THE ORBITALS THE RE-OPTIMIZATION STARTS FROM are the analysis’ own where the ESS relaxed into the lower solution, which its verdict reports as followed_to_stable, and none otherwise. ORCA follows an instability it finds and writes the relaxed orbitals to the analysis job’s input.gbw, which is the broken-symmetry solution the re-optimization is meant to sit on. Gaussian’s stable=(rext,noopt) reports an instability without following it, so its checkfile still holds the restricted orbitals; handing those to an unrestricted SCF returns it to the very solution the analysis rejected, since a restricted solution is a stationary point of the unrestricted equations too. Dropping the checkfile sends the job to guess=mix, whose deliberately symmetry-broken guess is what finds the lower solution.

Parameters:

label (str) – The species label.

spawn_ts_jobs()[source]

Check if any new reaction has all of its reactants and products optimized, and if so spawn the respective TSG jobs. Don’t spawn TS jobs if the multiplicity of the reaction could not be determined.

stability_verdict_can_be_honoured(label)[source]

Check whether every ESS this species’ E0 is built from can be given a broken-symmetry reference.

Acting on a wavefunction-stability verdict re-optimizes the species and computes its Hessian and its electronic energy on the lower, symmetry-broken solution. An unrestricted SCF reaches that solution only from a reference composed to break the spin symmetry, which the adapters in SYMMETRY_BREAKING_ADAPTERS compose and the rest do not: an adapter absent from that set writes one spin-symmetric determinant, whose SCF converges back to the restricted solution the verdict rejected. A geometry composed by one adapter and an energy by another is the standard arrangement, so a verdict adopted with only the first of them composing a symmetry-broken reference moves the geometry and the Hessian onto the lower solution and leaves the energy on the restricted one, and the E0 the run publishes sums terms from two surfaces rather than being the lower solution’s E0 or the restricted one’s. The job that could not compose the reference also records an unrestricted memo for an SCF that reached the restricted solution, which check_scf_reference_consistency then reads as agreement.

The three levels tested are the ones those terms come from: the optimization, which supplies the geometry, the frequency job, which supplies the ZPE, and the single point, which supplies the electronic energy. A job type the run does not compute is not tested, and a species whose single point runs at its optimization level tests that one level twice rather than none.

A LEVEL AN ADOPTED VERDICT DOES NOT REACH IS NOT TESTED, since its adapter is asked for no symmetry-broken reference and so can neither honour a verdict nor fail to. Two kinds of level are outside the verdict’s reach. A reference-agnostic one, for which ARC writes no reference prefix at all, is one; a correlated wavefunction level, whose energy is an expansion about a spin-adapted reference rather than the energy of that reference, is the other, and level_admits_a_broken_symmetry_reference tells both from the levels a verdict does decide. A single point at a correlated level therefore keeps its restricted reference in every adapter alike, and what it costs is a mismatch against the ZPE rather than a collapse, which check_scf_reference_consistency reports.

What this reports is that every level the verdict does reach is composed by an adapter writing a symmetry-broken reference; anything less is reported as not honourable and the verdict is measured and logged without being acted on.

Parameters:

label (str) – The species label.

Returns: bool

Whether adopting the verdict would give this species one reference throughout.

switch_ts(label)[source]

Try the next optimized TS guess in line if a previous TS guess was found to be wrong.

Parameters:

label (str) – The TS species label.

troubleshoot_conformer_isomorphism(label)[source]

Troubleshoot conformer optimization for a species that failed isomorphic test in determine_most_stable_conformer.

Parameters:

label (str) – The species label.

troubleshoot_ess(label, job, level_of_theory, conformer=None)[source]

Troubleshoot issues related to the electronic structure software, such as conversion.

Parameters:
  • label (str) – The species label.

  • job (JobAdapter) – The job object to troubleshoot.

  • level_of_theory (Level, dict, str) – The level of theory to use.

  • conformer (int, optional) – The conformer index.

troubleshoot_negative_freq(label, job)[source]

Troubleshooting cases where non-TS species have negative frequencies. Run newly generated conformers.

Parameters:
  • label (str) – The species label.

  • job (JobAdapter) – The frequency job object.

troubleshoot_opt_jobs(label)[source]

We’re troubleshooting for opt jobs. First check for server status and troubleshoot if needed. Then check for ESS status and troubleshoot if needed. Finally, check whether the last job had fine=True, add if it didn’t run with fine.

Parameters:

label (str) – The species label.

troubleshoot_scan_job(job, methods=None)[source]

Troubleshooting rotor scans Using the following methods: 1. freeze: freezing specific internal coordinates or all torsions other than the scan’s pivots 2. inc_res: increasing the scan resolution. 3. change conformer: changing to a conformer with a lower energy

Parameters:
  • job (JobAdapter) – The scan Job object.

  • methods (dict) –

    The troubleshooting method/s to try:

    {'freeze': <a list of problematic internal coordinates>,
     'inc_res': ``None``,
     'change conformer': <a xyz dict>}
    

Returns: tuple[bool, dict]:
  • True if the troubleshooting is valid.

  • The actions are applied in the troubleshooting.

warn_on_collapsible_unrestricted_reference(label, job)[source]

Report a job running an adopted unrestricted reference its adapter cannot keep from collapsing.

A species carrying an adopted wavefunction-stability verdict runs every job that follows it unrestricted, and an unrestricted SCF started from a spin-symmetric guess converges, in all but pathological cases, back to the restricted solution the verdict rejected: a restricted solution is a stationary point of the unrestricted equations too, so a gradient-following SCF sits on it. The job then reports the restricted energy under an unrestricted label, which is the energy the analysis found a lower solution than.

TWO MECHANISMS PREVENT THAT, and the adapters in SYMMETRY_BREAKING_ADAPTERS write them: an orbital guess taken from the broken-symmetry solution, which is Gaussian’s guess=read and ORCA’s !MORead, and a symmetry-breaking directive that needs no guess, which is Gaussian’s guess=mix and ORCA’s BrokenSym. Those two adapters write whichever of the pair the job admits.

EVERY OTHER ADAPTER WRITES NEITHER. An adopted verdict was measured by an optimization composed by one of the adapters in STABILITY_ANALYSIS_ADAPTERS, so whatever broken-symmetry orbitals a later job could start from were written in that ESS’s own format; a third adapter writes no keyword that reads them, and no symmetry-breaking directive either. Whether its ESS could be asked for one is a separate question: this reports what ARC composes. The standard arrangement of a geometry from one adapter and an energy from another is exactly where this lands, and what it costs is the electronic energy the run publishes.

WHAT REACHES THIS AT ALL. A verdict is adopted only where the adapters composing every level of the species the verdict decides write a symmetry-breaking reference, which stability_verdict_can_be_honoured decides, so the geometry, the Hessian and an electronic energy at such a level do not reach this. An electronic energy at a correlated level does not either: the verdict decides no reference there, so the job composes a restricted one and is not a collapse. What does reach this is a job type that decision does not cover, the IRC and the rotor scans of an adopted species, composed at a level whose adapter writes neither mechanism.

WHAT IS REPORTED WHERE. The species’ output warnings carry COLLAPSED_REFERENCE_MESSAGE, once per species, so output.yml names every species the condition was reached for rather than only the first. The log carries the full message once per adapter per run, as run_stability_job reports an adapter with no analysis implemented, since the statement is the same for every species that adapter composes a job for.

WHAT THIS DOES NOT REACH. The ESS name is what decides whether a mechanism exists, so a Gaussian job whose SCF troubleshooting replaced its guess keyword with guess=INDO carries neither guess=read nor guess=mix and is not reported. A single point batched through the pipe is spawned by the pipe planner rather than by run_job, and is not reported either.

Parameters:
  • label (str) – The species label.

  • job (JobAdapter) – The job that was spawned.

arc.scheduler.species_has_freq(species_output_dict, yml_path=None)[source]

Checks whether a species has valid converged frequencies using it’s output dict.

Parameters:
  • species_output_dict (dict) – The species output dict (i.e., Scheduler.output[label]).

  • yml_path (str) – THe species Arkane YAML file path.

Returns: bool

Whether a species has valid converged frequencies.

arc.scheduler.species_has_geo(species_output_dict, yml_path=None)[source]

Checks whether a species has a valid converged geometry using it’s output dict.

Parameters:
  • species_output_dict (dict) – The species output dict (i.e., Scheduler.output[label]).

  • yml_path (str) – THe species Arkane YAML file path.

Returns: bool

Whether a species has a valid converged geometry.

arc.scheduler.species_has_sp(species_output_dict, yml_path=None)[source]

Checks whether a species has a valid converged single-point energy using it’s output dict.

Parameters:
  • species_output_dict (dict) – The species output dict (i.e., Scheduler.output[label]).

  • yml_path (str) – THe species Arkane YAML file path.

Returns: bool

Whether a species has a valid converged single-point energy.

arc.scheduler.species_has_sp_and_freq(species_output_dict, yml_path=None)[source]

Checks whether a species has a valid converged single-point energy and valid converged frequencies.

Parameters:
  • species_output_dict (dict) – The species output dict (i.e., Scheduler.output[label]).

  • yml_path (str) – THe species Arkane YAML file path.

Returns: bool

Whether a species has a valid converged single-point energy and frequencies.

arc.scheduler.tsg_method_matches_adapter(method, job_adapter)[source]

Determine whether a TSGuess.method was produced by a given TS-search adapter.

The two spellings differ (e.g. the xtb_gsm adapter labels its guesses 'xTB-GSM', kinbot labels them 'KinBot' or 'KinBot-UMA'), so both strings are lower-cased and stripped of '-' and '_' before testing for containment.

Parameters:
  • method (str, optional) – The TSGuess.method string.

  • job_adapter (str, optional) – The TS-search job adapter name.

Returns:

Whether the guess was produced by this adapter.

Return type:

bool