Beispiel #1
0
def test1():
  # Compare over a range of lengths from 2 to 200 with random data
  for i in range(2, 201):
    dat = flex.random_double(i)
    a = Periodogram(dat)
    b = rpgram(dat)

    assert approx_equal(a.freq, b.freq)
    assert approx_equal(a.spec, b.spec)
  print "OK"
Beispiel #2
0
def test1():
    # Compare over a range of lengths from 2 to 200 with random data
    for i in range(2, 201):
        dat = flex.random_double(i)
        a = Periodogram(dat)
        b = rpgram(dat)

        assert approx_equal(a.freq, b.freq)
        assert approx_equal(a.spec, b.spec)
    print "OK"
Beispiel #3
0
def test2():
  # compare plots
  dat = flex.random_double(50)
  a = Periodogram(dat)
  b = rpgram(dat)

  from matplotlib.pyplot import ion
  ion()
  a.plot()
  b.plot()
Beispiel #4
0
def test2():
    # compare plots
    dat = flex.random_double(50)
    a = Periodogram(dat)
    b = rpgram(dat)

    from matplotlib.pyplot import ion
    ion()
    a.plot()
    b.plot()
def generate_intensities(crystal_symmetry, anomalous_flag=False, d_min=1):
    from cctbx import miller

    indices = miller.index_generator(
        crystal_symmetry.unit_cell(),
        crystal_symmetry.space_group().type(),
        anomalous_flag,
        d_min,
    ).to_array()
    miller_set = crystal_symmetry.miller_set(indices, anomalous_flag)
    intensities = flex.random_double(indices.size()) * 1000
    miller_array = miller.array(
        miller_set, data=intensities,
        sigmas=flex.sqrt(intensities)).set_observation_type_xray_intensity()
    return miller_array
Beispiel #6
0
def test3():
    # compare smoothed pgrams with even and odd length sequences
    for i in range(2):
        dat = flex.random_double(50 + i)
        a = Periodogram(dat, spans=4)
        b = rpgram(dat, spans=4)

        #from matplotlib.pyplot import ion
        #ion()
        #a.plot()
        #b.plot()

        assert approx_equal(a.freq, b.freq)
        assert approx_equal(a.spec, b.spec)

        print "OK"
Beispiel #7
0
def test3():
  # compare smoothed pgrams with even and odd length sequences
  for i in range(2):
    dat = flex.random_double(50+i)
    a = Periodogram(dat, spans=4)
    b = rpgram(dat, spans=4)

    #from matplotlib.pyplot import ion
    #ion()
    #a.plot()
    #b.plot()

    assert approx_equal(a.freq, b.freq)
    assert approx_equal(a.spec, b.spec)

    print "OK"
