def sph_harm_table(reflection_table, lmax): """Calculate the spherical harmonic table for a spherical harmonic absorption correction.""" theta_phi = calc_theta_phi(reflection_table["s0c"]) theta_phi_2 = calc_theta_phi(reflection_table["s1c"]) sph_h_t = create_sph_harm_table(theta_phi, theta_phi_2, lmax) return sph_h_t
def test_create_sph_harm_table(test_reflection_table, mock_exp): """Simple test for the spherical harmonic table, constructing the table step by step, and verifying the values of a few easy-to-calculate entries. This also acts as a test for the calc_theta_phi function as well.""" rt, exp = test_reflection_table, mock_exp reflection_table = calc_crystal_frame_vectors(rt, exp) theta_phi = calc_theta_phi(reflection_table["s0c"]) expected = [ (pi / 2.0, 0.0), (pi / 2.0, -1.0 * pi / 4.0), (pi / 2.0, -1.0 * pi / 2.0), ] for v1, v2 in zip(theta_phi, expected): assert v1 == pytest.approx(v2) theta_phi_2 = calc_theta_phi(reflection_table["s1c"]) expected = [ (pi / 4.0, 0.0), (pi / 4.0, -1.0 * pi / 4.0), (pi / 4.0, -1.0 * pi / 2.0), ] for v1, v2 in zip(theta_phi_2, expected): assert v1 == pytest.approx(v2) sph_h_t = create_sph_harm_table(theta_phi, theta_phi_2, 2) Y10 = ((3.0 / (8.0 * pi)) ** 0.5) / 2.0 Y20 = -1.0 * ((5.0 / (256.0 * pi)) ** 0.5) assert sph_h_t[1, 0] == pytest.approx(Y10) assert sph_h_t[1, 1] == pytest.approx(Y10) assert sph_h_t[1, 2] == pytest.approx(Y10) assert sph_h_t[5, 0] == pytest.approx(Y20) assert sph_h_t[5, 1] == pytest.approx(Y20) assert sph_h_t[5, 2] == pytest.approx(Y20)
def test_create_sph_harm_table(test_reflection_table, mock_exp): """Simple test for the spherical harmonic table, constructing the table step by step, and verifying the values of a few easy-to-calculate entries. This also acts as a test for the calc_theta_phi function as well.""" rt, exp = test_reflection_table, mock_exp reflection_table = calc_crystal_frame_vectors(rt, exp) theta_phi = calc_theta_phi(reflection_table["s0c"]) assert approx_equal( list(theta_phi), [(pi / 2.0, 0.0), (pi / 2.0, -1.0 * pi / 4.0), (pi / 2.0, -1.0 * pi / 2.0)], ) theta_phi_2 = calc_theta_phi(reflection_table["s1c"]) assert approx_equal( list(theta_phi_2), [(pi / 4.0, 0.0), (pi / 4.0, -1.0 * pi / 4.0), (pi / 4.0, -1.0 * pi / 2.0)], ) sph_h_t = create_sph_harm_table(theta_phi, theta_phi_2, 2) Y10 = ((3.0 / (8.0 * pi)) ** 0.5) / 2.0 Y20 = -1.0 * ((5.0 / (256.0 * pi)) ** 0.5) assert approx_equal(sph_h_t[1, 0], Y10) assert approx_equal(sph_h_t[1, 1], Y10) assert approx_equal(sph_h_t[1, 2], Y10) assert approx_equal(sph_h_t[5, 0], Y20) assert approx_equal(sph_h_t[5, 1], Y20) assert approx_equal(sph_h_t[5, 2], Y20)
def test_create_sph_harm_table(test_reflection_table, test_experiment_singleaxisgonio): """Simple test for the spherical harmonic table, constructing the table step by step, and verifying the values of a few easy-to-calculate entries. This also acts as a test for the calc_theta_phi function as well.""" rt, exp = test_reflection_table, test_experiment_singleaxisgonio reflection_table = calc_crystal_frame_vectors(rt, exp) reflection_table["s0c"] = align_axis_along_z( (1.0, 0.0, 0.0), reflection_table["s0c"] ) reflection_table["s1c"] = align_axis_along_z( (1.0, 0.0, 0.0), reflection_table["s1c"] ) theta_phi = calc_theta_phi(reflection_table["s0c"]) # so s0c vectors realigned in xyz is # (1.0, 0.0, 0.0), # (1.0 / sqrt(2.0), -1.0 / sqrt(2.0), 0.0), # (0.0, -1.0, 0.0), # physics conventions, theta from 0 to pi, phi from 0 to 2pi expected = [ (pi / 2.0, 0.0), (pi / 2.0, 7.0 * pi / 4.0), (pi / 2.0, 3.0 * pi / 2.0), ] for v1, v2 in zip(theta_phi, expected): assert v1 == pytest.approx(v2) theta_phi_2 = calc_theta_phi(reflection_table["s1c"]) expected = [ (pi / 4.0, pi), (pi / 4.0, 3 * pi / 4.0), (pi / 4.0, 1.0 * pi / 2.0), ] for v1, v2 in zip(theta_phi_2, expected): assert v1 == pytest.approx(v2) sph_h_t = create_sph_harm_table(theta_phi, theta_phi_2, 2) Y10 = ((3.0 / (8.0 * pi)) ** 0.5) / 2.0 Y20 = -1.0 * ((5.0 / (256.0 * pi)) ** 0.5) assert sph_h_t[1, 0] == pytest.approx(Y10) assert sph_h_t[1, 1] == pytest.approx(Y10) assert sph_h_t[1, 2] == pytest.approx(Y10) assert sph_h_t[5, 0] == pytest.approx(Y20) assert sph_h_t[5, 1] == pytest.approx(Y20) assert sph_h_t[5, 2] == pytest.approx(Y20)
def test_equality_of_two_harmonic_table_methods(dials_regression, run_in_tmpdir): from dials_scaling_ext import calc_theta_phi, calc_lookup_index from dxtbx.serialize import load from dials.util.options import OptionParser from libtbx import phil from dials.algorithms.scaling.scaling_library import create_scaling_model data_dir = os.path.join(dials_regression, "xia2-28") pickle_path = os.path.join(data_dir, "20_integrated.pickle") sequence_path = os.path.join(data_dir, "20_integrated_experiments.json") phil_scope = phil.parse( """ include scope dials.command_line.scale.phil_scope """, process_includes=True, ) optionparser = OptionParser(phil=phil_scope, check_format=False) params, _ = optionparser.parse_args(args=[], quick_parse=True) params.model = "physical" lmax = 2 params.physical.lmax = lmax reflection_table = flex.reflection_table.from_file(pickle_path) experiments = load.experiment_list(sequence_path, check_format=False) experiments = create_scaling_model(params, experiments, [reflection_table]) experiment = experiments[0] # New method reflection_table["phi"] = ( reflection_table["xyzobs.px.value"].parts()[2] * experiment.scan.get_oscillation()[1] ) reflection_table = calc_crystal_frame_vectors(reflection_table, experiment) theta_phi_0 = calc_theta_phi(reflection_table["s0c"]) # array of tuples in radians theta_phi_1 = calc_theta_phi(reflection_table["s1c"]) points_per_degree = 2 s0_lookup_index = calc_lookup_index(theta_phi_0, points_per_degree) s1_lookup_index = calc_lookup_index(theta_phi_1, points_per_degree) print(list(s0_lookup_index[0:20])) print(list(s1_lookup_index[0:20])) coefficients_list = create_sph_harm_lookup_table(lmax, points_per_degree) experiment.scaling_model.components["absorption"].data = { "s0_lookup": s0_lookup_index, "s1_lookup": s1_lookup_index, } experiment.scaling_model.components[ "absorption" ].coefficients_list = coefficients_list assert experiment.scaling_model.components["absorption"]._mode == "memory" experiment.scaling_model.components["absorption"].update_reflection_data() absorption = experiment.scaling_model.components["absorption"] harmonic_values_list = absorption.harmonic_values[0] experiment.scaling_model.components["absorption"].parameters = flex.double( [0.1, -0.1, 0.05, 0.02, 0.01, -0.05, 0.12, -0.035] ) scales, derivatives = experiment.scaling_model.components[ "absorption" ].calculate_scales_and_derivatives() # Old method: old_data = {"sph_harm_table": create_sph_harm_table(theta_phi_0, theta_phi_1, lmax)} experiment.scaling_model.components["absorption"].data = old_data assert experiment.scaling_model.components["absorption"]._mode == "speed" experiment.scaling_model.components["absorption"].update_reflection_data() old_harmonic_values = absorption.harmonic_values[0] for i in range(0, 8): print(i) assert list(harmonic_values_list[i]) == pytest.approx( list(old_harmonic_values.col(i).as_dense_vector()), abs=0.01 ) experiment.scaling_model.components["absorption"].parameters = flex.double( [0.1, -0.1, 0.05, 0.02, 0.01, -0.05, 0.12, -0.035] ) scales_1, derivatives_1 = experiment.scaling_model.components[ "absorption" ].calculate_scales_and_derivatives() assert list(scales_1) == pytest.approx(list(scales), abs=0.001) assert list(scales_1) != [1.0] * len(scales_1)
def test_equality_of_two_harmonic_table_methods(dials_data): location = dials_data("l_cysteine_dials_output", pathlib=True) refl = location / "20_integrated.pickle" expt = location / "20_integrated_experiments.json" phil_scope = phil.parse( """ include scope dials.command_line.scale.phil_scope """, process_includes=True, ) parser = ArgumentParser(phil=phil_scope, check_format=False) params, _ = parser.parse_args(args=[], quick_parse=True) params.model = "physical" lmax = 2 params.physical.lmax = lmax reflection_table = flex.reflection_table.from_file(refl) experiments = load.experiment_list(expt, check_format=False) experiments = create_scaling_model(params, experiments, [reflection_table]) experiment = experiments[0] # New method reflection_table["phi"] = (reflection_table["xyzobs.px.value"].parts()[2] * experiment.scan.get_oscillation()[1]) reflection_table = calc_crystal_frame_vectors(reflection_table, experiment) reflection_table["s1c"] = align_axis_along_z((1.0, 0.0, 0.0), reflection_table["s1c"]) reflection_table["s0c"] = align_axis_along_z((1.0, 0.0, 0.0), reflection_table["s0c"]) theta_phi_0 = calc_theta_phi( reflection_table["s0c"]) # array of tuples in radians theta_phi_1 = calc_theta_phi(reflection_table["s1c"]) points_per_degree = 4 s0_lookup_index = calc_lookup_index(theta_phi_0, points_per_degree) s1_lookup_index = calc_lookup_index(theta_phi_1, points_per_degree) print(list(s0_lookup_index[0:20])) print(list(s1_lookup_index[0:20])) coefficients_list = create_sph_harm_lookup_table(lmax, points_per_degree) experiment.scaling_model.components["absorption"].data = { "s0_lookup": s0_lookup_index, "s1_lookup": s1_lookup_index, } experiment.scaling_model.components[ "absorption"].coefficients_list = coefficients_list assert experiment.scaling_model.components["absorption"]._mode == "memory" experiment.scaling_model.components["absorption"].update_reflection_data() absorption = experiment.scaling_model.components["absorption"] harmonic_values_list = absorption.harmonic_values[0] experiment.scaling_model.components["absorption"].parameters = flex.double( [0.1, -0.1, 0.05, 0.02, 0.01, -0.05, 0.12, -0.035]) scales, derivatives = experiment.scaling_model.components[ "absorption"].calculate_scales_and_derivatives() # Old method: old_data = { "sph_harm_table": create_sph_harm_table(theta_phi_0, theta_phi_1, lmax) } experiment.scaling_model.components["absorption"].data = old_data assert experiment.scaling_model.components["absorption"]._mode == "speed" experiment.scaling_model.components["absorption"].update_reflection_data() old_harmonic_values = absorption.harmonic_values[0] for i in range(0, 8): print(i) assert list(harmonic_values_list[i]) == pytest.approx(list( old_harmonic_values.col(i).as_dense_vector()), abs=0.01) experiment.scaling_model.components["absorption"].parameters = flex.double( [0.1, -0.1, 0.05, 0.02, 0.01, -0.05, 0.12, -0.035]) scales_1, derivatives_1 = experiment.scaling_model.components[ "absorption"].calculate_scales_and_derivatives() assert list(scales_1) == pytest.approx(list(scales), abs=0.001) assert list(scales_1) != [1.0] * len(scales_1)