class openff.toolkit.typing.engines.smirnoff.parameters.ParameterAttribute(default=UNDEFINED, unit=None, converter=None, docstring='')[source]

A descriptor for ParameterType attributes.

The descriptors allows associating to the parameter a default value, which makes the attribute optional, a unit, and a custom converter.

Because we may want to have None as a default value, required attributes have the default set to the special type UNDEFINED.

Converters can be both static or instance functions/methods with respective signatures:

converter(value): -> converted_value
converter(instance, parameter_attribute, value): -> converted_value

A decorator syntax is available (see example below).

  • default (object, optional) – When specified, the descriptor makes this attribute optional by attaching a default value to it.

  • unit (openmm.unit.Quantity, optional) – When specified, only quantities with compatible units are allowed to be set, and string expressions are automatically parsed into a Quantity.

  • converter (callable, optional) – An optional function that can be used to convert values before setting the attribute.

See also


A parameter attribute with multiple terms.


Create a parameter type with an optional and a required attribute.

>>> class MyParameter:
...     attr_required = ParameterAttribute()
...     attr_optional = ParameterAttribute(default=2)
>>> my_par = MyParameter()

Even without explicit assignment, the default value is returned.

>>> my_par.attr_optional

If you try to access an attribute without setting it first, an exception is raised.

>>> my_par.attr_required
Traceback (most recent call last):
AttributeError: 'MyParameter' object has no attribute '_attr_required'

The attribute allow automatic conversion and validation of units.

>>> from openmm import unit
>>> class MyParameter:
...     attr_quantity = ParameterAttribute(unit=unit.angstrom)
>>> my_par = MyParameter()
>>> my_par.attr_quantity = '1.0 * nanometer'
>>> my_par.attr_quantity
Quantity(value=1.0, unit=nanometer)
>>> my_par.attr_quantity = 3.0
Traceback (most recent call last):
openff.toolkit.utils.utils.IncompatibleUnitError: attr_quantity=3.0 dimensionless should have units of angstrom

You can attach a custom converter to an attribute.

>>> class MyParameter:
...     # Both strings and integers convert nicely to floats with float().
...     attr_all_to_float = ParameterAttribute(converter=float)
...     attr_int_to_float = ParameterAttribute()
...     @attr_int_to_float.converter
...     def attr_int_to_float(self, attr, value):
...         # This converter converts only integers to float
...         # and raise an exception for the other types.
...         if isinstance(value, int):
...             return float(value)
...         elif not isinstance(value, float):
...             raise TypeError(f"Cannot convert '{value}' to float")
...         return value
>>> my_par = MyParameter()

attr_all_to_float accepts and convert to float both strings and integers

>>> my_par.attr_all_to_float = 1
>>> my_par.attr_all_to_float
>>> my_par.attr_all_to_float = '2.0'
>>> my_par.attr_all_to_float

The custom converter associated to attr_int_to_float converts only integers instead.

>>> my_par.attr_int_to_float = 3
>>> my_par.attr_int_to_float
>>> my_par.attr_int_to_float = '4.0'
Traceback (most recent call last):
TypeError: Cannot convert '4.0' to float
__init__(default=UNDEFINED, unit=None, converter=None, docstring='')[source]


__init__([default, unit, converter, docstring])


Create a new ParameterAttribute with an associated converter.



class UNDEFINED[source]

Custom type used by ParameterAttribute to differentiate between None and undeclared default.


Create a new ParameterAttribute with an associated converter.

This is meant to be used as a decorator (see main examples).