4.7. Parameter Interfaces

Any AMS engine that can be parameterized is represented by an Interface class (derived from BaseParameters). This is mostly acting as a translation layer between the Optimizer and AMS.

4.7.2. Parameter Interface Basics

The following examples showcase the use of the parameter interface to ReaxFF, however, the methods discussed are available to all other interfaces as well. The API is defined through the BaseParameters base class.

>>> # The initialization parameters might be different for every interface
>>> # Here, we are reading the parameters from a force field file
>>> interface = ReaxFFParameters('my_ffield.ff')

A parameter interface behaves like a list. It stores instances of the Parameter class:

>>> interface[0]
>>> len(interface) # The total number of parameters in this instance
>>> # We can iterate over all stored parameters:
>>> for parameter in interface:
...   do_something(parameter)


Although the underlying data structure of the parameter interface is a list, dict-like look-ups are also supported. Instead of accessing an entry by its list index, it can also be accessed by the parameter’s name string:

>>> interface[121].name               # List-like behaviour, same as interface(121)
>>> interface["parameter_name"].name  # Dict-like behaviour

This works because name strings in the same interface are required to be unique, but is slower than a genuine dictionary lookup.

4.7.3. Working with Parameters

The user can interact with a single Parameter by its attributes name, value, range, is_active:

>>> interface[0]
Parameter(50, "x_1", True, (10,100))
>>> interface[0].value
>>> interface[0].name = 'y_1'
>>> interface[0].name
>>> interface[0].is_active
>>> interface[0].range

In addition to single-parameter interactions, the user can interact with all parameters in an interface at once through the attributes names, x, range, is_active:

>>> interface.x           # Returns the `Parameter.value` of every parameter in the interface
>>> [50, 1.23, ..., 321]
>>> interface.names       # Returns the `Parameter.name` of every parameter in the interface
['y_1', 'x_2', ..., 'x_N']
>>> interface.range       # Returns the `Parameter.range` of every parameter in the interface
[(10, 100), ..., (0,1)]
>>> interface.is_active   # Returns the `Parameter.is_active` of every parameter in the interface
[True, False, ..., True]


The attributes range, is_active are present in both, Parameter and BaseParameters classes.

Any of the above attributes can be used as a setter, to change or set multiple parameter values at once:

>>> interface.x
[50, 1.23, ..., 321]
>>> new_x = interface.x
>>> new_x[0] = 1000.
>>> interface.x = new_x
>>> interface.x
[1000., 1.23, ..., 321]
>>> interface.is_active = len(interface)*[False] # Sets all parameters to is_active=False
>>> not all(interface.is_active)


The above setters only work when the value they are being set to is of the same length as len(interface):

>>> len(interface)
>>> interface.x = [1,2]
ValueError: Len of passed values is not the same as size of this interface.

4.7.4. The Active Parameters Subset


During an optimization, only the active subset of parameters will be optimized.

The dynamic active attribute returns a subset of all parameters that meet the Parameter.is_active==True comparison:

>>> len(interface)
>>> interface.is_active.count(True) # Number of is_active parameters
>>> len(interface.active)
>>> interface.is_active = len(interface)*[False]
>>> len(interface.active)

This subset of a parameter interface behaves just like the main interface:

>>> for active_param in interface.active:
...   do_something(active_param)
>>> interface.active.x     = new_x
>>> interface.active.range = new_ranges
>>> all(interface.active.is_active) # Obviously

4.7.5. Storage

Each parameter interface has a write() method which will write the currently stored parameter values to disk in a format native to the associated engine and readable by AMS. For more information check out the respective parameter interface documentation. Lossless Storage

In most cases, storing an interface with the write() method will not preserve any information that might be relevant for future parameterizations. In such cases, the

methods can be used to store and load the complete instance in a text (yaml) or binary (pkl) format. This preserves all additional parameter attributes such as range or is_active:

>>> ljp1 = LennardJonesParameters()
>>> ljp1[0].value = 42
>>> ljp1[0].range = (0, 43)
>>> ljp1.yaml_store('ljp1.yaml')
>>> ljp2 = LennardJonesParameters.yaml_load('ljp1.yaml')
>>> ljp1 == ljp2
>>> ljp1.pickle_dump('ljp1.pkl')
>>> ljp2 = LennardJonesParameters.pickle_load('ljp1.pkl')
>>> ljp1 == ljp2


The DFTBSplineRepulsivePotentialParameters can only be stored/loaded in binary (pkl) format.

4.7.6. Relation to PLAMS Settings

Each parameter interface can be represented as a PLAMS Settings instance. This happens through the get_engine() method, which returns an intermediary Engine instance:

>>> ljp    = LennardJonesParameters()
>>> engine = ljp.get_engine()
>>> print(engine)
AMSInput: |
   Engine lennardjones
     eps 0.0003
     rmin 3.0

Engine instances are intended to be stored in engine collections whenever data needs to be reproduced or shared. The PLAMS Settings instance associated with each Engine instance can be accessed through the Engine.settings attribute:

>>> print(engine.settings)
                   eps:         0.0003
                   rmin:        3.0

4.7.7. Parameter API

class Parameter(value=None, name=None, is_active=True, range=[None, None], _id=None, _metadata=None)

A helper class representing a single parameter in the BaseParameters.


