# Getting Started

The `propertyestimator` currently exists as two key components:

- a client object which the user can use to request the estimation of data sets of physical properties.

- a server object which accepts requests from a client and performs the estimations.

Warning

These instructions are still a work in progress, and may not run as expected.

## Creating an Estimator Server

The `PropertyEstimatorServer` class creates objects that handle property estimation of all of the properties in a dataset given a set.

Create the file `run_server.py`. Tell server to log to file in case of failure:

    setup_timestamp_logging()

Create directory structure to store intermediary results:

    # Set the name of the directory in which all temporary files
    # will be generated.
    working_directory = 'working_directory'

    # Remove any existing data.
    if path.isdir(working_directory):
        shutil.rmtree(working_directory)

Set up a calculation backend. Different backends will take different optional arguments, but here is an example that will launch a backend with a single worker process:

    # Create a calculation backend to perform workflow
    # calculations on.
    calculation_backend = DaskLocalCluster(1)

Set up storage the storage backend which will cache any generated simulation data:

    # Create a backend to handle storing and retrieving
    # cached simulation data.
    storage_backend = LocalFileStorage()

Start the server running:

    # Create a server instance.
    property_server = server.PropertyEstimatorServer(calculation_backend,
                                                     storage_backend,
                                                     working_directory=working_directory)

    # Tell the server to start listening for incoming
    # estimation requests.
    property_server.start_listening_loop()

To start the server, call the following command from the command line:

    python run_server.py

The server will wait for requests until killed.

## Submitting Estimation Requests

Create the file `run_client.py` Load in the data set of properties to estimate, and the force field parameters to use in the calculations:

    # Load in the data set of interest.
    data_set = ThermoMLDataSet.from_file(get_data_filename('properties/single_density.xml'))

    # Load in the force field to use.
    force_field_source = SmirnoffForceFieldSource.from_path('smirnoff99Frosst-1.1.0.offxml')

Create the client object and use it to send the estimation request to the server:

    # Create the client object.
    property_estimator = client.PropertyEstimatorClient()
    # Submit the request to a running server.
    result = property_estimator.request_estimate(data_set, force_field_source)

Query the result until all of the properties have either been estimated or have errored:

    # Wait for the results synchronously.
    results = request.results(True)
    logging.info('The server has returned a response: {}'.format(result))

Save the results to a file:

    with open('results.json', 'w') as file:

        json_results = json.dump(results, file, sort_keys=True, indent=2,
                                 separators=(',', ': '), cls=TypedJSONEncoder)