Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
def test_calc_crystal_frame_vectors(test_reflection_table, mock_exp):
    """Test the namesake function, to check that the vectors are correctly rotated
    into the crystal frame."""
    rt, exp = test_reflection_table, mock_exp
    s0_vec = (1.0, 0.0, 0.0)
    s1_vec = (1.0 / sqrt(2.0), 0.0, 1.0 / sqrt(2.0))
    reflection_table = calc_crystal_frame_vectors(rt, exp)
    assert list(reflection_table["s0"]) == list(
        flex.vec3_double([s0_vec, s0_vec, s0_vec])
    )
    assert approx_equal(
        list(reflection_table["s0c"]),
        list(
            flex.vec3_double(
                [s0_vec, (1.0 / sqrt(2.0), -1.0 / sqrt(2.0), 0.0), (0.0, -1.0, 0.0)]
            )
        ),
    )
    assert approx_equal(
        list(reflection_table["s1c"]),
        list(
            flex.vec3_double(
                [
                    s1_vec,
                    (1.0 / 2.0, -1.0 / 2.0, 1.0 / sqrt(2.0)),
                    (0.0, -1.0 / sqrt(2.0), 1.0 / sqrt(2.0)),
                ]
            )
        ),
    )
Ejemplo n.º 4
0
def test_calc_crystal_frame_vectors_single_axis_gonio(
    test_reflection_table, test_experiment_singleaxisgonio
):
    """Test the namesake function, to check that the vectors are correctly rotated
    into the crystal frame."""
    rt, exp = test_reflection_table, test_experiment_singleaxisgonio
    reflection_table = calc_crystal_frame_vectors(rt, exp)

    # s0c and s1c are normalised. s0c points towards the source.
    # as the crystal rotates about the x axis, the s0 vector moves in the y-z plane towards -y
    expected_s0c = [
        (0.0, 0.0, -1.0),
        (0.0, -1.0 / sqrt(2.0), -1.0 / sqrt(2.0)),
        (0.0, -1.0, 0.0),
    ]
    for v1, v2 in zip(reflection_table["s0c"], expected_s0c):
        assert v1 == pytest.approx(v2)
    # the s1c vector should have fixed x-component, rotating in the y-z plane towards +y
    expected_s1c = [
        (1.0 / sqrt(2.0), 0.0, 1.0 / sqrt(2.0)),
        (1.0 / sqrt(2.0), 0.5, 0.5),
        (1.0 / sqrt(2.0), 1.0 / sqrt(2.0), 0.0),
    ]
    for v1, v2 in zip(reflection_table["s1c"], expected_s1c):
        assert v1 == pytest.approx(v2)

    # now test redefined coordinates so that the lab x-axis is along the
    # z-axis in the crystal frame
    alignment_axis = (1.0, 0.0, 0.0)
    reflection_table["s1c"] = align_axis_along_z(
        alignment_axis, reflection_table["s1c"]
    )
    reflection_table["s0c"] = align_axis_along_z(
        alignment_axis, reflection_table["s0c"]
    )
    expected_s0c_realigned = [
        (1.0, 0.0, 0.0),
        (1.0 / sqrt(2.0), -1.0 / sqrt(2.0), 0.0),
        (0.0, -1.0, 0.0),
    ]
    for v1, v2 in zip(reflection_table["s0c"], expected_s0c_realigned):
        assert v1 == pytest.approx(v2)
    expected_s1c_realigned = [
        (-1.0 / sqrt(2.0), 0.0, 1.0 / sqrt(2.0)),
        (-0.5, 0.5, 1.0 / sqrt(2.0)),
        (0.0, 1.0 / sqrt(2.0), 1.0 / sqrt(2.0)),
    ]
    for v1, v2 in zip(reflection_table["s1c"], expected_s1c_realigned):
        assert v1 == pytest.approx(v2)