This class is not public in this module, as it is not possible to create these entries on their own. They can only be managed by an instance of a BaseParameters class.

name : str
Parameter name
value : float
Parameter value
range : Tuple[float, float]

Upper and lower ranges for the parameter value. Anything outside of that range will not be considered by the optimizer.


Providing a range with the same lower and upper values does not automatically set the parameter to is_active=False.

atoms : List[str]
If the parameter is atom-specific, will store a list of all atoms involved in this attribute, empty list otherwise.
is_active : bool
The optimizer will only optimize parameters set to is_active==True. Within a BaseParameters instance, a BaseParameters.active subset is generated based on this attribute.

4.7.8. Interface Base Class API

Base class from which all engine specific parameterizations should derive:

class BaseParameters(names=None, active=None, values=None, ranges=None, parameters=None, _set_ids=True)

A class representing the interface to an arbitrary AMS engine. Classes representing specific engines (e.g. ReaxFF) can derive from this abstract base class.

Will generate entries of a Parameter helper class type. Each entry holds the following attributes: value, range, name, atoms and is_active.


The attributes range and is_active are available to both, the Parameter and BaseParameters classes.

>>> # Init BaseParameters()-derived class
>>> type(self[0])
<class 'scm.params.parameter_interfaces.base.Parameter'>
>>> self[0].range       # The attribute of a single entry, returns a single tuple
>>> self[0].is_active   # The attribute of a single entry, returns a single bool
>>> self.range          # Attributes of all entries in this class, return a list of tuples
[(x1,y1), ..., (xn,yn)]
>>> self.is_active      # Attributes of all entries in this class., return a list of bools
[True, False ..., True]
__init__(names=None, active=None, values=None, ranges=None, parameters=None, _set_ids=True)

Base class constructor to be called from the derived classes. Performs a few basic checks.


names : list or tuple
Data structure holding the unique names of each parameter.
active : list or tuple of bools
Data structure specifying, whether to optimize this parameter (True), or not.
values : list or tuple of floats
Data structure with the initial parameter values.
ranges : list or tuple of (float,float) or [float,float]
Data structure specifying the lower and upper bounds for each parameter.
parameters: optional, List of Parameter instances
Alternative constructor from a list of already initialized Parameter instances. Takes precendence if provided.
_set_ids: bool
Setting of each parameter’s _id is disabled when generating the active subset.
Returns:A list of the current parameter values.

Note: Batch-set all Parameter values with self.x = List[float].
Works only, if len(List[float]) == len(self).

Returns:A list of parameter names.
Returns:A list of bools, marking the parameter active (True) or inactive for an optimization.

Note: Batch-set all Parameter.is_active values with self.is_active = List[bool].
Works only, if len(List[bool]) == len(self).

Returns:A list of parameter ranges.

Note: Batch-set all Parameter ranges with self.is_active = List[Tuple(float,flaot)].
Works only, if len(List[Tuple(float,flaot)]) == len(self)



This subset contains all parameters that will be optimized.

Given the initial set of all parameters in this class, generates and stores a subset in this attribute, which only contains the parameters marked as is_active == True.

The inherits the same properties and methods as its parent (with the exclusion of write() and get_engine()), e.g.:

>>> self.range          # Returns the range  of ALL parameters in this class
>>> self.active.range   # Returns the range  of the active parameters only
>>> self.active.x       # Returns the values of the active parameters only
>>> self.active[0]
>>> len(self.active)

Setting a Parameter.is_active attribute in the parent will include / exclude it from the active subset:

>>> len(self)
>>> len(self.active)
>>> self('ParameterX').is_active
>>> self('ParameterX').is_active = True
>>> len(self.active)
get_engine(parameters=None, path=None, write=True, *args, **kwargs)

Given a set of parameters returns a ready-to-run Engine.


This abstract method has to be overwritten by a derived class. The parameter length check defined here should be propagated with super().get_engine().


Parameters can be None, in which case an instance holding the current paramers will be returned. len(params) should be equal to len(self) or len(self.active).


Children that inherit from this class should lock this method to make it thread-safe:

with self._Lock: # This variable is generated by the base class
Returns:an Engine instance for the given parameters.
write(path, parameters=None)

Abstract method. Child class must have a write() method that stores the engine to disk. If parameters is provided, this method should call super().get_engine(parameters) prior to writing. before writing them to disk.


Children that inherit from this class should lock this method to make it thread-safe:

with self._Lock: # This variable is generated by the base class

Stores the entire parameter interface in a (compressed) human-readable yamlfile.

classmethod yaml_load(yamlfile, force=False)

Loads a parameter interface from a (compressed) human-readable yamlfile. Child classes should call super() in this method before implementing their own routines.


Stores the parameter interface instance in a binary format to fname. Loading it with pickle_load() will restore values, ranges and active settings. If fname does not end with the .pkl extension, it will be added.

classmethod pickle_load(fname)

Loads the parameter interface from a binary file stored with pickle_dump().

Returns:Number of parameters.

Iterates over Parameter entries .

Each entry has the attributes: value, range, name and is_active.


If i is a string, get the Parameter with name i,
if i is an int, get the Parameter at index i.


Same as __getitem__()


Checks if two interfaces are the same


Returns the index of parameter i in the interface, such that i == self[self.index(i)].