7.4. ParAMSJob

Starting with AMS2023.1, if you want to run ParAMS through Python it is recommended to use the ParAMSJob class, and to get the results with the corresponding ParAMSResults.

To get started, see the tutorial Getting Started: Python. Many other tutorials also give examples of ParAMSJob and ParAMSResults.

These classes can be used in the normal PLAMS way. See also: Python Scripting with PLAMS

In particular,

  • Specify the job settings in the ParAMSJob.settings.input like you would for other PLAMS jobs

  • ParAMSJob has some convenient functions like add_exit_condition to easily add Exit Conditions, Optimizers, and Stoppers to the input settings.

  • You can run several params runs in parallel by using a parallel JobRunner (and each params run may run multiple optimizers in parallel).

  • Use functions like ParAMSResults.get_loss() to get the loss function and other results

class ParAMSJob(name='plamsjob', use_relative_paths=False, **kwargs)

A class for running ParAMS jobs.

There are some convenient ways of setting up the input file:

To set training set, validation set, job collection, engine collection, and parameter interface, use the special attributes

  • job_collection, engine_collection, parameter_interface, and resume_checkpoint map directly to the yaml (or checkpoint .tar.gz) file. Usage:

    job.job_collection = 'path/to/job_collection.yaml' 
    

    Here the path is automatically converted to an absolute path.

  • training_set and validation_set : you can assign the path to these just as for the previous three:

    job.training_set = 'path/to/training_set.yaml' # can be a relative path
    

    However, job.training_set is actually a PLAMS Settings object, so you can also assign the path and other settings using

    job.training_set.path = '/path/to/training_set.yaml' # must be an absolute path
    job.training_set.LoggingInterval.General = 10
    

Note: If you do not specify paths to the above files they will be read with the default names from the current working directory if they exist (converted to absolute paths in the input file).

To add exit conditions, stoppers, or optimizers, you can use the add_exit_condition(), add_stopper(), and add_optimizer() functions. They are more convenient to use than accessing the settings directly because of the repeated keys in the input file.

Similarly, you can use set_optimizer_selector() and set_generator() to set the Type (and any additional options) easily.

Access the job settings with job.settings, e.g. to set the Task you can set job.settings.input.Task = 'Optimization'.

Example:

job = ParAMSJob(name="my_job")
job.settings.input.Task =  'Optimization'
job.parameter_interface = 'parameter_interface.yaml'
job.training_set = 'training_set.yaml'
job.job_collection = 'job_collection.yaml'
job.add_optimizer("CMAES", {'Sigma0': 0.01, 'PopSize': 4})
job.add_exit_condition("MaxTotalFunctionCalls", 20)
job.set_generator("Perturbation", {'StandardDeviation': 0.03})
job.settings.input.SkipX0 = "No"
job.settings.input.ParallelLevels.Optimizations = 1

print(job.get_input())

job.run()

loss = job.results.get_loss()
print(loss)

You can also create a ParAMSJob directly from a params.in file (e.g. created by a previous job, by the GUI, or by hand) using from_inputfile():

# any relative paths in params.in get converted to absolute paths
# this will load all settings from the input file
job = ParAMSJob.from_inputfile("/path/to/params.in")
print(job.get_input())

If you have a directory with .yaml files (e.g. the jobname.params directory created by the GUI), you can create a ParAMSJob (with empty settings other than for the paths to the .yaml files) using from_yaml():

# job.settings.input will contains paths to the .yaml files but no other settings
job = ParAMSJob.from_yaml("/path/to/directory_with_yaml_files")
print(job.get_input())

To load a previously finished job (settings, and more importantly results), use load_external():

# give the path to the results directory
# If the original job was run with the GUI, it is called "jobname.results"
# Otherwise, the directory is likely called "results"
job = ParAMSJob.load_external("/path/to/jobname.results")
print(job.results.get_loss())
__init__(name='plamsjob', use_relative_paths=False, **kwargs)

See PLAMS SingleJob.__init__()

namestr

The name of the job

use_relative_pathsbool