Ejemplo n.º 5
0
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_reflection_selection(dials_regression):
    """Use a real dataset to test the selection algorithm."""
    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")
    reflection_table = flex.reflection_table.from_file(pickle_path)
    experiment = load.experiment_list(sequence_path, check_format=False)[0]

    reflection_table["intensity"] = reflection_table["intensity.sum.value"]
    reflection_table["variance"] = reflection_table["intensity.sum.variance"]
    reflection_table["inverse_scale_factor"] = flex.double(
        reflection_table.size(), 1.0)
    reflection_table = reflection_table.select(
        reflection_table["variance"] > 0)
    reflection_table = reflection_table.select(
        reflection_table.get_flags(reflection_table.flags.integrated,
                                   all=True))

    Ih_table_block = IhTable(
        [reflection_table],
        experiment.crystal.get_space_group()).Ih_table_blocks[0]

    reflection_table["phi"] = (reflection_table["xyzobs.px.value"].parts()[2] *
                               experiment.scan.get_oscillation()[1])
    reflection_table = calc_crystal_frame_vectors(reflection_table, experiment)
    Ih_table_block.Ih_table["s1c"] = reflection_table["s1c"].select(
        Ih_table_block.Ih_table["loc_indices"])

    indices = select_highly_connected_reflections(Ih_table_block,
                                                  experiment,
                                                  min_per_area=10,
                                                  n_resolution_bins=10)
    assert len(indices) > 1710 and len(indices) < 1800

    # Give a high min_per_area to check that all reflections with multiplciity > 1
    # are selected.
    indices = select_highly_connected_reflections(Ih_table_block,
                                                  experiment,
                                                  min_per_area=50,
                                                  n_resolution_bins=10)
    # this dataset has 48 reflections with multiplicity = 1
    assert len(indices) == reflection_table.size() - 48
Ejemplo n.º 7
0
def test_calc_crystal_frame_vectors(test_reflection_table, mock_exp):
    """Test the namesake function, to check that the vectors are correctly rotated
    into the crystal frame."""
    rt, exp = test_reflection_table, mock_exp
    s0_vec = (1.0, 0.0, 0.0)
    s1_vec = (1.0 / sqrt(2.0), 0.0, 1.0 / sqrt(2.0))
    reflection_table = calc_crystal_frame_vectors(rt, exp)
    assert list(reflection_table["s0"]) == list(
        flex.vec3_double([s0_vec, s0_vec, s0_vec])
    )
    expected = [s0_vec, (1.0 / sqrt(2.0), -1.0 / sqrt(2.0), 0.0), (0.0, -1.0, 0.0)]
    for v1, v2 in zip(reflection_table["s0c"], expected):
        assert v1 == pytest.approx(v2)
    expected = [
        s1_vec,
        (1.0 / 2.0, -1.0 / 2.0, 1.0 / sqrt(2.0)),
        (0.0, -1.0 / sqrt(2.0), 1.0 / sqrt(2.0)),
    ]
    for v1, v2 in zip(reflection_table["s1c"], expected):
        assert v1 == pytest.approx(v2)
