Ejemplo n.º 1
0
def setup(dials_data):
    from dials.algorithms.profile_model.gaussian_rs import BBoxCalculator3D
    from dials.model.serialize import load

    sequence = load.sequence(
        dials_data("centroid_test_data").join("sweep.json").strpath)

    fixture = {}

    # Get the models
    fixture["beam"] = sequence.get_beam()
    fixture["detector"] = sequence.get_detector()
    fixture["gonio"] = sequence.get_goniometer()
    fixture["scan"] = sequence.get_scan()

    # Set the delta_divergence/mosaicity
    n_sigma = 5
    sigma_divergence = 0.060 * math.pi / 180
    mosaicity = 0.154 * math.pi / 180
    fixture["delta_divergence"] = n_sigma * sigma_divergence
    fixture["delta_mosaicity"] = n_sigma * mosaicity

    # Create the bounding box calculator
    fixture["calculate_bbox"] = BBoxCalculator3D(
        fixture["beam"],
        fixture["detector"],
        fixture["gonio"],
        fixture["scan"],
        fixture["delta_divergence"],
        fixture["delta_mosaicity"],
    )
    return fixture
Ejemplo n.º 2
0
def test_run(dials_data):
    from dials.algorithms.profile_model.gaussian_rs import transform
    from dials.algorithms.profile_model.gaussian_rs import CoordinateSystem
    from scitbx import matrix
    from dials.model.serialize import load

    sequence = load.sequence(
        dials_data("centroid_test_data").join("sweep.json").strpath)

    # Get the models
    beam = sequence.get_beam()
    detector = sequence.get_detector()
    gonio = sequence.get_goniometer()
    assert len(detector) == 1

    # Get some stuff
    s0 = beam.get_s0()
    m2 = gonio.get_rotation_axis()
    image_size = detector[0].get_image_size()

    # Get a random s1/phi
    i = random.uniform(0, image_size[0])
    j = random.uniform(1, image_size[1])
    s1 = matrix.col(detector[0].get_pixel_lab_coord((i, j)))
    s1 = s1.normalize() * matrix.col(s0).length()
    phi = random.uniform(0, 5)
    x0 = int(math.floor(i - 10))
    y0 = int(math.floor(j - 10))

    # Set some parameters
    sigma_divergence = beam.get_sigma_divergence(deg=False)
    delta_divergence = 3 * sigma_divergence
    grid_half_size = 4
    step_size = (delta_divergence / grid_half_size,
                 delta_divergence / grid_half_size)

    # Create the coordinate system
    cs = CoordinateSystem(m2, s0, s1, phi)

    # Create the map of s1 coordinates
    s1_map = transform.beam_vector_map(detector[0], beam, True)

    # Create the grid index generator
    generate_indices = transform.GridIndexGenerator(cs, x0, y0, step_size,
                                                    grid_half_size, s1_map)

    for j in range(0, 20):
        for i in range(0, 20):

            xx = x0 + i
            yy = y0 + j
            if xx < 0 or yy < 0 or xx >= image_size[0] or yy >= image_size[0]:
                continue

            # Get the grid indices
            gi_1, gj_1 = generate_indices(j, i)

            # Get the grid indices
            xyz = matrix.col(detector[0].get_pixel_lab_coord((x0 + i, y0 + j)))
            xyz = xyz.normalize() * matrix.col(s0).length()
            c1, c2 = matrix.col(cs.from_beam_vector(xyz))
            gi_2 = grid_half_size + c1 / step_size[0] + 0.5
            gj_2 = grid_half_size + c2 / step_size[1] + 0.5

            # Check both are the same
            eps = 1e-7
            assert abs(gj_1 - gj_2) <= eps, (gi_1, gi_2, gj_1, gj_2)
            assert abs(gi_1 - gi_2) <= eps, (gi_1, gi_2, gj_1, gj_2)
