Ejemplo n.º 1
0
def test_multiscaler_update_for_minimisation():
    """Test the multiscaler update_for_minimisation method."""

    p, e = (generated_param(), generated_exp(2))
    p.reflection_selection.method = "use_all"
    r1 = generated_refl(id_=0)
    r1["intensity.sum.value"] = r1["intensity"]
    r1["intensity.sum.variance"] = r1["variance"]
    r2 = generated_refl(id_=1)
    r2["intensity.sum.value"] = r2["intensity"]
    r2["intensity.sum.variance"] = r2["variance"]
    p.scaling_options.nproc = 2
    p.model = "physical"
    exp = create_scaling_model(p, e, [r1, r2])
    singlescaler1 = create_scaler(p, [exp[0]], [r1])
    singlescaler2 = create_scaler(p, [exp[1]], [r2])

    multiscaler = MultiScaler([singlescaler1, singlescaler2])
    pmg = ScalingParameterManagerGenerator(
        multiscaler.active_scalers,
        ScalingTarget,
        multiscaler.params.scaling_refinery.refinement_order,
    )
    multiscaler.single_scalers[0].components["scale"].parameters /= 2.0
    multiscaler.single_scalers[1].components["scale"].parameters *= 1.5
    apm = pmg.parameter_managers()[0]
    multiscaler.update_for_minimisation(apm, 0)
    multiscaler.update_for_minimisation(apm, 1)
    # bf[0], bf[1] should be list of scales and derivatives
    s1, d1 = RefinerCalculator.calculate_scales_and_derivatives(
        apm.apm_list[0], 0)
    s2, d2 = RefinerCalculator.calculate_scales_and_derivatives(
        apm.apm_list[1], 0)
    s3, d3 = RefinerCalculator.calculate_scales_and_derivatives(
        apm.apm_list[0], 1)
    s4, d4 = RefinerCalculator.calculate_scales_and_derivatives(
        apm.apm_list[1], 1)
    expected_scales_for_block_1 = s1
    expected_scales_for_block_1.extend(s2)
    expected_scales_for_block_2 = s3
    expected_scales_for_block_2.extend(s4)

    expected_derivatives_for_block_1 = sparse.matrix(
        expected_scales_for_block_1.size(), apm.n_active_params)
    expected_derivatives_for_block_2 = sparse.matrix(
        expected_scales_for_block_2.size(), apm.n_active_params)

    expected_derivatives_for_block_1.assign_block(d1, 0, 0)
    expected_derivatives_for_block_1.assign_block(d2, d1.n_rows,
                                                  apm.apm_data[1]["start_idx"])
    expected_derivatives_for_block_2.assign_block(d3, 0, 0)
    expected_derivatives_for_block_2.assign_block(d4, d3.n_rows,
                                                  apm.apm_data[1]["start_idx"])

    block_list = multiscaler.Ih_table.blocked_data_list

    assert block_list[0].inverse_scale_factors == expected_scales_for_block_1
    assert block_list[1].inverse_scale_factors == expected_scales_for_block_2
    assert block_list[1].derivatives == expected_derivatives_for_block_2
    assert block_list[0].derivatives == expected_derivatives_for_block_1