If True, paths to .yaml and checkpoint files will be copied to the job directory before running, and any absolute paths in the settings will be replaced with the corresponding relative paths. Note: the paths in the settings must still be absolute! They will be replaced when the job is created/run.

classmethod from_yaml(path=None, name='plamsjob', use_relative_paths: bool = False, **kwargs)scm.params.plams.paramsjob.ParAMSJob

Initializes a ParAMSJob with the paths to yaml files taken from a directory

path: str

A directory. Defaults to the current working directory

name: str

Job name

classmethod from_inputfile(path, name='plamsjob', use_relative_paths: bool = False)

Initializes a ParAMSJob with settings taken from an input file (e.g. params.in)

Paths are replaced with absolute paths to enable the running of new jobs

Note: if e.g. job_collection.yaml exists in the same directory as the params.in file, but no JobCollection is specified in the params.in, then the path to that job_collection.yaml file will be inserted into the new ParAMSJob settings. Similarly for training set, validation set, parameter interface, and engine collection.

classmethod load_external(path, name=None, finalize=False)

Method to load a Python ParAMSJob from a previously run (through the GUI or Python) ParAMS job.

This loads the settings from the results/settings_and_initial_data/params.in.

pathstr

This should be the path to the results folder from a previous ParAMS run. The folder is called jobname.results if the job was run via the GUI, and likely called results otherwise.

namestr

Name of the new job.

set_generator(generator_type, value=None)

Sets the Generator. Example: set_generator(“Perturbation”, {‘StandardDeviation’: 0.03})

set_optimizer_selector(selector_type, value=None)

Sets the OptimizerSelector. Example: set_optimizer_selector(“Cycle”)

set_parameters_kernel(kernel_type, value=None)

Sets the kernel applied to the parameter values.

set_lossvalues_kernel(kernel_type, value=None)

Sets the kernel applied to the parameter values.

add_exit_condition(key, value)

Adds an exit condition to the list self.settings.input.ExitCondition (if the list does not yet exist it will be created).

Example:

job.add_exit_condition("MaxTotalFunctionCalls", 10) 
# the above will configure 'job' such that:
# job.settings.input.ExitCondition[-1].Type == 'MaxTotalFunctionCalls'
# job.settings.input.ExitCondition[-1].MaxTotalFunctionCalls == 10

The above gives the following ExitCondition in the input file:

ExitCondition
    Type MaxTotalFunctionCalls
    MaxTotalFunctionCalls 10
End

value can also be a dictionary:

job.add_exit_condition("StopsAfterConvergence", {'OptimizersStopped': 10})

The above gives

ExitCondition
    Type StopsAfterConvergence
    StopsAfterConvergence
        OptimizersStopped 10
    End
End
key: str

The type of ExitCondition.

value: int/float/str or dict

The value

add_stopper(key, value)

Adds a Stopper to the list self.settings.input.Stopper (if it does not yet exist it will be created).

For details, see add_exit_condition().

add_optimizer(key: str, value: Optional[dict] = None)

Adds an optimizer to the list self.settings.input.Optimizer (if it does not yet exist it will be created).

Example:

job.add_optimizer("CMAES", {'Sigma0': 0.01, 'Popsize': 4})

gives

Optimizer
    Type CMAES
    CMAES
        Sigma0 0.01
        Popsize 4
    End
End

in the input file.

key: str

The type of Optimizer

value: dict or Settings

Settings for the type of optimizer.

get_input(use_defaults=True, validate=True)
use_defaultsbool

Try to locate some yaml files in the current working directory if they are not explicitly specified in the settings

validatebool

Validate the written input file, calls validate_input()

classmethod validate_input(inp: str)
inp: str

The contents of a params.in file

Will raise an error if something is wrong with the input (e.g. misspelled key names).

load_settings(path)

Initializes the job.settings from a params.in file

pathstr

Path to params.in

prerun()

If self.use_relative_paths is set, call self._copy_to_relative_paths().

If you override this method and want to maintain the use_relative_paths functionality, you need to call self._copy_to_relative_paths()