def __init__(self, plots = False):

    # Do we make scatterplots?
    self.do_plots = plots

    # Let's say we have a scan of 100 images
    self.image_range = (1, 100)

    # Make a random P1 crystal
    a = random.uniform(10,50) * \
        self.random_direction_close_to(matrix.col((1, 0, 0)))
    b = random.uniform(10,50) * \
        self.random_direction_close_to(matrix.col((0, 1, 0)))
    c = random.uniform(10,50) * \
        self.random_direction_close_to(matrix.col((0, 0, 1)))
    self.xl = crystal_model(a, b, c, space_group_symbol = "P 1")

    # Make a beam with wavelength in the range 0.8--1.2 and s0 direction close
    # to 0,0,1
    s0 = random.uniform(0.8, 1.2) * \
        self.random_direction_close_to(matrix.col((0, 0, 1)))
    self.beam = Beam(s0)

    # Make a standard goniometer model along X
    self.goniometer = Goniometer((1,0,0))

    # Make a simple single panel detector
    d1 = matrix.col((1, 0, 0))
    d2 = matrix.col((0, -1, 0))
    npx_fast = 1475
    npx_slow = 1679
    pix_size_f = pix_size_s = 0.172
    from dxtbx.model.experiment import detector_factory
    self.detector = detector_factory.make_detector("PAD", d1, d2,
      matrix.col((0, 0, -110)), (pix_size_f, pix_size_s),
      (npx_fast, npx_slow), (0, 2e20))
Example #2
0
def test_elliptical_distortion(run_in_tmpdir):
    """Create distortion maps for elliptical distortion using a dummy experiments
    with a small detector, for speed. Check those maps seem sensible"""

    # Make a detector model
    d = make_detector()

    # The beam is also essential for a experiments to be serialisable
    b = Beam((0, 0, 1), 1.0)

    # Create and write out a experiments
    imageset = ImageSet(ImageSetData(Reader(None, ["non-existent.cbf"]), None))
    imageset.set_detector(d)
    imageset.set_beam(b)
    experiments = ExperimentListFactory.from_imageset_and_crystal(
        imageset, None)
    experiments.as_json("dummy.expt")

    # Centre of distortion will be the far corner from the origin of the first
    # panel
    centre_xy = d[0].get_image_size_mm()

    # Generate distortion maps
    cmd = ("dials.generate_distortion_maps dummy.expt "
           "mode=ellipse centre_xy={},{} "
           "phi=0 l1=1.0 l2=0.95").format(*centre_xy)
    easy_run.fully_buffered(command=cmd).raise_if_errors()

    # Load the maps
    with open("dx.pickle", "rb") as f:
        dx = pickle.load(f)
    with open("dy.pickle", "rb") as f:
        dy = pickle.load(f)

    # Check there are 4 maps each
    assert len(dx) == len(dy) == 4

    # Ellipse has phi=0, so all correction is in the dy map
    for arr in dx:
        assert min(arr) == max(arr) == 0.0

    # The ellipse correction is centred at the middle of the detector and all in
    # the Y direction. Therefore we expect a few things from the dy maps:
    #
    # (1) Within each panel the columns of the array are identical.
    # (2) The two upper panels should be the same
    # (3) The two lower panels should be the same.
    # (4) One column from an upper panel is a negated, reversed column from a
    #     lower panel.
    #
    # All together expect the 4 dy maps to look something like this:
    #
    # /-----------\ /-----------\
    # |-3 -3 -3 -3| |-3 -3 -3 -3|
    # |-2 -2 -2 -2| |-2 -2 -2 -2|
    # |-1 -1 -1 -1| |-1 -1 -1 -1|
    # | 0  0  0  0| | 0  0  0  0|
    # \-----------/ \-----------/
    # /-----------\ /-----------\
    # | 0  0  0  0| | 0  0  0  0|
    # | 1  1  1  1| | 1  1  1  1|
    # | 2  2  2  2| | 2  2  2  2|
    # | 3  3  3  3| | 3  3  3  3|
    # \-----------/ \-----------/

    # So the fundamental data is all in the first column of first panel's map
    col0 = dy[0].matrix_copy_column(0)

    # The correction should be 5% of the distance from the ellipse centre to a
    # corrected pixel (l2 = 0.95 above) along the slow axis. Check that is the
    # case (for the first pixel at least)
    vec_centre_to_first_px = matrix.col(d[0].get_pixel_lab_coord(
        (0.5, 0.5))) - matrix.col(d[0].get_lab_coord(centre_xy))
    dist_centre_to_first_px = vec_centre_to_first_px.dot(
        matrix.col(d[0].get_slow_axis()))
    corr_mm = dist_centre_to_first_px * 0.05
    corr_px = corr_mm / d[0].get_pixel_size()[1]
    assert col0[0] == pytest.approx(corr_px)

    # Test (1) from above list for panel 0
    for i in range(1, 50):
        assert (col0 == dy[0].matrix_copy_column(i)).all_eq(True)

    # Test (2)
    assert (dy[0] == dy[1]).all_eq(True)

    # Test (3)
    assert (dy[2] == dy[3]).all_eq(True)

    # Test (4)
    assert col0 == pytest.approx(-1.0 * dy[2].matrix_copy_column(0).reversed())

    # Test (1) for panel 2 as well, which then covers everything needed
    col0 = dy[2].matrix_copy_column(0)
    for i in range(1, 50):
        assert (col0 == dy[2].matrix_copy_column(i)).all_eq(True)