Ejemplo n.º 3
0
def test_forward(dials_data):
    sequence = load.sequence(
        dials_data("centroid_test_data").join("sweep.json").strpath)

    # Get the models
    beam = sequence.get_beam()
    detector = sequence.get_detector()
    gonio = sequence.get_goniometer()
    scan = sequence.get_scan()

    # Set some parameters
    sigma_divergence = beam.get_sigma_divergence(deg=False)
    mosaicity = 0.157 * math.pi / 180
    n_sigma = 3
    grid_size = 7
    delta_divergence = n_sigma * sigma_divergence

    step_size = delta_divergence / grid_size
    delta_divergence2 = delta_divergence + step_size * 0.5
    delta_mosaicity = n_sigma * mosaicity

    # Create the bounding box calculator
    calculate_bbox = BBoxCalculator3D(beam, detector, gonio, scan,
                                      delta_divergence2, delta_mosaicity)

    # Initialise the transform
    spec = transform.TransformSpec(beam, detector, gonio, scan,
                                   sigma_divergence, mosaicity, n_sigma + 1,
                                   grid_size)

    # tst_conservation_of_counts(self):

    assert len(detector) == 1

    s0 = beam.get_s0()
    m2 = gonio.get_rotation_axis()
    s0_length = matrix.col(beam.get_s0()).length()

    # Create an s1 map
    s1_map = transform.beam_vector_map(detector[0], beam, True)

    for i in range(100):

        # Get random x, y, z
        x = random.uniform(300, 1800)
        y = random.uniform(300, 1800)
        z = random.uniform(0, 9)

        # Get random s1, phi, panel
        s1 = matrix.col(detector[0].get_pixel_lab_coord(
            (x, y))).normalize() * s0_length
        phi = scan.get_angle_from_array_index(z, deg=False)
        panel = 0

        # Calculate the bounding box
        bbox = calculate_bbox(s1, z, panel)
        x0, x1, y0, y1, z0, z1 = bbox

        # Create the coordinate system
        cs = CoordinateSystem(m2, s0, s1, phi)

        # The grid index generator
        step_size = delta_divergence / grid_size
        grid_index = transform.GridIndexGenerator(cs, x0, y0,
                                                  (step_size, step_size),
                                                  grid_size, s1_map)

        # Create the image
        # image = flex.double(flex.grid(z1 - z0, y1 - y0, x1 - x0), 1)
        image = gaussian((z1 - z0, y1 - y0, x1 - x0), 10.0,
                         (z - z0, y - y0, x - x0), (2.0, 2.0, 2.0))
        mask = flex.bool(flex.grid(image.all()), False)
        for j in range(y1 - y0):
            for i in range(x1 - x0):
                inside = False
                gx00, gy00 = grid_index(j, i)
                gx01, gy01 = grid_index(j, i + 1)
                gx10, gy10 = grid_index(j + 1, i)
                gx11, gy11 = grid_index(j + 1, i + 1)
                mingx = min([gx00, gx01, gx10, gx11])
                maxgx = max([gx00, gx01, gx10, gx11])
                mingy = min([gy00, gy01, gy10, gy11])
                maxgy = max([gy00, gy01, gy10, gy11])
                if (mingx >= 0 and maxgx < 2 * grid_size + 1 and mingy >= 0
                        and maxgy < 2 * grid_size + 1):
                    inside = True
                for k in range(1, z1 - z0 - 1):
                    mask[k, j, i] = inside

        # Transform the image to the grid
        transformed = transform.TransformForward(spec, cs, bbox, 0,
                                                 image.as_double(), mask)
        grid = transformed.profile()

        # Get the sums and ensure they're the same
        eps = 1e-7
        sum_grid = flex.sum(grid)
        sum_image = flex.sum(flex.double(flex.select(image, flags=mask)))
        assert abs(sum_grid - sum_image) <= eps

    # Test passed

    # tst_transform_with_background(self):

    assert len(detector) == 1
    s0 = beam.get_s0()
    m2 = gonio.get_rotation_axis()
    s0_length = matrix.col(beam.get_s0()).length()

    # Create an s1 map
    s1_map = transform.beam_vector_map(detector[0], beam, True)

    for i in range(100):

        # Get random x, y, z
        x = random.uniform(300, 1800)
        y = random.uniform(300, 1800)
        z = random.uniform(0, 9)

        # Get random s1, phi, panel
        s1 = matrix.col(detector[0].get_pixel_lab_coord(
            (x, y))).normalize() * s0_length
        phi = scan.get_angle_from_array_index(z, deg=False)
        panel = 0

        # Calculate the bounding box
        bbox = calculate_bbox(s1, z, panel)
        x0, x1, y0, y1, z0, z1 = bbox

        # Create the coordinate system
        cs = CoordinateSystem(m2, s0, s1, phi)

        # The grid index generator
        step_size = delta_divergence / grid_size
        grid_index = transform.GridIndexGenerator(cs, x0, y0,
                                                  (step_size, step_size),
                                                  grid_size, s1_map)

        # Create the image
        # image = flex.double(flex.grid(z1 - z0, y1 - y0, x1 - x0), 1)
        image = gaussian((z1 - z0, y1 - y0, x1 - x0), 10.0,
                         (z - z0, y - y0, x - x0), (2.0, 2.0, 2.0))
        background = flex.random_double(len(image))
        background.resize(image.accessor())
        mask = flex.bool(flex.grid(image.all()), False)
        for j in range(y1 - y0):
            for i in range(x1 - x0):
                inside = False
                gx00, gy00 = grid_index(j, i)
                gx01, gy01 = grid_index(j, i + 1)
                gx10, gy10 = grid_index(j + 1, i)
                gx11, gy11 = grid_index(j + 1, i + 1)
                mingx = min([gx00, gx01, gx10, gx11])
                maxgx = max([gx00, gx01, gx10, gx11])
                mingy = min([gy00, gy01, gy10, gy11])
                maxgy = max([gy00, gy01, gy10, gy11])
                if (mingx >= 0 and maxgx <= 2 * grid_size + 1 and mingy >= 0
                        and maxgy <= 2 * grid_size + 1):
                    inside = True
                for k in range(1, z1 - z0 - 1):
                    mask[k, j, i] = inside

        # Transform the image to the grid
        transformed = transform.TransformForward(spec, cs, bbox, 0,
                                                 image.as_double(),
                                                 background.as_double(), mask)
        igrid = transformed.profile()
        bgrid = transformed.background()

        # Get the sums and ensure they're the same
        eps = 1e-7
        sum_igrid = flex.sum(igrid)
        sum_bgrid = flex.sum(bgrid)
        sum_image = flex.sum(flex.double(flex.select(image, flags=mask)))
        sum_bkgrd = flex.sum(flex.double(flex.select(background, flags=mask)))
        try:
            assert abs(sum_igrid - sum_image) <= eps
            assert abs(sum_bgrid - sum_bkgrd) <= eps
        except Exception:
            print("Failed for: ", (x, y, z))
            raise
