示例#1
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)
示例#2
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)
示例#3
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
示例#4
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)
示例#5
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)