Ejemplo n.º 2
0
def test_multiscaler_initialisation():
    """Unit tests for the MultiScalerBase class."""
    p, e = (generated_param(), generated_exp(2))
    r1 = generated_refl(id_=0)
    r1["intensity.sum.value"] = r1["intensity"]
    r1["intensity.sum.variance"] = r1["variance"]
    r2 = generated_refl(id_=1)
    r2["intensity.sum.value"] = r2["intensity"]
    r2["intensity.sum.variance"] = r2["variance"]
    exp = create_scaling_model(p, e, [r1, r2])
    singlescaler1 = create_scaler(p, [exp[0]], [r1])
    singlescaler2 = create_scaler(p, [exp[1]], [r2])

    multiscaler = MultiScaler([singlescaler1, singlescaler2])

    # check initialisation
    assert len(multiscaler.active_scalers) == 2
    assert multiscaler.active_scalers[0] == singlescaler1
    assert multiscaler.active_scalers[1] == singlescaler2

    # check for correct setup of global Ih table
    assert multiscaler.global_Ih_table.size == 14
    assert (
        list(multiscaler.global_Ih_table.blocked_data_list[0].intensities)
        == [3.0, 1.0, 500.0, 2.0, 2.0, 2.0, 4.0] * 2
    )
    block_selections = multiscaler.global_Ih_table.blocked_data_list[0].block_selections
    assert list(block_selections[0]) == [2, 0, 4, 5, 6, 1, 3]
    assert list(block_selections[1]) == [2, 0, 4, 5, 6, 1, 3]

    # check for correct setup of Ih_table
    assert multiscaler.Ih_table.size == 12
    assert (
        list(multiscaler.Ih_table.blocked_data_list[0].intensities)
        == [3.0, 1.0, 2.0, 2.0, 2.0, 4.0] * 2
    )
    block_selections = multiscaler.Ih_table.blocked_data_list[0].block_selections
    assert list(block_selections[0]) == [2, 0, 5, 6, 1, 3]
    assert list(block_selections[1]) == [2, 0, 5, 6, 1, 3]

    # check for correct data/d_values in components
    for i, scaler in enumerate(multiscaler.active_scalers):
        d_suitable = scaler.reflection_table["d"].select(
            scaler.suitable_refl_for_scaling_sel
        )
        decay = scaler.experiment.scaling_model.components["decay"]
        # first check 'data' contains all suitable reflections
        assert list(decay.data["d"]) == list(d_suitable)
        # Now check 'd_values' (which will be used for minim.) matches Ih_table data
        assert list(decay.d_values[0]) == list(
            d_suitable.select(flumpy.from_numpy(block_selections[i]))
        )
Ejemplo n.º 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."""
    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)
Ejemplo n.º 4
0
def test_scaler_factory_helper_functions(
    mock_experimentlist, generated_param, refl_list, mock_scaling_component
):
    """Test the helper functions."""

    test_refl, exp = test_refl_and_exp(mock_scaling_component)

    # Test is_scaled function
    scaled_list = is_scaled(mock_experimentlist)
    assert scaled_list == [True, True, False, True, False]

    # Test create_scaler
    # Test case for single refl and exp
    scaler = create_scaler(generated_param, [exp], [test_refl])
    assert isinstance(scaler, SingleScaler)

    # If none or allscaled
    explist = mock_explist_3exp(mock_scaling_component)
    scaler = create_scaler(generated_param, explist, refl_list)
    assert isinstance(scaler, MultiScaler)

    explist[0].scaling_model.is_scaled = False
    # ^ changes all in list as same instance of exp.
    scaler = create_scaler(
        generated_param, mock_explist_3exp(mock_scaling_component), refl_list
    )
    assert isinstance(scaler, MultiScaler)

    # If only some scaled
    explist = []
    explist.append(mock_exp(mock_scaling_component))
    explist.append(mock_exp(mock_scaling_component))
    explist[1].scaling_model.is_scaled = True
    r1 = generated_refl()
    r2 = generated_refl()
    refl_list = [r1, r2]
    scaler = create_scaler(generated_param, explist, refl_list)
    assert isinstance(scaler, TargetScaler)

    # If no reflections passed in.
    with pytest.raises(ValueError):
        scaler = create_scaler(
            generated_param, mock_explist_3exp(mock_scaling_component), []
        )
Ejemplo n.º 5
0
    def _create_model_and_scaler(self):
        """Create the scaling models and scaler."""
        self.experiments = create_scaling_model(
            self.params, self.experiments, self.reflections
        )
        logger.info("\nScaling models have been initialised for all experiments.")
        logger.info("%s%s%s", "\n", "=" * 80, "\n")

        self.experiments = set_image_ranges_in_scaling_models(self.experiments)

        self.scaler = create_scaler(self.params, self.experiments, self.reflections)
Ejemplo n.º 6
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