Ejemplo n.º 1
0
    def _execute_without_bootstrapping(self, observable_unit, **observables):
        """Calculates the average reweighted observables at the target state,
        using the built-in pymbar method to estimate uncertainties.

        Parameters
        ----------
        observables: dict of str and numpy.ndarray
            The observables to reweight which have been stripped of their units.
        """

        if len(observables) > 1:

            raise ValueError('Currently only a single observable can be reweighted at'
                             'any one time.')

        reference_reduced_potentials, target_reduced_potentials = self._load_reduced_potentials()

        values, uncertainties, self.effective_samples = self._reweight_observables(reference_reduced_potentials,
                                                                                   target_reduced_potentials,
                                                                                   **observables)

        observable_key = next(iter(observables))
        uncertainty = uncertainties[observable_key]

        if self.effective_samples < self.required_effective_samples:

            return PropertyEstimatorException(message=f'{self.id}: There was not enough effective samples '
                                                      f'to reweight - {self.effective_samples} < '
                                                      f'{self.required_effective_samples}')

        self.value = EstimatedQuantity(values[observable_key] * observable_unit,
                                       uncertainty * observable_unit,
                                       self.id)
Ejemplo n.º 2
0
    def _execute_with_bootstrapping(self, observable_unit, **observables):
        """Calculates the average reweighted observables at the target state,
        using bootstrapping to estimate uncertainties.

        Parameters
        ----------
        observable_unit: propertyestimator.unit.Unit:
            The expected unit of the reweighted observable.
        observables: dict of str and numpy.ndarray
            The observables to reweight which have been stripped of their units.

        Returns
        -------
        PropertyEstimatorException, optional
            None if the method executed normally, otherwise the exception that was raised.
        """

        reference_reduced_potentials, target_reduced_potentials = self._load_reduced_potentials()

        frame_counts = np.array([len(observable) for observable in self._reference_observables])

        # Construct a dummy mbar object to get out the number of effective samples.
        mbar = self._construct_mbar_object(reference_reduced_potentials)

        (self.effective_samples,
         effective_sample_indices) = self._compute_effective_samples(mbar, target_reduced_potentials)

        if self.effective_samples < self.required_effective_samples:

            return PropertyEstimatorException(message=f'{self.id}: There was not enough effective samples '
                                                      f'to reweight - {self.effective_samples} < '
                                                      f'{self.required_effective_samples}')

        # Transpose the observables ready for bootstrapping.
        reference_reduced_potentials = np.transpose(reference_reduced_potentials)
        target_reduced_potentials = np.transpose(target_reduced_potentials)

        transposed_observables = {}

        for observable_key in observables:
            transposed_observables[observable_key] = np.transpose(observables[observable_key])

        value, uncertainty = bootstrap(self._bootstrap_function,
                                       self.bootstrap_iterations,
                                       self.bootstrap_sample_size,
                                       frame_counts,
                                       reference_reduced_potentials=reference_reduced_potentials,
                                       target_reduced_potentials=target_reduced_potentials,
                                       **transposed_observables)

        self.effective_sample_indices = effective_sample_indices

        self.value = EstimatedQuantity(value * observable_unit,
                                       uncertainty * observable_unit,
                                       self.id)
Ejemplo n.º 3
0
    def execute(self, directory, available_resources):

        logging.info('Extracting {}: {}'.format(self.statistics_type, self.id))

        if self.statistics_path is None:

            return PropertyEstimatorException(directory=directory,
                                              message='The ExtractAverageStatistic protocol '
                                                       'requires a previously calculated statistics file')

        self._statistics = statistics.StatisticsArray.from_pandas_csv(self.statistics_path)

        if self.statistics_type not in self._statistics:

            return PropertyEstimatorException(directory=directory,
                                              message=f'The {self.statistics_path} statistics file contains no '
                                                      f'data of type {self.statistics_type}.')

        values = self._statistics[self.statistics_type]

        statistics_unit = values[0].units
        unitless_values = values.to(statistics_unit).magnitude

        divisor = self.divisor

        if isinstance(self.divisor, unit.Quantity):
            statistics_unit /= self.divisor.units
            divisor = self.divisor.magnitude

        unitless_values = np.array(unitless_values) / divisor

        unitless_values, self.equilibration_index, self.statistical_inefficiency = \
            timeseries.decorrelate_time_series(unitless_values)

        final_value, final_uncertainty = bootstrap(self._bootstrap_function,
                                                   self.bootstrap_iterations,
                                                   self.bootstrap_sample_size,
                                                   values=unitless_values)

        self.uncorrelated_values = unitless_values * statistics_unit

        self.value = EstimatedQuantity(final_value * statistics_unit,
                                       final_uncertainty * statistics_unit, self.id)

        logging.info('Extracted {}: {}'.format(self.statistics_type, self.id))

        return self._get_output_dictionary()
Ejemplo n.º 4
0
def test_simple_workflow_graph():
    dummy_schema = WorkflowSchema()

    dummy_protocol_a = DummyInputOutputProtocol('protocol_a')
    dummy_protocol_a.input_value = EstimatedQuantity(1 * unit.kelvin, 0.1 * unit.kelvin, 'dummy_source')

    dummy_schema.protocols[dummy_protocol_a.id] = dummy_protocol_a.schema

    dummy_protocol_b = DummyInputOutputProtocol('protocol_b')
    dummy_protocol_b.input_value = ProtocolPath('output_value', dummy_protocol_a.id)

    dummy_schema.protocols[dummy_protocol_b.id] = dummy_protocol_b.schema

    dummy_schema.final_value_source = ProtocolPath('output_value', dummy_protocol_b.id)

    dummy_schema.validate_interfaces()

    dummy_property = create_dummy_property(Density)

    dummy_workflow = Workflow(dummy_property, {})
    dummy_workflow.schema = dummy_schema

    with tempfile.TemporaryDirectory() as temporary_directory:

        workflow_graph = WorkflowGraph(temporary_directory)
        workflow_graph.add_workflow(dummy_workflow)

        dask_local_backend = DaskLocalCluster(1, ComputeResources(1))
        dask_local_backend.start()

        results_futures = workflow_graph.submit(dask_local_backend)

        assert len(results_futures) == 1

        result = results_futures[0].result()
        assert isinstance(result, CalculationLayerResult)
        assert result.calculated_property.value == 1 * unit.kelvin
Ejemplo n.º 5
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)