Ejemplo n.º 8
0
    def create(cls, params, experiment, reflection_table, for_multi=False):
        """Perform reflection_table preprocessing and create a SingleScaler."""

        cls.ensure_experiment_identifier(params, experiment, reflection_table)

        logger.info(
            "Preprocessing data for scaling. The id assigned to this \n"
            "dataset is %s, and the scaling model type being applied is %s. \n",
            list(reflection_table.experiment_identifiers().values())[0],
            experiment.scaling_model.id_,
        )

        reflection_table, reasons = cls.filter_bad_reflections(
            reflection_table)

        if "inverse_scale_factor" not in reflection_table:
            reflection_table["inverse_scale_factor"] = flex.double(
                reflection_table.size(), 1.0)
        elif (reflection_table["inverse_scale_factor"].count(0.0) ==
              reflection_table.size()):
            reflection_table["inverse_scale_factor"] = flex.double(
                reflection_table.size(), 1.0)
        reflection_table = choose_scaling_intensities(
            reflection_table, params.reflection_selection.intensity_choice)

        excluded_for_scaling = reflection_table.get_flags(
            reflection_table.flags.excluded_for_scaling)
        user_excluded = reflection_table.get_flags(
            reflection_table.flags.user_excluded_in_scaling)
        reasons.add_reason("user excluded", user_excluded.count(True))
        reasons.add_reason("excluded for scaling",
                           excluded_for_scaling.count(True))
        n_excluded = (excluded_for_scaling | user_excluded).count(True)
        if n_excluded == reflection_table.size():
            logger.info(
                "All reflections were determined to be unsuitable for scaling."
            )
            logger.info(reasons)
            raise BadDatasetForScalingException(
                """Unable to use this dataset for scaling""")
        else:
            logger.info(
                "%s/%s reflections not suitable for scaling\n%s",
                n_excluded,
                reflection_table.size(),
                reasons,
            )

        if not for_multi:
            determine_reflection_selection_parameters(params, [experiment],
                                                      [reflection_table])
        if params.reflection_selection.method == "intensity_ranges":
            reflection_table = quasi_normalisation(reflection_table,
                                                   experiment)
        if (params.reflection_selection.method
                in (None, Auto, "auto", "quasi_random")) or (
                    experiment.scaling_model.id_ == "physical"
                    and "absorption" in experiment.scaling_model.components):
            if experiment.scan:
                # calc theta and phi cryst
                reflection_table["phi"] = (
                    reflection_table["xyzobs.px.value"].parts()[2] *
                    experiment.scan.get_oscillation()[1])
                reflection_table = calc_crystal_frame_vectors(
                    reflection_table, experiment)

        return SingleScaler(params, experiment, reflection_table, for_multi)
Ejemplo n.º 9
0
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)
Ejemplo n.º 10
0
    def create(cls, params, experiment, reflection_table, for_multi=False):
        """Perform reflection_table preprocessing and create a SingleScaler."""

        cls.ensure_experiment_identifier(experiment, reflection_table)

        logger.info(
            "The scaling model type being applied is %s. \n",
            experiment.scaling_model.id_,
        )
        try:
            reflection_table = cls.filter_bad_reflections(
                reflection_table,
                partiality_cutoff=params.cut_data.partiality_cutoff,
                min_isigi=params.cut_data.min_isigi,
                intensity_choice=params.reflection_selection.intensity_choice,
            )
        except ValueError:
            raise BadDatasetForScalingException

        # combine partial measurements of same reflection, to handle those reflections
        # that were split by dials.integrate  - changes size of reflection table.
        reflection_table = sum_partial_reflections(reflection_table)

        if "inverse_scale_factor" not in reflection_table:
            reflection_table["inverse_scale_factor"] = flex.double(
                reflection_table.size(), 1.0)
        elif (reflection_table["inverse_scale_factor"].count(0.0) ==
              reflection_table.size()):
            reflection_table["inverse_scale_factor"] = flex.double(
                reflection_table.size(), 1.0)
        reflection_table = choose_initial_scaling_intensities(
            reflection_table, params.reflection_selection.intensity_choice)

        excluded_for_scaling = reflection_table.get_flags(
            reflection_table.flags.excluded_for_scaling)
        user_excluded = reflection_table.get_flags(
            reflection_table.flags.user_excluded_in_scaling)
        reasons = Reasons()
        reasons.add_reason("user excluded", user_excluded.count(True))
        reasons.add_reason("excluded for scaling",
                           excluded_for_scaling.count(True))
        n_excluded = (excluded_for_scaling | user_excluded).count(True)
        if n_excluded == reflection_table.size():
            logger.info(
                "All reflections were determined to be unsuitable for scaling."
            )
            logger.info(reasons)
            raise BadDatasetForScalingException(
                """Unable to use this dataset for scaling""")
        else:
            logger.info(
                "Excluding %s/%s reflections\n%s",
                n_excluded,
                reflection_table.size(),
                reasons,
            )

        if params.reflection_selection.method == "intensity_ranges":
            reflection_table = quasi_normalisation(reflection_table,
                                                   experiment)
        if (params.reflection_selection.method
                in (None, Auto, "auto", "quasi_random")) or (
                    experiment.scaling_model.id_ == "physical"
                    and "absorption" in experiment.scaling_model.components):
            if experiment.scan:
                reflection_table = calc_crystal_frame_vectors(
                    reflection_table, experiment)
                alignment_axis = (1.0, 0.0, 0.0)
                reflection_table["s0c"] = align_axis_along_z(
                    alignment_axis, reflection_table["s0c"])
                reflection_table["s1c"] = align_axis_along_z(
                    alignment_axis, reflection_table["s1c"])
        try:
            scaler = SingleScaler(params, experiment, reflection_table,
                                  for_multi)
        except BadDatasetForScalingException as e:
            raise ValueError(e)
        else:
            return scaler
