Source code for openff.evaluator.datasets.thermoml.plugins

"""A collection of utility functions for registering mappings between
ThermoML archive properties, and properties supported by the estimation
framework.
"""
import functools

from openff.evaluator.datasets.thermoml import ThermoMLDataSet


class _ThermoMLPlugin:
    """Represents a property which may be extracted from a ThermoML archive."""

    def __init__(self, string_identifier, conversion_function, supported_phases):
        """Constructs a new ThermoMLPlugin object.

        Parameters
        ----------
        string_identifier: str
            The ThermoML string identifier (ePropName) for this property.
        conversion_function: function
            A function which maps a `ThermoMLProperty` into a
            `PhysicalProperty`.
        supported_phases: PropertyPhase:
            An enum which encodes all of the phases for which this
            property supports being estimated in.
        """

        self.string_identifier = string_identifier
        self.conversion_function = conversion_function

        self.supported_phases = supported_phases


def _default_mapping(property_class, property_to_map):
    """

    Parameters
    ----------
    property_class: type of PhysicalProperty
        The class to map this property into.
    property_to_map: ThermoMLProperty
        The ThermoML property to map.
    """

    mapped_property = property_class()

    mapped_property.value = property_to_map.value

    if property_to_map.uncertainty is not None:
        mapped_property.uncertainty = property_to_map.uncertainty

    mapped_property.phase = property_to_map.phase

    mapped_property.thermodynamic_state = property_to_map.thermodynamic_state
    mapped_property.substance = property_to_map.substance

    return mapped_property


[docs]def register_thermoml_property( thermoml_string, supported_phases, property_class=None, conversion_function=None ): """A function used to map a property from the ThermoML archive to an internal `PhysicalProperty` object of the correct type. This function takes either a specific class (e.g. `Density`) which maps directly to the specified `thermoml_string`, or a a function which maps a `ThermoMLProperty` into a `PhysicalProperty` allowing fuller control. Parameters ---------- thermoml_string: str The ThermoML string identifier (ePropName) for this property. supported_phases: PropertyPhase: An enum which encodes all of the phases for which this property supports being estimated in. property_class: type of PhysicalProperty, optional The class associated with this physical property. This argument is mutually exclusive with the `conversion_function` argument. conversion_function: function A function which maps a `ThermoMLProperty` into a `PhysicalProperty`. This argument is mutually exclusive with the `property_class` argument. """ if (property_class is None and conversion_function is None) or ( property_class is not None and conversion_function is not None ): raise ValueError( "Only one of the `property_class` and `conversion_function` must be set." ) if conversion_function is None: conversion_function = functools.partial(_default_mapping, property_class) ThermoMLDataSet.registered_properties[thermoml_string] = _ThermoMLPlugin( thermoml_string, conversion_function, supported_phases )
[docs]def thermoml_property(thermoml_string, supported_phases): """A decorator which wraps around the `register_thermoml_property` method. Parameters ---------- thermoml_string: str The ThermoML string identifier (ePropName) for this property. supported_phases: PropertyPhase: An enum which encodes all of the phases for which this property supports being estimated in. """ def decorator(cls): register_thermoml_property(thermoml_string, supported_phases, cls) return cls return decorator