def __init__(self, parameters_dict, configdict, is_scaled=False): """Create the array scaling model components.""" super(ArrayScalingModel, self).__init__(configdict, is_scaled) if not any(i in configdict["corrections"] for i in ["decay", "absorption"]): raise ValueError( "Array model must have at least one of decay or absorption corrections" ) if "decay" in configdict["corrections"]: decay_setup = parameters_dict["decay"] self._components["decay"] = SmoothScaleComponent2D( decay_setup["parameters"], shape=(configdict["n_res_param"], configdict["n_time_param"]), parameter_esds=decay_setup["parameter_esds"], ) if "absorption" in configdict["corrections"]: abs_setup = parameters_dict["absorption"] self._components["absorption"] = SmoothScaleComponent3D( abs_setup["parameters"], shape=( configdict["n_x_param"], configdict["n_y_param"], configdict["n_time_param"], ), parameter_esds=abs_setup["parameter_esds"], ) if "modulation" in configdict["corrections"]: mod_setup = parameters_dict["modulation"] self._components["modulation"] = SmoothScaleComponent2D( mod_setup["parameters"], shape=(configdict["n_x_mod_param"], configdict["n_y_mod_param"]), parameter_esds=mod_setup["parameter_esds"], )
def test_SmoothScaleFactor2D(): """Test the 2D smooth scale factor class.""" with pytest.raises(AssertionError): # Test incorrect shape initialisation SF = SmoothScaleComponent2D(flex.double(30, 1.1), shape=(5, 5)) SF = SmoothScaleComponent2D(flex.double(30, 1.1), shape=(6, 5)) assert SF.n_x_params == 6 assert SF.n_y_params == 5 assert SF.n_params == 30 assert list(SF.parameters) == [1.1] * 30 norm_rot = flex.double(30, 0.5) norm_time = flex.double(30, 0.5) norm_rot[0] = 0.0 norm_time[0] = 0.0 norm_rot[29] = 3.99 norm_time[29] = 2.99 SF.data = {"x": norm_rot, "y": norm_time} SF.update_reflection_data() # assert list(SF.normalised_x_values) == list(flex.double( # [0.5, 0.5, 0.5, 0.0, 0.0, 0.0])) # assert list(SF.normalised_y_values) == list(flex.double( # [0.0, 0.0, 0.0, 0.5, 0.5, 0.5])) SF.smoother.set_smoothing(4, 1.0) # will average 3 in x,y dims. assert list(SF.smoother.x_positions()) == [-0.5, 0.5, 1.5, 2.5, 3.5, 4.5] assert list(SF.smoother.y_positions()) == [-0.5, 0.5, 1.5, 2.5, 3.5] s, d = SF.calculate_scales_and_derivatives() assert list(s) == pytest.approx([1.1] * 30) sumexp = exp(0.0) + (4.0 * exp(-1.0 / 1.0)) + (4.0 * exp(-2.0 / 1.0)) assert d[1, 7] == pytest.approx(exp(-0.0) / sumexp) # Test again with a small number of params to check different behaviour. SF = SmoothScaleComponent2D(flex.double(6, 1.1), shape=(3, 2)) _ = flex.reflection_table() norm_rot = flex.double(6, 0.5) norm_time = flex.double(6, 0.5) norm_rot[0] = 0.0 norm_time[0] = 0.0 norm_rot[5] = 1.99 norm_time[5] = 0.99 SF.data = {"x": norm_rot, "y": norm_time} SF.update_reflection_data() SF.smoother.set_smoothing(4, 1.0) # will average 3,2 in x,y dims. assert list(SF.smoother.x_positions()) == [0.0, 1.0, 2.0] assert list(SF.smoother.y_positions()) == [0.0, 1.0] s, d = SF.calculate_scales_and_derivatives() s2 = SF.calculate_scales() assert list(s) == list(s2) sumexp = (4.0 * exp(-0.5 / 1.0)) + (2.0 * exp(-2.5 / 1.0)) assert d[1, 1] == pytest.approx(exp(-0.5) / sumexp) # Test that if one or none in block, then doesn't fail but returns sensible value SF._normalised_x_values = [flex.double([0.5])] SF._normalised_y_values = [flex.double([0.5])] SF._n_refl = [1] assert list(SF.normalised_x_values[0]) == [0.5] assert list(SF.normalised_y_values[0]) == [0.5] s, d = SF.calculate_scales_and_derivatives() s2 = SF.calculate_scales() assert list(s) == list(s2) assert list(s) == pytest.approx([1.1]) SF._normalised_x_values = [flex.double()] SF._normalised_y_values = [flex.double()] SF._n_refl = [0] assert list(SF.normalised_x_values[0]) == [] assert list(SF.normalised_y_values[0]) == [] s, d = SF.calculate_scales_and_derivatives() s2 = SF.calculate_scales() assert list(s) == list(s2) assert list(s) == [] assert d == sparse.matrix(0, 0)