def test_sub_division_at_corners(sweep_and_model): from scitbx import matrix sweep_and_model.n_div = 2 # The detector beam vectors ds1 = beam_vector_map(sweep_and_model.detector[0], sweep_and_model.beam, sweep_and_model.n_div, True) expected_size = sweep_and_model.detector[0].get_image_size()[::-1] expected_size = tuple( [e * sweep_and_model.n_div + 1 for e in expected_size]) assert ds1.all() == expected_size s0 = sweep_and_model.beam.get_s0() m2 = sweep_and_model.gonio.get_rotation_axis() s0_length = matrix.col(sweep_and_model.beam.get_s0()).length() # Ensure a few random points are correct eps = 1e-7 for k in range(1000): j = random.randint(0, ds1.all()[0] - 1) i = random.randint(0, ds1.all()[1] - 1) y = float(j) / sweep_and_model.n_div x = float(i) / sweep_and_model.n_div xyz = sweep_and_model.detector[0].get_pixel_lab_coord((x, y)) s11 = matrix.col(xyz).normalize() * s0_length s12 = matrix.col(ds1[j, i]) assert (s11 - s12).length() <= eps
def test_sub_division_at_centres(sequence_and_model): sequence_and_model.n_div = 2 # The detector beam vectors ds1 = beam_vector_map( sequence_and_model.detector[0], sequence_and_model.beam, sequence_and_model.n_div, False, ) expected_size = sequence_and_model.detector[0].get_image_size()[::-1] expected_size = tuple( [e * sequence_and_model.n_div for e in expected_size]) assert ds1.all() == expected_size s0_length = matrix.col(sequence_and_model.beam.get_s0()).length() # Ensure a few random points are correct eps = 1e-7 for k in range(1000): j = random.randint(0, ds1.all()[0] - 1) i = random.randint(0, ds1.all()[1] - 1) y = float(j + 0.5) / sequence_and_model.n_div x = float(i + 0.5) / sequence_and_model.n_div xyz = sequence_and_model.detector[0].get_pixel_lab_coord((x, y)) s11 = matrix.col(xyz).normalize() * s0_length s12 = matrix.col(ds1[j, i]) assert (s11 - s12).length() <= eps
def tst_sub_division_at_centres(self): from scitbx import matrix from random import randint self.n_div = 2 # The detector beam vectors ds1 = beam_vector_map(self.detector[0], self.beam, self.n_div, False) expected_size = self.detector[0].get_image_size()[::-1] expected_size = tuple([e * self.n_div for e in expected_size]) assert(ds1.all() == expected_size) s0 = self.beam.get_s0() m2 = self.gonio.get_rotation_axis() s0_length = matrix.col(self.beam.get_s0()).length() # Ensure a few random points are correct eps = 1e-7 for k in range(1000): j = randint(0, ds1.all()[0]-1) i = randint(0, ds1.all()[1]-1) y = float(j + 0.5) / self.n_div x = float(i + 0.5) / self.n_div xyz = self.detector[0].get_pixel_lab_coord((x, y)) s11 = matrix.col(xyz).normalize() * s0_length s12 = matrix.col(ds1[j,i]) assert((s11 - s12).length() <= eps) # Test passed print 'OK'
class Test(object): def __init__(self): from dials.algorithms.profile_model.gaussian_rs import transform from dials.algorithms.profile_model.gaussian_rs import CoordinateSystem import os import libtbx.load_env from math import floor from scitbx import matrix from dials.model.serialize import load from random import uniform try: dials_regression = libtbx.env.dist_path('dials_regression') except KeyError, e: print 'FAIL: dials_regression not configured' exit(0) # Set the sweep filename and load the sweep filename = os.path.join(dials_regression, 'centroid_test_data', 'sweep.json') self.sweep = load.sweep(filename) # Get the models self.beam = self.sweep.get_beam() self.detector = self.sweep.get_detector() self.gonio = self.sweep.get_goniometer() assert (len(self.detector) == 1) # Get some stuff self.s0 = self.beam.get_s0() self.m2 = self.gonio.get_rotation_axis() self.image_size = self.detector[0].get_image_size() # Get a random s1/phi i = uniform(0, self.image_size[0]) j = uniform(1, self.image_size[1]) self.s1 = matrix.col(self.detector[0].get_pixel_lab_coord((i, j))) self.s1 = self.s1.normalize() * matrix.col(self.s0).length() self.phi = uniform(0, 5) self.x0 = int(floor(i - 10)) self.y0 = int(floor(j - 10)) # Set some parameters self.sigma_divergence = self.beam.get_sigma_divergence(deg=False) self.delta_divergence = 3 * self.sigma_divergence self.grid_half_size = 4 self.step_size = (self.delta_divergence / self.grid_half_size, self.delta_divergence / self.grid_half_size) # Create the coordinate system self.cs = CoordinateSystem(self.m2, self.s0, self.s1, self.phi) # Create the map of s1 coordinates self.s1_map = transform.beam_vector_map(self.detector[0], self.beam, True) # Create the grid index generator self.generate_indices = transform.GridIndexGenerator( self.cs, self.x0, self.y0, self.step_size, self.grid_half_size, self.s1_map)
def test_at_corners(sequence_and_model): assert len(sequence_and_model.detector) == 1 # The detector beam vectors ds1 = beam_vector_map(sequence_and_model.detector[0], sequence_and_model.beam, True) expected_size = sequence_and_model.detector[0].get_image_size()[::-1] expected_size = tuple([e + 1 for e in expected_size]) assert ds1.all() == expected_size s0_length = matrix.col(sequence_and_model.beam.get_s0()).length() # Ensure a few random points are correct eps = 1e-7 for k in range(1000): j = random.randint(0, ds1.all()[0] - 1) i = random.randint(0, ds1.all()[1] - 1) y = float(j) x = float(i) xyz = sequence_and_model.detector[0].get_pixel_lab_coord((x, y)) s11 = matrix.col(xyz).normalize() * s0_length s12 = matrix.col(ds1[j, i]) assert (s11 - s12).length() <= eps
def tst_conservation_of_counts(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)) 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(), 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 print 'OK'
def tst_conservation_of_counts(self): from scitbx import matrix from random import uniform, seed from dials.algorithms.profile_model.gaussian_rs import CoordinateSystem from dials.algorithms.profile_model.gaussian_rs import transform from scitbx.array_family import flex seed(0) 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(500, 600) # 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) if abs(cs.zeta()) < 0.1: continue # 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)) 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.TransformForwardNoModel( self.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( self.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( self.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( self.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) # if cc < 0.99: # print cc, bbox # from matplotlib import pylab # pylab.plot(image.as_numpy_array()[(z1-z0)/2,(y1-y0)/2,:]) # pylab.show() # pylab.plot(image2.as_numpy_array()[(z1-z0)/2,(y1-y0)/2,:]) # pylab.show() # pylab.plot((image.as_double()-image2).as_numpy_array()[(z1-z0)/2,(y1-y0)/2,:]) # pylab.show() # Test passed print 'OK'
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)
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
def test_forward_no_model(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() 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
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
def tst_conservation_of_counts(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)) 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(), 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 print "OK"
def tst_conservation_of_counts(self): from scitbx import matrix from random import uniform, seed from dials.algorithms.profile_model.gaussian_rs import CoordinateSystem from dials.algorithms.profile_model.gaussian_rs import transform from scitbx.array_family import flex seed(0) 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(500, 600) # 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) if abs(cs.zeta()) < 0.1: continue # 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)) 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.TransformForwardNoModel(self.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(self.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(self.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(self.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 # if cc < 0.99: # print cc, bbox # from matplotlib import pylab # pylab.plot(image.as_numpy_array()[(z1-z0)/2,(y1-y0)/2,:]) # pylab.show() # pylab.plot(image2.as_numpy_array()[(z1-z0)/2,(y1-y0)/2,:]) # pylab.show() # pylab.plot((image.as_double()-image2).as_numpy_array()[(z1-z0)/2,(y1-y0)/2,:]) # pylab.show() # Test passed print "OK"