def submit_jobs(self, mvals, AGrad=True, AHess=True):
        """
        Submit jobs for evaluating the objective function

        Parameters
        ----------
        mvals: np.ndarray
            mvals array containing the math values of the parameters
        AGrad: bool
            Flag for computing gradients of not
        AHess: bool
            Flag for computing hessian or not

        Notes
        -----
        1. This function is called before wq_complete() and get().
        2. This function should not block.
        """

        # Make the force field based on the current values of the parameters.
        self.FF.make(mvals)

        force_field = smirnoff.ForceField(self.FF.offxml,
                                          allow_cosmetic_attributes=True)

        # strip out cosmetic attributes
        with tempfile.NamedTemporaryFile(mode='w', suffix='.offxml') as file:
            force_field.to_file(file.name, discard_cosmetic_attributes=True)
            force_field = smirnoff.ForceField(file.name)

        # Determine which gradients (if any) we should be estimating.
        parameter_gradient_keys = []

        self._gradient_key_mappings = {}
        self._parameter_units = {}

        if AGrad is True:

            index_counter = 0

            for field_list in self.FF.pfields:

                string_key = field_list[0]
                key_split = string_key.split('/')

                parameter_tag = key_split[0].strip()
                parameter_smirks = key_split[3].strip()
                parameter_attribute = key_split[2].strip()

                # Use the full attribute name (e.g. k1) for the gradient key.
                parameter_gradient_key = ParameterGradientKey(
                    tag=parameter_tag,
                    smirks=parameter_smirks,
                    attribute=parameter_attribute)

                # Find the unit of the gradient parameter.
                parameter_value, is_cosmetic = self._parameter_value_from_gradient_key(
                    parameter_gradient_key)

                if parameter_value is None or is_cosmetic:
                    # We don't wan't gradients w.r.t. cosmetic parameters.
                    continue

                parameter_unit = parameter_value.units
                parameter_gradient_keys.append(parameter_gradient_key)

                self._gradient_key_mappings[
                    parameter_gradient_key] = index_counter
                self._parameter_units[parameter_gradient_key] = parameter_unit

                index_counter += 1

        # Submit the estimation request.
        self._pending_estimate_request = self._client.request_estimate(
            property_set=self._data_set,
            force_field_source=force_field,
            options=self._options.estimation_options,
            parameter_gradient_keys=parameter_gradient_keys)

        logger.info('Requesting the estimation of {} properties, and their '
                    'gradients with respect to {} parameters.\n'.format(
                        self._data_set.number_of_properties,
                        len(parameter_gradient_keys)))

        if self._pending_estimate_request.results(True) is None:

            raise RuntimeError(
                'No `PropertyEstimatorServer` could be found to submit the '
                'calculations to. Please double check that a server is running, '
                'and that the connection settings specified in the input script '
                'are correct.')
Example #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'))
Example #3
0
from propertyestimator import unit
from propertyestimator.backends import ComputeResources
from propertyestimator.properties import ParameterGradient, ParameterGradientKey
from propertyestimator.protocols.miscellaneous import AddValues, FilterSubstanceByRole, SubtractValues, MultiplyValue, \
    DivideValue, WeightByMoleFraction
from propertyestimator.substances import Substance
from propertyestimator.utils.exceptions import PropertyEstimatorException
from propertyestimator.utils.quantities import EstimatedQuantity


@pytest.mark.parametrize("values", [
    [random.randint(1, 10) for _ in range(10)],
    [random.random() for _ in range(10)],
    [random.random() * unit.kelvin for _ in range(10)],
    [EstimatedQuantity(random.random() * unit.kelvin, random.random() * unit.kelvin, f'{x}') for x in range(10)],
    [ParameterGradient(ParameterGradientKey('a', 'b', 'c'), random.random() * unit.kelvin) for x in range(10)]
])
def test_add_values_protocol(values):

    with tempfile.TemporaryDirectory() as temporary_directory:

        add_quantities = AddValues('add')
        add_quantities.values = values

        result = add_quantities.execute(temporary_directory, ComputeResources())

        assert not isinstance(result, PropertyEstimatorException)
        assert add_quantities.result == reduce(operator.add, values)


@pytest.mark.parametrize("values", [