Beispiel #8
0
def test4():
    # compare kernapply
    from scitbx.math.periodogram import Kernel, kernapply
    spans = 4
    dat = flex.random_double(50)
    k1 = Kernel('modified.daniell', spans // 2)
    a = kernapply(dat, k1, circular=True)

    x = robjects.FloatVector(list(dat))
    kernel = robjects.r['kernel']
    k2 = kernel('modified.daniell', spans // 2)
    kernapply2 = robjects.r['kernapply']
    b = flex.double(kernapply2(x, k2, circular=True))

    for e1, e2 in zip(a, b):
        assert approx_equal(e1, e2)
    print "OK"
Beispiel #9
0
def test4():
  # compare kernapply
  from scitbx.math.periodogram import Kernel, kernapply
  spans = 4
  dat = flex.random_double(50)
  k1 = Kernel('modified.daniell', spans//2)
  a = kernapply(dat, k1, circular=True)

  x = robjects.FloatVector(list(dat))
  kernel = robjects.r['kernel']
  k2 = kernel('modified.daniell', spans//2)
  kernapply2 = robjects.r['kernapply']
  b = flex.double(kernapply2(x, k2, circular=True))

  for e1, e2 in zip(a, b):
    assert approx_equal(e1, e2)
  print "OK"
Beispiel #10
0
def test5():
    # compare smoothed pgrams with convolved kernel, even and odd length sequences
    for i in range(2):
        dat = flex.random_double(50 + i)

        a = Periodogram(dat, spans=[4, 4])
        b = rpgram(dat, spans=robjects.FloatVector(list([4, 4])))

        #from matplotlib.pyplot import ion
        #ion()
        #a.plot()
        #b.plot()

        assert approx_equal(a.freq, b.freq)
        assert approx_equal(a.spec, b.spec)

        print "OK"
Beispiel #11
0
def test5():
  # compare smoothed pgrams with convolved kernel, even and odd length sequences
  for i in range(2):
    dat = flex.random_double(50+i)

    a = Periodogram(dat, spans=[4,4])
    b = rpgram(dat, spans=robjects.FloatVector(list([4,4])))

    #from matplotlib.pyplot import ion
    #ion()
    #a.plot()
    #b.plot()

    assert approx_equal(a.freq, b.freq)
    assert approx_equal(a.spec, b.spec)

    print "OK"
        def __init__(
            self,
            experiments,
            reflections,
            initial_mosaic_parameters,
            wavelength_func,
            refine_bandpass=False,
        ):
            """Initialize the minimizer and perform the minimization
            @param experiments ExperimentList
            @param reflections flex.reflection_table
            @param initial_mosaic_parameters Tuple of domain size (angstroms) and half mosaic angle (degrees)
            @param wavelength_func Function to compute wavelengths
            @param refine_bandpass If True, refine band pass for each experiment.
            """
            self.experiments = experiments
            self.reflections = reflections
            self.wavelength_func = wavelength_func
            self.refine_bandpass = refine_bandpass
            self.x = flex.double(initial_mosaic_parameters)
            self.n = 2
            if refine_bandpass:
                for expt_id, expt in enumerate(experiments):
                    refls = reflections.select(reflections["id"] == expt_id)
                    wavelength_min, wavelength_max = estimate_bandpass(refls)
                    expt.crystal.bandpass = wavelength_min, wavelength_max
                    # actually refine the midpoint and the width.  That ensures the two values don't cross over.
                    self.x.append(wavelength_max - wavelength_min)
                    self.x.append((wavelength_min + wavelength_max) / 2)
                    self.n += 2

            self.starting_simplex = []
            for i in xrange(self.n + 1):
                self.starting_simplex.append(
                    (0.9 + (flex.random_double(self.n) / 10)) * self.x)

            self.optimizer = simplex_opt(
                dimension=self.n,
                matrix=self.starting_simplex,
                evaluator=self,
                tolerance=1e-1,
            )
            self.x = self.optimizer.get_solution()
Beispiel #13
0
def test_max_cell_low_res_with_high_res_noise(setup):
    reflections = setup["reflections"]
    crystal_symmetry = setup["crystal_symmetry"]

    rlp = reflections["rlp"]
    # select only low resolution reflections
    reflections = reflections.select(1 / rlp.norms() > 4)

    n = int(0.1 * reflections.size())
    rlp_noise = flex.vec3_double(*(flex.random_double(n) for i in range(3)))
    reflections["rlp"].extend(rlp_noise)
    reflections["imageset_id"].extend(flex.int(rlp_noise.size()))
    reflections["xyzobs.mm.value"].extend(flex.vec3_double(rlp_noise.size()))

    max_cell_multiplier = 1.3
    max_cell = find_max_cell(reflections,
                             max_cell_multiplier=max_cell_multiplier)

    known_max_cell = max(
        crystal_symmetry.primitive_setting().unit_cell().parameters()[:3])
    assert max_cell.max_cell > known_max_cell
Beispiel #14
0
    def tst_transform_with_background(self):

        from scitbx import matrix
        from random import uniform
        from dials.algorithms.profile_model.gaussian_rs import CoordinateSystem
        from dials.algorithms.profile_model.gaussian_rs import transform
        from scitbx.array_family import flex

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

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

        for i in range(100):

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

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

            # Calculate the bounding box
            bbox = self.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 = self.delta_divergence / self.grid_size
            grid_index = transform.GridIndexGenerator(cs, x0, y0, (step_size, step_size), self.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 * self.grid_size + 1
                        and mingy >= 0
                        and maxgy <= 2 * self.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(
                self.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
        # Test passed
        print "OK"
Beispiel #15
0
    def tst_transform_with_background(self):

        from scitbx import matrix
        from random import uniform
        from dials.algorithms.profile_model.gaussian_rs import CoordinateSystem
        from dials.algorithms.profile_model.gaussian_rs import transform
        from scitbx.array_family import flex
        assert (len(self.detector) == 1)
        s0 = self.beam.get_s0()
        m2 = self.gonio.get_rotation_axis()
        s0_length = matrix.col(self.beam.get_s0()).length()

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

        for i in range(100):

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

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

            # Calculate the bounding box
            bbox = self.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 = self.delta_divergence / self.grid_size
            grid_index = transform.GridIndexGenerator(cs, x0, y0,
                                                      (step_size, step_size),
                                                      self.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 * self.grid_size + 1
                            and mingy >= 0
                            and maxgy <= 2 * self.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(self.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
        # Test passed
        print 'OK'
Beispiel #16
0
def test_contraints_manager_simple_test():

    x = flex.random_double(10)

    # constrain parameters 2 and 4 and 6, 7 and 8
    c1 = EqualShiftConstraint([1, 3], x)
    c2 = EqualShiftConstraint([5, 6, 7], x)

    cm = ConstraintManager([c1, c2], len(x))
    constrained_x = cm.constrain_parameters(x)

    # check the constrained parameters are as expected
    assert len(constrained_x) == 7
    assert constrained_x[5] == flex.mean(x.select([1, 3]))
    assert constrained_x[6] == flex.mean(x[5:8])

    # minimiser would modify the constrained parameters
    mod_constrained_x = constrained_x + 10.0

    # check the expanded parameters are as expected
    expanded = cm.expand_parameters(mod_constrained_x)
    assert x + 10.0 == expanded

    # make a matrix to exercise jacobian compaction
    j = flex.random_double(20 * 10)
    j.reshape(flex.grid(20, 10))

    # for constrained columns, elements that are non-zero in one column are
    # zero in the other columns. Enforce that in this example
    mask2 = flex.bool([True] * 10 + [False] * 10)
    mask4 = ~mask2
    col2 = j.matrix_copy_column(1)
    col2.set_selected(mask2, 0)
    j.matrix_paste_column_in_place(col2, 1)
    col4 = j.matrix_copy_column(3)
    col4.set_selected(mask4, 0)
    j.matrix_paste_column_in_place(col4, 3)

    mask6 = flex.bool([False] * 7 + [True] * 13)
    mask7 = mask6.reversed()
    mask8 = ~(mask6 & mask7)
    col6 = j.matrix_copy_column(5)
    col6.set_selected(mask6, 0)
    j.matrix_paste_column_in_place(col6, 5)
    col7 = j.matrix_copy_column(6)
    col7.set_selected(mask7, 0)
    j.matrix_paste_column_in_place(col7, 6)
    col8 = j.matrix_copy_column(7)
    col8.set_selected(mask8, 0)
    j.matrix_paste_column_in_place(col8, 7)

    cj = cm.constrain_jacobian(j)

    # check expected dimensions
    assert cj.all() == (20, 7)

    # check that the constrained columns are equal to sums of the relevant
    # columns in the original Jacobian
    tmp = j.matrix_copy_column(1) + j.matrix_copy_column(3)
    assert (cj.matrix_copy_column(5) == tmp).all_eq(True)

    tmp = j.matrix_copy_column(5) + j.matrix_copy_column(
        6) + j.matrix_copy_column(7)
    assert (cj.matrix_copy_column(6) == tmp).all_eq(True)

    # convert to a sparse matrix to exercise the sparse Jacobian compaction
    j2 = sparse.matrix(20, 10)
    mask = flex.bool(20, True)
    for i, c in enumerate(j2.cols()):
        c.set_selected(mask, j.matrix_copy_column(i))
    assert (j2.as_dense_matrix() == j).all_eq(True)

    cm2 = SparseConstraintManager([c1, c2], len(x))
    cj2 = cm2.constrain_jacobian(j2)

    # ensure dense and sparse calculations give the same result
    assert (cj2.as_dense_matrix() == cj).all_eq(True)

    # construct derivatives of the objective dL/dp from the Jacobian to test
    # constrain_gradient_vector. Here assume unit weights
    dL_dp = [sum(col.as_dense_vector()) for col in j2.cols()]
    constr_dL_dp = cm.constrain_gradient_vector(dL_dp)

    # check constrained values are equal to sums of relevant elements in the
    # original gradient vector
    assert constr_dL_dp[5] == dL_dp[1] + dL_dp[3]
    assert constr_dL_dp[6] == dL_dp[5] + dL_dp[6] + dL_dp[7]
Beispiel #17
0
def test_forward(dials_data):
    sequence = load.imageset(
        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
Beispiel #18
0
def test_forward(dials_data):
    from dials.model.serialize import load
    from dials.algorithms.profile_model.gaussian_rs import transform
    from dials.algorithms.profile_model.gaussian_rs import BBoxCalculator3D

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

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

    #        beam.set_direction((0.0, 0.0, 1.0))
    #        gonio.set_rotation_axis((1.0, 0.0, 0.0))
    #        detector.set_frame((1.0, 0.0, 0.0),
    #                                (0.0, 1.0, 0.0),
    #                                (-150, -150, -200))

    # 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):

    from scitbx import matrix
    from dials.algorithms.profile_model.gaussian_rs import CoordinateSystem
    from dials.algorithms.profile_model.gaussian_rs import transform
    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()

    # 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

    #    def tst_transformed_centroid(self):

    #        from scitbx import matrix
    #        from random import uniform
    #        from dials.algorithms.profile_model.gaussian_rs import CoordinateSystem
    #        from dials.algorithms.profile_model.gaussian_rs import transform
    #        from scitbx.array_family import flex
    #        from time import time

    #        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, beam, True)

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

    #        # Get random s1, phi, panel
    #        s1 = matrix.col(detector.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 = gaussian((z1 - z0, y1 - y0, x1 - x0), 10.0,
    #            (z - z0, y - y0, x - x0), (2.0, 2.0, 2.0))

    #        print x, y, z, bbox
    #        print (z1 - z0, y1 - y0, x1 - x0), (z - z0, y - y0, x - x0)

    #        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
    #                    #image[k,j,i] *= inside
    #        from matplotlib import pylab
    #        pylab.imshow(image.as_numpy_array()[(z1 - z0) / 2,:,:], interpolation='none')
    #        pylab.show()

    #        # Transform the image to the grid
    #        grid = transform(cs, bbox, image, mask)

    #        from matplotlib import pylab
    #        pylab.imshow(grid.as_numpy_array()[7,:,:], interpolation='none')
    #        pylab.show()

    #        # 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)

    #        # Check the centroid
    #        sz = grid_size * 2 + 1
    #        grid_x = flex.double(flex.grid(sz, sz, sz))
    #        grid_y = flex.double(flex.grid(sz, sz, sz))
    #        grid_z = flex.double(flex.grid(sz, sz, sz))
    #        for k in range(sz):
    #            for j in range(sz):
    #                for i in range(sz):
    #                    grid_x[k,j,i] = i + 0.5
    #                    grid_y[k,j,i] = j + 0.5
    #                    grid_z[k,j,i] = k + 0.5
    #
    #        sum_grid_x = flex.sum(grid * grid_x)
    #        sum_grid_y = flex.sum(grid * grid_y)
    #        sum_grid_z = flex.sum(grid * grid_z)
    #        xc = sum_grid_x / sum_grid
    #        yc = sum_grid_y / sum_grid
    #        zc = sum_grid_z / sum_grid
    #        print xc, yc, zc
    #        assert(abs(xc - grid_size + 0.5) <= 0.5)
    #        assert(abs(yc - grid_size + 0.5) <= 0.5)
    #        assert(abs(zc - grid_size + 0.5) <= 0.5)

    #        # Test passed
    #        print 'OK'

    # tst_transform_with_background(self):

    from scitbx import matrix
    from dials.algorithms.profile_model.gaussian_rs import CoordinateSystem
    from dials.algorithms.profile_model.gaussian_rs import transform
    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()

    # 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