class propertyestimator.client.PropertyEstimatorClient(connection_options=<propertyestimator.client.ConnectionOptions object>)[source]

The PropertyEstimatorClient is the main object that users of the property estimator will interface with. It is responsible for requesting that a PropertyEstimatorServer estimates a set of physical properties, as well as querying for when those properties have been estimated.

The PropertyEstimatorClient supports two main workflows: one where a PropertyEstimatorServer lives on a remote supercomputing cluster where all of the expensive calculations will be run, and one where the users local machine acts as both the server and the client, and all calculations will be performed locally.


While the API of this class in now close to being final, the internals and implementation are still heavily under development and is subject to rapid changes.


Setting up the client instance:

>>> from propertyestimator.client import PropertyEstimatorClient
>>> property_estimator = PropertyEstimatorClient()

If the PropertyEstimatorServer is not running on the local machine, you will need to specify its address and the port that it is listening on:

>>> from propertyestimator.client import ConnectionOptions
>>> connection_options = ConnectionOptions(server_address='server_address',
>>>                                                         server_port=8000)
>>> property_estimator = PropertyEstimatorClient(connection_options)

To asynchronously submit a request to the running server using the default estimator options:

>>> # Load in the data set of properties which will be used for comparisons
>>> from propertyestimator.datasets import ThermoMLDataSet
>>> data_set = ThermoMLDataSet.from_doi('10.1016/j.jct.2016.10.001')
>>> # Filter the dataset to only include densities measured between 130-260 K
>>> from import Density
>>> data_set.filter_by_property_types(Density)
>>> data_set.filter_by_temperature(min_temperature=130*unit.kelvin, max_temperature=260*unit.kelvin)
>>> # Load in the force field parameters
>>> from openforcefield.typing.engines import smirnoff
>>> from propertyestimator.forcefield import SmirnoffForceFieldSource
>>> smirnoff_force_field = smirnoff.ForceField('smirnoff99Frosst-1.1.0.offxml')
>>> force_field_source = SmirnoffForceFieldSource.from_object(smirnoff_force_field)
>>> request = property_estimator.request_estimate(data_set, force_field_source)

The status of the request can be asynchronously queried by calling

>>> results = request.results()

or the main thread can be blocked until the results are available by calling

>>> results = request.results(synchronous=True)

How the property set will be estimated can easily be controlled by passing a PropertyEstimatorOptions object to the estimate commands.

The calculations layers which will be used to estimate the properties can be controlled for example like so:

>>> from propertyestimator.layers import ReweightingLayer, SimulationLayer
>>> options = PropertyEstimatorOptions(allowed_calculation_layers = [ReweightingLayer,
>>>                                                                  SimulationLayer])
>>> request = property_estimator.request_estimate(data_set, force_field_source, options)

Options for how properties should be estimated can be set on a per property, and per layer basis. For example, the relative uncertainty that properties should estimated to within by the SimulationLayer can be set as:

>>> from propertyestimator.workflow import WorkflowOptions
>>> workflow_options = WorkflowOptions(WorkflowOptions.ConvergenceMode.RelativeUncertainty,
>>>                                    relative_uncertainty_fraction=0.1)
>>> options.workflow_options = {
>>>     'Density': {'SimulationLayer': workflow_options},
>>>     'Dielectric': {'SimulationLayer': workflow_options}
>>> }

Or alternatively, as absolute uncertainty tolerance can be set as:

>>> density_options = WorkflowOptions(WorkflowOptions.ConvergenceMode.AbsoluteUncertainty,
>>>                                   absolute_uncertainty=0.0002 * unit.gram / unit.milliliter)
>>> dielectric_options = WorkflowOptions(WorkflowOptions.ConvergenceMode.AbsoluteUncertainty,
>>>                                      absolute_uncertainty=0.02 * unit.dimensionless)
>>> options.workflow_options = {
>>>     'Density': {'SimulationLayer': density_options},
>>>     'Dielectric': {'SimulationLayer': dielectric_options}
>>> }

The gradients of the observables of interest with respect to a number of chosen parameters can be requested by passing a parameter_gradient_keys parameter. In the below example, gradients will be calculated with respect to both the bond length parameter for the [#6:1]-[#8:2] chemical environment, and the bond angle parameter for the [:1]-[#8:2]-[:3] chemical environment:

>>> from import ParameterGradientKey
>>> parameter_gradient_keys = [
>>>     ParameterGradientKey('Bonds', '[#6:1]-[#8:2]', 'length')
>>>     ParameterGradientKey('Angles', '[*:1]-[#8:2]-[*:3]', 'angle')
>>> ]
>>> request = property_estimator.request_estimate(data_set, force_field_source, options, parameter_gradient_keys)
__init__(connection_options=<propertyestimator.client.ConnectionOptions object>)[source]

Constructs a new PropertyEstimatorClient object.


connection_options (ConnectionOptions) – The options used when connecting to the calculation server.



Constructs a new PropertyEstimatorClient object.

request_estimate(property_set, …[, …])

Requests that a PropertyEstimatorServer attempt to estimate the provided property set using the supplied force field and estimator options.




class Request(request_id, connection_options, client=None)[source]

An object representation of a estimation request which has been sent to a PropertyEstimatorServer instance. This object can be used to query and retrieve the results of the request, or be stored to retrieve the request at some point in the future.

property id

The id of the submitted request.



property server_address

The address of the server that the request was sent to.



property server_port

The port that the server is listening on.


Returns a JSON representation of the Request object.


The JSON representation of the Request object.

Return type


classmethod from_json(json_string)[source]

Creates a new Request object from a JSON representation.


json_string (str) – The JSON representation of the Request object.


The created Request object.

Return type


results(synchronous=False, polling_interval=5)[source]

Retrieve the results of an estimate request.

  • synchronous (bool) – If true, this method will block the main thread until the server either returns a result or an error.

  • polling_interval (int) – If running synchronously, this is the time interval (seconds) between checking if the calculation has finished.


Returns either the results of the requested estimate, or any exceptions which were raised.

If the method is run synchronously then this method will block the main thread until all of the requested properties have been estimated, or an exception is returned.

Return type

PropertyEstimatorResult or PropertyEstimatorException

request_estimate(property_set, force_field_source, options=None, parameter_gradient_keys=None)[source]

Requests that a PropertyEstimatorServer attempt to estimate the provided property set using the supplied force field and estimator options.

  • property_set (PhysicalPropertyDataSet) – The set of properties to attempt to estimate.

  • force_field_source (ForceFieldSource or openforcefield.typing.engines.smirnoff.ForceField) – The source of the force field parameters to use for the calculations.

  • options (PropertyEstimatorOptions, optional) – A set of estimator options. If None, default options will be used.

  • parameter_gradient_keys (list of ParameterGradientKey, optional) – A list of references to all of the parameters which all observables should be differentiated with respect to.


An object which will provide access the the results of the request.

Return type