Ejemplo n.º 4
0
def test_forward_no_model(dials_data):
    sequence = load.sequence(
        dials_data("centroid_test_data").join("sweep.json").strpath)

    # Get the models
    beam = sequence.get_beam()
    detector = sequence.get_detector()
    gonio = sequence.get_goniometer()
    scan = sequence.get_scan()
    scan.set_image_range((0, 1000))

    # Set some parameters
    sigma_divergence = beam.get_sigma_divergence(deg=False)
    mosaicity = 0.157 * math.pi / 180
    n_sigma = 3
    grid_size = 20
    delta_divergence = n_sigma * sigma_divergence

    step_size = delta_divergence / grid_size
    delta_divergence2 = delta_divergence + step_size * 0.5
    delta_mosaicity = n_sigma * mosaicity

    # Create the bounding box calculator
    calculate_bbox = BBoxCalculator3D(beam, detector, gonio, scan,
                                      delta_divergence2, delta_mosaicity)

    # Initialise the transform
    spec = transform.TransformSpec(beam, detector, gonio, scan,
                                   sigma_divergence, mosaicity, n_sigma + 1,
                                   grid_size)

    # tst_conservation_of_counts(self):

    random.seed(0)

    assert len(detector) == 1

    s0 = beam.get_s0()
    m2 = gonio.get_rotation_axis()
    s0_length = matrix.col(beam.get_s0()).length()

    # Create an s1 map
    s1_map = transform.beam_vector_map(detector[0], beam, True)

    for i in range(100):

        # Get random x, y, z
        x = random.uniform(300, 1800)
        y = random.uniform(300, 1800)
        z = random.uniform(500, 600)

        # Get random s1, phi, panel
        s1 = matrix.col(detector[0].get_pixel_lab_coord(
            (x, y))).normalize() * s0_length
        phi = scan.get_angle_from_array_index(z, deg=False)
        panel = 0

        # Calculate the bounding box
        bbox = calculate_bbox(s1, z, panel)
        x0, x1, y0, y1, z0, z1 = bbox

        # Create the coordinate system
        cs = CoordinateSystem(m2, s0, s1, phi)
        if abs(cs.zeta()) < 0.1:
            continue

        # The grid index generator
        step_size = delta_divergence / grid_size
        grid_index = transform.GridIndexGenerator(cs, x0, y0,
                                                  (step_size, step_size),
                                                  grid_size, s1_map)

        # Create the image
        # image = flex.double(flex.grid(z1 - z0, y1 - y0, x1 - x0), 1)
        image = gaussian((z1 - z0, y1 - y0, x1 - x0), 10.0,
                         (z - z0, y - y0, x - x0), (2.0, 2.0, 2.0))
        mask = flex.bool(flex.grid(image.all()), False)
        for j in range(y1 - y0):
            for i in range(x1 - x0):
                inside = False
                gx00, gy00 = grid_index(j, i)
                gx01, gy01 = grid_index(j, i + 1)
                gx10, gy10 = grid_index(j + 1, i)
                gx11, gy11 = grid_index(j + 1, i + 1)
                mingx = min([gx00, gx01, gx10, gx11])
                maxgx = max([gx00, gx01, gx10, gx11])
                mingy = min([gy00, gy01, gy10, gy11])
                maxgy = max([gy00, gy01, gy10, gy11])
                if (mingx >= 0 and maxgx < 2 * grid_size + 1 and mingy >= 0
                        and maxgy < 2 * grid_size + 1):
                    inside = True
                for k in range(1, z1 - z0 - 1):
                    mask[k, j, i] = inside

        # Transform the image to the grid
        transformed = transform.TransformForwardNoModel(
            spec, cs, bbox, 0, image.as_double(), mask)
        grid = transformed.profile()

        # Get the sums and ensure they're the same
        eps = 1e-7
        sum_grid = flex.sum(grid)
        sum_image = flex.sum(flex.double(flex.select(image, flags=mask)))
        assert abs(sum_grid - sum_image) <= eps

        mask = flex.bool(flex.grid(image.all()), True)
        transformed = transform.TransformForwardNoModel(
            spec, cs, bbox, 0, image.as_double(), mask)
        grid = transformed.profile()

        # Boost the bbox to make sure all intensity is included
        x0, x1, y0, y1, z0, z1 = bbox
        bbox2 = (x0 - 10, x1 + 10, y0 - 10, y1 + 10, z0 - 10, z1 + 10)

        # Do the reverse transform
        transformed = transform.TransformReverseNoModel(
            spec, cs, bbox2, 0, grid)
        image2 = transformed.profile()

        # Check the sum of pixels are the same
        sum_grid = flex.sum(grid)
        sum_image = flex.sum(image2)
        assert abs(sum_grid - sum_image) <= eps

        # Do the reverse transform
        transformed = transform.TransformReverseNoModel(
            spec, cs, bbox, 0, grid)
        image2 = transformed.profile()

        from dials.algorithms.statistics import pearson_correlation_coefficient

        cc = pearson_correlation_coefficient(image.as_1d().as_double(),
                                             image2.as_1d())
        assert cc >= 0.99
