Пример #1
0
def test_target_jacobian_calculation_finite_difference(physical_param,
                                                       single_exp,
                                                       large_reflection_table):
    """Test the calculated jacobian against a finite difference calculation."""
    test_params, exp, test_refl = physical_param, single_exp, large_reflection_table
    test_params.parameterisation.decay_term = False
    test_params.model = "physical"
    experiments = create_scaling_model(test_params, exp, test_refl)
    assert experiments[0].scaling_model.id_ == "physical"
    scaler = create_scaler(test_params, experiments, test_refl)

    apm = multi_active_parameter_manager([scaler.components], [["scale"]],
                                         scaling_active_parameter_manager)

    target = ScalingTarget()
    scaler.update_for_minimisation(apm, 0)

    fd_jacobian = calculate_jacobian_fd(target, scaler, apm)
    _, jacobian, _ = target.compute_residuals_and_gradients(
        scaler.Ih_table.blocked_data_list[0])

    n_rows = jacobian.n_rows
    n_cols = jacobian.n_cols

    print(jacobian)
    print(fd_jacobian)

    for i in range(0, n_rows):
        for j in range(0, n_cols):
            assert jacobian[i, j] == pytest.approx(fd_jacobian[i, j], abs=1e-4)
Пример #2
0
def test_target_gradient_calculation_finite_difference(small_reflection_table,
                                                       single_exp,
                                                       physical_param):
    """Test the calculated gradients against a finite difference calculation."""
    model = PhysicalScalingModel.from_data(physical_param, single_exp,
                                           small_reflection_table)

    # need to 'add_data'
    model.configure_components(small_reflection_table, single_exp,
                               physical_param)
    model.components["scale"].update_reflection_data()
    model.components["decay"].update_reflection_data()
    apm = multi_active_parameter_manager(
        ScalingTarget(),
        [model.components],
        [["scale", "decay"]],
        scaling_active_parameter_manager,
    )
    model.components["scale"].inverse_scales = flex.double([2.0, 1.0, 2.0])
    model.components["decay"].inverse_scales = flex.double([1.0, 1.0, 0.4])

    Ih_table = IhTable([small_reflection_table],
                       single_exp.crystal.get_space_group())

    with patch.object(SingleScaler, "__init__", lambda x, y, z, k: None):
        scaler = SingleScaler(None, None, None)
        scaler._Ih_table = Ih_table

        # Now do finite difference check.
        target = ScalingTarget()

        scaler.update_for_minimisation(apm, 0)
        grad = target.calculate_gradients(scaler.Ih_table.blocked_data_list[0])
        res = target.calculate_residuals(scaler.Ih_table.blocked_data_list[0])

        assert (res >
                1e-8), """residual should not be zero, or the gradient test
        below will not really be working!"""

        # Now compare to finite difference
        f_d_grad = calculate_gradient_fd(target, scaler, apm)
        print(list(f_d_grad))
        print(list(grad))
        assert list(grad) == pytest.approx(list(f_d_grad))

        sel = f_d_grad > 1e-8
        assert sel, """assert sel has some elements, as finite difference grad should
Пример #3
0
def test_target_jacobian_calculation_finite_difference(physical_param,
                                                       single_exp,
                                                       large_reflection_table):
    """Test the calculated jacobian against a finite difference calculation."""
    physical_param.physical.decay_correction = False
    model = PhysicalScalingModel.from_data(physical_param, single_exp,
                                           large_reflection_table)
    # need to 'add_data'
    model.configure_components(large_reflection_table, single_exp,
                               physical_param)
    model.components["scale"].update_reflection_data()
    apm = multi_active_parameter_manager(
        ScalingTarget(),
        [model.components],
        [["scale"]],
        scaling_active_parameter_manager,
    )
    Ih_table = IhTable([large_reflection_table],
                       single_exp.crystal.get_space_group())

    with patch.object(SingleScaler, "__init__", lambda x, y, z, k: None):
        scaler = SingleScaler(None, None, None)
        scaler._Ih_table = Ih_table

        target = ScalingTarget()
        scaler.update_for_minimisation(apm, 0)

        fd_jacobian = calculate_jacobian_fd(target, scaler, apm)
        r, jacobian, w = target.compute_residuals_and_gradients(
            scaler.Ih_table.blocked_data_list[0])
        assert r == pytest.approx(
            [-50.0 / 3.0, 70.0 / 3.0, -20.0 / 3.0, 12.5, -2.5] +
            [-25.0, 0.0, -75.0, 0.0, 200.0])
        assert w == pytest.approx(
            [0.1, 0.1, 0.1, 0.02, 0.1, 0.02, 0.01, 0.02, 0.01, 0.01])

        n_rows = jacobian.n_rows
        n_cols = jacobian.n_cols

        print(jacobian)
        print(fd_jacobian)

        for i in range(0, n_rows):
            for j in range(0, n_cols):
                assert jacobian[i, j] == pytest.approx(fd_jacobian[i, j],
                                                       abs=1e-4)
Пример #4
0
def test_multi_apm():
    """Test for the general multi_active_parameter_manage class."""

    components_1 = {
        "scale": mock_component(),
        "decay": mock_component(),
        "absorption": mock_component(),
    }
    components_2 = {"scale": mock_component(), "decay": mock_component()}

    multi_apm = multi_active_parameter_manager(
        ScalingTarget(),
        [components_1, components_2],
        [["scale", "decay"], ["scale"]],
        active_parameter_manager,
    )

    # Test correct setup of apm_list attribute.
    for apm in multi_apm.apm_list:
        assert isinstance(apm, active_parameter_manager)
    assert len(multi_apm.apm_list) == 2
    assert multi_apm.components_list == ["scale", "decay", "scale"]
    assert multi_apm.n_active_params == 3
    assert multi_apm.apm_data[0] == {"start_idx": 0, "end_idx": 2}
    assert multi_apm.apm_data[1] == {"start_idx": 2, "end_idx": 3}

    # Test parameter selection.
    multi_apm.set_param_vals(flex.double([3.0, 2.5, 2.0]))
    assert multi_apm.get_param_vals() == flex.double([3.0, 2.5, 2.0])
    assert multi_apm.select_parameters(0) == flex.double([3.0, 2.5])
    assert multi_apm.select_parameters(1) == flex.double([2.0])

    # Test setting parameter esds.
    multi_apm.set_param_esds(flex.double([0.1, 0.2, 0.3]))
    assert components_1["scale"].free_parameter_esds == flex.double([0.1])
    assert components_1["decay"].free_parameter_esds == flex.double([0.2])
    assert components_2["scale"].free_parameter_esds == flex.double([0.3])

    # Test setting var_cov matrices for each component.
    var_cov = flex.double([1.0, 0.5, 0.5, 0.5, 2.0, 0.5, 0.5, 0.5, 3.0])
    var_cov.reshape(flex.grid(3, 3))
    multi_apm.calculate_model_state_uncertainties(var_cov)
    assert components_1["scale"].var_cov_matrix[0, 0] == 1.0
    assert components_1["decay"].var_cov_matrix[0, 0] == 2.0
    assert components_2["scale"].var_cov_matrix[0, 0] == 3.0
Пример #5
0
def test_target_gradient_calculation_finite_difference(small_reflection_table,
                                                       single_exp,
                                                       physical_param):
    """Test the calculated gradients against a finite difference calculation."""
    (test_reflections, test_experiments, params) = (
        small_reflection_table,
        single_exp,
        physical_param,
    )
    assert len(test_experiments) == 1
    assert len(test_reflections) == 1
    experiments = create_scaling_model(params, test_experiments,
                                       test_reflections)
    scaler = create_scaler(params, experiments, test_reflections)
    assert scaler.experiment.scaling_model.id_ == "physical"

    # Initialise the parameters and create an apm
    scaler.components["scale"].inverse_scales = flex.double([2.0, 1.0, 2.0])
    scaler.components["decay"].inverse_scales = flex.double([1.0, 1.0, 0.4])
    apm = multi_active_parameter_manager([scaler.components],
                                         [["scale", "decay"]],
                                         scaling_active_parameter_manager)

    # Now do finite difference check.
    target = ScalingTarget()
    scaler.update_for_minimisation(apm, 0)
    grad = target.calculate_gradients(scaler.Ih_table.blocked_data_list[0])
    res = target.calculate_residuals(scaler.Ih_table.blocked_data_list[0])

    assert (res > 1e-8), """residual should not be zero, or the gradient test
    below will not really be working!"""

    # Now compare to finite difference
    f_d_grad = calculate_gradient_fd(target, scaler, apm)
    print(list(f_d_grad))
    print(list(grad))
    assert approx_equal(list(grad), list(f_d_grad))

    sel = f_d_grad > 1e-8
    assert sel, """assert sel has some elements, as finite difference grad should