pyretis.inout package

The sub-package handles input and output for PyRETIS.

This package is intended for creating various forms of output from the PyRETIS program. It includes writers for simple text-based output and plotters for creating figures. Figures and the text results can be combined into reports, which are handled by the report module.

Package structure

Modules

__init__.py

Imports from the other modules.

checker.py (pyretis.inout.checker)

Functions to check the compatibility and consistency of various input values.

common.py (pyretis.inout.common)

Common functions and variables for the input/output. These functions are mainly intended for internal use and are not imported here.

fileio.py (pyretis.inout.fileio)

A module which defines a generic file class for PyRETIS output files.

settings.py (pyretis.inout.settings)

A module which handles the reading/writing of settings.

simulationio.py (pyretis.inout.simulationio)

A module which handles th reading/writing of the main simulations.

restart.py (pyretis.inout.restart)

A module which handles restart reading/writing.

Sub-packages

analysisio (pyretis.inout.analysisio)

Handles the input and output needed for analysis.

formats (pyretis.inout.formats)

Handles the input and output of different data formats. This includes the configurations and the internal data formats.

plotting (pyretis.inout.plotting)

Handles the plotting needed by the analysis by defining plotting tools, methods and styles.

report (pyretis.inout.report)

Generate reports with results from simulations.

Important classes defined in this package

Important methods defined in this package

generate_report (generate_report())

A function to generate reports from analysis output(s).

parse_settings_file (parse_settings_file())

Method for parsing settings from a given input file.

write_settings_file (write_settings_file())

Method for writing settings from a simulation to a given file.

write_restart_file (write_restart_file())

Method for writing restart information.

Subpackages

List of submodules

pyretis.inout.clean module

Removal of PyRETIS run artifacts (the pyretis clean command).

This module implements the cleanup otherwise duplicated in the per-example Makefile clean targets. It deletes the artifacts a PyRETIS run leaves behind so an example (or any run directory) can be reset to its committed inputs.

What is removed is the union of:

  • a built-in set of always-generated PyRETIS artifacts (see DEFAULT_FIND_FILES and DEFAULT_FIND_DIRS), and

  • whatever an optional per-directory CONFIG_NAME file adds.

The per-directory config (TOML) mirrors the variables the old shared common-clean.mk used:

[clean]
use_defaults = true        # apply the built-in defaults (default: true)
find_files = ["*.tpr"]     # extra file-name globs (recursive find -delete)
find_dirs  = ["dump"]      # extra directory names (recursive rm -rf)
rm_paths   = ["lammps/system.data"]  # root-relative rm -rf globs
keep       = ["load/0"]    # never delete these (or their ancestors)

keep protects committed inputs that would otherwise match (for example the committed load/0 .. load/7 initial paths of the validation suite). Anything that is a kept path, lies inside a kept path, or is an ancestor directory of a kept path is left untouched.

The load input the TOML inputs in or below the cleaned directory name is kept the same way (see load_inputs()): the [initial-path] load_folder a classic load reads, and the flat store <load_dir> a fresh scheduler run reads its initial paths from. The store of the paths a scheduler run writes in each of its ensemble directories, <ensemble>/<load_dir>, is removed under the name these inputs give it (see run_stores()).

pyretis.inout.clean.EXCLUDED_DIR_NAMES = ('results', 'output_data', 'load', 'load_copy', 'lammps_input', 'gromacs_input', 'cp2k_input', 'openmm_input')

The engine input_path directories are inputs by convention too: a committed lammps_input/conf.lammpstrj matches the aggressive *.lammpstrj default and was deleted by an ancestor-directory clean. A test that STAGES such a directory still removes it through an explicit rm_paths entry, which this exclusion does not guard.

pyretis.inout.clean._clean_find_dirs(directory, patterns, protected, dry_run, removed)

Delete directories whose name matches one of patterns.

The walk is top-down so a matched directory is removed before its children are visited; dirs is pruned in place to avoid descending into something already scheduled for removal.

pyretis.inout.clean._clean_find_files(directory, patterns, protected, dry_run, removed)

Delete files whose name matches one of patterns (recursive).

pyretis.inout.clean._clean_rm_paths(directory, patterns, protected, dry_run, removed)

Delete root-relative paths/globs with rm -rf semantics.

pyretis.inout.clean._clean_run_stores(directory, stores, protected, dry_run, removed)

Delete the stores of the paths the TOML inputs name.

A store that lies in a path removed before, such as its ensemble directory, is removed with it, and is not listed again.

Parameters:
  • directory (string) – The root of the clean.

  • stores (list of str) – The stores run_stores() found.

  • protected (set of str) – Absolute normalised kept paths.

  • dry_run (boolean) – When True, nothing is deleted.

  • removed (list of str) – The paths removed so far; each store removed is appended.

pyretis.inout.clean._is_protected(path, protected)

Return True if path must not be deleted given protected.

A path is protected when it equals a kept path, lies inside one, or is an ancestor directory of one (so we never delete a parent that still holds something we must keep).

Parameters:
  • path (string) – The candidate path to delete.

  • protected (set of str) – Absolute normalised kept paths.

Returns:

boolean – True when the candidate must be left untouched.

pyretis.inout.clean._named_load_input(path)

Return the load input one TOML input file names.

Parameters:

path (string) – The TOML file, an input of a run in the directory holding it.

Returns:

set of str – The absolute paths of the [initial-path] load_folder and the flat store [simulation] load_dir the file names, resolved against the directory holding it, for those that exist.

Raises:

ValueError – If the file cannot be parsed.

pyretis.inout.clean._named_run_stores(path)

Return the stores of the paths one TOML input file names.

Parameters:

path (string) – The TOML file, an input of a run in the directory holding it.

Returns:

set of str – The absolute normalised paths <ensemble>/<load_dir> that exist, for each ensemble directory of the run, when the file holds a [simulation] section.

Raises:

ValueError – If the file cannot be parsed.

pyretis.inout.clean._nested_keeps(directory)

Collect the keep declarations of every nested config.

Parameters:

directory (string) – The root of the clean; its own config is handled by the caller.

Returns:

set of str – Absolute normalised paths protected by nested clean.toml files, resolved relative to the directory each one lives in.

pyretis.inout.clean._normalise_keep(directory, keep)

Return the set of absolute, normalised kept paths.

Parameters:
  • directory (string) – The root directory of the clean.

  • keep (list of str) – The configured keep entries (root-relative, may be globs).

Returns:

set of str – Absolute normalised paths that must be protected.

pyretis.inout.clean._read_input(path, what)

Parse a TOML input of the cleaned tree.

Parameters:
  • path (string) – The TOML file.

  • what (string) – What the file names that the clean needs, for the message.

Returns:

dict – The parsed configuration.

Raises:

ValueError – If the file cannot be parsed.

pyretis.inout.clean._read_toml(path)

Parse a TOML file, returning the top-level mapping.

Parameters:

path (string) – Path to the TOML file.

Returns:

dict – The parsed configuration.

pyretis.inout.clean._remove_file(path, dry_run, removed)

Delete a file (unless dry-run) and record it.

pyretis.inout.clean._remove_tree(path, dry_run, removed)

Delete a file or directory tree (unless dry-run) and record it.

pyretis.inout.clean._toml_inputs(directory)

Return the TOML inputs in and below a directory.

Parameters:

directory (string) – The directory to be cleaned.

Returns:

list of str – The TOML files other than CONFIG_NAME in directory and in the directories below it, in the order of a walk with sorted names.

pyretis.inout.clean._under_excluded_dir(path, root)

Return True if path lies under an excluded directory name.

Parameters:
  • path (string) – The path to test.

  • root (string) – The clean root (its own name is not considered).

Returns:

boolean – True when a path component (below root) is excluded.

pyretis.inout.clean._walked_to(root, path)

Tell whether a clean of root walks down to path.

Parameters:
  • root (string) – The absolute normalised root of the clean.

  • path (string) – An absolute normalised path.

Returns:

boolean – True when path lies below root and no directory between them is a symbolic link. path itself may be a link.

pyretis.inout.clean.clean_directory(directory='.', dry_run=False)

Remove PyRETIS run artifacts from a directory.

Parameters:
  • directory (string, optional) – The directory to clean. Defaults to the current directory.

  • dry_run (boolean, optional) – When True, nothing is deleted; the would-be-removed paths are only collected and returned.

Returns:

list of str – The paths that were removed (or, for a dry run, that would be removed), sorted for a stable report.

pyretis.inout.clean.load_clean_config(directory)

Load the cleanup configuration for a directory.

Reads the built-in defaults and merges in the optional CONFIG_NAME file found in directory.

Parameters:

directory (string) – The directory to be cleaned.

Returns:

dict – A configuration with the keys find_files, find_dirs, rm_paths and keep (all lists of strings), and use_defaults (boolean): whether the built-in defaults and the stores of the paths of the runs (see run_stores()) are removed.

pyretis.inout.clean.load_inputs(directory)

Return the load input the TOML inputs of the cleaned tree name.

A run reads the paths the user staged for it. A classic load reads [initial-path] load_folder, and a fresh scheduler run reads its initial paths from the flat store <load_dir>/<path number> of the run directory ([simulation] load_dir, by default accepted). Every TOML file in directory and in the directories below it, other than CONFIG_NAME, is read as an input of a run in the directory holding it, so a clean started above a run directory keeps the load input of that run too.

Parameters:

directory (string) – The directory to be cleaned.

Returns:

set of str – Absolute normalised paths of the load folders and staged stores that exist, which a clean leaves untouched.

Raises:

ValueError – If a TOML file in or below directory cannot be parsed: the load input it names is then unknown.

pyretis.inout.clean.run_stores(directory)

Return the stores of the paths the TOML inputs of the tree name.

A scheduler run writes its ensemble directories (000, 001, …) in the directory of its input, or in [output] data_dir relative to it, and stores the paths of each ensemble in <ensemble>/<load_dir> ([simulation] load_dir, by default accepted). Every TOML file load_inputs() reads is read here as the input of a run in the directory holding it.

Parameters:

directory (string) – The directory to be cleaned.

Returns:

list of str – Absolute normalised paths of the stores that exist below directory, sorted. A store is listed when it lies inside its ensemble directory and the path from directory down to it passes through no symbolic link, the directories a clean walks.

Raises:

ValueError – If a TOML file in or below directory cannot be parsed: the store it names is then unknown.

pyretis.inout.common module

This file contains common functions for the input/output.

It contains some slave functions that are used in the in/output function of PyRETIS.

Important classes defined here

OutputBase (OutputBase)

A base class for handling the output.

Important methods defined here

check_python_version (check_python_version())

A method that will give warnings when we use older and possibly unsupported Python versions.

create_backup (create_backup())

A function to handle the creation of backups of old files.

prepare_log_file (prepare_log_file())

Apply the [output] log_mode start-of-run treatment to an existing run log (append / backup / overwrite).

peek_output_log_settings (peek_output_log_settings())

Read the [output] log keywords from an input file before the logging system is configured.

make_dirs (make_dirs())

Create directories (for path simulation).

atomic_write (atomic_write())

Write a file atomically and durably (crash-safe).

durable_copy (durable_copy())

Copy a file and flush the copy to stable storage.

fsync_dir (fsync_dir())

Flush a directory entry to disk.

create_empty_ensembles (create_ensembles())

A method to prepare the ensembles inputs in settings

generate_file_name (generate_file_name())

Generate file name for an output task, from settings.

class pyretis.inout.common.OutputBase(formatter)

Bases: object

A generic class for handling output.

Variables:
  • formatter (object like py:class:.OutputFormatter) – The object responsible for formatting output.

  • target (string) – Determines where the target for the output, for instance “screen” or “file”.

  • first_write (boolean) – Determines if we have written something yet, or if this is the first write.

__init__(formatter)

Create the object and attach a formatter.

__str__()

Return basic info.

formatter_info()

Return a string with info about the formatter.

output(step, data)

Use the formatter to write data to the file.

Parameters:
  • step (int) – The current step number.

  • data (list) – The data we are going to output.

target = None
abstractmethod write(towrite, end='\n')

Write a string to the output defined by this class.

Parameters:
  • towrite (string) – The string to write.

  • end (string, optional) – A “terminator” for the given string.

Returns:

status (boolean) – True if we managed to write, False otherwise.

pyretis.inout.common.add_dirname(filename, dirname)

Add a directory as a prefix to a filename, i.e. dirname/filename.

Parameters:
  • filename (string) – The filename.

  • dirname (string) – The directory we want to prefix. It can be None, in which case we ignore it.

Returns:

out (string) – The path to the resulting file.

pyretis.inout.common.atomic_write(path, write_fn, binary=True, keep_prev=False)

Write a file atomically and durably.

The payload is first written to a temporary file in the same directory, flushed to disk with os.fsync and then moved into place with os.replace (an atomic operation on POSIX systems when both files reside on the same filesystem). Finally the parent directory entry is flushed so that the rename itself survives a crash.

This guarantees that path is never observed in a half-written state: after a crash it is either the complete new content or the complete previous content.

Parameters:
  • path (string) – The file we want to create.

  • write_fn (callable) – A function that takes a single argument, the open file handle, and writes the payload to it.

  • binary (boolean, optional) – If True, the temporary file is opened in binary mode, otherwise in (utf-8) text mode.

  • keep_prev (boolean, optional) – If True, an existing path is copied to path + '.prev' before the replace. This keeps the previous version available even if a crash happens in the (tiny) window around the rename.

Returns:

out (string) – The path that was written.

pyretis.inout.common.check_python_version()

Give a warning about old python version(s).

pyretis.inout.common.create_backup(outputfile)

Check if a file exist and create backup if requested.

This function will check if the given file name exists and if it does, it will move that file to a new file name such that the given one can be used without overwriting.

Parameters:

outputfile (string) – This is the name of the file we wish to create.

Returns:

out (string) – This string is None if no backup is made, otherwise, it will just say what file was moved (and to where).

Note

No warning is issued here. This is just in case the msg returned here will be part of some more elaborate message.

pyretis.inout.common.create_empty_ensembles(settings)

Create missing ensembles in the settings.

Checks the input and allocate it to the right ensemble. In theory inouts shall include all these info, but it is not practical.

pyretis.inout.checker.ensemble_layout() says which of the [0^-] and the [0^+] exist. The ensembles of every task but pptis are numbered in the full layout (pyretis.core.pathensemble.FULL_LAYOUT): the [0^-] is ensemble number 0, the [0^+] number 1 and the body ensemble [i^+] number i + 1, also when the run leaves out the first two. A pptis run numbers the windows its layout holds from 0, in the order [0^-], [0^+], [1^+], …, so that the number of an ensemble is the slot of its window in the scheduler and the name of its directory (pyretis.core.pathensemble.ensemble_label() reads the number in that layout). A tis run with [tis] ensemble_number has one ensemble, of the number pyretis.inout.checker.tis_ensemble_number() reads, and a single TIS run without it has the one ensemble number 2.

Parameters:

settings (dict) – The current input settings.

Returns:

None, but this method might add data to the input settings.

pyretis.inout.common.durable_copy(src, dst)

Copy a file and flush the copy to stable storage.

Used for trajectory files (and other binary payloads) that must be on disk before we record them as part of an archived path. Both the copied file and its parent directory entry are flushed with os.fsync.

Parameters:
  • src (string) – The file to copy.

  • dst (string) – The destination file name.

pyretis.inout.common.fsync_dir(dirname)

Flush a directory entry to disk.

After an atomic rename, the directory entry itself must be flushed for the rename to be durable across a crash (e.g. a power loss). This is best-effort: some filesystems do not allow fsync on a directory handle, and that single situation is the only one we ignore here.

Parameters:

dirname (string) – The directory whose metadata we flush. An empty string is interpreted as the current working directory.

pyretis.inout.common.generate_file_name(basename, directory, settings)

Generate file name for an output task, from settings.

Parameters:
  • basename (string) – The base file name to use.

  • directory (string) – A directory to output to. Can be None to output to the current working directory.

  • settings (dict) – The input settings

Returns:

filename (string) – The file name to use.

Give a file a second name, or a copy where that is not possible.

A hard link makes dst a second name of the file src names: both directories reach one copy on disk, and removing or renaming either name leaves the other. Where hard links are unavailable – another filesystem, or one that does not support them – the content is copied instead, which is correct but uses space.

Through a hard link, writing into dst writes into the file src names, so this is for files that are only read, renamed or removed afterwards.

Parameters:
  • src (string) – The existing file.

  • dst (string) – The new name. It must not exist.

pyretis.inout.common.make_dirs(dirname)

Create directories for path simulations.

This function will create a folder using a specified path. If the path already exists and if it’s a directory, we will do nothing. If the path exists and is a file we will raise an OSError exception here.

Parameters:

dirname (string) – This is the directory to create.

Returns:

out (string) – A string with some info on what this function did. Intended for output.

pyretis.inout.common.name_file(name, extension, path=None)

Return a file name by joining a name and an file extension.

This function is used to create file names. It will use os.extsep to create the file names and os.path.join to add a path name if the path is given. The returned file name will be of form (example for posix): path/name.extension.

Parameters:
  • name (string) – This is the name, without extension, for the file.

  • extension (string) – The extension to use for the file name.

  • path (string, optional) – An optional path to add to the file name.

Returns:

out (string) – The resulting file name.

pyretis.inout.common.peek_output_log_settings(input_file)

Read the [output] log keywords from an input file.

The run-log handler must exist before the input file is properly parsed (everything, including parse errors, is logged to it), so the log_file / log_mode keywords are peeked here with a minimal read. A TOML input (either schema – both keep these keys in [output]) is read with tomllib; the deprecated .rst frontend is scanned line by line for the two keywords. A file that cannot be read or parsed yields no settings – the real parse reports that failure properly, into a default-named log.

Parameters:

input_file (string) – The simulation input file handed to pyretis run.

Returns:

out (dict) – The log_file / log_mode values found (missing keys absent).

pyretis.inout.common.prepare_log_file(log_file, log_mode='append')

Apply the start-of-run treatment to an existing run log.

Called once, before the logging file handler is opened (the handler itself always opens in append mode).

Parameters:
  • log_file (string) – The run-log file name.

  • log_mode (string, optional) – What to do with an existing log: 'append' (the default) leaves it in place so the run – e.g. a restart – continues the same growing file; 'backup' rotates it aside first (create_backup()); 'overwrite' truncates it.

Returns:

out (string or None) – A message describing what was done to a pre-existing log, or None when there was nothing to do.

Raises:

ValueError – If log_mode is not one of LOG_MODES.

pyretis.inout.common.stage_files(source, target)

Give every file of one directory the same name in another.

This makes a working copy of input a run must not change. Text files (.txt: the traj.txt, order.txt and energy.txt of a path) are copied, so the copy may be rewritten. Every other file – the trajectory frames – is linked where the filesystem allows it (link_or_copy()) and may only be read, renamed or removed in target.

Parameters:
  • source (string) – The directory whose files are staged. Its subdirectories are left out.

  • target (string) – The existing directory receiving them. It holds none of their names.

pyretis.inout.engine_temperature module

Read the temperature an external engine runs and draws at.

An external engine states its temperature in its own input: the GROMACS mdp file, the CP2K input, the OpenMM Simulation, the AMS input and the LAMMPS script. The readers in this module read that temperature from the input alone, without building an engine. Each reader returns every temperature the input sets, keyed by the name of the setting, because one input can set several (one ref-t per GROMACS coupling group, a LAMMPS SET_TEMP variable next to a thermostat fix). A reader raises a ValueError that names the file and the key to set when the input leaves the temperature out, sets it in a form the reader cannot turn into a number, or changes it during the run (annealing, a ramp, a schedule). The LAMMPS and AMS readers also refuse a setting that sets or changes the temperature of the atoms by other means (a heat source, Monte Carlo moves at a temperature of their own), and a LAMMPS fix style or AMS block outside the ones the reader knows, whose effect on the temperature is unknown.

Important classes and functions defined here

EngineTemperatures (EngineTemperatures)

The temperatures read from one engine input.

read_gromacs_temperatures (read_gromacs_temperatures())

Read gen-temp and the thermostat ref-t of a GROMACS mdp file.

cp2k_md_temperature (cp2k_md_temperature())

Return the TEMPERATURE keyword of a CP2K MOTION/MD section.

read_cp2k_temperatures (read_cp2k_temperatures())

Read MOTION/MD TEMPERATURE of a CP2K input file.

openmm_temperatures (openmm_temperatures())

Read the integrator and thermostat temperatures of an OpenMM Simulation.

read_ams_temperatures (read_ams_temperatures())

Read the initial-velocity and thermostat temperatures of an AMS input.

read_lammps_temperatures (read_lammps_temperatures())

Read SET_TEMP, the thermostat fixes and the velocity commands of a LAMMPS script.

class pyretis.inout.engine_temperature.EngineTemperatures(source: str, values: dict = <factory>, unit: str = 'K', engine_units: str | None = None)

Bases: object

The temperatures read from one engine input.

Variables:
  • source (string) – The file (or module) the temperatures were read from.

  • values (dict of float) – One entry per setting of the input that holds a temperature, keyed by the name of that setting (for instance 'gen-temp' or 'ref-t[System]'), in the order of the input.

  • unit (string) – 'K' for kelvin, or 'lj' for the reduced temperature of a LAMMPS script in units lj.

  • engine_units (string or None) – The unit system the input declares (the LAMMPS units command), or None for an input that declares none.

agreed()

Return the one temperature that every setting holds.

The values are read from text, so equal temperatures written in different ways (300, 300.0, 3.0E+02) are the same float, and the comparison is exact.

Returns:

out (float) – The temperature.

Raises:

ValueError – If the input holds no temperature, or holds different ones.

engine_units: str | None = None
source: str
unit: str = 'K'
values: dict
pyretis.inout.engine_temperature.cp2k_md_temperature(md_lines, source)

Return the TEMPERATURE keyword of a CP2K MOTION/MD section.

The keyword is matched as a whole word and ignoring case, and it takes an optional [K] unit tag: TEMPERATURE 300, temperature 300 and TEMPERATURE [K] 300 all give 300. Other keywords that start with the same letters, such as TEMPERATURE_ANNEALING, are other keywords.

Parameters:
Returns:

out (float or None) – The temperature in kelvin, or None when the section sets no TEMPERATURE.

Raises:

ValueError – If the section sets TEMPERATURE more than once, gives it in another unit than kelvin, or sets a value that is not a number.

pyretis.inout.engine_temperature.openmm_temperatures(simulation, source)

Read the temperatures of an OpenMM Simulation.

The integrator temperature is getTemperature(). A Nose-Hoover integrator has one temperature per thermostat chain, plus the relative temperature of a chain that thermostats particle pairs (Drude pairs), and a Drude Langevin integrator has the Drude temperature. A force of the System that carries a temperature parameter (AndersenThermostat and the Monte Carlo barostats) adds the value of that parameter in the Context.

Parameters:
  • simulation (object like openmm.app.Simulation) – The simulation, with its integrator, System and Context.

  • source (string) – The module the simulation comes from, for the error message.

Returns:

out (object like EngineTemperatures) – The temperatures in kelvin, keyed by the integrator method or the force parameter they come from.

Raises:

ValueError – If neither the integrator nor a force of the System carries a temperature, or a temperature is not positive.

pyretis.inout.engine_temperature.read_ams_temperatures(filename)

Read the temperatures of an AMS input file.

MolecularDynamics%InitialVelocities%Temperature is the temperature of the velocities AMS draws, and it is required. Every MolecularDynamics%Thermostat block with a Type other than None (the AMS default) adds its Temperature, which must be one value: several values are an annealing schedule.

The MolecularDynamics block is read with the blocks and keys of the AMS 2026.1 input. A line that is not a block or key of that input is refused, since its effect on the temperature is unknown, and so are the blocks that set or change the temperature of the atoms in another way: AddMolecules, fbMC, HeatExchange and ReplicaExchange. An input that includes another file (@include) is refused.

Parameters:

filename (string) – The AMS input file.

Returns:

out (object like EngineTemperatures) – 'MolecularDynamics%InitialVelocities%Temperature', and 'MolecularDynamics%Thermostat[<n>]%Temperature' for the n-th Thermostat block (counted from 1) that has a thermostat, in kelvin.

Raises:

ValueError – If the input has no initial-velocity temperature, a thermostat has no temperature or a schedule, a temperature is not a positive number, or the input holds a line the reader refuses.

pyretis.inout.engine_temperature.read_cp2k_temperatures(filename)

Read MOTION/MD TEMPERATURE of a CP2K input file.

The temperature is required: CP2K runs at 300 K when it is absent. The reader refuses the inputs whose temperature changes during the run or differs between regions: TEMPERATURE_ANNEALING or ANNEALING other than 1, and MOTION/MD/THERMAL_REGION. It also refuses preprocessor lines (@INCLUDE, @IF) in the MOTION/MD section, because they can set keywords outside the lines of the section.

Parameters:

filename (string) – The CP2K input file.

Returns:

out (object like EngineTemperatures) – 'MOTION/MD TEMPERATURE', in kelvin.

Raises:

ValueError – If the input has no MOTION/MD section or no TEMPERATURE in it, or sets one of the refused keywords or sections.

pyretis.inout.engine_temperature.read_gromacs_temperatures(filename)

Read the temperatures of a GROMACS mdp file.

gen-temp is the temperature of the velocities GROMACS draws for a velocity_generation = "engine" run, and it is required: GROMACS draws at 300 K when it is absent. When the run is coupled to a thermostat (integrator = sd or bd, or tcoupl other than no), each ref-t value is the bath temperature of one tc-grps group and is read too. A ref-t without a thermostat has no effect in GROMACS and is left out.

Parameters:

filename (string) – The mdp file.

Returns:

out (object like EngineTemperatures) – 'gen-temp', and 'ref-t[<group>]' for every tc-grps group of a coupled run, in kelvin.

Raises:

ValueError – If gen-temp is absent, annealing is set for a group, a coupled run does not give one ref-t per tc-grps group, or a temperature is not a positive number.

pyretis.inout.engine_temperature.read_lammps_temperatures(filename)

Read the temperatures of a LAMMPS script.

The script is read from top to bottom, with its include files, as LAMMPS reads it; a variable is substituted with the value it has where it is used. The temperatures are:

  • the variable SET_TEMP, which the velocity_generation = "engine" draw of the PyRETIS LAMMPS engines uses;

  • the Tstart (equal to Tstop) of every thermostat fix that is defined at the end of the script (nvt, npt and their variants, bocs, langevin, langevin/eff, temp/berendsen, temp/csvr, temp/csld, temp/rescale, temp/rescale/eff, and the thermostats of the rigid-body fixes), and the temp of every qtb fix;

  • the temperature of every velocity create and velocity scale command.

Every other fix style is looked up in the fix styles of the LAMMPS documentation and of LAMMPS 22 Jul 2025: a style that leaves the temperature to the thermostat fixes (an integrator, a constraint, a force, an output) is passed, and a style that sets or changes the temperature in another way (another thermostat, Monte Carlo moves at a temperature, a heat source, a friction force) is refused, as is a style outside these fix styles. A pair_style that sets or changes the temperature through the pair forces (dissipative particle dynamics, brownian, dsmc, the lubrication, granular and mesocnt/viscous friction styles) is refused.

The reader sees the variables the files define. On the LAMMPS command line (-var) the PyRETIS LAMMPS engines add only pyretis_seed.

Parameters:

filename (string) – The LAMMPS script.

Returns:

out (object like EngineTemperatures) – The temperatures, keyed 'variable SET_TEMP', 'fix <ID> <style>' and 'velocity <group> <create|scale>'. unit is 'lj' for units lj (the LAMMPS default) and 'K' for the other unit systems, and engine_units is the unit system.

Raises:

ValueError – If the script sets no temperature, sets one that is not a plain number (an equal formula, a v_ reference), ramps one, uses a refused or unknown fix style or a refused pair style, uses a command that changes which commands LAMMPS runs (if, jump, label, next, python, run ... every), reads a restart file, or names an unknown unit system.

pyretis.inout.engine_temperature.read_mdp_settings(filename)

Read the settings of a GROMACS mdp file as grompp reads them.

A ; starts a comment. Every other non-blank line is key = value, split at its first = (a define value can hold more). A key with an empty value takes the GROMACS default, so it is left out of the result.

Parameters:

filename (string) – The mdp file.

Returns:

out (dict of string) – The values, keyed by the key in the form _gromacs_name() gives it ('reft' for ref-t).

Raises:

ValueError – If a line has no = or no key, or a key is set twice (grompp refuses all three).

pyretis.inout.fileio module

Module defining the base classes for the PyRETIS output.

Important classes defined here

FileIO (FileIO)

A generic class for handling input & output with files.

Important methods defined here

read_some_lines (read_some_lines())

Method to read lines from PyRETIS data files.

class pyretis.inout.fileio.FileIO(filename, file_mode, formatter, backup=True)

Bases: OutputBase

A generic class for handling IO with files.

This class defines how PyRETIS stores and reads data. Formatting is handled by an object like OutputFormatter

Variables:
  • filename (string) – Name (e.g. path) to the file to read or write.

  • file_mode (string) – Specifies the mode in which the file is opened.

  • backup (boolean) – Determines the behavior if we want to write to a file that is already existing.

  • fileh (object like io.IOBase) – The file handle we are interacting with.

  • last_flush (object like datetime.datetime) – The previous time for flushing to the file.

__del__()

Close the file in case the object is deleted.

__enter__()

Context manager for opening the file.

__exit__(*args)

Context manager for closing the file.

__init__(filename, file_mode, formatter, backup=True)

Set up the file object.

Parameters:
  • filename (string) – The path to the file to open or read.

  • file_mode (string) – Specifies the mode for opening the file.

  • formatter (object like py:class:.OutputFormatter) – The object responsible for formatting output.

  • backup (boolean, optional) – Defines how we handle cases where we write to a file which is already existing.

__iter__()

Make it possible to iterate over lines in the file.

__next__()

Let the file object handle the iteration.

__str__()

Return basic info.

close()

Close the file.

fileh = None
flush()

Flush file buffers to file.

A handle opened for reading is skipped. close flushes unconditionally and this class supports read mode (open_file_read()), so a read handle reaches here and os.fsync is then called on a descriptor that was never written. Linux tolerates that; other platforms raise OSError, which would turn merely closing a file that was read into a failure.

load()

Read blocks or lines from the file.

open()

Open a file for reading or writing.

open_file_read()

Open a file for reading.

A file that cannot be opened raises. Swallowing the error left fileh as None, and iteration over this object then stops immediately (see __next__()), so an unreadable file was indistinguishable from an empty one. Callers for which a missing file is a legitimate state check for it first, as pyretis.core.path_load._load_energies_for_path() does.

open_file_write()

Open a file for writing.

In this method, we also handle the possible backup settings.

output(step, data)

Open file before first write.

target = 'file'
write(towrite, end='\n')

Write a string to the file.

Parameters:
  • towrite (string) – The string to output to the file.

  • end (string, optional) – Appended to towrite when writing, can be used to print a new line after the input towrite.

Returns:

status (boolean) – True if we managed to write, False otherwise.

Note

A write that fails on I/O (a full disk, a quota, a failing device) raises. No caller inspects the returned status, so an absorbed error would let the run report success with a truncated output file.

pyretis.inout.fileio.read_some_lines(filename, line_parser, block_label='#')

Open a file and try to read as many lines as possible.

This method will read a file using the given line_parser. If the given line_parser fails at a line in the file, read_some_lines will stop here. Further, this method will read data in blocks and yield a block when a new block is found. A special string (block_label) is assumed to identify the start of blocks.

Parameters:
  • filename (string) – This is the name/path of the file to open and read.

  • line_parser (function, optional) – This is a function which knows how to translate a given line to a desired internal format. If not given, a simple float will be used.

  • block_label (string, optional) – This string is used to identify blocks.

Yields:

data (list) – The data read from the file, arranged in dicts.

pyretis.inout.restart module

This module defines how we write and read restart files.

Important methods defined here

read_restart_file (read_restart_file())

A method for reading restart information from a file.

write_restart_file (write_restart_file())

A method for writing the restart file.

write_ensemble_restart (write_ensemble_restart())

A method for writing restart files for path ensembles.

pyretis.inout.restart.load_system_restart(system, info)

Restore System state from a restart-info dict.

Equivalent to the soon-to-go System.load_restart_info(info) method on the harness System.

Parameters:
pyretis.inout.restart.read_restart_file(filename)

Read restart info for a simulation.

Parameters:

filename (string) – The file we are going to read from.

pyretis.inout.restart.system_restart_info(system)

Collect restart info for a System (free-function form).

Equivalent to the soon-to-go System.restart_info() method on the harness System. Returns the same dict shape; works on any System with the bridge surface (units, temperature, post_setup, order, box, particles).

Parameters:

system (object like System) – The system whose state to serialise.

Returns:

dict – Restart-info dictionary.

pyretis.inout.restart.write_ensemble_restart(ensemble, settings_ens)

Write a restart file for a path ensemble.

Parameters:
  • ensemble (dict) – it contains:

    • path_ensemble : object like PathEnsemble The path ensemble we are writing restart info for.

    • ` system` : object like System System is used here since we need access to the temperature and to the particle list.

    • order_function : object like OrderParameter The class used for calculating the order parameter(s).

    • engine : object like EngineBase The engine to use for propagating a path.

  • settings_ens (dict) – A dictionary with the ensemble settings.

pyretis.inout.restart.write_restart_file(filename, simulation)

Write restart info for a simulation.

Parameters:
  • filename (string) – The file we are going to write to.

  • simulation (object like Simulation) – A simulation object we will get information from.

pyretis.inout.screen module

Module defining the base classes for the PyRETIS output.

Important classes defined here

ScreenOutput (FileIO)

A generic class for handling output to the screen.

Important constants defined here

PROGRESSint

Custom log level (25) between INFO (20) and WARNING (30). Used for user-facing progress messages (green on console).

BANNERint

Custom log level (26) between PROGRESS (25) and WARNING (30). Used for decorative/banner text (cyan on console): logo, version info, references.

REPORTint

Custom log level (29) between SUCCESS (28) and WARNING (30). Used for generated analysis report blocks (plain console text).

class pyretis.inout.screen.ScreenOutput(formatter)

Bases: OutputBase

A class for handling output to the screen.

target = 'screen'
write(towrite, end=None)

Write a string to the file.

Parameters:
  • towrite (string) – The string to output to the file.

  • end (string, optional) – Override how the print statements ends.

Returns:

status (boolean) – True if we managed to write, False otherwise.

pyretis.inout.settings module

This module handles parsing of input settings.

This module defines the file format for PyRETIS input files.

Important methods defined here

parse_settings_file (parse_settings_file())

Method for parsing settings from a given input file.

write_settings_file (write_settings_file())

Method for writing settings from a simulation to a given file.

pyretis.inout.settings.DEFAULT_MAXLENGTH = 20000

the maximum number of steps a generated path may reach before it is rejected as too long.

The value is deliberately GENEROUS. A cap that is too small biases the sampled path-length distribution (paths that would legitimately be longer are rejected instead of sampled), so erring high costs some CPU on runaway trajectories while erring low would corrupt the result – and a wrong result is the one outcome this code must never produce silently. 20000 is the larger of the two values the shipped examples use, so a defaulted run is at least as permissive as the reference setups. Runs that fall back to it say so in the log, and the effective value is echoed to the resolved settings file.

Type:

The [tis] maxlength used when an input does not set one

pyretis.inout.settings.PATH_SAMPLING_TASKS = frozenset({'explore', 'pptis', 'repptis', 'retis', 'tis'})

The [simulation] task values of a path-sampling run, which pyretis run runs with the scheduler. The scheduler gives every ensemble the settings of the general sections.

pyretis.inout.settings.POOL_ENGINE_SECTION = re.compile('engine[1-9][0-9]*')

The name of a numbered engine section of an engine pool, beside [engine] and [engine0]: engine1, engine2, … [simulation] ensemble_engines names the sections each ensemble runs with. Such a section holds the keyword arguments of its engine class, as [engine] does, and the parse adds no default to it.

pyretis.inout.settings.add_default_settings(settings)

Add default settings.

Parameters:

settings (dict) – The current input settings.

Returns:

None, but this method might add data to the input settings.

pyretis.inout.settings.add_specific_default_settings(settings)

Add specific default settings for each simulation task.

Parameters:

settings (dict) – The current input settings.

Returns:

None, but this method might add data to the input settings.

pyretis.inout.settings.fill_up_tis_and_retis_settings(settings)

Make the life of sloppy users easier.

The full input set-up will be here completed.

Parameters:

settings (dict) – The current input settings.

Returns:

None, but this method might add data to the input settings.

pyretis.inout.settings.is_pool_engine_section(name)

Tell whether a section name is a numbered engine section of a pool.

Parameters:

name (string) – The name of a section of the input.

Returns:

boolean – True for engine1, engine2, … (POOL_ENGINE_SECTION).

pyretis.inout.settings.parse_settings_dict(raw, add_default=True, refuse_without_effect=True, legacy_keys=None)

Parse settings from the dict a canonical TOML input holds.

The dict goes through the pipeline of parse_settings_toml(), so a dict read from a file gives the settings of that file.

Parameters:
  • raw (dict) – The document of a canonical TOML input, as tomllib reads it. Its sections may be changed in place.

  • add_default (boolean) – If True, we will add default settings as well for keywords not found in the input.

  • refuse_without_effect (boolean) – If True, as for a TOML input, a key the dict gives that takes no effect on its run is refused (pyretis.inout.key_table.NO_EFFECT). The reader of a run file (pyretis.inout.run_record) passes False to find such keys in a run file written before the parse refused them.

  • legacy_keys (dict, optional) – For the canonical form of an input of the legacy-runner schema, the dotted key of that input of each canonical input key its conversion places under another name (pyretis.inout.config_adapter.legacy_input_keys()). The refusal of a key without effect names that key after the canonical one.

Returns:

settings (dict) – A dictionary with settings for PyRETIS.

Raises:

ValueError – If refuse_without_effect is True and the dict gives a key that takes no effect on its run.

pyretis.inout.settings.parse_settings_file(filename, add_default=True)

Parse settings from a file name.

Dispatches on the file extension: .toml uses the canonical TOML reader; anything else (typically .rst) falls back to the legacy rst parser.

Parameters:
  • filename (string) – The file to parse.

  • add_default (boolean) – If True, we will add default settings as well for keywords not found in the input.

Returns:

settings (dict) – A dictionary with settings for PyRETIS.

pyretis.inout.settings.parse_settings_rst(filename, add_default=True, refuse_without_effect=False)

Parse settings from the legacy .rst PyRETIS input format.

Deprecated since version The: rst input format is deprecated in favour of TOML and will be removed in a future release. This reader still works so existing scripts keep running; to silence the warning, run python -m pyretis.tools.convert_settings YOUR.rst and switch your workflow to the resulting .toml file.

Parameters:
  • filename (string) – The file to parse.

  • add_default (boolean) – If True, we will add default settings as well for keywords not found in the input.

  • refuse_without_effect (boolean) – If True, as the TOML parse does, a key the input gives that takes no effect on its run is refused (pyretis.inout.key_table.NO_EFFECT). pyretis run parses an rst input this way before it routes the input (pyretis.bin.pyretisrun.legacy_input_path_sampling_task()).

Returns:

settings (dict) – A dictionary with settings for PyRETIS.

Raises:

ValueError – If refuse_without_effect is True and the input gives a key that takes no effect on its run.

pyretis.inout.settings.parse_settings_toml(filename, add_default=True)

Parse settings from a canonical .toml input file.

The TOML schema mirrors the rst section layout one-to-one: each rst section is a TOML table of the same name; sections that can repeat (potential, collective-variable, ensemble) are TOML arrays-of-tables; hyphenated keys (order-file, trajectory-file …) are emitted with quoted keys.

The returned dict has the same shape as parse_settings_rst(), so downstream PyRETIS code does not need to know which frontend was used.

A key the input gives that takes no effect on its run is refused (pyretis.inout.key_table.NO_EFFECT).

Parameters:
  • filename (string) – The TOML file to parse.

  • add_default (boolean) – If True, we will add default settings as well for keywords not found in the input.

Returns:

settings (dict) – A dictionary with settings for PyRETIS.

Raises:

ValueError – If the input gives a key that takes no effect on its run; the message names the key, and the key to set instead when one sets what it would set.

pyretis.inout.settings.settings_to_toml_dict(settings)

Project a settings dict onto a TOML-serialisable shape.

  • drops the decorative heading section

  • drops None-valued keys recursively

  • coerces integer dict keys to strings (TOML keys must be strings; see _stringify_int_keys() for why this is round-trip safe)

  • preserves SPECIAL_MULTIPLE sections as lists of dicts so tomli_w emits them as arrays-of-tables ([[potential]]).

pyretis.inout.settings.write_settings_file(settings, outfile, backup=True)

Write simulation settings to an output file.

Dispatches on the output extension: .toml writes the canonical TOML schema; anything else writes the legacy rst.

Parameters:
  • settings (dict) – The dictionary to write.

  • outfile (string) – The file to create.

  • backup (boolean, optional) – If True, we will backup existing files with the same file name as the provided file name.

Note

This will currently fail if objects have made it into the supplied settings.

pyretis.inout.settings.write_settings_rst(settings, outfile, backup=True)

Write settings to a file in the legacy rst PyRETIS format.

pyretis.inout.settings.write_settings_toml(settings, outfile, backup=True)

Write settings to a file in the canonical TOML schema.

The schema mirrors the rst section layout one-to-one. None values are dropped (the parser refills defaults). The decorative heading section is dropped.

pyretis.inout.simulationio module

Definition of a class for handling output related to simulations.

Important classes defined here

Task (Task)

Base class for tasks. This is used by SimulationTask and OutputTask.

OutputTask (OutputTask)

A class representing a simulation output task.

Important methods defined here

get_task_type (get_task_type())

Do additional handling for a path task.

get_file_mode (get_file_mode())

Determine if we should append or backup existing files.

task_from_settings (task_from_settings())

Create output task from simulation settings.

Important variables defined here

OUTPUT_TASKS (OUTPUT_TASKS)

A dictionary defining the different output tasks known to PyRETIS.

pyretis.inout.simulationio.OUTPUT_TASKS = {'cross': {'filename': 'cross.txt', 'formatter': <class 'pyretis.inout.formats.cross.CrossFormatter'>, 'result': ('cross',), 'target': 'file', 'when': 'cross-file'}, 'energy': {'filename': 'energy.txt', 'formatter': <class 'pyretis.inout.formats.energy.EnergyFormatter'>, 'result': ('thermo',), 'target': 'file', 'when': 'energy-file'}, 'order': {'filename': 'order.txt', 'formatter': <class 'pyretis.inout.formats.order.OrderFormatter'>, 'result': ('order',), 'target': 'file', 'when': 'order-file'}, 'path-energy': {'filename': 'energy.txt', 'formatter': <class 'pyretis.inout.formats.energy.EnergyPathFormatter'>, 'result': ('path', 'status'), 'target': 'file', 'when': 'energy-file'}, 'path-order': {'filename': 'order.txt', 'formatter': <class 'pyretis.inout.formats.order.OrderPathFormatter'>, 'result': ('path', 'status'), 'target': 'file', 'when': 'order-file'}, 'pathensemble': {'filename': 'pathensemble.txt', 'formatter': <class 'pyretis.inout.formats.pathensemble.PathEnsembleFormatter'>, 'result': ('pathensemble',), 'target': 'file', 'when': 'pathensemble-file'}, 'pathensemble-retis-screen': {'formatter': <class 'pyretis.inout.formats.txt_table.RETISResultFormatter'>, 'result': ('pathensemble',), 'target': 'screen', 'when': 'screen'}, 'pathensemble-screen': {'formatter': <class 'pyretis.inout.formats.txt_table.PathTableFormatter'>, 'result': ('pathensemble',), 'target': 'screen', 'when': 'screen'}, 'thermo-file': {'filename': 'thermo.txt', 'formatter': <class 'pyretis.inout.formats.txt_table.ThermoTableFormatter'>, 'result': ('thermo',), 'target': 'file', 'when': 'energy-file'}, 'thermo-screen': {'formatter': <class 'pyretis.inout.formats.txt_table.ThermoTableFormatter'>, 'result': ('thermo',), 'target': 'screen', 'when': 'screen'}, 'traj-txt': {'filename': 'traj.txt', 'formatter': <class 'pyretis.inout.formats.snapshot.SnapshotFormatter'>, 'result': ('system',), 'target': 'file', 'when': 'trajectory-file'}, 'traj-xyz': {'filename': 'traj.xyz', 'formatter': <class 'pyretis.inout.formats.snapshot.SnapshotFormatter'>, 'result': ('system',), 'target': 'file', 'when': 'trajectory-file'}}

Define a set of known output tasks.

The output tasks are defined as dictionaries with the following keys:

  • targetstring

    “file” or “screen”, defines where the task writes to.

  • filenamestring

    A default file name for an output file if writing to a file.

  • resulttuple of strings

    Determines what item from the result dictionary we are outputting.

  • whenstring

    Determines what input setting from the “output” section is used to define the output frequency. Default values are defined by the output section, see: py:mod:pyretis.inout.settings.settings.

  • formatterobject like OutputFormatter

    Selects the formatter for the output.

  • writerobject like OutputBase

    Selects the writer for the output.

  • settingstuple of strings, optional

    A dict with additional settings which can be passed to the formatter if needed. These settings can, for instance, be defined in the output section of the input file.

The writer can be defined explicitly, or via the formatter. If a formatter is given, then the generic FileIO will be used. If no formatter is given, then the writer is assumed to be given.

class pyretis.inout.simulationio.OutputTask(name, result, writer, when)

Bases: Task

A base class for simulation output.

This class will handle an output task for a simulation. The output task consists of one object which is responsible for formatting the output data and one object which is responsible for writing that data, for instance to the screen or to a file.

Variables:
  • target (string) – This string identifies what kind of output we are dealing with. This will typically be either “screen” or “file”.

  • name (string) – This string identifies the task, it can, for instance, be used to reference the dictionary for creating the writer.

  • result (tuple of strings) – This string defines the result we are going to output.

  • writer (object like OutputBase) – This object will handle the actual outputting of the result.

  • when (dict) – Determines if the task should be executed.

__init__(name, result, writer, when)

Initialise the generic output task.

Parameters:
  • name (string) – This string identifies the task, it can, for instance, be used to reference the dictionary for creating the writer.

  • result (list of strings) – These strings define the results we are going to output.

  • writer (object like IOBase) – This object will handle formatting of the actual result and output to screen or to a file.

  • when (dict) – Determines when the output should be written. Example: {‘every’: 10} will be executed at every 10th step.

__str__()

Print information about the output task.

output(simulation_result)

Output given results from simulation steps.

This will output the task using the result found in the simulation_result which should be the dictionary returned from a simulation object (e.g. object like Simulation) after a step.

Parameters:

simulation_result (dict) – This is the result from a simulation step.

Returns:

out (boolean) – True if the writer wrote something, False otherwise.

task_dict()

Return a dict with info about the task.

class pyretis.inout.simulationio.Task(when)

Bases: object

Base representation of a “task”.

A task is just something that is supposed to be executed at a certain point. This class will just set up functionality that is common for output tasks and for simulation tasks.

Variables:

when (dict) – Determines when the task should be executed.

__init__(when)

Initialise the task.

Parameters:

when (dict, optional) – Determines if the task should be executed.

execute_now(step)

Determine if a task should be executed.

Parameters:

step (dict of ints) – Keys are ‘step’ (current cycle number), ‘start’ cycle number at start ‘stepno’ the number of cycles we have performed so far.

Returns:

out (boolean) – True of the task should be executed.

task_dict()

Return basic info about the task.

property when

Return the “when” property.

pyretis.inout.simulationio.get_file_mode(settings)

Determine if we should append or backup existing files.

This method translates the backup settings into a file mode string. We assume here that the file is opened for writing.