Ejemplo n.º 5
0
def test_map_frames_forward(dials_data):
    from dials.model.serialize import load
    from dials.algorithms.profile_model.gaussian_rs.transform import MapFramesForward
    from dials.algorithms.profile_model.gaussian_rs import BBoxCalculator3D

    sequence = load.sequence(
        dials_data("centroid_test_data").join("sweep.json").strpath)

    # Get the models
    beam = sequence.get_beam()
    detector = sequence.get_detector()
    gonio = sequence.get_goniometer()
    scan = sequence.get_scan()

    # Set the delta_divergence/mosaicity
    n_sigma = 3
    sigma_divergence = 0.060 * math.pi / 180
    mosaicity = 0.154 * math.pi / 180
    delta_divergence = n_sigma * sigma_divergence
    delta_mosaicity = n_sigma * mosaicity

    # Set the grid size
    grid_size = (4, 4, 4)

    # Create the E3 fraction object
    transform = MapFramesForward(
        scan.get_array_range()[0],
        scan.get_oscillation(deg=False)[0],
        scan.get_oscillation(deg=False)[1],
        mosaicity,
        n_sigma,
        grid_size[2],
    )

    # Create the bounding box calculator
    calculate_bbox = BBoxCalculator3D(beam, detector, gonio, scan,
                                      delta_divergence, delta_mosaicity)

    from dials.algorithms.profile_model.gaussian_rs import CoordinateSystem
    from scitbx.array_family import flex

    assert len(detector) == 1
    s0 = beam.get_s0()
    m2 = gonio.get_rotation_axis()
    s0_length = matrix.col(beam.get_s0()).length()

    for i in range(100):

        # Get random x, y, z
        x = random.uniform(0, 2000)
        y = random.uniform(0, 2000)
        z = random.uniform(0, 9)

        # Get random s1, phi, panel
        s1 = matrix.col(detector[0].get_pixel_lab_coord(
            (x, y))).normalize() * s0_length
        phi = scan.get_angle_from_array_index(z, deg=False)
        panel = 0

        # Calculate the bounding box
        bbox = calculate_bbox(s1, z, panel)

        # Create the XDS coordinate system
        xcs = CoordinateSystem(m2, s0, s1, phi)

        # Calculate the transform fraction
        fraction = transform(bbox[4:], phi, xcs.zeta())

        # Ensure the minimum and maximum are 0 < 1
        fmax = flex.max(fraction)
        fmin = flex.min(fraction)
        assert fmax <= (
            1.0 + 5e-15) and fmax > 0.0, "%.16f not between 0 and 1" % fmax
        assert fmin >= 0.0 and fmin <= 1.0

        # Ensure the fraction for each image frame adds up to 1.0 for
        # all those frames completely within the grid
        for j in range(1, fraction.all()[0] - 1):
            tot = flex.sum(fraction[j:j + 1, :])
            assert abs(tot - 1.0) < 1e-7

        # Ensure the frames follow a progression through the grid. I.e,
        # check that values increase then decrease and don't jump around
        for j in range(fraction.all()[0]):
            f = fraction[j:j + 1, :]
            last = f[0]
            rev = False
            for i in range(1, len(f)):
                curr = f[1]
                if rev is False:
                    if curr < last:
                        rev = True
                else:
                    assert curr <= last
                last = curr