Ejemplo n.º 11
0
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)
Ejemplo n.º 12
0
def test_calc_crystal_frame_vectors_multi_axis_gonio(test_reflection_table):
    """Test the namesake function, to check that the vectors are correctly rotated
    into the crystal frame."""
    experiments = test_experiments_multiaxisgonio()
    table = generate_reflection_table()

    # for the first scan, the rotation axis is the (1,0,0) direction, like the
    # single axis gonio test case above, so check that first.

    table = calc_crystal_frame_vectors(table, experiments[0])

    # s0c and s1c are normalised. s0c points towards the source.
    # as the crystal rotates about the x axis, the s0 vector moves in the y-z plane towards -y
    expected_s0c = [
        (0.0, 0.0, -1.0),
        (0.0, -1.0 / sqrt(2.0), -1.0 / sqrt(2.0)),
        (0.0, -1.0, 0.0),
    ]
    for v1, v2 in zip(table["s0c"], expected_s0c):
        assert v1 == pytest.approx(v2)
    # the s1c vector should have fixed x-component, rotating in the y-z plane towards +y
    expected_s1c = [
        (1.0 / sqrt(2.0), 0.0, 1.0 / sqrt(2.0)),
        (1.0 / sqrt(2.0), 0.5, 0.5),
        (1.0 / sqrt(2.0), 1.0 / sqrt(2.0), 0.0),
    ]
    for v1, v2 in zip(table["s1c"], expected_s1c):
        assert v1 == pytest.approx(v2)

    # for second scan, the rotation axis is the (1,1,0) direction
    table = generate_reflection_table().select(flex.bool([True, False, True]))
    table = calc_crystal_frame_vectors(table, experiments[1])

    # s0c and s1c are normalised. s0c points towards the source.
    # as the crystal rotates about the (1,1,0) axis, the s0 vector rotates towards (1, -sqrt2, -1)
    # the y-z plane towards -y
    expected_s0c = [
        (0.0, 0.0, -1.0),
        (0.5, -1.0 / sqrt(2.0), -0.5),
    ]
    for v1, v2 in zip(table["s0c"], expected_s0c):
        assert v1 == pytest.approx(v2)
    # the s1c vector should rotate to +y
    expected_s1c = [
        (1.0 / sqrt(2.0), 0.0, 1.0 / sqrt(2.0)),
        (0.0, 1.0, 0.0),
    ]
    for v1, v2 in zip(table["s1c"], expected_s1c):
        assert v1 == pytest.approx(v2)

    # now test redefined coordinates so that the lab x-axis is along the
    # z-axis in the crystal frame
    alignment_axis = (1.0, 0.0, 0.0)
    table["s1c"] = align_axis_along_z(alignment_axis, table["s1c"])
    table["s0c"] = align_axis_along_z(alignment_axis, table["s0c"])
    expected_s0c_realigned = [
        (1.0, 0.0, 0.0),
        (0.5, -1.0 / sqrt(2.0), 0.5),
    ]
    for v1, v2 in zip(table["s0c"], expected_s0c_realigned):
        assert v1 == pytest.approx(v2)
    # the s1c vector should rotate to +y
    expected_s1c_realigned = [
        (-1.0 / sqrt(2.0), 0.0, 1.0 / sqrt(2.0)),
        (0.0, 1.0, 0.0),
    ]
    for v1, v2 in zip(table["s1c"], expected_s1c_realigned):
        assert v1 == pytest.approx(v2)