Parameters:

settings (dict) – The simulation settings.

Returns:

file_mode (string) – A string representing the file mode to use.

pyretis.inout.simulationio.get_task_type(task, engine)

Do additional handling for a path task.

The path task is special since we do very different things for external paths. The set-up required to do this is handled here.

Parameters:
  • task (dict) – Settings related to the specific task.

  • engine (object like EngineBase) – This object is used to determine if we need to do something special for external engines. If no engine is given, we do not do anything special.

Returns:

out (string) – The task type we are going to be creating for.

pyretis.inout.simulationio.task_from_settings(task, settings, directory, engine, progress=False)

Create output task from simulation settings.

Parameters:
  • task (dict) – Settings for creating a task. This dict contains the type and name of the task to create. It can also contain overrides to the default settings in OUTPUT_TASKS.

  • settings (dict) – Settings for the simulation.

  • directory (string) – The directory to write output files to.

  • engine (object like EngineBase) – This object is used to determine if we need to do something special for external engines. If no engine is given, we do not do anything special.

  • progress (boolean, optional) – For some simulations, the user may select to display a progress bar. We will then just disable the other screen output.

Returns:

out (object like OutputTask) – An output task we can use in the simulation.

pyretis.inout.checker module

This module checks that the inputs are meaningful.

Main methods defined here

check_ensemble (check_ensemble())

Function to check the ensemble settings.

check_interfaces (check_interfaces())

Function to check the number and the order of the interfaces.

check_for_bullshitt (check_for_bullshitt())

Function to compare nested dicts and lists.

check_engine (check_engine())

Function to check engine set-up.

zero_left_interface (zero_left_interface())

Function to read the lambda_{-1} interface, if one is set.

is_single_tis (is_single_tis())

Function to say whether a run is a single TIS run.

tis_ensemble_number (tis_ensemble_number())

Function to read the [tis] ensemble_number a run reads.

ensemble_layout (ensemble_layout())

Function to read which of the [0^-] and [0^+] windows a run builds.

interface_count_problem (interface_count_problem())

Function to describe a run with too few interfaces for its task.

check_layout_settings (check_layout_settings())

Function to check that the task builds the ensembles of an input.

pptis_layout (pptis_layout())

Function to read which optional windows a PPTIS run builds.

pptis_layout_problem (pptis_layout_problem())

Function to describe a PPTIS window layout that is refused.

pyretis.inout.checker.check_engine(settings)

Check the engine settings.

Checks that the input engine settings are correct, and automatically determine the ‘internal’ or ‘external’ engine setting.

Parameters:

settings (dict) – The current input settings.

pyretis.inout.checker.check_ensemble(settings)

Check that the ensemble input parameters are complete.

Parameters:

settings (dict) – The settings needed to set up the simulation.

pyretis.inout.checker.check_for_bullshitt(settings)

Do what is stated.

Just for the input settings.

Parameters:

settings (dict) – The current input settings.

pyretis.inout.checker.check_interfaces(settings)

Check the number and the order of the interfaces.

The number a task needs comes from interface_count_problem(), and the interfaces of a retis, tis, repptis or pptis run are in ascending order.

Parameters:

settings (dict) – The current input settings.

Returns:

out (boolean) – False, after a critical log line that says why, when there are too few interfaces or they are not in ascending order, and True otherwise.

pyretis.inout.checker.check_layout_settings(settings)

Check that the task builds the ensembles of an input.

The ensembles are built from the interfaces, so a run with fewer interfaces than its task needs (interface_count_problem()) is refused. [tis] ensemble_number is refused when it is not an integer, and a task other than tis, which does not read it (tis_ensemble_number()), logs a warning that names it (_check_ensemble_number()). make-tis-files writes one single TIS input per [i^+] ensemble, the [0^+] only with zero_ensemble = true, and a single TIS window starts at its left interface, so it refuses the [0^-] that flux = true or zero_left asks for.

Parameters:

settings (dict) – The input settings, with the [simulation] section and, when the input has one, the [tis] section.

Raises:

ValueError – If a run has fewer interfaces than its task needs, the [tis]     ensemble_number is not an integer, or a make-tis-files task sets flux = true or zero_left.

pyretis.inout.checker.ensemble_layout(settings)

Say which of the [0^-] and [0^+] windows a run builds.

The kick initiation (pyretis.inout.common.create_empty_ensembles() and pyretis.setup.createsimulation.create_ensembles()) builds one ensemble per window named here, followed by the body ensembles [1^+], [2^+], …, as the scheduler’s pyretis.simulation.repex.InfSwapState.initiate_ensembles() does. Per task:

  • pptis: the layout pptis_layout() gives.

  • explore: the [0^+], and no [0^-].

  • tis: neither window for a single TIS run (is_single_tis()), whose one ensemble is the window of its three interfaces, numbered by tis_ensemble_number() (2 when the input sets no [tis] ensemble_number), and for a tis input with [tis] ensemble_number and two, or four or more interfaces, which has the one ensemble of that number (the window [lambda_0, lambda_1, lambda_last] with four or more interfaces); the scheduler adapter refuses to run such an input. Both windows for a tis run with two, or four or more interfaces and no ensemble number, whose ensembles the scheduler samples as a RETIS run without swaps.

  • make-tis-files: the [0^+] when zero_ensemble is true, and no [0^-] (check_layout_settings() refuses one). The settings parser gives zero_ensemble = false to an input that does not set it (pyretis.inout.settings.add_specific_default_settings()); a [simulation] section without the key counts as true here.

  • retis, repptis and every other task: both windows.

Call it with the global settings. Each per-ensemble dict holds the three interfaces of its own window and its own ensemble_number.

The tuple says which windows exist. The number of a kick ensemble names its directory, and the scheduler writes the window to the directory of the same name (pyretis.inout.archive_paths.output_ensemble_number()). The kick ensembles of a pptis run are numbered from 0 in the layout pptis_layout() gives, so that ensemble i is the window of scheduler slot i. Those of every other task keep their numbers in the full layout (pyretis.core.pathensemble.FULL_LAYOUT, where 0 is the [0^-], 1 the [0^+] and i + 1 the [i^+]): the one ensemble of a tis run is number 2 or its [tis] ensemble_number, and the explore ensembles are 1, 2, …. pyretis.core.pathensemble.PathEnsemble and pyretis.core.pathensemble.ensemble_label() are given the layout the number counts in (pyretis.setup.createsimulation.create_ensemble()).

Parameters:

settings (dict) – The input settings, with the [simulation] section and, when the input has one, the [tis] section.

Returns:

  • out[0] (boolean) – Whether the run builds the [0^-] window.

  • out[1] (boolean) – Whether the run builds the [0^+] window.

pyretis.inout.checker.interface_count_problem(simulation)

Describe a run with too few interfaces for its task, if this is one.

A run needs the interfaces of at least one ensemble. A tis or retis run needs two interfaces, and a pptis or repptis run three (MIN_INTERFACES). An explore run samples no [0^-], and needs two interfaces for the [0^+] [lambda_0, lambda_0, lambda_last], the lowest ensemble it samples. A make-tis-files run needs two when it writes the input of the [0^+] (zero_ensemble true, as ensemble_layout() reads it), and otherwise three, for the [1^+] [lambda_0, lambda_1, lambda_last], the lowest ensemble it writes an input for. The settings parser gives zero_ensemble = false to a make-tis-files input that does not set it (pyretis.inout.settings.add_specific_default_settings()). check_layout_settings(), check_for_bullshitt() and check_interfaces() take the rule and the message from this function.

Parameters:

simulation (dict) – The [simulation] section of the input settings.

Returns:

out (string or None) – The refusal message, which names the task, the number of interfaces the input gives and the number the task needs, or None when there is nothing to refuse.

pyretis.inout.checker.is_single_tis(simulation)

Say whether a run is a single TIS run.

A task = "tis" run with three interfaces samples one ensemble, and the three interfaces are its left, middle and right interfaces. The scheduler adapter (pyretis.inout.config_adapter.to_scheduler_config()) and ensemble_layout() take the rule from this function.

Parameters:

simulation (dict) – The [simulation] section of the input settings.

Returns:

out (boolean) – True for a tis task with three interfaces.

pyretis.inout.checker.pptis_layout(simulation)

Say which of the optional PPTIS windows a run builds.

A pptis run has a [0^-] only when zero_left or flux is set, and a [0^+] only when zero_ensemble is. Here zero_left counts as set whenever it is present and not False. For every other task this returns both windows. The scheduler adapter (pyretis.inout.config_adapter.to_scheduler_config()), the settings check, the analysis and pyretis.setup.createsimulation.create_ensemble(), which gives a path ensemble the layout its number counts in and keeps the start side of ensemble 0 of a pptis or repptis run when the layout has a [0^-], read the pptis layout from this function. The windows the kick initiation builds for every task come from ensemble_layout(), which takes the pptis layout from here.

Parameters:

simulation (dict) – The [simulation] section of the input settings.

Returns:

  • out[0] (boolean) – Whether the layout includes the minus window.

  • out[1] (boolean) – Whether the layout includes the [0^+] window.

pyretis.inout.checker.pptis_layout_problem(has_minus, has_zero_plus)

Describe a refused PPTIS window layout, if this is one.

A minus window without a [0^+] is refused. The flux through lambda_0 combines the path lengths of the two windows, and the rate and the permeability take that flux. The scheduler’s initiate_ensembles builds the [0^+] whenever the layout has a minus window, while the analysis numbers the directories by the windows the settings ask for, so the two would read one directory as two different windows. The message names flux = true together with zero_ensemble = true, which build the minus window and the [0^+] whether or not zero_left is given, and says that a zero_left that is given bounds the minus window.

Serves every check of a PPTIS layout: the canonical settings parser here, the coordinator’s check_config, the analysis in pyretis.inout.analysisio.analysisio.get_path_simulation_files(), and the ensemble labels in pyretis.core.pathensemble.ensemble_label(). All of them take the rule and the wording from this function.

Parameters:
  • has_minus (boolean) – Whether the layout includes the minus window.

  • has_zero_plus (boolean) – Whether the layout includes the [0^+] window.

Returns:

out (string or None) – The refusal message, or None when there is nothing to refuse.

pyretis.inout.checker.reread_quietly()

Parse settings that a run has read once, without the keyword warning.

A run record reads the settings of a run again from the sections it stores (pyretis.inout.run_record). Inside this context the parse logs no warning for a [tis] ensemble_number that the task ignores, so a run or an analysis warns once, when it reads its input.

Yields:

None

pyretis.inout.checker.tis_ensemble_number(settings)

Return the [tis] ensemble_number a run reads, or None.

A task = "tis" run reads the keyword as the number of its one ensemble, for any number of interfaces. For a single TIS run (is_single_tis()) the ensemble is the window of its three interfaces, and the scheduler adapter (pyretis.inout.config_adapter.to_scheduler_config()) names the directory of the ensemble with the number. A tis input with two, or four or more interfaces and the keyword, the PyRETIS 3 form of a single TIS input, is read as the one ensemble of that number as well: pyretis.inout.common.create_empty_ensembles() builds it, and pyretis analyse reads its directory. With four or more interfaces, pyretis.setup.createsimulation.create_ensembles() gives it the window [lambda_0, lambda_1, lambda_last]. The scheduler samples every window of those interfaces, so the scheduler adapter refuses to run such an input. Every other task samples every ensemble it builds from its interfaces, or writes an input for each (make-tis-files), and reads no ensemble number from [tis]; check_layout_settings() logs a warning for a keyword that the task does not read.

Parameters:

settings (dict) – The input settings, with the [simulation] section and, when the input has one, the [tis] section.

Returns:

out (object or None) – The [tis] ensemble_number of a tis run, and None for every other task and for a tis run without the keyword.

pyretis.inout.checker.zero_left_interface(simulation)

Return the zero_left interface, or None when it is not set.

zero_left is a position on the order parameter, and 0.0 is a valid one. The settings mark it unset with None (the default) or False, so those two values, and only they, mean that no lambda_{-1} interface is given.

Parameters:

simulation (dict) – The [simulation] section of the input settings.

Returns:

out (float or None) – The lambda_{-1} interface, or None.

pyretis.inout.archive_paths module

Central construction of the scheduler’s trajectory-archive paths.

The infinite-swapping scheduler keeps its live accepted trajectories in a per-path archive: one subdirectory per global path number, holding the trajectory files plus the order.txt / energy.txt a resume reloads from. To keep the run’s output a single canonical tree, that archive lives inside the per-ensemble output directories, nested under each path’s birth ensemble (the ens_save_idx fixed when the path is first created and carried, swap-invariant, for its lifetime):

<ens_save_idx>/<subdir>/<path_number>/...

where <subdir> is the [simulation] load_dir name (default accepted) and the path directory holds the order.txt / energy.txt / traj.txt and the trajectory frames flat (no inner accepted/ subfolder). Nesting by the birth ensemble (rather than the current one) keeps a swap a zero-copy bookkeeping change – the swap-invariant anchor is the birth ensemble, so no trajectory file ever moves between ensemble directories.

The per-ensemble archive is the run’s OPERATIONAL store: it holds the live (active) paths at <ensemble>/<load_dir>/<pn>. A path that has been replaced everywhere moves to the per-ensemble LONG-TERM store (LONG_TERM_DIR, <ensemble>/archive/<pn> – the sibling of the operational store under the SAME birth ensemble, so the move is a same-directory rename) via long_term_path_dir(), thinned to the [output] archive_every cadence.

Routing every construction site (writer, eviction mover, restart reader, restart-viability check, initial seeding) through archive_root() / path_dir() gives a single seam. Passing ens_save_idx=None yields the legacy flat <subdir>/<path_number> layout, which the restart reader falls back to for an output.toml written before the per-ensemble nesting (its persisted load_dir is then the old top-level store name).

pyretis.inout.archive_paths.ARCHIVE_SUBDIR = 'accepted'

The default name of the per-ensemble trajectory-archive subdirectory ([simulation] load_dir). Single source for the 'accepted' literal; every construction site imports it from here. Runs recorded under a previous default (paths or trajs) keep working: the run file persists its own load_dir, which takes precedence over this default on restart.

pyretis.inout.archive_paths.LONG_TERM_DIR = 'archive'

The per-ensemble long-term trajectory store’s subdirectory name. A path that has been replaced in every ensemble is MOVED here from its operational per-ensemble store (<ens>/<load_dir>/<pn> -> <ens>/archive/<pn>, a same-parent rename), thinned to the [output] archive_every cadence. Analysis never needs the moved files (it reads the per-ensemble text output); the long-term store is for the user.

pyretis.inout.archive_paths.REJECTED_DIR = 'rejected'

The per-ensemble store for rejected trials the user asked to keep ([output] keep_rejected_status). A rejected trial is normally discarded: the ensemble keeps its existing occupant and the trial’s frames are left in the worker scratch. Keeping the interesting ones makes a rare rejection inspectable after the fact, which moves.txt alone cannot do – it records THAT a move was rejected, not the trajectory that was rejected.

Rejected trials are NOT numbered: numbering happens on acceptance, so borrowing a path number here would collide with a live path and shift the sequence that appears in the output. They are named by the cycle and ensemble that produced them instead, which is also how a user looks one up.

pyretis.inout.archive_paths.STAGED_FRAMES_SUBDIR = 'accepted'

The subdirectory of a user-staged path directory that may hold its frames, <load_dir>/<pn>/accepted/<frame>. The loader reads a frame from there when it is not beside traj.txt (pyretis.core.path_load.load_path()), and the archive links such a frame into the archive directory of a path that names it (pyretis.inout.scheduler_archive._place_frame()).

pyretis.inout.archive_paths.archive_root(config, ens_save_idx=None, base='', subdir=None)

Return the directory the per-path archive subdirectories live under.

Parameters:
  • config (dict) – The scheduler config; config['simulation']['load_dir'] names the per-ensemble archive subdirectory (default accepted). A non-default config['output']['data_dir'] re-roots the per-ensemble output directories (see pyretis.inout.pathensemble_output. _ensemble_dirs()), and the nested archive follows it – the archive lives INSIDE those directories. The legacy flat layout predates data_dir support and stays relative to the run directory.

  • ens_save_idx (int, optional) – The birth ensemble the path archive nests under. None selects the legacy flat layout (just the subdirectory, no ensemble parent).

  • base (str, optional) – A directory to resolve the (relative) root against – callers that need an absolute archive root pass the run directory (e.g. os.getcwd()); the default leaves the root relative.

  • subdir (str, optional) – The per-ensemble subdirectory name. None uses the operational store’s load_dir (default accepted); the long-term store passes LONG_TERM_DIR so replaced paths nest as <ensemble>/archive/<pn> beside the live <ensemble>/accepted/<pn>.

Returns:

str – The archive root directory.

pyretis.inout.archive_paths.is_ensemble_dir_name(name)

Tell whether a name is the name of an ensemble directory.

An ensemble directory is named by its ensemble number, written by pyretis.core.pathensemble.generate_ensemble_name(): three digits for the numbers below 1000 (000, 001, …), and the number itself from 1000 on.

Parameters:

name (str) – The name to test.

Returns:

out (boolean) – True when generate_ensemble_name writes name for an ensemble number.

pyretis.inout.archive_paths.long_term_path_dir(config, path_number, ens_save_idx=None, base='')

Return a path’s directory in the long-term store.

The long-term store is per-ensemble, nested under the path’s birth ensemble exactly like the operational store: a replaced path moves from <ensemble>/<load_dir>/<pn> to <ensemble>/archive/<pn> – a same-directory rename (guaranteed same-filesystem, no cross-device copy). A legacy flat-layout path (ens_save_idx=None) uses the flat archive/<pn> at the run root.

Parameters:
  • config (dict) – The scheduler config (locates the per-ensemble output dirs; see archive_root()).

  • path_number (int or str) – The global path number keying the store subdirectory.

  • ens_save_idx (int, optional) – The path’s birth ensemble; None selects the flat run-root layout.

  • base (str, optional) – A directory to resolve the (relative) store against – callers that need an absolute location pass the run directory; the default leaves it relative.

Returns:

str – <base>/<ensemble>/archive/<path_number> (or the flat <base>/archive/<path_number> for a legacy path).

pyretis.inout.archive_paths.move_to_long_term(config, path_number, ens_save_idx=None, base='')

Move a replaced path from the operational archive to long-term.

Called when a path has been replaced in every ensemble: its whole archive directory (text files + accepted/ trajectory frames) moves from the per-ensemble operational store <ensemble>/<load_dir>/<pn> to the per-ensemble long-term store <ensemble>/archive/<pn> (a same-parent rename), keeping the operational store bounded to the live paths without losing sampled trajectories.

The source is resolved through resolve_path_dir(), so a legacy-flat-layout path moves from its actual location. A missing source (e.g. an in-memory internal-engine path that never wrote trajectory files, or a directory already moved by a replayed cycle after a restart) is a no-op, not an error – the move is bookkeeping, never load-bearing for the sampling. An existing destination (a replayed cycle) is replaced, keeping the operation idempotent.

Parameters:
  • config (dict) – The scheduler config (locates the operational archive).

  • path_number (int or str) – The global path number to move.

  • ens_save_idx (int, optional) – The path’s birth ensemble (see archive_root()).

  • base (str, optional) – The run directory to resolve both stores against.

Returns:

str or None – The destination directory when the path was moved; None when there was nothing to move.

pyretis.inout.archive_paths.output_ensemble_number(config, ens_save_idx)

Map a birth-ensemble slot to its output ensemble number.

The per-ensemble output directories are numbered by route, and the trajectory archive nests under the SAME directory as a slot’s analysis logs (see pyretis.inout.pathensemble_output._ensemble_dirs()): an explore run’s positive ensembles are 1-based (slot j -> j+1, no 000); a single_tis run’s one ensemble is named by its interface number; every other route maps slot j -> j.

Parameters:
  • config (dict) – The scheduler config; its [simulation] route flags select the numbering.

  • ens_save_idx (int) – The birth-ensemble slot (0-based coordinator index).

Returns:

int – The output ensemble number to name the archive directory with.

pyretis.inout.archive_paths.path_dir(config, path_number, ens_save_idx=None, base='')

Return the archive directory for a single path.

Parameters:
  • config (dict) – The scheduler config.

  • path_number (int or str) – The global path number keying the archive subdirectory.

  • ens_save_idx (int, optional) – The birth ensemble to nest under (see archive_root()).

  • base (str, optional) – Resolved through archive_root() (see there).

Returns:

str – <archive_root>/<path_number>.

pyretis.inout.archive_paths.resolve_path_dir(config, path_number, ens_save_idx=None, base='')

Locate an EXISTING path archive, honouring the legacy flat layout.

path_dir() constructs where a path’s archive belongs under the current (nested, per-ensemble) layout; this function resolves where an existing path actually IS. The two differ for runs whose paths live in the legacy flat top-level <load_dir>/<path_number> store: a user-staged flat load directory (the upstream staging contract) read by a fresh run, or a run recorded before the per-ensemble nesting. Such a legacy run’s paths never move – even after a resume stamps a [current] ens_save_idx for them – so the fallback must apply whenever the nested directory is absent, not only when the birth ensemble is unknown.

Every reader of an existing archive (the restart loader, the restart-viability check, the eviction mover) resolves through this function, so they all agree on the location.

Parameters:
  • config (dict) – The scheduler config.

  • path_number (int or str) – The global path number keying the archive subdirectory.

  • ens_save_idx (int, optional) – The birth ensemble the nested layout files under (see archive_root()). None selects the flat layout directly.

  • base (str, optional) – Resolved through archive_root() (see there).

Returns:

str – The nested archive directory when it exists (or when neither layout does – so a missing path is reported at its canonical location); the flat legacy directory when only that one exists.

pyretis.inout.staged_paths module

Initial paths staged for a fresh scheduler run, and the run’s copies.

A user stages an initial path for a fresh scheduler run in the flat <load_dir>/<path number> of the run directory. That directory is input: the load of the run reads the path from it and keeps its own copy of the path in the path’s archive directory, <ensemble>/<load_dir>/ <path number> of its birth ensemble (see pyretis.inout.archive_paths), where a restart reads it. The copy holds files of its own, and the run reads the frames of the path from the copy once it is made. An archive directory of an active path that stands there before the load makes the copy was left by an earlier run.

Important methods defined here

reads_staged_paths (reads_staged_paths())

Tell whether a load reads the paths the user staged.

reads_flat_store (reads_flat_store())

Tell whether a load reads its paths from the flat <load_dir>.

loaded_path_dir (loaded_path_dir())

The directory a load reads a path from.

left_copies (left_copies())

The archive directories an earlier run left for the active paths.

missing_staged_dirs (missing_staged_dirs())

The flat directories of the active paths that are missing.

archive_dirs (archive_dirs())

Pair each loaded path with its archive directory, copying a staged path there.

pyretis.inout.staged_paths.INITIATED_PATHS_KEY = 'initiated_paths'

The key of the scheduler config that is True when the caller has just generated the initial paths of a new simulation into the per-ensemble store, having refused before its initiation a run directory with files of an earlier run where the run reads or writes them (pyretis run, see pyretis.simulation.setup.refuse_before_initiation()). The load of such a run reads the paths without the checks of pyretis.simulation.setup.refuse_before_staged_load(). pyretis.bin.pyretisrun.run_infinite_swapping() sets it, and pyretis.simulation.setup.setup_internal() removes it before the config is written to the state file.

pyretis.inout.staged_paths._copy_files(source: str, target: str) → int

Copy the bytes of every file of one directory into another.

Each file is written anew in target (shutil.copyfile()); a symbolic link in source is copied as the file it points to.

Parameters:
  • source (str) – The directory whose files are copied. Its subdirectories are left out.

  • target (str) – The existing directory receiving them. It holds none of their names.

Returns:

out (int) – The number of bytes written into target: the sum of the sizes of the copies.

pyretis.inout.staged_paths._copy_staged_path(path_number: int, source: str, archive: str) → None

Copy a staged path directory into its archive directory in the run.