Ejemplo n.º 6
0
def test_map_forward_reverse(dials_data):
    from dials.model.serialize import load
    from dials.algorithms.profile_model.gaussian_rs.transform import MapFramesReverse
    from dials.algorithms.profile_model.gaussian_rs.transform import MapFramesForward
    from dials.algorithms.profile_model.gaussian_rs import BBoxCalculator3D

    sequence = load.sequence(
        dials_data("centroid_test_data").join("sweep.json").strpath)

    # Get the models
    beam = sequence.get_beam()
    detector = sequence.get_detector()
    gonio = sequence.get_goniometer()
    scan = sequence.get_scan()

    # Set the delta_divergence/mosaicity
    n_sigma = 3
    sigma_divergence = 0.060 * math.pi / 180
    mosaicity = 0.154 * math.pi / 180
    delta_divergence = n_sigma * sigma_divergence
    delta_mosaicity = n_sigma * mosaicity

    # Set the grid size
    grid_size = (4, 4, 4)

    # Create the E3 fraction object
    transform_forward = MapFramesForward(
        scan.get_array_range()[0],
        scan.get_oscillation(deg=False)[0],
        scan.get_oscillation(deg=False)[1],
        mosaicity,
        n_sigma,
        grid_size[2],
    )

    # Create the E3 fraction object
    transform_reverse = MapFramesReverse(
        scan.get_array_range()[0],
        scan.get_oscillation(deg=False)[0],
        scan.get_oscillation(deg=False)[1],
        mosaicity,
        n_sigma,
        grid_size[2],
    )

    # Create the bounding box calculator
    calculate_bbox = BBoxCalculator3D(beam, detector, gonio, scan,
                                      delta_divergence, delta_mosaicity)

    from dials.algorithms.profile_model.gaussian_rs import CoordinateSystem

    s0 = beam.get_s0()
    m2 = gonio.get_rotation_axis()
    s0_length = matrix.col(beam.get_s0()).length()

    for i in range(100):

        # Get random x, y, z
        x = random.uniform(0, 2000)
        y = random.uniform(0, 2000)
        z = random.uniform(0, 9)

        # Get random s1, phi, panel
        s1 = matrix.col(detector[0].get_pixel_lab_coord(
            (x, y))).normalize() * s0_length
        phi = scan.get_angle_from_array_index(z, deg=False)
        panel = 0

        # Calculate the bounding box
        bbox = calculate_bbox(s1, phi, panel)

        # Create the XDS coordinate system
        xcs = CoordinateSystem(m2, s0, s1, phi)

        # Calculate the transform fraction
        forward_fraction = transform_forward(bbox[4:], phi, xcs.zeta())

        # Calculate the transform fraction
        reverse_fraction = transform_reverse(bbox[4:], phi, xcs.zeta())

        # Check the same points are non-zero
        eps = 1e-7
        for j in range(forward_fraction.all()[0]):
            for i in range(forward_fraction.all()[1]):
                if forward_fraction[j, i] > 0.0:
                    assert reverse_fraction[i, j] > 0.0
                else:
                    assert reverse_fraction[i, j] < eps