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
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])) )
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)
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), [] )
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)
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