def _initialize(self):
        """Initializes the property estimator target from an input json file.

        1. Reads the user specified input file.
        2. Creates a `propertyestimator` client object.
        3. Loads in a reference experimental data set.
        4. Assigns and normalises weights for each property.
        """

        # Load in the options from a user provided JSON file.
        print(os.path.join(self.tgtdir, self.prop_est_input))
        options_file_path = os.path.join(self.tgtdir, self.prop_est_input)
        self._options = self.OptionsFile.from_json(options_file_path)

        # Attempt to create a property estimator client object using the specified
        # connection options.
        self._client = PropertyEstimatorClient(
            connection_options=self._options.connection_options)

        # Load in the experimental data set.
        data_set_path = os.path.join(self.tgtdir, self._options.data_set_path)

        with open(data_set_path, 'r') as file:
            self._data_set = PhysicalPropertyDataSet.parse_json(file.read())

        if len(self._data_set.properties) == 0:
            raise ValueError(
                'The physical property data set to optimise against is empty.')

        # Convert the reference data into a more easily comparable form.
        self._reference_properties = self._refactor_properties_dictionary(
            self._data_set.properties)

        # Print the reference data, and count the number of instances of
        # each property type.
        printcool("Loaded experimental data from property estimator")

        number_of_properties = {
            property_name: 0.0
            for property_name in self._reference_properties
        }

        for property_name in self._reference_properties:

            for substance_id in self._reference_properties[property_name]:

                dict_for_print = {}

                for state_tuple in self._reference_properties[property_name][
                        substance_id]:

                    value = self._reference_properties[property_name][
                        substance_id][state_tuple]['value']
                    uncertainty = self._reference_properties[property_name][
                        substance_id][state_tuple]['uncertainty']

                    dict_for_print["%sK-%satm" %
                                   state_tuple] = ("%f+/-%f" %
                                                   (value, uncertainty))

                    number_of_properties[property_name] += 1.0

                printcool_dictionary(dict_for_print,
                                     title="Reference %s (%s) data" %
                                     (property_name, substance_id))

        # Assign and normalize weights for each phase point (average for now)
        self._normalised_weights = {}

        for property_name in self._reference_properties:

            self._normalised_weights[property_name] = (
                self._options.weights[property_name] /
                number_of_properties[property_name])
Exemple #2
0
def main():

    setup_timestamp_logging()

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

    # Load in the data set containing a single dielectric
    # property.
    with open('pure_data_set.json') as file:
        data_set = PhysicalPropertyDataSet.parse_json(file.read())

    data_set.filter_by_property_types('DielectricConstant')

    # Set up the server object which run the calculations.
    setup_server(backend_type=BackendType.LocalGPU,
                 max_number_of_workers=1,
                 port=8001)

    # Request the estimates.
    property_estimator = client.PropertyEstimatorClient(
        client.ConnectionOptions(server_port=8001))

    options = PropertyEstimatorOptions()
    options.allowed_calculation_layers = ['SimulationLayer']

    options.workflow_options = {
        'DielectricConstant': {
            'SimulationLayer':
            WorkflowOptions(WorkflowOptions.ConvergenceMode.NoChecks),
            'ReweightingLayer':
            WorkflowOptions(WorkflowOptions.ConvergenceMode.NoChecks)
        }
    }

    parameter_gradient_keys = [
        ParameterGradientKey(tag='vdW', smirks='[#6X4:1]',
                             attribute='epsilon'),
        ParameterGradientKey(tag='vdW',
                             smirks='[#6X4:1]',
                             attribute='rmin_half')
    ]

    request = property_estimator.request_estimate(
        property_set=data_set,
        force_field_source=force_field_source,
        options=options,
        parameter_gradient_keys=parameter_gradient_keys)

    # Wait for the results.
    results = request.results(True, 5)

    # Save the result to file.
    with open('dielectric_simulation.json', 'wb') as file:

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

        file.write(json_results.encode('utf-8'))

    # Attempt to reweight the cached data.
    options.allowed_calculation_layers = ['ReweightingLayer']

    request = property_estimator.request_estimate(
        property_set=data_set,
        force_field_source=force_field_source,
        options=options,
        parameter_gradient_keys=parameter_gradient_keys)

    # Wait for the results.
    results = request.results(True, 5)

    # Save the result to file.
    with open('dielectric_reweight.json', 'wb') as file:

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

        file.write(json_results.encode('utf-8'))
def main():
    """The main script which will create an estimation server, request
    the curated data set be estimated for each force field of interest,
    wait for the calculations to be complete, and save the results.
    """

    setup_timestamp_logging()
    logger = logging.getLogger()

    # Define those force fields to use in the calculations
    force_field_sources = {
        'smirnoff99frosst 1.1.0':
        SmirnoffForceFieldSource.from_path('smirnoff99Frosst-1.1.0.offxml'),
        'parsley 0.0.9':
        SmirnoffForceFieldSource.from_path('smirnoff_release_1_v0_0_9.offxml'),
        'parsley rc 1':
        SmirnoffForceFieldSource.from_path('openff_hbonds-1.0.0-RC1.offxml'),
        'gaff 1.81':
        TLeapForceFieldSource(leap_source='leaprc.gaff'),
        'gaff 2.11':
        TLeapForceFieldSource(leap_source='leaprc.gaff2')
    }

    # Set up the server object which will run the calculations.
    setup_server(max_number_of_workers=50)

    # Set up the client which will request the estimates.
    estimator_client = PropertyEstimatorClient()

    # Load in the data set to estimate.
    with open('curated_data_set.json') as file:
        data_set = PhysicalPropertyDataSet.parse_json(file.read())

    # Specify the estimation options
    protocol_replacements = {
        'gaff_1': {
            'BuildSmirnoffSystem': 'BuildTLeapSystem'
        },
        'gaff_2': {
            'BuildSmirnoffSystem': 'BuildTLeapSystem'
        }
    }

    requests = {}

    # Request estimates using each force field, storing the request
    # object used to query the status of the results.
    for force_field_key in force_field_sources:

        force_field_source = force_field_sources[force_field_key]

        options = get_estimation_options(
            protocol_replacements.get(force_field_key, {}))

        requests[force_field_key] = estimator_client.request_estimate(
            property_set=data_set,
            force_field_source=force_field_source,
            options=options)

    # Wait for the results.
    should_run = True
    finished_force_fields = []

    while should_run:

        sleep(60)

        for force_field_key in force_field_sources:

            if force_field_key in finished_force_fields:
                continue

            results = requests[force_field_key].results(False)

            if isinstance(results, PropertyEstimatorResult) and len(
                    results.queued_properties) > 0:
                continue

            logger.info(f'The server has completed {force_field_key}.')

            # Save the result to file.
            save_results(force_field_key, results)
            finished_force_fields.append(force_field_key)

        if len(finished_force_fields) == len(force_field_sources):
            should_run = False