def test_SingleScaler_update_for_minimisation(): """Test the update_for_minimisation method of the singlescaler.""" # test_params.scaling_options.nproc = 1 p, e, r = (generated_param(), generated_exp(), generated_refl_2()) exp = create_scaling_model(p, e, r) p.reflection_selection.method = "use_all" single_scaler = SingleScaler(p, exp[0], r) pmg = ScalingParameterManagerGenerator( single_scaler.active_scalers, ScalingTarget(), single_scaler.params.scaling_refinery.refinement_order, ) single_scaler.components["scale"].parameters /= 2.0 apm = pmg.parameter_managers()[0] Ih_table = single_scaler.Ih_table.blocked_data_list[0] Ih_table.calc_Ih() assert list(Ih_table.inverse_scale_factors) == [1.0, 1.0] assert list(Ih_table.Ih_values) == [10.0, 1.0] single_scaler.update_for_minimisation(apm, 0) # Should set new scale factors, and calculate Ih and weights. bf = RefinerCalculator.calculate_scales_and_derivatives(apm.apm_list[0], 0) assert list(Ih_table.inverse_scale_factors) == list(bf[0]) assert list(Ih_table.Ih_values) != [1.0, 10.0] assert list(Ih_table.Ih_values) == pytest.approx( list(Ih_table.intensities / bf[0])) for i in range(Ih_table.derivatives.n_rows): for j in range(Ih_table.derivatives.n_cols): assert Ih_table.derivatives[i, j] == pytest.approx(bf[1][i, j]) assert Ih_table.derivatives.non_zeroes == bf[1].non_zeroes
def test_SingleScaler_update_for_minimisation(): """Test the update_for_minimisation method of the singlescaler.""" # test_params.scaling_options.nproc = 1 p, e, r = (generated_param(), generated_exp(), generated_refl_2()) exp = create_scaling_model(p, e, r) p.reflection_selection.method = "use_all" single_scaler = SingleScaler(p, exp[0], r) apm_fac = create_apm_factory(single_scaler) single_scaler.components["scale"].parameters /= 2.0 apm = apm_fac.make_next_apm() Ih_table = single_scaler.Ih_table.blocked_data_list[0] Ih_table.calc_Ih() assert list(Ih_table.inverse_scale_factors) == [1.0, 1.0] assert list(Ih_table.Ih_values) == [10.0, 1.0] single_scaler.update_for_minimisation(apm, 0) # Should set new scale factors, and calculate Ih and weights. bf = basis_function().calculate_scales_and_derivatives(apm.apm_list[0], 0) assert list(Ih_table.inverse_scale_factors) == list(bf[0]) assert list(Ih_table.Ih_values) != [1.0, 10.0] assert approx_equal(list(Ih_table.Ih_values), list(Ih_table.intensities / bf[0])) for i in range(Ih_table.derivatives.n_rows): for j in range(Ih_table.derivatives.n_cols): assert approx_equal(Ih_table.derivatives[i, j], bf[1][i, j]) assert Ih_table.derivatives.non_zeroes == bf[1].non_zeroes
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
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)