Esempio n. 1
0
def test_physical_model_from_data(mock_physical_params, mock_exp, test_reflections):
    """Test that it passes the correct dict to physical model."""
    physicalmodel = PhysicalScalingModel.from_data(
        mock_physical_params, mock_exp, test_reflections
    )
    assert physicalmodel.configdict["lmax"] == (mock_physical_params.physical.lmax)
    assert physicalmodel.components["absorption"].n_params == 24
    assert list(physicalmodel.components["absorption"].parameters) == [0.0] * 24
Esempio n. 2
0
def test_model_creation_from_data(default_params, mock_exp, test_reflections):
    """Test the factory creation of the three standard scaling models with the
    default params."""

    _ = KBScalingModel.from_data(default_params, [], [])

    _ = PhysicalScalingModel.from_data(default_params, mock_exp, test_reflections)

    _ = ArrayScalingModel.from_data(default_params, mock_exp, test_reflections)
Esempio n. 3
0
def plot_scaling_models(scaling_model_dict):
    d = OrderedDict()
    if scaling_model_dict["__id__"] == "physical":
        model = PhysicalScalingModel.from_dict(scaling_model_dict)
        d.update(_plot_smooth_scales(model))
        if "absorption" in model.components:
            d.update(plot_absorption_parameters(model))
            d.update(plot_absorption_surface(model))
    return d
Esempio n. 4
0
def test_physical_model_from_data(mock_physical_params, mock_exp,
                                  test_reflections):
    """Test that it passes the correct dict to physical model."""
    physicalmodel = PhysicalScalingModel.from_data(mock_physical_params,
                                                   mock_exp, test_reflections)
    assert physicalmodel.configdict["lmax"] == (
        mock_physical_params.physical.lmax)
    assert physicalmodel.components["absorption"].n_params == 24
    assert list(
        physicalmodel.components["absorption"].parameters) == [0.0] * 24

    # test updating the absorption parameters
    mock_physical_params.physical.absorption_level = "high"
    physicalmodel.update(mock_physical_params)
    assert len(physicalmodel.components["absorption"].parameters) == 48
    assert physicalmodel.configdict["abs_surface_weight"] == 5e3

    mock_physical_params.physical.absorption_level = "medium"
    physicalmodel.update(mock_physical_params)
    assert len(physicalmodel.components["absorption"].parameters) == 48
    assert physicalmodel.configdict["abs_surface_weight"] == 5e4

    mock_physical_params.physical.absorption_level = None
    mock_physical_params.physical.lmax = 4
    physicalmodel.update(mock_physical_params)
    assert len(physicalmodel.components["absorption"].parameters) == 24
    assert physicalmodel.configdict["abs_surface_weight"] == 5e4

    mock_physical_params.physical.surface_weight = 1e5
    physicalmodel.update(mock_physical_params)
    assert len(physicalmodel.components["absorption"].parameters) == 24
    assert physicalmodel.configdict["abs_surface_weight"] == 1e5

    # try fixing a parameter
    mock_physical_params.physical.correction.fix = ["decay"]
    physicalmodel = PhysicalScalingModel.from_data(mock_physical_params,
                                                   mock_exp, test_reflections)
    assert physicalmodel.configdict["lmax"] == (
        mock_physical_params.physical.lmax)
    assert physicalmodel.components["absorption"].n_params == 24
    assert list(
        physicalmodel.components["absorption"].parameters) == [0.0] * 24
    assert physicalmodel.fixed_components == ["decay"]
def test_create_scaling_model():
    """Test the create scaling model function."""

    # Test that one can create the correct scaling model with the phil param.
    for m in ["physical", "array", "KB"]:
        params = generated_param()
        exp = generated_exp()
        rt = generated_refl()
        params.model = m
        new_exp = create_scaling_model(params, exp, [rt])
        assert new_exp[0].scaling_model.id_ == m

    # If a scaling model already exists, then nothing else should happen.
    params = generated_param()
    exp = generated_exp()
    rt = generated_refl()
    exp[0].scaling_model = PhysicalScalingModel.from_data(params, exp[0], rt)
    old_scaling_model = exp[0].scaling_model
    params.model = "KB"
    new_exp = create_scaling_model(params, exp, [rt])
    new_scaling_model = new_exp[0].scaling_model
    assert new_scaling_model is old_scaling_model  # Should not modify original.

    # Test multiple datasets, where one already has a scaling model.
    exp = generated_exp(3)
    params = generated_param()
    rt = generated_refl()
    rt_2 = generated_refl()
    rt_3 = generated_refl()
    exp[0].scaling_model = PhysicalScalingModel.from_data(params, exp[0], rt)
    params.model = "KB"
    new_exp = create_scaling_model(params, exp, [rt, rt_2, rt_3])
    assert new_exp[0].scaling_model is exp[0].scaling_model
    assert isinstance(new_exp[1].scaling_model, KBScalingModel)
    assert isinstance(new_exp[2].scaling_model, KBScalingModel)

    # Now test overwrite_existing_models option
    params.overwrite_existing_models = True
    params.model = "physical"
    newer_exp = create_scaling_model(params, new_exp, [rt, rt_2, rt_3])
    for exp in newer_exp:
        assert isinstance(exp.scaling_model, PhysicalScalingModel)