The files of source and those of its frame subdirectory accepted/ are copied into archive byte for byte (_copy_files()). The copy is a set of files of the run’s own: rewriting a staged file in place, as cp over an existing name or gmx trjconv writing the same name does, leaves it as it was. It takes as much disk space as the files it copies, and the log line of the copy gives their size in bytes.

Parameters:
  • path_number (int) – The number of the path.

  • source (str) – The directory the path was read from, which the user staged.

  • archive (str) – The archive directory of the path, which is created here.

pyretis.inout.staged_paths._frames_outside(path: Any, source: str) → list[str]

Return the frame files of a path outside its staged directory.

The loader names each frame of a staged path by its file in the path directory or in its frame subdirectory accepted/ (pyretis.core.path_load.load_path()), unless traj.txt names the file with a directory of its own.

Parameters:
  • path (object like Path) – The path read from source.

  • source (str) – The staged directory the path was read from.

Returns:

out (list of str) – The absolute names of the frame files in neither source nor source/accepted, each once, in the order of the phase points.

pyretis.inout.staged_paths._point_to_copy(path: Any, source: str, archive: str) → None

Name the frame files of the run’s copy in the phase points of a path.

The loader named each frame by its file in source or in its frame subdirectory accepted/, and _copy_staged_path() copies both under the same names into archive. Each phase point is given the file of the same name in archive, as a restart reads it, so the engines of the run and the archive of a path that shares a frame (pyretis.inout.scheduler_archive._place_frame()) read the run’s copy.

Parameters:
  • path (object like Path) – The path read from source; its phase points are changed in place.

  • source (str) – The staged directory the path was read from.

  • archive (str) – The archive directory holding the run’s copy of the path.

pyretis.inout.staged_paths.archive_dirs(config: dict[str, Any], paths: list[Any], birth_ensembles: dict[str, int] | None)

Pair each loaded path with its archive directory in the run.

The archive directory of a path is <ensemble>/<load_dir>/<pn> of its birth ensemble. A path read from another directory (loaded_path_dir()), a directory the user staged flat, is copied into it (_copy_staged_path()), and its frames are then read from the copy (_point_to_copy()). The birth ensemble, the frame files and the archive directory of every path are checked before the first copy is made, so a refusal leaves the run directory as it was.

Parameters:
  • config (dict) – The scheduler config of the load.

  • paths (list of objects like Path) – The loaded paths; None entries are skipped. The phase points of a path read from a staged directory are changed in place to name the frame files of the copy.

  • birth_ensembles (dict or None) – The birth ensemble of each path, keyed by its path number as a string; None takes [current] ens_save_idx.

Returns:

out (list of tuples) – Each path with its archive directory, in the order of paths.

Raises:
  • ValueError – If the birth ensemble of a path is not known, or if a path read from a staged directory names a frame file outside that directory and its frame subdirectory accepted/: the copy holds the files of these two directories.

  • FileExistsError – If a path was read from a staged directory and its archive directory exists already: it holds files an earlier run wrote. The message names every such directory, to be removed.

pyretis.inout.staged_paths.copy_staged_paths(config: dict[str, Any], paths: list[Any], birth_ensembles: dict[str, int] | None = None) → list[int]

Copy the paths a load read from staged directories into the run.

A path staged flat, <load_dir>/<pn>, is input. The run keeps its copy of the path in the path’s archive directory, where a restart reads it, and reads the frames of the path from the copy (archive_dirs()).

Parameters:
  • config (dict) – The scheduler config of the load.

  • paths (list of objects like Path) – The loaded paths; None entries are skipped.

  • birth_ensembles (dict, optional) – The birth ensemble of each path, keyed by its path number as a string; it names the path’s archive directory. The default is [current] ens_save_idx.

Returns:

out (list of int) – The sorted numbers of the paths, each held in its archive directory.

Raises:
  • ValueError – If the birth ensemble of a path is not known, or a staged path names a frame file outside its directory.

  • FileExistsError – If a staged path has an archive directory already. Either is raised before the first path is copied.

pyretis.inout.staged_paths.left_copies(config: dict[str, Any], base: str = '') → list[str]

Return the archive directories an earlier run left for the paths.

A load that reads the flat store (see reads_flat_store()) keeps a copy of each active path in the path’s archive directory, <ensemble>/<load_dir>/<pn> of its birth ensemble (see copy_staged_paths()). The birth ensemble is the one [current] ens_save_idx records, and otherwise the slot the path is loaded into, its position in [current] active (see pyretis.simulation.repex.InfSwapState.load_paths()). Before such a load, the archive directory of an active path holds files an earlier run wrote: a restart of the new run would read them.

Parameters:
  • config (dict) – The scheduler config of the load.

  • base (str, optional) – The run directory, which the returned directories are joined to; the default leaves them relative.

Returns:

out (list of str) – The archive directories of the active paths that exist, in the order of [current] active; empty for a load that reads no path from the flat store.

pyretis.inout.staged_paths.loaded_path_dir(config: dict[str, Any], path_number: int) → str

Return the directory a load reads a path from.

A load that reads the staged paths (see reads_staged_paths()) reads the path from the directory the user staged flat, <load_dir>/<pn>, when that directory exists. A load of the flat store (see reads_flat_store()) has such a directory for every active path: pyretis.core.path_load.load_paths_from_disk() and pyretis.simulation.setup.refuse_before_staged_load() stop a load that lacks one before it reads a path. Any other load reads the path’s archive directory, located by pyretis.inout.archive_paths.resolve_path_dir() with the birth ensemble [current] ens_save_idx records for the path: a new run with no path staged flat reads there the initial paths pyretis run generates, the interface optimizer seeds or a user places, and a restart reads the run’s own copies. For a run recorded before the per-ensemble nesting that is the flat <load_dir>/<pn>.

Parameters:
  • config (dict) – The scheduler config.

  • path_number (int) – The number of the path.

Returns:

out (str) – The directory holding the path’s traj.txt and order.txt.

pyretis.inout.staged_paths.missing_staged_dirs(config: dict[str, Any], base: str = '') → list[str]

Return the flat directories of the active paths that are missing.

A load that reads the flat store (see reads_flat_store()) reads every active path from its flat <load_dir>/<pn>. These are the directories of the active paths that are missing there.

Parameters:
  • config (dict) – The scheduler config of the load.

  • base (str, optional) – The run directory, which the returned directories are joined to; the default leaves them relative.

Returns:

out (list of str) – The flat directories of the active paths that are missing, in the order of [current] active; empty for a load that reads no path from the flat store.

pyretis.inout.staged_paths.reads_flat_store(config: dict[str, Any], base: str = '') → bool

Tell whether a load reads its initial paths from the flat store.

A load that reads the staged paths (see reads_staged_paths()) is a load of the flat store when at least one active path is staged flat, in <load_dir>/<pn>: it reads every active path from its flat directory, and stops before it reads when the directory of an active path is missing there (pyretis.simulation.setup.refuse_before_staged_load(), pyretis.core.path_load.load_paths_from_disk()). With no active path staged flat, the load reads each path from its archive directory, <ensemble>/<load_dir>/<pn>, where pyretis run writes the initial paths it generates, the interface optimizer seeds the paths of its steps, and a user may place them.

Parameters:
  • config (dict) – The scheduler config of the load.

  • base (str, optional) – The run directory the flat store is looked up in; the default is the working directory.

Returns:

out (boolean) – True when the load reads the staged paths and at least one active path is staged flat.

pyretis.inout.staged_paths.reads_staged_paths(config: dict[str, Any]) → bool

Tell whether the load of a run reads the paths the user staged.

The load of a new run reads its initial paths from the directories the user staged. The load records the paths it keeps in [current] load_recomputed (see pyretis.simulation.setup. setup_internal()), and the scheduler writes that record into the state file before the first cycle. A state that holds the record, resumed at cycle 0 or later, and a restart, which records restarted_from, read the run’s own copies.

Parameters:

config (dict) – The scheduler config of the load.

Returns:

out (boolean) – True when the load reads the staged paths.

pyretis.inout.staged_paths.staged_path_dirs(config: dict[str, Any], path_numbers, base: str = '') → list[str]

Return the directories staged flat for the given paths.

A user stages a path for a fresh scheduler run in the flat <load_dir>/<pn> of the run directory (see loaded_path_dir()).

Parameters:
  • config (dict) – The scheduler config; [simulation] load_dir names the staged store.

  • path_numbers (iterable of int) – The path numbers to look for.

  • base (str, optional) – The run directory, which the returned directories are joined to; the default leaves them relative.

Returns:

out (list of str) – The staged directories that exist, in the order of path_numbers.

pyretis.inout.scheduler_archive module

The infinite-swapping scheduler’s path-archive writer.

This module holds the one genuinely scheduler-specific piece of the old formatter_repex module: the path-data formatters and the path archive used by the infinite-swapping coordinator. Everything else in formatter_repex duplicated the canonical PyRETIS file-IO/formatter code under pyretis.inout.formats, pyretis.inout.common.OutputBase and pyretis.inout.fileio.FileIO; those duplicates have been removed and the base classes are imported from their canonical location.

What is kept here is specific to the infinite-swapping data model and the archive layout the scheduler writes, and is not a duplicate of the classic code:

The Scheduler* path formatters

SchedulerOrderPathFormatter, SchedulerEnergyPathFormatter and SchedulerPathExtFormatter read the infinite-swapping phase-point attributes directly (phasepoint.order, getattr(phasepoint, key) for the energy terms, phasepoint.config / phasepoint.vel_rev for the trajectory references). Their classic counterparts in pyretis.inout.formats read phasepoint.particles instead and reconstruct derived energy terms, so they cannot be reused here. The Scheduler prefix is what keeps the two families apart: they are different classes for different data models, and each name must resolve to exactly one of them. See SchedulerPathFormatter for the shape they share.

SchedulerPathStorage

The infinite-swapping path archive. It writes order.txt, energy.txt, traj.txt and the trajectory frames flat into <dir>/<path_number>/ (no inner accepted/ – it had no sibling rejected/ and only obscured the layout). It is called as output(step, {"path": ..., "dir": ...}) and returns the moved Path. (The retired classic PathStorage wrote a per-cycle accepted/rejected archive instead; this per-path writer is the only trajectory archiver left.)

class pyretis.inout.scheduler_archive.FormattersEntry

Bases: TypedDict

To store formatters and output files together.

file: str
fmt: OutputFormatter
class pyretis.inout.scheduler_archive.SchedulerEnergyPathFormatter

Bases: SchedulerPathFormatter, EnergyFormatter

Energy data for a path, as the scheduler’s restart store.

Deliberately a separate class from pyretis.inout.formats.energy.EnergyPathFormatter, not a duplicate to be merged: that one is the ANALYSIS writer and reconstructs the derived etot/temp (via its _dof_kb cache) so a reused/reloaded frame still reports them. This one writes each frame’s energies exactly as the phase point carries them (missing terms stay nan), so a continuation reloads byte-faithful values and does not resurrect a reconstructed number the uninterrupted run never stored. Keep the two apart; do not “dedup” them (same reasoning as the sibling SchedulerOrderPathFormatter full-precision override above).

__init__() → None

Initialise the formatter.

format_phasepoint(index: int, phasepoint: Any) → str

Return the energy row for one phase point.

The terms are read straight off the phase point; one that is absent stays None and is rendered as nan rather than being reconstructed.

class pyretis.inout.scheduler_archive.SchedulerOrderPathFormatter

Bases: SchedulerPathFormatter, OrderFormatter

Order-parameter data for a path, as the scheduler’s restart store.

Unlike the analysis order.txt (written by pyretis.inout.formats.order.OrderPathFormatter at the canonical 6-decimal precision for the histogram analysis), this is the scheduler’s RESTART store: pyretis.core.path_load.load_path() reads it back to reconstruct the active path’s phase points on a continuation. Restoring a rounded order parameter makes a reloaded frame’s value differ from the uninterrupted run, so any continuation whose Max-O / Min-O lands on a reloaded frame would diverge in the high-precision pathensemble.txt columns. Persist the order at full float64 round-trip precision (17 significant digits) so a restart reproduces the continuous run byte-for-byte; only the per-frame order column needs it (the integer time column is unchanged).

ORDER_FMT = ['{:>10d}', '{:>26.17e}']
__init__() → None

Initialise the formatter.

format_phasepoint(index: int, phasepoint: Any) → str

Return the order-parameter row for one phase point.

class pyretis.inout.scheduler_archive.SchedulerPathExtFormatter

Bases: SchedulerPathFormatter, OutputFormatter

Trajectory file references for a path, in the scheduler’s data model.

The trajectories are stored as files and this formatter creates a file that lists where those files are.

The column layout matches pyretis.inout.formats.path.PathExtFormatter, but the two are NOT interchangeable and neither can be deleted in favour of the other: this one reads phasepoint.config and phasepoint.vel_rev from the infinite-swapping phase point, while the classic one reads phasepoint.particles.get_pos() and .get_vel(). Swapping one for the other raises AttributeError on the model it was not written for. If they are ever unified, the unified class must accept both models, and the restart round-trip (test/infswap/simulations/test_restart_equivalence.py) must still reproduce the continuous run byte-for-byte.

FMT = '{:>10}  {:>20s}  {:>10}  {:>5}'
__init__() → None

Initialise the formatter.

cycle_comment(step: int, path: InfPath, status: str) → str

Return the # Cycle: comment, which carries no move here.

The trajectory listing records where the frames live, not how they were generated, so it omits the move: field its order and energy siblings carry.

format_phasepoint(index: int, phasepoint: Any) → str

Return the trajectory-reference row for one phase point.

static parse(line: str) → list[str]

Parse the line data by splitting the given text on spaces.

class pyretis.inout.scheduler_archive.SchedulerPathFormatter

Bases: object

The block shape shared by the scheduler’s path formatters.

Every file the scheduler archives per path has the same three-part layout: a # Cycle: provenance comment, the column header, then one row per phase point. Only the row differs between the order, energy and trajectory writers, so a subclass supplies just format_phasepoint() (and, where the comment carries the generating move, cycle_comment()).

This is a mixin: it is combined with the formatter base that owns header and the column formats, and must be listed first so its format() wins over the classic particles-based one.

cycle_comment(step: int, path: InfPath, status: str) → str

Return the # Cycle: provenance comment for a block.

Parameters:
  • step (int) – The cycle number we are creating output for.

  • path (object like Path) – The path the block is written for.

  • status (str) – The status of the path.

Returns:

out (str) – The comment line opening the block.

format(step: int, data: list[Any]) → Iterable[str]

Format one path as a block of lines.

Parameters:
  • step (int) – The cycle number we are creating output for.

  • data (list) – A tuple on the form (Path, status), where Path is the Path to write and status is the string representing the status of the path.

Yields:

out (str) – The lines of the block.

format_phasepoint(index: int, phasepoint: Any) → str

Return the row for a single phase point.

Parameters:
  • index (int) – The position of the phase point within the path.

  • phasepoint (object like System) – The phase point to format.

Returns:

out (str) – The formatted row.

header: str

Supplied by the formatter base this mixin is combined with (OutputFormatter defines it as a property). Annotated, not assigned, so the property still resolves through the MRO – this only states the contract a co-class has to satisfy.

class pyretis.inout.scheduler_archive.SchedulerPathStorage(keep_traj_fnames: list | None = None, archive_subdir: str = 'accepted')

Bases: OutputBase

A class for handling storage of external trajectories.

Variables:
  • target – Determines the target for this output class. Here it will be a file archive (i.e., a directory based collection of files).

  • formatters (dict[str, pyretis.inout.scheduler_archive.FormattersEntry]) – This dict contains the formatters for writing path data, with default filenames used for them.

  • out_dir_fmt – A format to use for creating directories within the archive. This one is applied to the step number for the output.

  • archive_subdir – The name of the per-ensemble archive directory, the [simulation] load_dir of the run. A frame already under a directory of this name belongs to an archived path and is linked, not moved (see _place_frame()).

__init__(keep_traj_fnames: list | None = None, archive_subdir: str = 'accepted')

Set up the storage.

Parameters:
  • keep_traj_fnames (list, optional) – A list of file extensions matched against the source directories of the trajectories; matching files are kept.

  • archive_subdir (str, optional) – The name of the per-ensemble archive directory, the [simulation] load_dir of the run (default accepted).

Notes

No formatters are passed to the parent class. This is because this class is less flexible and only intended to do one thing: write path data for external trajectories.

__str__() → str

Return basic info.

static _move_path(path: InfPath, target_dir: str, keep_traj_fnames: list, prefix: str | None = None, archive_subdir: str = 'accepted') → InfPath

Copy a path to a given target directory.

Parameters:
  • path (InfPath) – The path to copy.

  • target_dir (str) – The location where we are moving the path to.

  • keep_traj_fnames (list) – A list of file extensions that are matched against the source directories in which the trajectories are stored. File extensions that match the pattern are also stored.

  • prefix (str, optional) – A prefix for the file names of copied files.

  • archive_subdir (str, optional) – The name of the per-ensemble archive directory. Frames already under it, or in a staged load folder of that name, are linked into target_dir; all other frames are moved there (see _place_frame()).

Returns:

path_copy (InfPath) – A copy of the input path.

formatters: dict[str, FormattersEntry] = {'energy': {'file': 'energy.txt', 'fmt': <pyretis.inout.scheduler_archive.SchedulerEnergyPathFormatter object>}, 'order': {'file': 'order.txt', 'fmt': <pyretis.inout.scheduler_archive.SchedulerOrderPathFormatter object>}, 'traj': {'file': 'traj.txt', 'fmt': <pyretis.inout.scheduler_archive.SchedulerPathExtFormatter object>}}
out_dir_fmt = '{}'
output(step: int, data: Any) → InfPath

Format the path data and store the path.

Parameters:
  • step (int) – The current simulation step.

  • data (Any) – A dictionary containing the path and the directory to write to.

Returns:

path (InfPath) – A copy of the path (moved to the new directory).

output_path_files(step: int, data: list[Any], target_dir: str) → list[tuple[str, str]]

Write the output files for energy, path and order parameter.

Parameters:
  • step (int) – The current simulation step.

  • data (list) – A tuple containing:

    • The path as an object like Path.

    • A string containing the status of this path.

  • target_dir (str) – The path to where we archive the files.

Returns:

files (list) – The files created as a list of tuples. Each tuple contains:

  • The full path to the file.

  • A relative path to the file. The relative path is useful for organizing internally in archives.

output_to(step: int, path: InfPath, target_dir: str, status: str = 'ACC') → InfPath

Write a path’s files into a named directory and move its frames.

output() names the directory after the path number. A rejected trial has no number of its own – numbering happens only on acceptance – so the directory is passed in instead.

The text output (order/energy/traj.txt) and the trajectory frames live together, flat, in that one directory: there is no inner accepted/ (it had no sibling rejected/ and only obscured the layout). The loader falls back to a legacy accepted/ subdir for user-staged load dirs (see pyretis.core.path_load.load_path()).

Parameters:
  • step (int) – The current simulation step.

  • path (object like Path) – The path to store.

  • target_dir (str) – The directory to write into.

  • status (str, optional) – The status recorded in the written files.

Returns:

out (object like Path) – The path, with its frames moved into target_dir.

target = 'file-archive'
write(towrite: str, end: str = '\n') → bool

We do not need the write method for this object.

pyretis.inout.scheduler_archive._generate_file_names(path: InfPath, target_dir: str, prefix: str | None = None) → tuple[list[tuple[str, int]], dict[str, str]]

Generate new file names for moving or copying paths.

Parameters:
  • path (InfPath) – The path object we are going to store.

  • target_dir (str) – The location where we are moving the path to.

  • prefix (str, optional) – The prefix can be used to prefix the name of the files.

Returns:

out (tuple) – A tuple containing:

  • A list with new file names.

  • A dict which defines the unique “source -> destination” for the copy/move operations.

pyretis.inout.scheduler_archive._is_inside_archive(src: str, archive_subdir: str) → bool

Return whether a frame file already belongs to an archived path.

Archived paths live in <load_dir>/<path number>/, where the last component of [simulation] load_dir names the archive directory. A frame there is named by that path’s traj.txt.

Parameters:
  • src (string) – The frame file to classify.

  • archive_subdir (string) – The name of the per-ensemble archive directory.

Returns:

out (boolean) – True when the file sits inside a path archive.

pyretis.inout.scheduler_archive._is_staged_frame(src: str, archive_subdir: str) → bool

Return whether a frame file sits in a staged path’s frame subdirectory.

A user may stage a path with its frames in a subdirectory of its path directory, <load_dir>/<path number>/accepted/<frame>, where the last component of [simulation] load_dir is archive_subdir, and the run’s copy of such a path in its archive directory keeps them there.

Parameters:
  • src (string) – The frame file to classify.

  • archive_subdir (string) – The name of the per-ensemble archive directory.

Returns:

out (boolean) – True when the file sits in a staged path’s frame subdirectory.

pyretis.inout.scheduler_archive._place_frame(src: str, dest: str, archive_subdir: str = 'accepted') → None

Put a trajectory frame in an archive directory without orphaning it.

Paths SHARE frame files: a time reversal, and any move that reuses part of its parent, name the very same file from two different traj.txt. Relocating such a file satisfies the path that claims it and breaks its sharer, whose traj.txt then names a file that is not beside it.

Which frames those are is decidable from where the file already lives, and the distinction matters:

  • a file ALREADY INSIDE a path archive belongs to that path, whose traj.txt names it. Link it, never take it away. A path directory staged flat, <load_dir>/<pn>/<frame>, and the run’s copy of it in <ensemble>/<load_dir>/<pn> have this layout.

  • a file in the frame subdirectory of a path directory, <load_dir>/<pn>/accepted/<frame>, belongs to that path too: a user may stage a path with its frames there, and the run’s copy of such a path keeps them there. Link it: the directory keeps its files.

  • a file in the run’s scratch area belongs to nobody yet. Move it: archiving is also how scratch is cleaned up, and leaving those behind would accumulate them run after run.

Once the load of a run has copied a staged path, the phase points of the path name the frames of the run’s copy (see pyretis.inout.staged_paths.archive_dirs()), so the frames a run links here are files of the run’s own.

For the linked cases a hard link gives both directories a working name for one copy on disk, so keeping the old reference alive costs no space. Where hard links are unavailable – another filesystem, or one that does not support them – fall back to a copy, which is correct but uses space (pyretis.inout.common.link_or_copy()).

Parameters:
  • src (string) – The existing frame file.

  • dest (string) – Where this path wants to name it.

  • archive_subdir (string, optional) – The name of the per-ensemble archive directory, the [simulation] load_dir of the run (default accepted).

pyretis.inout.config_adapter module

Native-config compatibility layer for the infinite-swap coordinator.

This module builds the input half of a configuration-compatibility layer: it translates a canonical RETIS configuration (task = "retis", canonical [simulation] / [tis] / [retis] / [engine] / [orderparameter] sections, canonical [initial-path] method = "kick") into the configuration dictionary the infinite-swap (replica-exchange) coordinator consumes.

The translation is intentionally additive: it does not touch the in-process simulation flow. An opt-in route in pyretisrun calls to_scheduler_config() and then runs the (unchanged) coordinator on the translated dictionary.

The coordinator initiates from pre-generated paths on disk (load_dir); it has no kick-init of its own. So when the canonical config requests method = "kick" this module GENERATES the initial paths by running the kick initiation (pyretis.initiation.initiate_kick()) and serialises them into the load_dir the translated config points at – one accepted path per ensemble, in the coordinator’s external-path file format (traj.txt / order.txt / accepted/traj.xyz).

Notes

The internal engine (class = "Langevin") integrates from in-memory system.pos / system.vel and a system-attached force field, while external engines (gromacs, lammps, turtlemd) read their starting configuration from the file-backed phase points the coordinator’s propagate loop hands them (positions live in traj.xyz, read back by the engine). The internal engine runs fully through the coordinator regardless – EngineBase/internal.py support both; test/integration/test_pyretis_path_sampling.py exercises the full kick-init -> propagate -> per-ensemble-output path on it extensively, including at workers > 1.

