# openforcefield.typing.engines.smirnoff.parameters.ParameterType

class `openforcefield.typing.engines.smirnoff.parameters.``ParameterType`(smirks, allow_cosmetic_attributes=False, **kwargs)

  Base class for SMIRNOFF parameter types.

  This base class provides utilities to create new parameter types. See the below for examples of how to do this.

  Warning

  This API is experimental and subject to change.

  See also

  `ParameterAttribute`
  `IndexedParameterAttribute`

  Examples

  This class allows to define new parameter types by just listing its attributes. In the example below, `_VALENCE_TYPE` AND `_ELEMENT_NAME` are used for the validation of the SMIRKS pattern associated to the parameter and the automatic serialization/deserialization into a `dict`.

      >>> class MyBondParameter(ParameterType):
      ...     _VALENCE_TYPE = 'Bond'
      ...     _ELEMENT_NAME = 'Bond'
      ...     length = ParameterAttribute(unit=unit.angstrom)
      ...     k = ParameterAttribute(unit=unit.kilocalorie_per_mole / unit.angstrom**2)
      ...

  The parameter automatically inherits the required smirks attribute from `ParameterType`. Associating a `unit` to a `ParameterAttribute` cause the attribute to accept only values in compatible units and to parse string expressions.

      >>> my_par = MyBondParameter(
      ...     smirks='[*:1]-[*:2]',
      ...     length='1.01 * angstrom',
      ...     k=5 * unit.kilocalorie_per_mole / unit.angstrom**2
      ... )
      >>> my_par.length
      Quantity(value=1.01, unit=angstrom)
      >>> my_par.k = 3.0 * unit.gram
      Traceback (most recent call last):
      ...
      openforcefield.utils.utils.IncompatibleUnitError: k=3.0 g should have units of kilocalorie/(angstrom**2*mole)

  Each attribute can be made optional by specifying a default value, and you can attach a converter function by passing a callable as an argument or through the decorator syntax.

      >>> class MyParameterType(ParameterType):
      ...     _VALENCE_TYPE = 'Atom'
      ...     _ELEMENT_NAME = 'Atom'
      ...
      ...     attr_optional = ParameterAttribute(default=2)
      ...     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 floats
      ...         # 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 = MyParameterType(smirks='[*:1]', attr_all_to_float='3.0', attr_int_to_float=1)
      >>> my_par.attr_optional
      2
      >>> my_par.attr_all_to_float
      3.0
      >>> my_par.attr_int_to_float
      1.0

  The float() function can convert strings to integers, but our custom converter forbids it

      >>> my_par.attr_all_to_float = '2.0'
      >>> my_par.attr_int_to_float = '4.0'
      Traceback (most recent call last):
      ...
      TypeError: Cannot convert '4.0' to float

  Parameter attributes that can be indexed can be handled with the `IndexedParameterAttribute`. These support unit validation and converters exactly as ``ParameterAttribute``s, but the validation/conversion is performed for each indexed attribute.

      >>> class MyTorsionType(ParameterType):
      ...     _VALENCE_TYPE = 'ProperTorsion'
      ...     _ELEMENT_NAME = 'Proper'
      ...     periodicity = IndexedParameterAttribute(converter=int)
      ...     k = IndexedParameterAttribute(unit=unit.kilocalorie_per_mole)
      ...
      >>> my_par = MyTorsionType(
      ...     smirks='[*:1]-[*:2]-[*:3]-[*:4]',
      ...     periodicity1=2,
      ...     k1=5 * unit.kilocalorie_per_mole,
      ...     periodicity2='3',
      ...     k2=6 * unit.kilocalorie_per_mole,
      ... )
      >>> my_par.periodicity
      [2, 3]

  Indexed attributes, can be accessed both as a list or as their indexed parameter name.

      >>> my_par.periodicity2 = 6
      >>> my_par.periodicity[0] = 1
      >>> my_par.periodicity
      [1, 6]

  Attributes
    smirks str

      The SMIRKS pattern that this parameter matches.

    id str or None

      An optional identifier for the parameter.

    parent_id str or None

      Optionally, the identifier of the parameter of which this parameter is a specialization.

  Methods

  `add_cosmetic_attribute`(self, attr_name, …) | Add a cosmetic attribute to this object.
  `attribute_is_cosmetic`(self, attr_name) | Determine whether an attribute of this object is cosmetic.
  `delete_cosmetic_attribute`(self, attr_name) | Delete a cosmetic attribute from this object.
  `to_dict`(self[, discard_cosmetic_attributes]) | Convert this object to dict format.

  `__init__`(self, smirks, allow_cosmetic_attributes=False, **kwargs)

    Create a ParameterType.

    Parameters
      smirks str

        The SMIRKS match for the provided parameter type.

      allow_cosmetic_attributes bool optional. Default = False

        Whether to permit non-spec kwargs (“cosmetic attributes”). If True, non-spec kwargs will be stored as an attribute of this parameter which can be accessed and written out. Otherwise an exception will be raised.

  Methods

  `__init__`(self, smirks[, …]) | Create a ParameterType.
  `add_cosmetic_attribute`(self, attr_name, …) | Add a cosmetic attribute to this object.
  `attribute_is_cosmetic`(self, attr_name) | Determine whether an attribute of this object is cosmetic.
  `delete_cosmetic_attribute`(self, attr_name) | Delete a cosmetic attribute from this object.
  `to_dict`(self[, discard_cosmetic_attributes]) | Convert this object to dict format.

  Attributes

  `id` | A descriptor for `ParameterType` attributes.
  `parent_id` | A descriptor for `ParameterType` attributes.
  `smirks` | A descriptor for `ParameterType` attributes.