Esempio 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."""
    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
Esempio n. 7
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)
Esempio n. 8
0
def test_plot_scaling_models():

    physical_dict = {
        "__id__": "physical",
        "is_scaled": True,
        "scale": {
            "n_parameters": 2,
            "parameters": [0.5, 1.0],
            "est_standard_devs": [0.05, 0.1],
        },
        "configuration_parameters": {
            "corrections": ["scale", "decay", "absorption"],
            "s_norm_fac": 0.1,
            "d_norm_fac": 0.1,
            "scale_rot_interval": 10.0,
            "decay_rot_interval": 10.0,
            "decay_restaint": 1e-1,
            "valid_osc_range": [0.0, 2.0],
        },
        "decay": {
            "n_parameters": 2,
            "parameters": [0.5, 1.0],
            "est_standard_devs": [0.05, 0.1],
        },
        "absorption": {
            "n_parameters": 4,
            "parameters": [0.1, -0.1, 0.05, -0.05],
            "est_standard_devs": [0.005, 0.005, 0.005, 0.005],
        },
    }
    d = plot_scaling_models(PhysicalScalingModel.from_dict(physical_dict))
    assert "smooth_scale_model" in d
    assert "absorption_surface" in d
    assert "absorption_parameters" in d
    assert d["smooth_scale_model"]["data"][0] != []
    assert d["absorption_parameters"]["data"][0] != []
Esempio n. 9
0
def test_PhysicalScalingModel(test_reflections, mock_exp):
    """Test the PhysicalScalingModel class."""
    configdict = {
        "corrections": ["scale", "decay", "absorption"],
        "s_norm_fac": 1.0,
        "scale_rot_interval": 2.0,
        "d_norm_fac": 1.0,
        "decay_rot_interval": 2.0,
        "lmax": 1,
        "abs_surface_weight": 1e6,
    }

    parameters_dict = {
        "scale": {
            "parameters": flex.double([1.2, 1.1]),
            "parameter_esds": None
        },
        "decay": {
            "parameters": flex.double([0.1, 0.2]),
            "parameter_esds": None
        },
        "absorption": {
            "parameters": flex.double([0.01, 0.01, 0.01]),
            "parameter_esds": None,
        },
    }

    # Test standard factory initialisation
    physicalmodel = PhysicalScalingModel(parameters_dict, configdict)
    assert physicalmodel.id_ == "physical"
    assert "Absorption component" in str(physicalmodel)
    comps = physicalmodel.components
    assert "scale" in comps
    assert "absorption" in comps
    assert "decay" in comps
    assert list(comps["scale"].parameters) == [1.2, 1.1]
    assert list(comps["decay"].parameters) == [0.1, 0.2]
    assert list(comps["absorption"].parameters) == [0.01, 0.01, 0.01]

    # Test configure reflection table
    mock_params = Mock()
    mock_params.physical.decay_restraint = 0.0
    physicalmodel.configure_components(test_reflections, mock_exp, mock_params)

    # Test from_dict initialisation method.
    physical_dict = {
        "__id__": "physical",
        "is_scaled": True,
        "scale": {
            "n_parameters": 2,
            "parameters": [0.5, 1.0],
            "est_standard_devs": [0.05, 0.1],
            "null_parameter_value": 1,
        },
        "configuration_parameters": {
            "corrections": ["scale"],
            "s_norm_fac": 0.1,
            "scale_rot_interval": 10.0,
            "decay_restaint": 1e-1,
        },
    }
    physicalmodel = PhysicalScalingModel.from_dict(physical_dict)
    assert physicalmodel.id_ == "physical"
    assert "scale" in physicalmodel.components
    assert "absorption" not in physicalmodel.components
    assert "decay" not in physicalmodel.components
    assert list(physicalmodel.components["scale"].parameters) == [0.5, 1.0]
    assert list(
        physicalmodel.components["scale"].parameter_esds) == [0.05, 0.1]

    new_dict = physicalmodel.to_dict()
    assert new_dict == physical_dict

    # Test from_dict initialisation method for all components.
    physical_dict = {
        "__id__": "physical",
        "is_scaled": True,
        "scale": {
            "n_parameters": 2,
            "parameters": [0.5, 1.0],
            "est_standard_devs": [0.05, 0.1],
            "null_parameter_value": 1,
        },
        "decay": {
            "n_parameters": 2,
            "parameters": [0.1, 0.2],
            "est_standard_devs": [0.01, 0.01],
            "null_parameter_value": 0,
        },
        "absorption": {
            "n_parameters": 3,
            "parameters": [0.0, 0.1, 0.2],
            "est_standard_devs": [0.01, 0.02, 0.03],
            "null_parameter_value": 0,
        },
        "configuration_parameters": {
            "corrections": ["scale", "decay", "absorption"],
            "s_norm_fac": 0.1,
            "scale_rot_interval": 10.0,
            "d_norm_fac": 0.2,
            "decay_rot_interval": 20.0,
            "lmax": 1,
            "abs_surface_weight": 1e6,
        },
    }
    physicalmodel = PhysicalScalingModel.from_dict(physical_dict)
    assert physicalmodel.id_ == "physical"
    assert "scale" in physicalmodel.components
    assert "absorption" in physicalmodel.components
    assert "decay" in physicalmodel.components
    assert list(physicalmodel.components["scale"].parameters) == [0.5, 1.0]
    assert list(
        physicalmodel.components["scale"].parameter_esds) == [0.05, 0.1]
    assert list(physicalmodel.components["decay"].parameters) == [0.1, 0.2]
    assert list(
        physicalmodel.components["decay"].parameter_esds) == [0.01, 0.01]
    assert list(
        physicalmodel.components["absorption"].parameters) == [0.0, 0.1, 0.2]
    assert list(physicalmodel.components["absorption"].parameter_esds) == [
        0.01,
        0.02,
        0.03,
    ]

    new_dict = physicalmodel.to_dict()
    assert new_dict == physical_dict

    with pytest.raises(RuntimeError):
        physical_dict["__id__"] = "array"
        physicalmodel = PhysicalScalingModel.from_dict(physical_dict)

    assert len(physicalmodel.consecutive_refinement_order) == 2
    assert "Absorption component:" in str(physicalmodel)

    # test limit batch range
    parameters_dict = {
        "scale": {
            "n_parameters": 11,
            "parameters":
            [0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5],
            "parameter_esds": None,
        },
        "decay": {
            "n_parameters": 11,
            "parameters":
            [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1],
            "parameter_esds": None,
        },
    }
    configdict = {
        "corrections": ["scale", "decay"],
        "s_norm_fac": 0.1,
        "scale_rot_interval": 10.0,
        "d_norm_fac": 0.1,
        "decay_rot_interval": 10.0,
        "valid_image_range": (1, 90),
        "valid_osc_range": (0, 90),
    }
    physical = PhysicalScalingModel(parameters_dict, configdict)
    physical.limit_image_range((1, 50))
    assert list(physical.components["scale"].parameters) == [
        0.5,
        1.0,
        1.5,
        2.0,
        2.5,
        3.0,
        3.5,
    ]
    assert list(physical.components["decay"].parameters) == [
        0.1,
        0.2,
        0.3,
        0.4,
        0.5,
        0.6,
        0.7,
    ]
    assert physical.configdict["valid_osc_range"] == (0, 50)
    assert physical.configdict["valid_image_range"] == (1, 50)

    # try edge cases
    # if restricted by > rot int, then reduce number of params and shift offset
    # if necessary
    physical = PhysicalScalingModel(copy.deepcopy(parameters_dict),
                                    copy.deepcopy(configdict))
    physical.limit_image_range((7, 45))
    assert list(physical.components["scale"].parameters) == [
        1.0,
        1.5,
        2.0,
        2.5,
        3.0,
        3.5,
    ]
    assert list(physical.components["decay"].parameters) == [
        0.2,
        0.3,
        0.4,
        0.5,
        0.6,
        0.7,
    ]
    assert physical.configdict["valid_osc_range"] == (6, 45)
    assert physical.configdict["valid_image_range"] == (7, 45)

    # if not restricted by > rot int, then should 'squeeze' the parameters closer
    # in rotation angle, leaving the same number of params (as reducing number of
    # params would give parameter spacing greater than initially specified rot int)
    physical = PhysicalScalingModel(copy.deepcopy(parameters_dict),
                                    copy.deepcopy(configdict))
    physical.limit_image_range((5, 45))
    assert list(physical.components["scale"].parameters) == [
        0.5,
        1.0,
        1.5,
        2.0,
        2.5,
        3.0,
        3.5,
    ]
    assert list(physical.components["decay"].parameters) == [
        0.1,
        0.2,
        0.3,
        0.4,
        0.5,
        0.6,
        0.7,
    ]
    assert physical.configdict["valid_osc_range"] == (4, 45)
    assert physical.configdict["valid_image_range"] == (5, 45)
Esempio n. 10
0
    def from_dict(d):
        """creates a scaling model from a dict"""
        from dials.algorithms.scaling.model.model import PhysicalScalingModel

        return PhysicalScalingModel.from_dict(d)