TurtleMD is a partial exception: its own config nests particles/box/potential under [engine] ([engine.particles], …), which this module’s kick/load initiation (generate_load_dir() -> pyretis.setup. create_simulation) does not read – that in-process helper expects the top-level [particles]/[box]/[potential] sections the internal engine (and external engines driven the “classic” pyretis way) use instead. A TurtleMD translation (this module’s actual job) is unaffected and fully verified (see test/infswap/simulations/test_quantis_runner.py); only a fresh, kick-initiated canonical-syntax TurtleMD run cannot bootstrap its first load_dir through this route yet. Tracked as P7.10, not fixed here.

pyretis.inout.pathensemble_output module

Native per-ensemble output for the infinite-swap coordinator.

The coordinator internally shares each accepted path across ensembles via a frac vector instead of keeping a distinct scalar-weight path per ensemble. pyretisanalyse and the downstream crossing-probability / rate analysis expect the per-ensemble pathensemble.txt format – this is the only output format the coordinator writes, regardless of which TOML input schema (canonical or legacy-runner) launched the run; and WHAM-style analysis reconstructs the same matrix on demand (reconstruct_path_data_matrix() below).

This module bridges the two by emitting, for every ensemble j the accepted path contributed to in the current cycle, one pathensemble.txt row – reusing the canonical pyretis.inout.formats.pathensemble.PathEnsembleFormatter so the byte layout matches the classic output layout exactly. Alongside each row, one order.txt and energy.txt block (the # Cycle: block format of pyretis.inout.formats.order.OrderPathFormatter / pyretis.inout.formats.energy.EnergyPathFormatter) is appended in the same ensemble directory, because the analysis pairs those blocks with the pathensemble.txt rows one-to-one in row order (matched on the cycle number).

The frac -> Weight mapping

The crossing-probability analysis (pyretis.analysis.path_analysis.analyse_path_ensemble()) reads the Weight column as a high-acceptance weight: each row’s contribution to the order-parameter histogram is

mc_weight * (1.0 / Weight)

where mc_weight is the Monte-Carlo stationary count (1 for an accepted row, incremented on each following rejected row). The coordinator emits one accepted row per ensemble per cycle, so mc_weight == 1 for every row and the contribution reduces to 1.0 / Weight. To make the analysis histogram reproduce the infinite-swap frac-weighted histogram – where a path contributes its fractional occupancy frac[j] to ensemble j – the coordinator therefore writes

Weight = ha_factor / frac[j] (frac[j]: the cycle’s increment)

where ha_factor is the path’s high-acceptance factor for the ensemble: its crossing count for wire fencing and stone skipping, and 1.0 for the indicator moves sh/wt and for the minus ensemble, where 1.0 / Weight == frac[j]. The Step column carries the global coordinator cycle.

The three trailing columns (PathNumber, HA-weight, FracInc)

The combined Weight column is exactly what the classic crossing-probability histogram needs, but it is lossy for WHAM-style analysis (pyretis.analysis.wham_analysis, pyretis.analysis.path_weights): those need frac_inc and ha_factor as two independently-meaningful numbers (each ensemble’s WHAM q-factor weight is the raw, un-unweighted sum of frac_inc, not the sum of frac_inc / ha_factor), and neither can be recovered from the combined Weight alone. The 17 canonical columns also carry no path identity, which a reconstruction needs to group a path’s rows across cycles.

So each row carries, after the 17 canonical columns, the global PathNumber, the raw HA-weight (ha_factor) and FracInc (frac_inc). reconstruct_path_data_matrix() reads them directly. A run directory whose rows stop after HA-weight recovers frac_inc as ha_factor / Weight, and one whose rows stop after the 17 columns reads the pair from an ha_weight.txt beside it.

pyretis.inout.pathensemble_output.attempted_moves_per_ensemble(state: Any) → list[int]

Return the number of attempted moves recorded per ensemble.

Counts the data rows of each ensemble’s moves.txt, which holds one row per attempted move (a zero swap has a row in each of its two ensembles). An ensemble without the file counts zero.

Parameters:

state (object like pyretis.simulation.repex.InfSwapState) – The coordinator state.

Returns:

list of integers – One count per ensemble, in the order of _ensemble_dirs().

pyretis.inout.pathensemble_output.energy_output_requested(config: dict[str, Any]) → bool

Return True when per-ensemble energy.txt output is requested.

See order_output_requested(); this is the energy-file counterpart (carried as energy_file, default 1).

Parameters:

config (dict) – The coordinator configuration dictionary.

Returns:

boolean – True when per-ensemble energy.txt output is requested.

pyretis.inout.pathensemble_output.ensemble_output_dirs(config: dict, n_ensembles: int) → list[str]

Return the output directories of a run’s first n_ensembles slots.

Slot j of the coordinator writes its pathensemble.txt, moves.txt, order.txt and energy.txt into the directory named by its output ensemble number, below [output] data_dir.

Parameters:
  • config (dict) – The scheduler config. [output] data_dir roots the directories and the [simulation] route flags number them.

  • n_ensembles (integer) – The number of ensemble slots of the run.

Returns:

list of string – One directory per slot, in slot order: data_dir joined with the ensemble name, so relative to the run directory unless data_dir is absolute.

pyretis.inout.pathensemble_output.ensemble_output_files(config: dict, run_dir: str, n_ensembles: int) → list[str]

Return the pathensemble.txt files in the ensemble directories.

The scheduler writes the pathensemble.txt of every ensemble directory of a run once the load of the run has read its initial paths (init_pathensemble_files()). The directories are the ones the scheduler writes for the first n_ensembles slots of config (ensemble_output_dirs()).

Parameters:
  • config (dict) – The scheduler config of the simulation.

  • run_dir (string) – The directory the simulation runs from.

  • n_ensembles (integer) – The number of ensemble slots of the simulation.

Returns:

out (list of string) – The pathensemble.txt files that exist, with a data row or with the header alone, in ensemble order.

pyretis.inout.pathensemble_output.init_pathensemble_files(state: Any, overwrite: bool = True) → None

Create the per-ensemble directories and file headers.

Each ensemble directory gets a pathensemble.txt with the canonical standard header and the three trailing column names, a moves.txt with its header, plus empty order.txt / energy.txt files when those are requested (the path-data files carry no file-level header in the classic layout – each appended block starts with its own # Cycle: comment). A fresh start also counts each ensemble’s initial path in No.-acc (see _count_initial_paths()).

Parameters:
  • state (object like pyretis.simulation.repex.InfSwapState) – The coordinator state.

  • overwrite (bool, optional) – When True (a fresh start, the default) the files are (re)written with a clean header. When False (a restart) only missing files are created and existing ones are kept for appending. The restart path must still (re)create missing files: a run that always restarts (method="restart", e.g. a canonical config seeded from an infswap restart that never wrote per-ensemble output) would otherwise never get its pathensemble.txt and leave the analysis with nothing to read. On a restart the existing files are also trimmed to the committed state.cstep first (see _trim_ensemble_dir_to_cstep()), so an ungraceful crash between the per-cycle output append and the run-file commit cannot make the replay double-count.

pyretis.inout.pathensemble_output.map_move_to_mc_code(move: str) → str

Map a coordinator move tag to the pathensemble.txt Mc code.

Parameters:

move (string) – The coordinator’s move tag (generated[0]), e.g. "sh" or "tr".

Returns:

string – The two-character Mc code.

pyretis.inout.pathensemble_output.order_output_requested(config: dict[str, Any]) → bool

Return True when per-ensemble order.txt output is requested.

The input shim carries the [output] order-file interval as order_file (default 1). The analysis pairs one order.txt block with each pathensemble.txt row (see pyretis.analysis.path_analysis.analyse_path_ensemble()), and the coordinator writes a row every cycle a path contributes frac – so the interval reduces to an on (> 0) / off (<= 0) switch here.

Parameters:

config (dict) – The coordinator configuration dictionary.

Returns:

boolean – True when per-ensemble order.txt output is requested.

pyretis.inout.pathensemble_output.read_moves_file(moves_file: str, first_cycle: int | None = None, last_cycle: int | None = None) → list[dict]

Return the attempted moves recorded in a moves.txt file.

Every attempted Monte Carlo move is one line, accepted or rejected. Columns that do not apply to a move are written -; here only the produced-path column can carry one, and it is translated back to the -1 the counters expect. A line too short to hold the produced path is skipped.

Parameters:
  • moves_file (string) – The moves.txt file to read.

  • first_cycle (int, optional) – The first cycle to keep. None keeps every cycle before last_cycle.

  • last_cycle (int, optional) – The last cycle to keep. None keeps every cycle after first_cycle.

Returns:

list of dict – One entry per attempted move, with cycle, move (the move’s full tag, see pyretis.inout.formats.pathensemble.move_from_mc_code()), status, new_path and md_steps, the frames the attempt integrated (None for a line that does not record them).

pyretis.inout.pathensemble_output.reconstruct_path_data_matrix(run_dir: str, nskip: int = 0) → list[list[float]]

Rebuild the infswap_data.txt matrix from per-ensemble output.

The canonical route never writes infswap_data.txt; WHAM-style analysis (pyretis.analysis.wham_analysis, pyretis.analysis.path_weights, pyretis.analysis.training_set) instead reconstructs the same matrix from the pathensemble.txt in every numbered ensemble directory. For ensemble j and a captured row, FracInc is the cycle’s fractional occupancy increment (a row without that column recovers it as ha_factor / Weight; see the module docstring); a path’s Cxy for that ensemble is the sum of frac_inc over every cycle it was live there, and its HA for that ensemble is ha_factor itself (constant across those cycles by construction). Length and Max-O are path-intrinsic, so every row carrying a given path number must agree – a mismatch anywhere is a logic error in the writer, not data to silently average over, hence the loud failures below rather than a best-effort reconciliation.

Row order is not a byte-for-byte reproduction of the live writer’s append order (paths there are written when archived, in roughly-but-not-exactly path-number order under infinite swapping). Rows here are sorted by ascending path number instead. This is immaterial to pyretis.analysis.path_weights.get_path_weights() (and so to interfaces_from_data/infinit, its caller) and to pyretis.analysis.training_set.read_path_data() / pyretis.analysis.combine_data’s per-path remapping – all operate on the row set, not its sequence. It DOES affect the block-error / running-average machinery in pyretis.analysis.wham_analysis.analyse_wham_output() (a chronological proxy, not the original sequence); that estimator is superseded by the crossing-probability analysis once this function is wired in.

Two further, deliberate differences from the historical infswap_data.txt writer (verified empirically against it before it was retired, not assumed):

  • Still-live paths are excluded, via _read_active_paths() (the run file’s [current] active list) – matching the old writer, which only emitted a row once a path was archived, never for an in-progress (not-yet-final) total.

  • A path that never contributed a non-zero fraction anywhere has no row at all, unlike the old writer (which still wrote an all-"----" row for it on archival). Such a path leaves no trace in any per-cycle output file (frac_inc <= 0.0 rows are never written – see write_pathensemble_data()), so there is nothing to reconstruct it from. This is provably harmless: an all-zero row cannot change any sum, ratio, or weight any consumer computes from the matrix (it contributes exactly 0 everywhere it would appear).

Every row of an initialisation path is left out, by the rule the crossing analysis leaves it out with (pyretis.core.path.continues_initialisation(), applied to each ensemble’s rows in file order): a row whose move is one of pyretis.core.path.INITIAL_MOVES, and, in an ensemble whose moves.txt does not record the MD steps of every attempt (_labels_recorded()), a row of an MD-free move of a held initialisation path. These are the rows of the kicked and loaded paths, of the paths derived from them without dynamics, and of the paths held across a change of [tis] high_accept, re-tagged pyretis.core.path.HELD_ACROSS_RULE_CHANGE and recorded in the run file’s [current] high_accept_changes: such a path was accepted under the other acceptance rule, and its HA-weight after the change follows the rule the continuation runs with. A path whose rows are all left out has no row in the matrix. Length and Max-O are checked on every row, left out or not.

nskip counts the paths of the run’s full path list: every path with a row, the initialisation paths included, by ascending path number, the live paths left out. The first nskip of them are discarded, and the rows of initialisation paths are then left out of the paths that remain. A run whose initialisation rows all belong to the first nskip paths gives the matrix that keeps every row, with the same skip.

Parameters:
  • run_dir (string) – The directory holding the numbered ensemble directories (000, 001, …).

  • nskip (int, optional) – Number of paths of the run’s full path list, by ascending path number, to discard.

Returns:

matrix (list of list of float) – Exactly the shape pyretis.analysis.wham_analysis. read_data_matrix() returns: one row per path, [path_nr, length, max_op, Cxy_0 .. Cxy_{n-1}, HA_0 .. HA_{n-1}].

pyretis.inout.pathensemble_output.records_a_cycle(pathensemble_file: str) → bool

Return True when a pathensemble.txt holds a data row.

The scheduler writes the file’s header when a simulation starts and appends its rows from cycle 1 on, so a data row is the record of a sampled cycle. The file is read up to its first data row.

Parameters:

pathensemble_file (string) – The pathensemble.txt file to read.

Returns:

out (boolean) – True when a line other than a blank or # comment line is found.

pyretis.inout.pathensemble_output.sampled_ensemble_output(config: dict, run_dir: str, n_ensembles: int) → list[str]

Return the pathensemble.txt files that record sampled cycles.

A new simulation writes the output files of every ensemble directory it runs in afresh. These are the pathensemble.txt files among them (ensemble_output_files()) that hold a data row (records_a_cycle()), and that the new simulation would therefore erase.

Parameters:
  • config (dict) – The scheduler config of the new simulation.

  • run_dir (string) – The directory the simulation runs from.

  • n_ensembles (integer) – The number of ensemble slots of the new simulation.

Returns:

out (list of string) – The pathensemble.txt files that hold a data row, in ensemble order.

pyretis.inout.pathensemble_output.write_moves_rows(state: Any, md_items: dict, pn_news: Sequence) → None

Append this cycle’s attempted moves to moves.txt.

Every Monte Carlo move is recorded, accepted or rejected, with the move that ran, the status it ended in, and the path it produced. This is the only record of a rejection: pathensemble.txt says which path the ensemble held, and a rejected trial never becomes a held path.

The two running counters of pathensemble.txt are advanced here, because they count moves: No.-acc is the number of accepted paths this ensemble has produced and No.-shoot the number of accepted shooting moves among them.

A swap move touches two ensembles and so writes one line in each, naming the other as its partner.

Parameters:
  • state (object like pyretis.simulation.repex.InfSwapState) – The coordinator state.

  • md_items (dict) – The cycle’s move data: the ensembles picked, the move attempted in each, the resulting status and the trial path’s properties.

  • pn_news (list of integers) – The path number each picked ensemble ends the cycle with. Equal to the old number when the trial was rejected.

pyretis.inout.pathensemble_output.write_pathensemble_data(state: Any) → None

Append the cycle’s frac-contribution rows per ensemble.

Realises the ratified cycle decision: each accepted path gets a row in every ensemble ``j`` it has a non-zero per-cycle frac increment in. For ensemble j, one row is appended to its pathensemble.txt for every live path that contributed frac to j this cycle. Weight is written as ha_factor / frac_increment (so the analysis, which reads Weight as a 1/HA-weight, recovers frac_increment / ha_factor as the histogram weight – see the module docstring); Step is the global coordinator cycle.

When requested, every appended row is accompanied by one # Cycle: block in the ensemble’s order.txt and energy.txt carrying the path’s per-phase-point order parameters and energies. The classic analysis ( analyse_path_ensemble()) consumes these in lockstep – one block per pathensemble.txt row, matched on the cycle number – so the blocks are emitted exactly one per row, in row order. Every row also carries its path number, ha_factor and frac_inc in the three trailing columns – the WHAM-side consumers need frac_inc and ha_factor separately, not just their Weight ratio, and path identity to group/match rows, none of which the canonical columns carry.

Parameters:

state (object like pyretis.simulation.repex.InfSwapState) – The coordinator state, after the cycle’s frac increments have been applied (state.last_frac_increment populated, mapping each ensemble index to a list of (path_number, frac) pairs).

pyretis.inout.key_table module

The declared place of every canonical input key in the scheduler config.

A path-sampling run is driven by the scheduler configuration that pyretis.inout.config_adapter.to_scheduler_config() builds from the canonical input settings (the parsed [simulation], [tis], [retis], [engine], … sections). This module states that translation as data. TABLE holds one KeyEntry per path of the scheduler configuration: the canonical paths its value is read from, the kind of the mapping and the rule that forms the value. NOT_CARRIED holds the canonical keys that reach no scheduler path. RUN_DEFAULTS holds the input keys a run reads with a default of its own, past the settings parse and the table, with the runs that read them; the readers take the default from this module, and the run record writes it under the input key. NO_EFFECT holds the input keys and sections whose value takes no effect on a run, with the runs it takes none on: the settings parse of a TOML input, and of the legacy rst input of a path-sampling run before pyretis run translates it, refuses such a key the input gives (refuse_settings_without_effect()), naming the key and the input key to set instead when another one sets what it would set, and the run record leaves it out.

A path is a dotted string of section and key names: "tis.maxlength" in the canonical settings, "simulation.tis_set.maxlength" in the scheduler configuration. A last component * stands for every direct child of that section that no other entry names ("engine.*"). A path that names a section ("system") stands for the whole section, copied with every key it holds.

The numbered engine sections of an engine pool ([engine1], [engine2], …, see pyretis.inout.settings.is_pool_engine_section()), which [simulation] ensemble_engines names, take the entries of [engine0] for their own section (pool_engine_entries()); the helpers below add them for the sections a configuration or a path names.

Kinds

same

The same section and key name; the value is carried, with the declared type conversion.

moved

The same key name in another section.

renamed

Another key name, in the same section or another one.

derived

A value computed by the entry’s function from one or more canonical keys, or a constant.

not carried

The canonical key reaches no scheduler path.

When a carried path is set

always

On every translation: the value of the first source present, else the entry’s default.

always, default when empty

On every translation: the value of the first source that is true, else the entry’s default.

when present

When a source key is present, whatever its value.

when not None

When a source value is present and not None.

when true

When a source value is true.

when not False

When a source value is present and is not the False object.

Helpers

forward()

The scheduler paths a canonical configuration sets, with their values, as the table forms them.

split_declared()

A scheduler configuration split into its declared paths and the paths no entry declares.

canonical_paths()

The canonical input paths a scheduler path is read from (the old-name reader and the resume messages name the input key with it).

scheduler_places()

The scheduler paths a canonical input path reaches, with the kind.

scheduler_place()

The one scheduler path a carried input key reaches (the resume compares a locked input key at that path).

input_keys()

The input keys a scheduler path is read from, as a message names them ([simulation] zero_left).

resolved_defaults()

The defaults a run takes for the input keys it leaves out, which the run record writes.

keys_without_effect()

The input keys and sections whose value takes no effect on a run, which the run record leaves out.

refuse_settings_without_effect()

The refusal of an input that gives such a key, which the settings parse makes (refused_settings(), refusal_message()).

reset_accepted_settings()

The parse’s own value of such a key the input sets to a value that states what the run does (rgen = "pcg64"), which the settings parse gives the key after the refusal.

without_effect_in_run_file()

The sections of a run file without such keys, which the reader of a run file written before the refusal takes.

canonical_items()

The input keys, with their values, a scheduler configuration is read from: the inverse of the table, which reads a state file of the scheduler configuration under the names of the input.

is_constant_path()

Whether the table sets a scheduler path to a constant, which no input key gives.

pyretis.inout.key_table.ALWAYS = 'always'

Set on every translation; the default applies when no source is present.

pyretis.inout.key_table.ALWAYS_OR_DEFAULT = 'always, default when empty'

Set on every translation; the default applies when no source is true.

pyretis.inout.key_table.DERIVED = 'derived'

The kind of a scheduler path whose value a function computes.

pyretis.inout.key_table.EXACT_PERM_ONLY_DEFAULT = False

Whether a block above the threshold stops the run instead of taking the stochastic permanent, when the input sets no [tis] exact_perm_only: no.

pyretis.inout.key_table.INITIAL_PATH_FIX_MAXTRIES_DEFAULT = 1000

The Monte Carlo attempts a kick initiation may spend on an initial path that does not satisfy its ensemble yet, when the input sets no [tis] initial_path_fix_maxtries.

pyretis.inout.key_table.INITIAL_PATH_MAXTRIES_DEFAULT = 1000

The whole-path generate-and-test attempts a kick initiation may make for one ensemble when the input sets no [tis] initial_path_maxtries.

pyretis.inout.key_table.INITIAL_PATH_METHOD_DEFAULT = 'kick'

The initiation of a run whose input sets no [initial-path] method.

pyretis.inout.key_table.KICK_FROM_DEFAULT = 'initial'

The configuration a kick initiation starts every ensemble from when the input sets no [initial-path] kick-from: the initial configuration.

pyretis.inout.key_table.KICK_MAXTRIES = 100000

The cap on the MD advances one middle-interface crossing search of a kick may take (kick_across_middle), when the input sets no [tis] kick_maxtries. The search is a greedy hill-climb, so a legitimate one can be slow: the shipped minimal tutorial converges monotonically and needs about 2800 advances on the internal engine, which costs a few seconds. The default sits well above that, because its job is to terminate a search that cannot cross at all – not to police a slow one.

An external engine pays a full MD invocation per advance, so in wall-clock terms this default is far too permissive there; such users should set kick_maxtries in [tis] to match their step cost. A measured per-engine default would be better than one number, and is deliberately left open: there is no external measurement to base it on.

pyretis.inout.key_table.KICK_PARALLEL_DEFAULT = False

Whether a kick from the initial configuration runs one job per ensemble on a worker pool, when the input sets no [initial-path] kick-parallel: no.

pyretis.inout.key_table.KINDS = ('same', 'moved', 'renamed', 'derived', 'not carried')

Every kind, in the order the module docstring lists them.

class pyretis.inout.key_table.KeyEntry(scheduler: str, sources: tuple[str, ...], kind: str, when: str | None = None, default: Any = None, convert: Callable[[Any], Any] | None = None, derive: Callable[[Mapping[str, Any], Mapping[str, str]], Any] | None = None, gate: str | None = None, note: str = '')

Bases: object

One path of the scheduler configuration and where it comes from.

Variables:
  • scheduler (str) – The dotted scheduler path. A last component * stands for every direct child of that section that no other entry names.

  • sources (tuple of str) – The canonical paths the value is read from. The first one is the input key a message names for this path. A carried entry takes the first source its rule accepts, so the order is its precedence. A last component * stands for every key of that canonical section.

  • kind (str) – One of SAME, MOVED, RENAMED and DERIVED.

  • when (str or None) – For a carried entry, one of WHEN_RULES; None for a derived entry, whose function decides.

  • default (object) – The value an always entry takes when no source gives one; REQUIRED when the input must give it.

  • convert (callable or None) – The type conversion applied to a carried value, or None to carry it as it is.

  • derive (callable or None) – For a derived entry, the function derive(canonical_config, environ) that returns the value, or UNSET when the path is not set.

  • gate (str or None) – A canonical path whose value must be true for the entry to apply, or None when the entry always applies.

  • note (str) – What reads the path and why the rule is what it is.

convert: Callable[[Any], Any] | None = None
default: Any = None
derive: Callable[[Mapping[str, Any], Mapping[str, str]], Any] | None = None
gate: str | None = None
property is_wildcard: bool

Return True when the entry stands for the children of a section.

Returns:

bool – True when the last component of the scheduler path is *.

kind: str
note: str = ''
property parent: str

Return the scheduler section a wildcard entry fills.

Returns:

str – The scheduler path without its last component.

scheduler: str
sources: tuple[str, ...]
when: str | None = None
pyretis.inout.key_table.LOAD_AND_KICK_DEFAULT = False

Whether a load initiation kicks a loaded path its ensemble refuses, when the input sets no [initial-path] load_and_kick: no.

pyretis.inout.key_table.LOAD_FOLDER_DEFAULT = 'load'

The directory a load initiation reads its paths from when the input sets no [initial-path] load_folder.

pyretis.inout.key_table.MD_SUBCYCLES = NoEffect(canonical='engine.subcycles', applies=<function _integrates_one_step_per_frame>, reason='An md, md-nve or md-flux run stores a step after each integration step of an internal integrator (Verlet, VelocityVerlet, Langevin), whatever subcycles.', use='', accepted=(1,), tasks=frozenset({'md-nve', 'md', 'md-flux'}), read_as='', read_as_first=False)

The entry of [engine] subcycles on an MD task with an internal integrator, which NO_EFFECT holds; the subcycles of an internal integrator a module defines are refused with it once the run imports the class (pyretis.setup.common.create_engine()).

pyretis.inout.key_table.MD_TASKS = frozenset({'md', 'md-flux', 'md-nve'})

The tasks that run their MD in process with the integrate and integration_step of the engine (pyretis.simulation.md_simulation), which NO_EFFECT reads [engine] subcycles for.

pyretis.inout.key_table.MOVED = 'moved'

The kind of a scheduler path with the canonical key name elsewhere.

pyretis.inout.key_table.MOVED_KEYS: tuple[NoEffect, ...] = (NoEffect(canonical='simulation.zeroswap', applies=<function _every_run>, reason='[retis] swapfreq is the one input key of the swap probability.', use='[retis] swapfreq', accepted=(), tasks=None, read_as='retis.swapfreq', read_as_first=True), NoEffect(canonical='simulation.relative_shoots', applies=<function _every_run>, reason='[retis] relative_shoots is the one input key of the ensemble weights of the pick.', use='[retis] relative_shoots', accepted=(), tasks=None, read_as='', read_as_first=False), NoEffect(canonical='tis.relative_shoots', applies=<function _every_run>, reason='[retis] relative_shoots is the one input key of the ensemble weights of the pick.', use='[retis] relative_shoots', accepted=(), tasks=None, read_as='retis.relative_shoots', read_as_first=False))

The entries of NO_EFFECT of the keys whose value the input sets under another input key ([simulation] zeroswap, [tis] relative_shoots, …), which the settings parse knows no more: it refuses each one on every run.

pyretis.inout.key_table.MWF_NSUBPATH_DEFAULT = 3

The number of sub-paths of a multiresolution wire-fencing move when the input sets no [tis] mwf_nsubpath.

pyretis.inout.key_table.NOT_CARRIED: tuple[NotCarried, ...] = (NotCarried(canonical='heading', note='Decorative text.'), NotCarried(canonical='simulation.endcycle', note="A record of the in-process route's output."), NotCarried(canonical='simulation.startcycle', note="A record of the in-process route's output."), NotCarried(canonical='simulation.exe_path', note='Read from the canonical settings by the kick initiation and the external-module loaders; the engine takes [engine] exe_path.'), NotCarried(canonical='simulation.restart', note='The scheduler resumes from the output.toml of the run directory.'), NotCarried(canonical='simulation.rgen', note='The scheduler builds its generators with numpy default_rng.'), NotCarried(canonical='simulation.umbrella', note='Read by the umbrella and Monte Carlo tasks.'), NotCarried(canonical='simulation.overlap', note='Read by the umbrella and Monte Carlo tasks.'), NotCarried(canonical='simulation.maxdx', note='Read by the umbrella and Monte Carlo tasks.'), NotCarried(canonical='simulation.mincycle', note='Read by the umbrella and Monte Carlo tasks.'), NotCarried(canonical='simulation.swap_attributes', note='Removed by the settings parse, with a warning.'), NotCarried(canonical='output.backup', note=''), NotCarried(canonical='output.cross-file', note=''), NotCarried(canonical='output.pathensemble-file', note=''), NotCarried(canonical='output.prefix', note=''), NotCarried(canonical='output.restart-file', note=''), NotCarried(canonical='output.trajectory-file', note=''), NotCarried(canonical='tis.aimless', note='Removed by the settings parse; the sign of sigma_v rules.'), NotCarried(canonical='tis.detect', note='Read from the canonical settings by the analysis.'), NotCarried(canonical='tis.nullmoves', note=''), NotCarried(canonical='tis.rgen', note=''), NotCarried(canonical='tis.seed', note='A non-zero [tis] seed that differs from [simulation] seed is refused; the kick initiation reads it from the canonical settings.'), NotCarried(canonical='retis.nullmoves', note=''), NotCarried(canonical='retis.rgen', note=''), NotCarried(canonical='retis.seed', note=''), NotCarried(canonical='retis.swapsimul', note=''), NotCarried(canonical='initial-path', note='Read from the canonical settings by the run routing and the initiation of the load directory.'), NotCarried(canonical='ensemble', note="The per-ensemble sections; only the first one's [tis] ensemble_number is read (simulation.single_tis_ens_num)."), NotCarried(canonical='infinit', note='Read from the input by the interface optimiser.'), NotCarried(canonical='analysis', note='Read from the canonical settings by pyretis analyse.'))

The canonical keys and sections that reach no scheduler path.

pyretis.inout.key_table.NOT_CARRIED_KIND = 'not carried'

The kind of a canonical key that reaches no scheduler path.

pyretis.inout.key_table.NO_EFFECT: tuple[NoEffect, ...] = (NoEffect(canonical='simulation.zeroswap', applies=<function _every_run>, reason='[retis] swapfreq is the one input key of the swap probability.', use='[retis] swapfreq', accepted=(), tasks=None, read_as='retis.swapfreq', read_as_first=True), NoEffect(canonical='simulation.relative_shoots', applies=<function _every_run>, reason='[retis] relative_shoots is the one input key of the ensemble weights of the pick.', use='[retis] relative_shoots', accepted=(), tasks=None, read_as='', read_as_first=False), NoEffect(canonical='tis.relative_shoots', applies=<function _every_run>, reason='[retis] relative_shoots is the one input key of the ensemble weights of the pick.', use='[retis] relative_shoots', accepted=(), tasks=None, read_as='retis.relative_shoots', read_as_first=False), NoEffect(canonical='retis.relative_shoots', applies=<function _picks_one_ensemble>, reason='The weights select the ensemble of a move of a path-sampling run with several ensembles; this run picks no ensemble.', use='', accepted=(), tasks=None, read_as='', read_as_first=False), NoEffect(canonical='retis.swapfreq', applies=<function _attempts_no_swap>, reason='A tis, pptis or explore run, and the tis run of each input make-tis-files writes, shoots each ensemble on its own and attempts no swap; a retis or repptis run reads the probability.', use='', accepted=(), tasks=frozenset({'tis', 'retis', 'pptis', 'repptis', 'make-tis-files', 'explore'}), read_as='', read_as_first=False), NoEffect(canonical='retis.nullmoves', applies=<function _every_run>, reason='No part of a path-sampling run reads it.', use='', accepted=(), tasks=frozenset({'tis', 'retis', 'pptis', 'repptis', 'make-tis-files', 'explore'}), read_as='', read_as_first=False), NoEffect(canonical='tis.nullmoves', applies=<function _every_run>, reason='No part of a path-sampling run reads it.', use='', accepted=(), tasks=frozenset({'tis', 'retis', 'pptis', 'repptis', 'make-tis-files', 'explore'}), read_as='', read_as_first=False), NoEffect(canonical='retis.swapsimul', applies=<function _every_run>, reason='No part of a path-sampling run reads it.', use='', accepted=(), tasks=frozenset({'tis', 'retis', 'pptis', 'repptis', 'make-tis-files', 'explore'}), read_as='', read_as_first=False), NoEffect(canonical='retis.seed', applies=<function _every_run>, reason='The scheduler spawns its random streams from [simulation] seed, and the in-process kick initiation seeds its generators from [tis] seed.', use='[simulation] seed', accepted=(), tasks=frozenset({'tis', 'retis', 'pptis', 'repptis', 'make-tis-files', 'explore'}), read_as='', read_as_first=False), NoEffect(canonical='simulation.rgen', applies=<function _every_run>, reason="The scheduler builds its generators with numpy's default_rng (PCG64) from [simulation] seed, and the in-process kick initiation builds its own from [tis], [engine] and [system].", use='', accepted=('pcg64',), tasks=frozenset({'tis', 'retis', 'pptis', 'repptis', 'make-tis-files', 'explore'}), read_as='', read_as_first=False), NoEffect(canonical='simulation.restart', applies=<function _every_run>, reason='The scheduler continues a run from the output.toml of the run directory and reads no restart file; the settings parse derives the value from [initial-path] method = "restart".', use='[initial-path] method = "restart"', accepted=(), tasks=frozenset({'tis', 'retis', 'pptis', 'repptis', 'make-tis-files', 'explore'}), read_as='', read_as_first=False), NoEffect(canonical='simulation.startcycle', applies=<function _every_run>, reason='The scheduler counts the cycles of a run in the [current] state of output.toml.', use='', accepted=(), tasks=frozenset({'tis', 'retis', 'pptis', 'repptis', 'make-tis-files', 'explore'}), read_as='', read_as_first=False), NoEffect(canonical='simulation.endcycle', applies=<function _every_run>, reason='The scheduler counts the cycles of a run in the [current] state of output.toml.', use='', accepted=(), tasks=frozenset({'tis', 'retis', 'pptis', 'repptis', 'make-tis-files', 'explore'}), read_as='', read_as_first=False), NoEffect(canonical='simulation.umbrella', applies=<function _every_run>, reason='Read by the umbrella and Monte Carlo tasks.', use='', accepted=(), tasks=frozenset({'tis', 'retis', 'pptis', 'repptis', 'make-tis-files', 'explore'}), read_as='', read_as_first=False), NoEffect(canonical='simulation.overlap', applies=<function _every_run>, reason='Read by the umbrella and Monte Carlo tasks.', use='', accepted=(), tasks=frozenset({'tis', 'retis', 'pptis', 'repptis', 'make-tis-files', 'explore'}), read_as='', read_as_first=False), NoEffect(canonical='simulation.maxdx', applies=<function _every_run>, reason='Read by the umbrella and Monte Carlo tasks.', use='', accepted=(), tasks=frozenset({'tis', 'retis', 'pptis', 'repptis', 'make-tis-files', 'explore'}), read_as='', read_as_first=False), NoEffect(canonical='simulation.mincycle', applies=<function _every_run>, reason='Read by the umbrella and Monte Carlo tasks.', use='', accepted=(), tasks=frozenset({'tis', 'retis', 'pptis', 'repptis', 'make-tis-files', 'explore'}), read_as='', read_as_first=False), NoEffect(canonical='simulation.flux', applies=<function _reads_no_flux>, reason='The ensembles of the run are the ones its task builds from the interfaces (pyretis.inout.checker.ensemble_layout), whatever the value. Only a pptis run reads it, for its [0^-] ensemble.', use='', accepted=(), tasks=frozenset({'tis', 'retis', 'pptis', 'repptis', 'make-tis-files', 'explore'}), read_as='', read_as_first=False), NoEffect(canonical='simulation.zero_ensemble', applies=<function _reads_no_zero_ensemble>, reason='The ensembles of the run are the ones its task builds from the interfaces (pyretis.inout.checker.ensemble_layout), whatever the value. Only a pptis run and make-tis-files read it, for the [0^+] ensemble.', use='', accepted=(), tasks=frozenset({'tis', 'retis', 'pptis', 'repptis', 'make-tis-files', 'explore'}), read_as='', read_as_first=False), NoEffect(canonical='tis.ensemble_number', applies=<function _reads_no_ensemble_number>, reason='It numbers the one ensemble of a tis run; this run samples every ensemble it builds from its interfaces, or writes the input of each (make-tis-files).', use='', accepted=(), tasks=frozenset({'tis', 'retis', 'pptis', 'repptis', 'make-tis-files', 'explore'}), read_as='', read_as_first=False), NoEffect(canonical='tis.detect', applies=<function _reads_no_detect>, reason='Each ensemble counts a crossing at the interface after its middle one; the analysis reads [tis] detect only for the one ensemble of a tis run with [tis] ensemble_number.', use='', accepted=(), tasks=frozenset({'tis', 'retis', 'pptis', 'repptis', 'make-tis-files', 'explore'}), read_as='', read_as_first=False), NoEffect(canonical='tis.rgen', applies=<function _no_in_process_kick>, reason="The in-process kick initiation builds a generator from it; the scheduler, the parallel kick phase and the load initiation hand every engine and ensemble a stream of numpy's PCG64 generator spawned from [simulation] seed. The kick draws the velocities with it.", use='', accepted=('pcg64',), tasks=frozenset({'tis', 'retis', 'pptis', 'repptis', 'make-tis-files', 'explore'}), read_as='', read_as_first=False), NoEffect(canonical='engine.rgen', applies=<function _no_in_process_kick>, reason="The in-process kick initiation builds a generator from it; the scheduler, the parallel kick phase and the load initiation hand every engine and ensemble a stream of numpy's PCG64 generator spawned from [simulation] seed. The kick engine takes it when its class takes a generator.", use='', accepted=('pcg64',), tasks=frozenset({'tis', 'retis', 'pptis', 'repptis', 'make-tis-files', 'explore'}), read_as='', read_as_first=False), NoEffect(canonical='system.rgen', applies=<function _no_in_process_kick>, reason="The in-process kick initiation builds a generator from it; the scheduler, the parallel kick phase and the load initiation hand every engine and ensemble a stream of numpy's PCG64 generator spawned from [simulation] seed. The kick hands it to an engine without a generator of its own.", use='', accepted=('pcg64',), tasks=frozenset({'tis', 'retis', 'pptis', 'repptis', 'make-tis-files', 'explore'}), read_as='', read_as_first=False), NoEffect(canonical='retis.rgen', applies=<function _every_run>, reason="The scheduler builds its generators with numpy's default_rng (PCG64) from [simulation] seed.", use='', accepted=('pcg64',), tasks=frozenset({'tis', 'retis', 'pptis', 'repptis', 'make-tis-files', 'explore'}), read_as='', read_as_first=False), NoEffect(canonical='engine0', applies=<function _uses_no_engine0>, reason='No ensemble of this run runs the engine of [engine0]: with [simulation] ensemble_engines, each ensemble whose list names it runs it, and without it the [0^-] ensemble of a run with [tis] quantis = true.', use='', accepted=(), tasks=None, read_as='', read_as_first=False), NoEffect(canonical='engine0.rgen', applies=<function _every_run>, reason='The scheduler hands the engine of the section a stream spawned from [simulation] seed on every move, and the in-process kick initiation builds its engines from [engine].', use='', accepted=('pcg64',), tasks=frozenset({'tis', 'retis', 'pptis', 'repptis', 'make-tis-files', 'explore'}), read_as='', read_as_first=False), NoEffect(canonical='engine.subcycles', applies=<function _integrates_one_step_per_frame>, reason='An md, md-nve or md-flux run stores a step after each integration step of an internal integrator (Verlet, VelocityVerlet, Langevin), whatever subcycles.', use='', accepted=(1,), tasks=frozenset({'md-nve', 'md', 'md-flux'}), read_as='', read_as_first=False), NoEffect(canonical='output.backup', applies=<function _every_run>, reason='A setting of the output of the in-process tasks (md, md-flux): the scheduler writes its own output files, and the in-process initiation of the initial paths writes the same files whatever the value; the tis run of each input make-tis-files writes runs the scheduler.', use='', accepted=(), tasks=frozenset({'tis', 'retis', 'pptis', 'repptis', 'make-tis-files', 'explore'}), read_as='', read_as_first=False), NoEffect(canonical='output.cross-file', applies=<function _every_run>, reason='A setting of the output of the in-process tasks (md, md-flux): the scheduler writes its own output files, and the in-process initiation of the initial paths writes the same files whatever the value; the tis run of each input make-tis-files writes runs the scheduler.', use='', accepted=(), tasks=frozenset({'tis', 'retis', 'pptis', 'repptis', 'make-tis-files', 'explore'}), read_as='', read_as_first=False), NoEffect(canonical='output.pathensemble-file', applies=<function _every_run>, reason='A setting of the output of the in-process tasks (md, md-flux): the scheduler writes its own output files, and the in-process initiation of the initial paths writes the same files whatever the value; the tis run of each input make-tis-files writes runs the scheduler.', use='', accepted=(), tasks=frozenset({'tis', 'retis', 'pptis', 'repptis', 'make-tis-files', 'explore'}), read_as='', read_as_first=False), NoEffect(canonical='output.prefix', applies=<function _every_run>, reason='A setting of the output of the in-process tasks (md, md-flux): the scheduler writes its own output files, and the in-process initiation of the initial paths writes the same files whatever the value; the tis run of each input make-tis-files writes runs the scheduler.', use='', accepted=(), tasks=frozenset({'tis', 'retis', 'pptis', 'repptis', 'make-tis-files', 'explore'}), read_as='', read_as_first=False), NoEffect(canonical='output.restart-file', applies=<function _every_run>, reason='A setting of the output of the in-process tasks (md, md-flux): the scheduler writes its own output files, and the in-process initiation of the initial paths writes the same files whatever the value; the tis run of each input make-tis-files writes runs the scheduler.', use='', accepted=(), tasks=frozenset({'tis', 'retis', 'pptis', 'repptis', 'make-tis-files', 'explore'}), read_as='', read_as_first=False), NoEffect(canonical='output.trajectory-file', applies=<function _every_run>, reason='A setting of the output of the in-process tasks (md, md-flux): the scheduler writes its own output files, and the in-process initiation of the initial paths writes the same files whatever the value; the tis run of each input make-tis-files writes runs the scheduler.', use='', accepted=(), tasks=frozenset({'tis', 'retis', 'pptis', 'repptis', 'make-tis-files', 'explore'}), read_as='', read_as_first=False))

The input keys and sections whose value takes no effect on a run, with the runs it takes none on. The settings parse of a TOML input refuses each one the input gives on such a run, and the run record leaves each one out there. The rgen key of each numbered engine section of a pool takes the entry _pool_engine_rgen() gives.

pyretis.inout.key_table.N_JUMPS_DEFAULT = 2

The number of jumps of a wire-fencing move, and the number of sub-path sets of a multiresolution wire-fencing move, when the input sets no [tis] n_jumps. Stone skipping and web throwing take no default: the input of a run with one of them sets n_jumps (pyretis.inout.checker.n_jumps_problem()).

class pyretis.inout.key_table.NoEffect(canonical: str, applies: Callable[[Mapping[str, Any]], bool], reason: str = '', use: str = '', accepted: tuple[Any, ...] = (), tasks: frozenset[str] | None = frozenset({'explore', 'make-tis-files', 'pptis', 'repptis', 'retis', 'tis'}), read_as: str = '', read_as_first: bool = False)

Bases: object

An input key, or a section, whose value takes no effect on a run.

The settings parse of a TOML input refuses a key the input gives on a run it takes no effect on, unless the value is one of accepted (refused_settings()). The run record leaves out the key on such a run: its value there is the parse’s default or a value the parse derives from the other keys, or one of accepted, which the parse gives as well.

Variables:
  • canonical (str) – The dotted input key, or the name of a section for a rule on the whole section.

  • applies (callable) – applies(settings) is True for the runs on which the value takes no effect. It is given the parsed settings with the defaults of the [initial-path] keys of RUN_DEFAULTS resolved.

  • reason (str) – Why the value takes no effect on those runs.

  • use (str) – The input key that sets what the key would set, as a message names it ("[retis] swapfreq"); empty when no key does.

  • accepted (tuple) – The values the run takes for the key: a value among them states what the run does, and is accepted on every run.

  • tasks (frozenset of str or None) – The [simulation] task values of the runs the entry is read for, RUN_TASKS by default; None for every task.

  • read_as (str) – For a key whose value an earlier PyRETIS took as the value of another input key, the dotted input key a run file written by it is read with the value under; empty for every other key.

  • read_as_first (bool) – True when that PyRETIS took the value of the key before the value of read_as, so the value of the key is the one the run took when a run file holds both.

accepted: tuple[Any, ...] = ()
applies: Callable[[Mapping[str, Any]], bool]
canonical: str
read_as: str = ''
read_as_first: bool = False
reads(task: str) → bool

Return whether the entry is read for a run of a task.

Parameters:

task (str) – The [simulation] task of the run, lower case.

Returns:

bool – True when tasks is None or holds the task.

reason: str = ''
tasks: frozenset[str] | None = frozenset({'explore', 'make-tis-files', 'pptis', 'repptis', 'retis', 'tis'})
use: str = ''
class pyretis.inout.key_table.NotCarried(canonical: str, note: str = '')

Bases: object

A canonical key, or a whole section, that reaches no scheduler path.

Variables:
  • canonical (str) – The dotted canonical path. A section name stands for every key of the section.

  • note (str) – What reads the key, when something does.

canonical: str
note: str = ''
pyretis.inout.key_table.PERM_N_SAMPLES_DEFAULT = 10000

The samples of the stochastic permanent of a larger block when the input sets no [tis] perm_n_samples.

pyretis.inout.key_table.PERM_THRESHOLD_DEFAULT = 12

The largest block of the swap-probability matrix whose permanent the scheduler computes exactly when the input sets no [tis] perm_threshold.

pyretis.inout.key_table.PICK_SCHEME_DEFAULT = 0

The exponent of the ensemble weights in the scheduler’s pick of the next ensemble when the input sets no [simulation] pick_scheme: 0, an unweighted pick (pyretis.simulation.setup.apply_config_defaults()).

pyretis.inout.key_table.PPTIS_MEMORY_DEFAULT = 1

The PPTIS memory, the half-width of each local window, of a repptis or pptis run whose input sets no memory.

pyretis.inout.key_table.RENAMED = 'renamed'

The kind of a scheduler path with another key name.

pyretis.inout.key_table.REQUIRED = _Marker.REQUIRED

The default of an always entry whose source the input must give.

pyretis.inout.key_table.RUN_DEFAULTS: tuple[RunDefault, ...] = (RunDefault(canonical='simulation.pick_scheme', value=0, applies=<function _every_run>, given_by=(), scheduler='simulation.pick_scheme', reader='pyretis.simulation.setup.apply_config_defaults; the scheduler picks the next ensemble of every run with it.'), RunDefault(canonical='retis.swapfreq', value=0.5, applies=<function _swapping_run>, given_by=(), scheduler='simulation.zeroswap', reader='The table gives a repptis run the default, and pyretis.simulation.setup.apply_config_defaults a retis run; tis, explore and pptis runs attempt no swap. [retis] swapfreq is the one input name of the probability.'), RunDefault(canonical='repptis.memory', value=1, applies=<function _repptis_run>, given_by=(), scheduler='simulation.repptis_memory', reader='The table (simulation.repptis_memory).'), RunDefault(canonical='pptis.memory', value=1, applies=<function _pptis_run>, given_by=(), scheduler='simulation.repptis_memory', reader='The table (simulation.repptis_memory).'), RunDefault(canonical='tis.freq', value=0.0, applies=<function _every_run>, given_by=(), scheduler='simulation.tis_set.freq', reader='The scheduler (InfSwapState), for every run.'), RunDefault(canonical='tis.perm_threshold', value=12, applies=<function _every_run>, given_by=(), scheduler='simulation.tis_set.perm_threshold', reader='The scheduler (InfSwapState), for every run.'), RunDefault(canonical='tis.perm_n_samples', value=10000, applies=<function _every_run>, given_by=(), scheduler='simulation.tis_set.perm_n_samples', reader='The scheduler (InfSwapState), for every run.'), RunDefault(canonical='tis.exact_perm_only', value=False, applies=<function _every_run>, given_by=(), scheduler='simulation.tis_set.exact_perm_only', reader='The scheduler (InfSwapState), for every run.'), RunDefault(canonical='tis.mwf_nsubpath', value=3, applies=<function _multiresolution_run>, given_by=(), scheduler='simulation.tis_set.mwf_nsubpath', reader='The multiresolution wire-fencing move (multires_wf).'), RunDefault(canonical='tis.n_jumps', value=2, applies=<function _wire_fencing_run>, given_by=(), scheduler='simulation.tis_set.n_jumps', reader='The wire-fencing move (moves.wire_fencing) and the multiresolution wire-fencing move (multires_wf).'), RunDefault(canonical='initial-path.method', value='kick', applies=<function _every_run>, given_by=(), scheduler=None, reader='The run routing (pyretis.bin.pyretisrun) and the initiation.'), RunDefault(canonical='initial-path.kick-from', value='initial', applies=<function _kick_initiation>, given_by=(), scheduler=None, reader='The kick initiation.'), RunDefault(canonical='initial-path.kick-parallel', value=False, applies=<function _kick_from_initial>, given_by=(), scheduler=None, reader='The run routing, for a kick from the initial configuration.'), RunDefault(canonical='initial-path.load_folder', value='load', applies=<function _load_initiation>, given_by=(), scheduler=None, reader='The load initiation.'), RunDefault(canonical='initial-path.load_and_kick', value=False, applies=<function _load_initiation>, given_by=(), scheduler=None, reader='The load initiation, for a loaded path its ensemble refuses.'), RunDefault(canonical='tis.kick_maxtries', value=100000, applies=<function _kicking_initiation>, given_by=(), scheduler='simulation.tis_set.kick_maxtries', reader='The engines, in the crossing search of a kick.'), RunDefault(canonical='tis.initial_path_maxtries', value=1000, applies=<function _kicking_initiation>, given_by=(), scheduler='simulation.tis_set.initial_path_maxtries', reader='The kick initiation (generate_initial_path_kick).'), RunDefault(canonical='tis.initial_path_fix_maxtries', value=1000, applies=<function _kicking_initiation>, given_by=(), scheduler='simulation.tis_set.initial_path_fix_maxtries', reader='The kick initiation (fix_path_by_tis).'))

The input keys a run reads with a default of its own, with the runs that read them. An entry sees the defaults of the entries before it.

pyretis.inout.key_table.RUN_TASKS = frozenset({'explore', 'make-tis-files', 'pptis', 'repptis', 'retis', 'tis'})

The tasks of the runs NO_EFFECT reads an entry for by default: the path-sampling tasks the scheduler runs, and make-tis-files, which writes the input of a tis run of each ensemble with the settings of its own input.

class pyretis.inout.key_table.RunDefault(canonical: str, value: Any, applies: Callable[[Mapping[str, Any]], bool], given_by: tuple[str, ...] = (), scheduler: str | None = None, reader: str = '')

Bases: object

An input key a run reads with a default of its own.

The settings parse leaves such a key out when the input does, and the table sets the key’s scheduler path, when it has one, only from a value the input gives. The part of the run that reads the key then takes the default: the completion of the scheduler configuration (pyretis.simulation.setup.apply_config_defaults()), a derived entry of the table, the scheduler, the initiation or a move. The run record writes the default under the input key (resolved_defaults()), so the record holds the value the run takes.

Variables:
  • canonical (str) – The dotted input key the record writes.

  • value (object) – The default the run takes.

  • applies (callable) – applies(canonical_config) is True for the runs that read the key. It is given the settings with the defaults of the entries before it resolved.

  • given_by (tuple of str) – The input keys whose value, when one is set and not None, the run takes for the key; the default applies when none is set. Empty for the key itself alone.

  • scheduler (str or None) – The dotted scheduler path the key reaches, or None for a key the run reads from the canonical settings alone.

  • reader (str) – What reads the key with the default.

applies: Callable[[Mapping[str, Any]], bool]
canonical: str
given_by: tuple[str, ...] = ()
reader: str = ''
scheduler: str | None = None
property sources: tuple[str, ...]

Return the input keys that give the run a value for the key.

Returns:

tuple of str – given_by, or the key itself when that is empty.

value: Any
pyretis.inout.key_table.SAME = 'same'

The kind of a scheduler path with the canonical section and key name.

pyretis.inout.key_table.TABLE: tuple[KeyEntry, ...] = (KeyEntry(scheduler='runner.workers', sources=('runner.workers',), kind='derived', when=None, default=None, convert=None, derive=<function _workers>, gate=None, note='The environment variables PYRETIS_WORKERS and PYRETIS_NATIVE_WORKERS override the input.'), KeyEntry(scheduler='runner.wmdrun', sources=('runner.wmdrun',), kind='same', when='when true', default=None, convert=None, derive=None, gate=None, note='One MD-launch command per worker, indexed by worker; a list shorter than the worker count is refused.'), KeyEntry(scheduler='simulation.interfaces', sources=('simulation.interfaces',), kind='same', when='always', default=<_Marker.REQUIRED: 'REQUIRED'>, convert=<class 'list'>, derive=None, gate=None, note=''), KeyEntry(scheduler='simulation.steps', sources=('simulation.steps',), kind='same', when='always', default=0, convert=<class 'int'>, derive=None, gate=None, note='The total cycle target.'), KeyEntry(scheduler='simulation.seed', sources=('simulation.seed',), kind='same', when='always', default=0, convert=<class 'int'>, derive=None, gate=None, note="The scheduler's random streams are spawned from it; a non-zero [tis] seed that differs from it is refused."), KeyEntry(scheduler='simulation.load_dir', sources=('simulation.load_dir',), kind='same', when='always, default when empty', default='accepted', convert=None, derive=None, gate=None, note='The per-ensemble archive subdirectory, and the flat store a staged load directory is read from.'), KeyEntry(scheduler='simulation.shooting_moves', sources=('tis.shooting_moves', 'tis.shooting_move', 'tis.move', 'simulation.interfaces'), kind='derived', when=None, default=None, convert=None, derive=<function _shooting_moves>, gate=None, note="One code per interface: the [tis] shooting_moves list, else the one [tis] shooting_move (or move) for every ensemble; 'exp' becomes 'sh'. The settings parser refuses [tis] move, so it only reaches here in a configuration built in code."), KeyEntry(scheduler='simulation.tis_set.maxlength', sources=('tis.maxlength',), kind='moved', when='always', default=20000, convert=None, derive=None, gate=None, note=''), KeyEntry(scheduler='simulation.tis_set.allowmaxlength', sources=('tis.allowmaxlength',), kind='moved', when='always', default=False, convert=None, derive=None, gate=None, note=''), KeyEntry(scheduler='simulation.tis_set.zero_momentum', sources=('tis.zero_momentum',), kind='moved', when='when present', default=None, convert=None, derive=None, gate=None, note=''), KeyEntry(scheduler='simulation.tis_set.sigma_v', sources=('tis.sigma_v',), kind='moved', when='when present', default=None, convert=None, derive=None, gate=None, note='Its sign selects aimless or soft shooting.'), KeyEntry(scheduler='simulation.tis_set.rescale_energy', sources=('tis.rescale_energy',), kind='moved', when='when present', default=None, convert=None, derive=None, gate=None, note=''), KeyEntry(scheduler='simulation.tis_set.n_jumps', sources=('tis.n_jumps',), kind='moved', when='when present', default=None, convert=None, derive=None, gate=None, note=''), KeyEntry(scheduler='simulation.tis_set.interface_cap', sources=('tis.interface_cap',), kind='moved', when='when present', default=None, convert=None, derive=None, gate=None, note=''), KeyEntry(scheduler='simulation.tis_set.kick_maxtries', sources=('tis.kick_maxtries',), kind='moved', when='when not None', default=None, convert=None, derive=None, gate=None, note=''), KeyEntry(scheduler='simulation.tis_set.initial_path_maxtries', sources=('tis.initial_path_maxtries',), kind='moved', when='when not None', default=None, convert=None, derive=None, gate=None, note=''), KeyEntry(scheduler='simulation.tis_set.initial_path_fix_maxtries', sources=('tis.initial_path_fix_maxtries',), kind='moved', when='when not None', default=None, convert=None, derive=None, gate=None, note=''), KeyEntry(scheduler='simulation.tis_set.quantis', sources=('tis.quantis',), kind='moved', when='when true', default=None, convert=<class 'bool'>, derive=None, gate=None, note=''), KeyEntry(scheduler='simulation.tis_set.accept_all', sources=('tis.accept_all',), kind='moved', when='when true', default=None, convert=<class 'bool'>, derive=None, gate=None, note=''), KeyEntry(scheduler='simulation.tis_set.high_accept', sources=('tis.high_accept',), kind='moved', when='always', default=True, convert=None, derive=None, gate=None, note='Carried on every translation, because the moves read an absent key as Metropolis acceptance.'), KeyEntry(scheduler='simulation.tis_set.interface_sour', sources=('tis.interface_sour',), kind='moved', when='when not None', default=None, convert=None, derive=None, gate=None, note=''), KeyEntry(scheduler='simulation.tis_set.mwf_subcycle_small', sources=('tis.mwf_subcycle_small',), kind='moved', when='when not None', default=None, convert=None, derive=None, gate=None, note=''), KeyEntry(scheduler='simulation.tis_set.mwf_subcycle_small_by_ensemble', sources=('tis.mwf_subcycle_small_by_ensemble',), kind='moved', when='when not None', default=None, convert=None, derive=None, gate=None, note=''), KeyEntry(scheduler='simulation.tis_set.mwf_nsubpath', sources=('tis.mwf_nsubpath',), kind='moved', when='when not None', default=None, convert=None, derive=None, gate=None, note=''), KeyEntry(scheduler='simulation.tis_set.perm_threshold', sources=('tis.perm_threshold',), kind='moved', when='when not None', default=None, convert=None, derive=None, gate=None, note=''), KeyEntry(scheduler='simulation.tis_set.perm_n_samples', sources=('tis.perm_n_samples',), kind='moved', when='when not None', default=None, convert=None, derive=None, gate=None, note=''), KeyEntry(scheduler='simulation.tis_set.exact_perm_only', sources=('tis.exact_perm_only',), kind='moved', when='when not None', default=None, convert=None, derive=None, gate=None, note=''), KeyEntry(scheduler='simulation.tis_set.enforce_must_cross_m', sources=('tis.enforce_must_cross_m',), kind='moved', when='when present', default=None, convert=<class 'bool'>, derive=None, gate=None, note='Carried whenever present, so that false reaches the sampler, which reads an absent key as true.'), KeyEntry(scheduler='simulation.tis_set.lambda_minus_one', sources=('simulation.zero_left',), kind='renamed', when='when not False', default=None, convert=None, derive=None, gate=None, note='The lambda_{-1} interface that bounds [0^-] on the left.'), KeyEntry(scheduler='simulation.tis_set.permeability', sources=('simulation.permeability',), kind='moved', when='when true', default=None, convert=<class 'bool'>, derive=None, gate=None, note=''), KeyEntry(scheduler='simulation.tis_set.freq', sources=('tis.freq',), kind='moved', when='when not None', default=None, convert=None, derive=None, gate=None, note=''), KeyEntry(scheduler='simulation.tis_set.mirror_freq', sources=('tis.mirror_freq',), kind='moved', when='when not None', default=None, convert=None, derive=None, gate=None, note=''), KeyEntry(scheduler='simulation.tis_set.target_freq', sources=('tis.target_freq',), kind='moved', when='when not None', default=None, convert=None, derive=None, gate=None, note=''), KeyEntry(scheduler='simulation.tis_set.target_indices', sources=('tis.target_indices',), kind='moved', when='when not None', default=None, convert=None, derive=None, gate=None, note=''), KeyEntry(scheduler='simulation.tis_set.explore', sources=('simulation.task',), kind='derived', when=None, default=None, convert=None, derive=<function _explore>, gate=None, note='True for explore; the moves read it off tis_set.'), KeyEntry(scheduler='simulation.zeroswap', sources=('retis.swapfreq', 'simulation.task'), kind='derived', when=None, default=None, convert=None, derive=<function _zeroswap>, gate=None, note='[retis] swapfreq, the one input key of the probability; a repptis run that sets none takes 0.5.'), KeyEntry(scheduler='simulation.pick_scheme', sources=('simulation.pick_scheme',), kind='same', when='when not None', default=None, convert=<class 'int'>, derive=None, gate=None, note=''), KeyEntry(scheduler='simulation.priority_shooting', sources=('simulation.priority_shooting',), kind='same', when='when true', default=None, convert=<class 'bool'>, derive=None, gate=None, note=''), KeyEntry(scheduler='simulation.allow_setting_change', sources=('simulation.allow_setting_change',), kind='same', when='when not None', default=None, convert=<class 'bool'>, derive=None, gate=None, note='The resume compatibility check reads it off this config.'), KeyEntry(scheduler='simulation.relative_shoots', sources=('retis.relative_shoots',), kind='moved', when='when not None', default=None, convert=<function _float_list>, derive=None, gate=None, note='[retis] relative_shoots, the one input key of the weights.'), KeyEntry(scheduler='simulation.repptis', sources=('simulation.task',), kind='derived', when=None, default=None, convert=None, derive=<function _repptis>, gate=None, note='True for pptis and repptis.'), KeyEntry(scheduler='simulation.repptis_memory', sources=('repptis.memory', 'pptis.memory', 'simulation.task'), kind='derived', when=None, default=None, convert=None, derive=<function _repptis_memory>, gate=None, note='[repptis] memory for repptis, [pptis] memory for pptis.'), KeyEntry(scheduler='simulation.noswap', sources=('simulation.task',), kind='derived', when=None, default=None, convert=None, derive=<function _noswap>, gate=None, note='True for tis, pptis and explore.'), KeyEntry(scheduler='simulation.single_tis', sources=('simulation.task', 'simulation.interfaces'), kind='derived', when=None, default=None, convert=None, derive=<function _single_tis>, gate=None, note='True for a tis input with three interfaces.'), KeyEntry(scheduler='simulation.single_tis_ens_num', sources=('tis.ensemble_number', 'ensemble.tis.ensemble_number', 'simulation.task', 'simulation.interfaces'), kind='derived', when=None, default=None, convert=None, derive=<function _single_tis_ens_num>, gate=None, note="Names the single TIS ensemble's directory; the first parsed ensemble's [tis] ensemble_number wins over the input's."), KeyEntry(scheduler='simulation.pptis_no_minus', sources=('simulation.zero_left', 'simulation.flux', 'simulation.task'), kind='derived', when=None, default=None, convert=None, derive=<function _pptis_no_minus>, gate=None, note='Set for pptis only, read through checker.pptis_layout.'), KeyEntry(scheduler='simulation.pptis_no_zero_plus', sources=('simulation.zero_ensemble', 'simulation.task'), kind='derived', when=None, default=None, convert=None, derive=<function _pptis_no_zero_plus>, gate=None, note='Set for pptis only, read through checker.pptis_layout.'), KeyEntry(scheduler='simulation.explore', sources=('simulation.task',), kind='derived', when=None, default=None, convert=None, derive=<function _explore>, gate=None, note='True for explore: N-1 positive ensembles, no [0^-].'), KeyEntry(scheduler='simulation.ensemble_engines', sources=('simulation.ensemble_engines',), kind='same', when='when not None', default=None, convert=None, derive=None, gate=None, note='The engine sections of each ensemble, one list per interface. A run without it runs every ensemble with [engine], the [0^-] of a quantis run with [engine0] (pyretis.simulation.setup.apply_config_defaults).'), KeyEntry(scheduler='engine.class', sources=('engine.class', 'engine.module'), kind='derived', when=None, default=None, convert=None, derive=functools.partial(<function _engine_class>, section='engine'), gate=None, note='Lower case for a built-in engine; the exact name for a module-provided one.'), KeyEntry(scheduler='engine.gmx_format', sources=('engine.gmx_format', 'engine.gmx'), kind='derived', when=None, default=None, convert=None, derive=functools.partial(<function _engine_format>, section='engine', key='gmx_format'), gate=None, note='g96 for a GROMACS engine that names none.'), KeyEntry(scheduler='engine.cp2k_format', sources=('engine.cp2k_format', 'engine.cp2k', 'engine.input_path'), kind='derived', when=None, default=None, convert=None, derive=functools.partial(<function _engine_format>, section='engine', key='cp2k_format'), gate=None, note='Detected from input_path/initial.* for a CP2K engine that names none, else xyz.'), KeyEntry(scheduler='engine.*', sources=('engine.*',), kind='same', when='when present', default=None, convert=None, derive=None, gate=None, note='Every other [engine] key, carried as it is: the engine constructor reads its own keyword arguments from them.'), KeyEntry(scheduler='output.data_dir', sources=('output.data_dir',), kind='same', when='always, default when empty', default='./', convert=None, derive=None, gate=None, note='The root of the per-ensemble output directories.'), KeyEntry(scheduler='output.screen', sources=('output.screen',), kind='same', when='always', default=10, convert=<class 'int'>, derive=None, gate=None, note="The scheduler writes its progress report to the log every 'screen' cycles; 0 writes none."), KeyEntry(scheduler='output.pattern', sources=(), kind='derived', when=None, default=None, convert=None, derive=<function _output_pattern>, gate=None, note='A constant the scheduler writes into its config.'), KeyEntry(scheduler='output.archive_every', sources=('output.archive_every',), kind='same', when='always', default=1, convert=<class 'int'>, derive=None, gate=None, note=''), KeyEntry(scheduler='output.order_file', sources=('output.order-file',), kind='renamed', when='always', default=1, convert=<class 'int'>, derive=None, gate=None, note="An interval in the input; the scheduler's path-file writer reads it as a switch (on when positive)."), KeyEntry(scheduler='output.energy_file', sources=('output.energy-file',), kind='renamed', when='always', default=1, convert=<class 'int'>, derive=None, gate=None, note='As output.order_file.'), KeyEntry(scheduler='output.keep_traj_fnames', sources=('output.keep_traj_fnames',), kind='same', when='when not None', default=None, convert=<class 'list'>, derive=None, gate=None, note=''), KeyEntry(scheduler='output.keep_rejected_status', sources=('output.keep_rejected_status',), kind='same', when='when not None', default=None, convert=None, derive=None, gate=None, note='Carried as given; apply_config_defaults validates it.'), KeyEntry(scheduler='output.log_file', sources=('output.log_file',), kind='same', when='when not None', default=None, convert=None, derive=None, gate=None, note=''), KeyEntry(scheduler='output.log_mode', sources=('output.log_mode',), kind='same', when='when not None', default=None, convert=None, derive=None, gate=None, note=''), KeyEntry(scheduler='output.engine_log', sources=('output.engine_log',), kind='same', when='when not None', default=None, convert=None, derive=None, gate=None, note=''), KeyEntry(scheduler='engine0.class', sources=('engine0.class', 'engine0.module'), kind='derived', when=None, default=None, convert=None, derive=functools.partial(<function _engine_class>, section='engine0'), gate='engine0.class', note='As engine.class, for the quantis [0^-] engine, or an engine [simulation] ensemble_engines names.'), KeyEntry(scheduler='engine0.gmx_format', sources=('engine0.gmx_format', 'engine0.gmx'), kind='derived', when=None, default=None, convert=None, derive=functools.partial(<function _engine_format>, section='engine0', key='gmx_format'), gate='engine0.class', note='As engine.gmx_format.'), KeyEntry(scheduler='engine0.cp2k_format', sources=('engine0.cp2k_format', 'engine0.cp2k', 'engine0.input_path'), kind='derived', when=None, default=None, convert=None, derive=functools.partial(<function _engine_format>, section='engine0', key='cp2k_format'), gate='engine0.class', note='As engine.cp2k_format.'), KeyEntry(scheduler='engine0.*', sources=('engine0.*',), kind='same', when='when present', default=None, convert=None, derive=None, gate='engine0.class', note='Every other [engine0] key, carried as it is.'), KeyEntry(scheduler='orderparameter', sources=('orderparameter',), kind='same', when='when present', default=None, convert=None, derive=None, gate=None, note='The order-parameter creation.'), KeyEntry(scheduler='system', sources=('system',), kind='same', when='when present', default=None, convert=None, derive=None, gate=None, note='The engine and the order-parameter creation.'), KeyEntry(scheduler='box', sources=('box',), kind='same', when='when present', default=None, convert=None, derive=None, gate=None, note='The engine and the order-parameter creation.'), KeyEntry(scheduler='particles', sources=('particles',), kind='same', when='when present', default=None, convert=None, derive=None, gate=None, note='The engine and the order-parameter creation.'), KeyEntry(scheduler='potential', sources=('potential',), kind='same', when='when present', default=None, convert=None, derive=None, gate=None, note='The engine and the order-parameter creation.'), KeyEntry(scheduler='forcefield', sources=('forcefield',), kind='same', when='when present', default=None, convert=None, derive=None, gate=None, note='The engine and the order-parameter creation.'), KeyEntry(scheduler='unit-system', sources=('unit-system',), kind='same', when='when present', default=None, convert=None, derive=None, gate=None, note="The custom unit system [system] units names: every process that builds an internal engine's streaming template registers it, each worker included."), KeyEntry(scheduler='collective-variable', sources=('collective-variable',), kind='same', when='when present', default=None, convert=None, derive=None, gate=None, note='The order-parameter creation.'), KeyEntry(scheduler='shooting-selector', sources=('shooting-selector',), kind='same', when='when present', default=None, convert=None, derive=None, gate=None, note='The biased shooting-point selection.'))

One entry per path of the scheduler configuration.

pyretis.inout.key_table.TIME_REVERSAL_FREQ_DEFAULT = 0.0

The weight of the time-reversal move the scheduler draws per cycle on top of the shooting move when the input sets no [tis] freq: none.

pyretis.inout.key_table.UNSET = _Marker.UNSET

What a derive function returns when it sets no scheduler path.

pyretis.inout.key_table.WHEN_NOT_FALSE = 'when not False'

Set when a source value is present and is not the False object.

pyretis.inout.key_table.WHEN_NOT_NONE = 'when not None'

Set when a source value is present and not None.

pyretis.inout.key_table.WHEN_PRESENT = 'when present'

Set when a source key is present.

pyretis.inout.key_table.WHEN_RULES = ('always', 'always, default when empty', 'when present', 'when not None', 'when true', 'when not False')

Every rule a carried (same, moved or renamed) entry can take.

pyretis.inout.key_table.WHEN_TRUE = 'when true'

Set when a source value is true.

pyretis.inout.key_table.ZEROSWAP_DEFAULT = 0.5

The zero-swap attempt probability of a run whose input sets no [retis] swapfreq: the value pyretis.simulation.setup.apply_config_defaults() gives the scheduler, and the run record writes as [retis] swapfreq.

pyretis.inout.key_table.build_scheduler_config(canonical_config: Mapping[str, Any], environ: Mapping[str, str] | None = None) → dict[str, Any]

Return the scheduler configuration the table forms.

The sections and keys follow the order of TABLE. A section a wildcard entry fills ([engine], [engine0]) lists the keys of its canonical section first, in their order, then the keys the table derives for it.

Parameters:
  • canonical_config (dict) – The parsed canonical configuration.

  • environ (mapping, optional) – The process environment the worker count is read from; None reads os.environ.

Returns:

dict – The nested scheduler configuration; every value is a copy.

Raises:

KeyError – If the configuration lacks a key the translation requires ([simulation] interfaces, the [engine] section).

pyretis.inout.key_table.canonical_items(scheduler_config: Mapping[str, Any]) → tuple[dict[str, Any], tuple[str, ...]]

Return the input keys a scheduler configuration is read from.

The inverse of the table. Each declared path of the configuration (split_declared()) gives its value to the input key the table reads it from:

  • a same, moved or renamed path, a child of a wildcard section and a whole section to its first canonical path (canonical_paths()), when the entry’s rule sets the path from that value; a value the rule does not set (False for a when not False entry, a false value for a when true entry, an empty value for an always, default when empty entry) is the value the scheduler takes for an absent key, and gives no input key;

  • a derived path by the read-back rule of its function (_DERIVED_READ_BACK): to its first source, as the task and the keys of the PPTIS windows (_task_items()), as the memory of the task, as the swap probability of a task that attempts swaps, or to no key for a constant.

A path no entry declares is read back under its own name when NOT_CARRIED declares it, a key the input gives the canonical settings alone; every other one is returned as unread.

Parameters:

scheduler_config (dict) – A scheduler configuration, without [current].

Returns:

  • out[0] (dict) – The value of each input key, keyed by its dotted canonical path, in the order of the configuration; the task first.

  • out[1] (tuple of str) – The paths of the configuration that no entry declares and NOT_CARRIED does not declare, in the order of the configuration.

Raises:

KeyError – If a derived path has no read-back rule (_read_back_rule()).

pyretis.inout.key_table.canonical_paths(scheduler_path: str) → tuple[str, ...]

Return the canonical input paths a scheduler path is read from.

Parameters:

scheduler_path (str) – The dotted scheduler path, e.g. "simulation.tis_set.maxlength" or a path inside a carried section, e.g. "system.temperature" or "engine.integrator.settings".

Returns:

tuple of str – The canonical paths, the input key a message names first; empty for a constant (output.pattern).

Raises:

KeyError – If no entry declares the path.

pyretis.inout.key_table.configured_shooting_moves(canonical_config: dict[str, Any], n_ensembles: int) → list[str]

Build the coordinator shooting_moves list from a canonical config.

The coordinator needs one move code per ensemble (length equal to the number of interfaces). Three canonical spellings are honoured, in precedence order:

  1. [tis] shooting_moves – a per-ensemble list (one code per ensemble). Both the in-process loop and the coordinator index this list as shooting_moves[i] -> ensemble i in the same [0^-] / [0^+] / [i^+] order, so it maps across 1:1 (verified against pyretis.simulation.repex ensemble construction). Its length must equal n_ensembles.

  2. [tis] shooting_move (or the legacy [tis] move) – a single code applied to every ensemble.

  3. nothing – a plain RETIS configuration shoots in every ensemble, i.e. ['sh', 'sh', ...].

Every code must be one of sh / wf / ss / wt / tr / bias.

Parameters:
  • canonical_config (dict) – The parsed canonical configuration.

  • n_ensembles (int) – The number of ensembles, equal to the number of interfaces.

Returns:

list of str – The per-ensemble move codes, length n_ensembles.

pyretis.inout.key_table.forward(canonical_config: Mapping[str, Any], environ: Mapping[str, str] | None = None) → dict[str, Any]

Return the scheduler paths a canonical configuration sets.

Parameters:
  • canonical_config (dict) – The parsed canonical configuration.

  • environ (mapping, optional) – The process environment the worker count is read from; None reads os.environ.

Returns:

dict – The value of every scheduler path the table sets for this configuration, keyed by the dotted path at the table’s granularity: one key per exact entry, one per child of a wildcard section, one per whole section. The values are copies.

Raises:

KeyError – If the configuration lacks a key the translation requires ([simulation] interfaces, the [engine] section).

pyretis.inout.key_table.given_key_name(canonical_path: str, legacy_keys: Mapping[str, str] | None = None) → str

Return how a message names an input key the input gives.

Parameters:
  • canonical_path (str) – The dotted canonical path of the key, e.g. "tis.nullmoves".

  • legacy_keys (dict, optional) – For the canonical form of an input of the legacy-runner schema, the dotted key of that input of each canonical input key the conversion places under another name (pyretis.inout.config_adapter.legacy_input_keys()).

Returns:

str – The key as the canonical input writes it (input_key_name()), followed by the key of the legacy-runner input when legacy_keys gives one: "[tis] nullmoves ([simulation.tis_set] nullmoves of the legacy-runner input)".

pyretis.inout.key_table.input_key_name(canonical_path: str) → str

Return how a message names a canonical input key.

Parameters:

canonical_path (str) – The dotted canonical path, e.g. "tis.maxlength" or "engine.integrator.settings".

Returns:

str – The table and the key, as the input writes them: "[tis] maxlength", "[engine.integrator] settings".

pyretis.inout.key_table.input_keys(scheduler_path: str) → tuple[str, ...]

Return the names of the input keys a scheduler path is read from.

Parameters:

scheduler_path (str) – The dotted scheduler path, e.g. "simulation.tis_set.lambda_minus_one".

Returns:

tuple of str – One name per canonical source of the path (canonical_paths(), input_key_name()), in the order of the table, each once: ("[simulation] zero_left",).

Raises:

KeyError – If no entry declares the path.

pyretis.inout.key_table.is_constant_path(scheduler_path: str) → bool

Return whether the table sets a scheduler path to a constant.

Parameters:

scheduler_path (str) – The dotted scheduler path.

Returns:

bool – True for a derived path with no source (output.pattern).

pyretis.inout.key_table.keys_without_effect(settings: Mapping[str, Any]) → tuple[str, ...]

Return the input keys and sections whose value takes no effect.

Parameters:

settings (dict) – The parsed settings of an input.

Returns:

tuple of str – The dotted input key, or the section name, of every entry of NO_EFFECT whose value takes no effect on the run, in the order of NO_EFFECT.

pyretis.inout.key_table.pool_engine_entries(section: str) → tuple[KeyEntry, ...]

Return the entries of a numbered engine section of a pool.

Parameters:

section (str) – A numbered pool section, e.g. "engine1" (pyretis.inout.settings.is_pool_engine_section()).

Returns:

tuple of KeyEntry – The entries of [engine0] for the section.

Raises:

ValueError – If the name is not the name of a numbered pool section.

pyretis.inout.key_table.refusal_message(refused: tuple[tuple[NoEffect, Any], ...], task: str, legacy_keys: Mapping[str, str] | None = None) → str

Return the message that refuses keys without effect on a run.

Parameters:
  • refused (tuple of (NoEffect, object)) – The entries and values refused_settings() returns.

  • task (str) – The [simulation] task of the run.

  • legacy_keys (dict, optional) – For an input of the legacy-runner schema, the key of that input of each canonical input key the conversion places under another name; each line names it after the canonical key (_refusal_line()).

Returns:

str – One line per key or section, then what to do.

pyretis.inout.key_table.refuse_settings_without_effect(given: Mapping[str, Any], settings: Mapping[str, Any], legacy_keys: Mapping[str, str] | None = None) → None

Refuse an input that gives a key without effect on its run.

Parameters:
  • given (dict) – The settings the input gives, before the parse adds its defaults.

  • settings (dict) – The parsed settings of the input.

  • legacy_keys (dict, optional) – For the canonical form of an input of the legacy-runner schema, the key of that input of each canonical input key the conversion places under another name, which the message names as well (refusal_message()).

Raises:

ValueError – If the input gives a key that refused_settings() returns. The message names each key, its value, why it takes no effect, and the key to set instead when one sets what it would set.

pyretis.inout.key_table.refused_settings(given: Mapping[str, Any], settings: Mapping[str, Any]) → tuple[tuple[NoEffect, Any], ...]

Return the keys an input gives that take no effect on its run.

Parameters:
  • given (dict) – The settings the input gives, before the parse adds its defaults.

  • settings (dict) – The parsed settings of the input.

Returns:

tuple of (NoEffect, object) – Each entry of NO_EFFECT whose key takes no effect on the run and is set by given to a value that is not one of the entry’s accepted values, with that value, in the order of NO_EFFECT.

pyretis.inout.key_table.reset_accepted_settings(given: Mapping[str, Any], settings: dict[str, Any]) → None

Give the keys of no effect set to an accepted value the parse’s value.

An input can set a key that takes no effect on its run to one of the values its entry accepts (NoEffect.accepted), a value that states what the run does: rgen = "pcg64". The run takes the value the settings parse gives an input that leaves the key out: its default, or no value for a key without one ([retis] rgen, the rgen of a numbered engine section of a pool). Each such key of the settings, and of the per-ensemble settings the parse makes from them, is given that value, so the settings are the ones of the input without the key, and the run record, which leaves the key out, gives the run back.

Parameters:
  • given (dict) – The settings the input gives, before the parse adds its defaults; the input gives no key refused_settings() returns.

  • settings (dict) – The parsed settings of the input, changed in place.

pyretis.inout.key_table.resolved_defaults(canonical_config: Mapping[str, Any]) → dict[str, Any]

Return the defaults a run takes for the input keys it leaves out.

A same, moved or renamed entry that is set on every translation (ALWAYS, ALWAYS_OR_DEFAULT) takes its default when no source gives a value its rule accepts. The default is then the value of the entry’s first source, the input key a message names. A key of RUN_DEFAULTS takes its default in a run that reads it when none of the keys that give the run its value is set.

Parameters:

canonical_config (dict) – The parsed canonical configuration.

Returns:

dict – The default of each such input key, keyed by its dotted canonical path, as the entry converts it; empty when the configuration gives every one.

pyretis.inout.key_table.scheduler_place(canonical_path: str) → str

Return the one scheduler path a canonical input key is carried to.

Parameters:

canonical_path (str) – The dotted canonical path, e.g. "tis.maxlength".

Returns:

str – The dotted scheduler path, e.g. "simulation.tis_set.maxlength".

Raises:

KeyError – If the table does not place the key at exactly one scheduler path (see scheduler_places()).

pyretis.inout.key_table.scheduler_places(canonical_path: str) → tuple[tuple[str, str], ...]

Return the scheduler paths a canonical input path reaches.

An entry with a gate reaches its path only when the gate value is true ([engine0] needs a class); the places are listed whatever the gate.

Parameters:

canonical_path (str) – The dotted canonical path, e.g. "tis.maxlength".

Returns:

tuple of (str, str) – One (scheduler path, kind) pair per place, in table order; empty for a key NOT_CARRIED declares.

Raises:

KeyError – If the table neither places the key nor declares it not carried.

pyretis.inout.key_table.split_declared(scheduler_config: Mapping[str, Any]) → tuple[dict[str, Any], list[str]]

Split a scheduler configuration into declared and undeclared paths.

Parameters:

scheduler_config (dict) – A scheduler configuration, e.g. the result of pyretis.inout.config_adapter.to_scheduler_config().

Returns:

  • out[0] (dict) – A copy of the value of every declared path, keyed by the dotted path at the granularity of forward().

  • out[1] (list of str) – The paths no entry declares, in the order of the configuration.

pyretis.inout.key_table.toml_value(value: Any) → str

Return a value on one line, as a TOML input writes it.

Parameters:

value (object) – A value of a TOML document: a boolean, a number, a string, a list or a table of them.

Returns:

str – The value in TOML syntax, e.g. true, "pcg64" or [0.1, 0.2].

pyretis.inout.key_table.without_effect_in_run_file(sections: Mapping[str, Any], settings: Mapping[str, Any] | None) → tuple[dict[str, Any], tuple[tuple[NoEffect, Any], ...], tuple[tuple[NoEffect, Any, Any], ...]]

Return the sections of a run file without the keys of no effect.

A run file written before the settings parse refused the keys of NO_EFFECT can hold them. Each one refused_settings() finds for the run is left out of the sections. A key with a NoEffect.read_as key took effect as that key: its value is set under it when the sections leave that key out, or when the key was taken first (NoEffect.read_as_first), which replaces the value of that key; otherwise the value took no effect, and is left out with the others.

Parameters:
  • sections (dict) – The canonical sections of a run file, without [current].

  • settings (dict or None) – The settings the parse gives from the sections, with no key refused; None for sections the parse cannot read yet, which leaves out the keys of MOVED_KEYS alone, whatever the run.

Returns:

  • out[0] (dict) – A copy of the sections without the keys of no effect, with each value that took effect under its input key.

  • out[1] (tuple of (NoEffect, object)) – The entries and values left out.

  • out[2] (tuple of (NoEffect, object, object)) – The entries and values read under their NoEffect.read_as key, each with the value of that key the sections held and the moved value replaces, or None when they held none.

pyretis.inout.run_record module

The record of a path-sampling run, and the loader that reads it back.

The run file of a path-sampling run, output.toml, holds the record of the run: the canonical input sections, under the names of the input, with every default resolved, and the [current] section, the state the scheduler writes at the start of the run and after every cycle. The record holds no key the settings parse derives from the other keys (DERIVED_SETTINGS), so the file reads as an input of the run.

canonical_record() forms the sections from the parsed settings of a run and checks that the settings parse gives those settings back from them. load_run() reads a run file: it splits [current] off, parses the sections with the parser of the canonical input and translates them with the declared key table (pyretis.inout.config_adapter.to_scheduler_config()). A fresh run, a method = "restart" continuation and pyretis run -i output.toml all build the scheduler configuration of the run this way, so each builds the configuration of the same settings.

A run file with the canonical sections of a run names the [simulation] task of the run and holds no [simulation.tis_set] table (is_run_record()). A file of the scheduler configuration itself, with its [simulation.tis_set] table, is either an input of the legacy-runner schema, without [current] (is_legacy_runner_input()), or a state file of the scheduler shape written by an earlier PyRETIS. load_legacy_run() reads a legacy-runner input in its canonical form: the validated conversion of pyretis.tools.convert_legacy_schema.load_legacy_input() gives its canonical settings, and the record of the run is formed from them as for a canonical input, so the run file of the run holds the canonical sections. load_run() refuses a state file of the scheduler shape, and every other file that holds no canonical sections of a run. scheduler_state_settings() reads the settings of such a state file through the inverse of the key table (pyretis.inout.key_table.canonical_items()), for the analysis of its run.

pyretis.inout.run_record.CURRENT = 'current'

The section of a run file that holds the state of the scheduler.

pyretis.inout.run_record.DERIVED_SETTINGS = (('engine', 'type'), ('engine0', 'type'), ('particles', 'type'), ('engine', 'input_files'), ('engine0', 'input_files'), ('simulation', 'exe_path'), ('engine', 'exe_path'), ('engine0', 'exe_path'))

The keys the settings parse derives from the other keys of an input, as paths of section and key names. The record leaves out each one whose value the parse derives again from the record: the engine and particle type, the input files the GROMACS and CP2K checkers find, and the directory the parse runs in as exe_path.

pyretis.inout.run_record.ENSEMBLE_SETTINGS = 'ensemble'

a copy of the general sections for each ensemble. The record holds none of them: the settings parse of the TOML input of a path-sampling run refuses an [[ensemble]] section, and makes the copies again from the general sections.

Type:

The per-ensemble settings of the parse

pyretis.inout.run_record.RUN_RECORD_KEY = 'run_record'

The key of the scheduler configuration under which pyretis.simulation.setup.setup_config() hands the recorded sections to the scheduler, which writes them into the run file with [current].

class pyretis.inout.run_record.RunRecord(sections: dict[str, Any], settings: dict[str, Any], scheduler_config: dict[str, Any], current: dict[str, Any] | None)

Bases: object

A run file, read back.

Variables:
  • sections (dict) – The canonical record of the run the file records (canonical_record() of settings, see load_run()).

  • settings (dict) – The settings the parser of the canonical input gives from the sections of the file, without the keys that took no effect on the run.

  • scheduler_config (dict) – The scheduler configuration the key table gives from settings, without [current].

  • current (dict or None) – The [current] section of the file, or None when the file holds none.

current: dict[str, Any] | None
scheduler_config: dict[str, Any]
sections: dict[str, Any]
settings: dict[str, Any]
pyretis.inout.run_record.canonical_record(settings: dict[str, Any]) → dict[str, Any]

Return the canonical sections a run records for its settings.

The sections are the parsed settings of the run, under the names of the input, as the canonical TOML writer projects them (pyretis.inout.settings.settings_to_toml_dict(): no [heading], no None value). The defaults are resolved: the settings parse gives the defaults of the settings, and pyretis.inout.key_table.resolved_defaults() the defaults the run takes for the keys the settings leave out: the key table’s (e.g. [simulation] seed = 0) and the ones the completed scheduler configuration holds (pyretis.inout.key_table.RUN_DEFAULTS, e.g. [simulation] pick_scheme = 0). Each key and section whose value takes no effect on the run (pyretis.inout.key_table.keys_without_effect(), e.g. [simulation] rgen, or [engine0] for a run that runs no [engine0] engine) is left out: the settings parse refuses such a key in the input, so its value is the parse’s own, which the parse of the record gives again. Each key of DERIVED_SETTINGS, in turn, is left out when the settings parse of the sections without it still gives the run back: the settings outside the per-ensemble ones, and the scheduler configuration the key table builds (pyretis.inout.key_table.build_scheduler_config()). The per-ensemble settings (ENSEMBLE_SETTINGS) are copies the parse makes of the general sections for each ensemble, and are not recorded: the scheduler reads only the first ensemble’s [tis] ensemble_number from them, which the parse of the record gives again; the check of the record compares the scheduler configuration it gives with the run’s.

Parameters:

settings (dict) – The parsed settings of the run, as pyretis.inout.settings.parse_settings_file() gives them, in the working directory they were parsed in.

Returns:

dict – The TOML-ready canonical sections.

Raises:

ValueError – If the settings parse of the sections, read from a file, does not give the run back. The message names the keys that differ.

pyretis.inout.run_record.has_state(document: dict[str, Any]) → bool

Tell whether a TOML document holds a [current] state.

Parameters:

document (dict) – The document of a TOML file.

Returns:

bool – True when the document has a [current] section.

pyretis.inout.run_record.is_legacy_runner_input(document: dict[str, Any]) → bool

Tell whether a TOML document is an input of the legacy-runner schema.

The legacy-runner schema keeps the [tis] settings in a [simulation.tis_set] table, as the scheduler configuration does (is_scheduler_shaped()). An input holds no [current] state; a document with one is a state file the scheduler wrote.

Parameters:

document (dict) – The document of a TOML file.

Returns:

bool – True when [simulation] holds a tis_set table and the document holds no [current] section.

pyretis.inout.run_record.is_run_record(document: dict[str, Any]) → bool

Tell whether a TOML document holds the canonical sections of a run.

The canonical sections of a run name its [simulation] task, which the scheduler configuration holds under no key, and hold no [simulation.tis_set] table, which the canonical input refuses. A document without a task holds no canonical sections of a run: the settings parse would give it the default task and the default of every setting it leaves out.

Parameters:

document (dict) – The document of a TOML file.

Returns:

bool – True when [simulation] holds a task and no tis_set.

pyretis.inout.run_record.is_scheduler_shaped(document: dict[str, Any]) → bool

Tell whether a TOML document is a scheduler configuration.

The scheduler configuration keeps the [tis] settings in a [simulation.tis_set] table, which the canonical input refuses.

Parameters:

document (dict) – The document of a TOML file.

Returns:

bool – True when [simulation] holds a tis_set table.

pyretis.inout.run_record.load_legacy_run(path: str) → RunRecord

Read an input of the legacy-runner schema in its canonical form.

The input (see is_legacy_runner_input()) is converted by pyretis.tools.convert_legacy_schema.load_legacy_input(), which logs the deprecation notice of the schema, refuses a key that takes no effect on the run, naming the key of the input with the canonical one, and checks that the canonical form gives the scheduler configuration of the input. The record of the run is then formed from the canonical settings as load_run() forms it from the sections of a run file, so the scheduler writes the canonical sections into the run file of the run. The conversion runs in the directory of the input, as load_run() parses a run file in its directory.

Parameters:

path (str) – The legacy-runner input, or a path to it.

Returns:

RunRecord – The canonical record of the run, the canonical settings, the scheduler configuration and no [current] state.

Raises:
  • ValueError – If the input has no canonical form, or gives a key that takes no effect on its run.

  • RuntimeError – If the canonical form does not give the scheduler configuration of the input.

pyretis.inout.run_record.load_run(path: str) → RunRecord

Read a run file with its canonical sections.

[current] is split off first. The canonical sections are parsed by the parser of the canonical input (pyretis.inout.settings.parse_settings_dict()), and the settings are translated by the declared key table (pyretis.inout.config_adapter.to_scheduler_config()). The parse runs in the directory of the run file, the run directory the scheduler wrote it in: the directories the parse derives from its working directory (exe_path) and the engine input files it finds from them are the ones of the run, wherever the reader runs. The keys a run file written before the settings parse refused them holds, and that took no effect on its run, are left out (_sections_with_effect()). The sections of the record are the canonical record of the settings (canonical_record()): the sections of a run file this PyRETIS wrote, and the sections of a run file an earlier one wrote without the keys left out and with the defaults the run takes that the file does not record (such as [output] screen).

Parameters:

path (str) – The run file, e.g. output.toml, or a path to it.

Returns:

RunRecord – The canonical record of the run, the settings, the scheduler configuration and the [current] state of the file.

Raises:

ValueError – If the file is a scheduler configuration (see is_scheduler_shaped()), or holds no canonical sections of a run in any other way (see is_run_record()).

pyretis.inout.run_record.read_run_file(path: str) → dict[str, Any]

Return the TOML document of a run file.

Parameters:

path (str) – The file.

Returns:

dict – The document, as tomllib reads it.

pyretis.inout.run_record.read_scheduler_config(path: str) → dict[str, Any]

Return the scheduler configuration of a run file, with its state.

Parameters:

path (str) – A run file: an output.toml with the canonical sections of a run (is_run_record()), or a state file of the scheduler configuration; or an input of the legacy-runner schema (is_legacy_runner_input()).

Returns:

dict – For a run file with the canonical sections, the scheduler configuration load_run() builds from them; for a legacy-runner input, the one load_legacy_run() builds from its canonical form; for every other file, the file’s document, the scheduler configuration it holds. The [current] state of the file is under "current" when the file holds one.

Raises:
  • ValueError – If a legacy-runner input has no canonical form, or gives a key that takes no effect on its run.

  • RuntimeError – If the canonical form of a legacy-runner input does not give the scheduler configuration of the input.

pyretis.inout.run_record.read_settings(path: str) → dict[str, Any]

Return the canonical settings of an input file or of a run file.

Parameters:

path (str) – A canonical input, an input of the legacy-runner schema, or a run file with a [current] section.

Returns:

dict – The parsed settings: load_run() gives them for a TOML file with a [current] section and the canonical sections of a run, scheduler_state_settings() for a TOML file with a [current] section and the scheduler configuration (see is_scheduler_shaped()), the conversion of pyretis.tools.convert_legacy_schema.load_legacy_input() for an input of the legacy-runner schema (see is_legacy_runner_input()), and pyretis.inout.settings.parse_settings_file() for every other file. A legacy-runner input is converted in the working directory, where the parse of a canonical input runs.

Raises:
  • ValueError – If the file holds a [current] section and the settings of the run cannot be read from it: a state file of the scheduler configuration scheduler_state_settings() refuses, or a file without a [simulation] task (see load_run()); or if a legacy-runner input has no canonical form, or gives a key that takes no effect on its run.

  • RuntimeError – If the canonical form of a legacy-runner input does not give the scheduler configuration of the input.

pyretis.inout.run_record.run_file_document(sections: dict[str, Any], current: dict[str, Any] | None) → dict[str, Any]

Return the document of a run file.

Parameters:
  • sections (dict) – The recorded canonical sections (canonical_record()).

  • current (dict or None) – The [current] state, or None for a run file written before the scheduler starts.

Returns:

dict – The sections, followed by [current] when it is given.

pyretis.inout.run_record.scheduler_state_settings(path: str) → dict[str, Any]

Return the canonical settings of a state file of the scheduler shape.

A state file of the scheduler configuration (see is_scheduler_shaped()) holds the configuration the scheduler ran: the output.toml of a legacy-runner run, or the output.toml or restart.toml of an earlier PyRETIS. The inverse of the key table (pyretis.inout.key_table.canonical_items()) gives each of its settings to the input key the table reads it from, without the settings the parse derives (DERIVED_SETTINGS), and the parser of the canonical input parses them in the directory of the file. The configuration the key table builds from the settings holds every setting of the file (_state_differences()). A setting the file does not hold takes the default of the settings parse: a key the table carries to no scheduler path, the [analysis] section among them unless the file holds one, which a warning says. The ensembles a run builds are the ones its layout flags give. The analysis of the one ensemble of a tis run counts a crossing at [tis] detect when the input gives [tis] ensemble_number; the scheduler configuration of a tis run of one ensemble names the number of the ensemble whether or not the input gave it, and holds no [tis] detect, so the state file of such a run is refused. The analysis of every other run counts the crossings of each ensemble at the interface after its middle one, whatever [simulation] flux and zero_ensemble (pyretis.inout.checker.ensemble_layout()). The keys of no effect a state file holds are left out (_sections_with_effect()).

Parameters:

path (str) – The state file.

Returns:

dict – The parsed settings.

Raises:

ValueError – If the file is the state of a tis run of one ensemble, holds a path the key table reads from no input key, or the configuration of the settings does not give back a setting of the file. The message names the paths.