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 compute_profile(experiments, reflection, reference, N): from dials.array_family import flex from dials.algorithms.profile_model.gaussian_rs import CoordinateSystem from dials.algorithms.profile_model.modeller import GridSampler from dials_scratch.jmp.sim import compute_profile_internal from random import uniform sbox = reflection["shoebox"] bbox = sbox.bbox zs = sbox.zsize() ys = sbox.ysize() xs = sbox.xsize() profile = flex.double(flex.grid(zs, ys, xs)) m2 = experiments[0].goniometer.get_rotation_axis_datum() s0 = experiments[0].beam.get_s0() s1 = reflection["s1"] phi = reflection["xyzcal.mm"][2] detector = experiments[0].detector scan = experiments[0].scan cs = CoordinateSystem(m2, s0, s1, phi) scan_range = scan.get_array_range() image_size = detector[0].get_image_size() grid_size = (3, 3, 40) assert grid_size[0] * grid_size[1] * grid_size[2] == len(reference[0]) sampler = GridSampler(image_size, scan_range, grid_size) xyz = reflection["xyzcal.px"] index = sampler.nearest(0, xyz) for g in reference[0]: assert abs(flex.sum(g) - 1.0) < 1e-7 grid = reference[0][index] sigma_d = experiments[0].profile.sigma_b(deg=False) sigma_m = experiments[0].profile.sigma_m(deg=False) delta_d = 3.0 * sigma_d delta_m = 3.0 * sigma_m profile = compute_profile_internal(grid, bbox, zs, ys, xs, N, delta_d, delta_m, detector, scan, cs) # from dials_scratch.jmp.viewer import show_image_stack_multi_view # show_image_stack_multi_view(profile.as_numpy_array(), vmax=max(profile)) sum_p = flex.sum(profile) print("Partiality: %f" % sum_p) try: assert sum_p > 0, "sum_p == 0" except Exception as e: print(e) return None return profile
def test_radius(setup): from dials.algorithms.profile_model.gaussian_rs import CoordinateSystem s0 = setup["beam"].get_s0() m2 = setup["gonio"].get_rotation_axis() s0_length = matrix.col(setup["beam"].get_s0()).length() width, height = setup["detector"][0].get_image_size() radius12 = setup["delta_divergence"] for i in range(1000): # 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(setup["detector"][0].get_pixel_lab_coord( (x, y))).normalize() * s0_length) phi = setup["scan"].get_angle_from_array_index(z, deg=False) panel = 0 # Calculate the bounding box bbox = setup["calculate_bbox"](s1, z, panel) # Create the XDS coordinate system xcs = CoordinateSystem(m2, s0, s1, phi) # Check vertical edges for j in range(bbox[2], bbox[3] + 1): xyz1 = setup["detector"][0].get_pixel_lab_coord((bbox[0], j)) xyz2 = setup["detector"][0].get_pixel_lab_coord((bbox[1] + 1, j)) sdash1 = matrix.col(xyz1).normalize() * s0_length sdash2 = matrix.col(xyz2).normalize() * s0_length e11, e21, e31 = xcs.from_beam_vector_and_rotation_angle( sdash1, phi) e12, e22, e31 = xcs.from_beam_vector_and_rotation_angle( sdash2, phi) if bbox[0] > 0 and bbox[1] < width: assert math.sqrt(e11**2 + e21**2) >= radius12 assert math.sqrt(e12**2 + e22**2) >= radius12 # Check horizontal edges for i in range(bbox[0], bbox[1] + 1): xyz1 = setup["detector"][0].get_pixel_lab_coord((i, bbox[2])) xyz2 = setup["detector"][0].get_pixel_lab_coord((i, bbox[3] + 1)) sdash1 = matrix.col(xyz1).normalize() * s0_length sdash2 = matrix.col(xyz2).normalize() * s0_length e11, e21, e32 = xcs.from_beam_vector_and_rotation_angle( sdash1, phi) e12, e22, e32 = xcs.from_beam_vector_and_rotation_angle( sdash2, phi) if bbox[2] > 0 and bbox[3] < height: assert math.sqrt(e11**2 + e21**2) >= radius12 assert math.sqrt(e12**2 + e22**2) >= radius12
def beamvector(): """Initialise the transform""" bv = { "s0": (0.013141995425357206, 0.002199999234194632, 1.4504754950989514), "s1": (-0.01752795848400313, -0.24786554213968193, 1.4290948735525306), "m2": (0.999975, -0.001289, -0.006968), "phi": 5.83575672475 * math.pi / 180, } bv["cs"] = CoordinateSystem(bv["m2"], bv["s0"], bv["s1"], bv["phi"]) return bv
def xdscoordinates(): """Initialise the coordinate system""" # Coordinate sensitive to length of vectors, so need to ensure that # lengths of both s0 and s1 are equal coords = { "s0": (0.013141995425357206, 0.002199999234194632, 1.4504754950989514), "s1": (-0.01752795848400313, -0.24786554213968193, 1.4290948735525306), "m2": (0.999975, -0.001289, -0.006968), "phi": 5.83575672475 * math.pi / 180, } coords["cs"] = CoordinateSystem(coords["m2"], coords["s0"], coords["s1"], coords["phi"]) return coords
def __call__(self): from scitbx import matrix from random import uniform from dials.algorithms.profile_model.gaussian_rs import CoordinateSystem s0 = self.beam.get_s0() m2 = self.gonio.get_rotation_axis() s0_length = matrix.col(self.beam.get_s0()).length() for i in range(100): # Get random x, y, z x = uniform(0, 2000) y = uniform(0, 2000) 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, phi, panel) x1, x2 = bbox[0], bbox[1] y1, y2 = bbox[2], bbox[3] z1, z2 = bbox[4], bbox[5] # Create the XDS coordinate system xcs = CoordinateSystem(m2, s0, s1, phi) # Calculate the transform fraction forward_fraction = self.transform_forward(bbox[4:], phi, xcs.zeta()) # Calculate the transform fraction reverse_fraction = self.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) # Test passed print 'OK'
def test_map_forward_reverse(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 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) 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
def test_map_frames_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 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) 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, f"{fmax:.16f} not between 0 and 1" 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
def test_outer_bounds(setup): assert len(setup["detector"]) == 1 s0 = setup["beam"].get_s0() m2 = setup["gonio"].get_rotation_axis() s0_length = matrix.col(setup["beam"].get_s0()).length() width, height = setup["detector"][0].get_image_size() zrange = setup["scan"].get_array_range() for i in range(1000): # 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(setup["detector"][0].get_pixel_lab_coord((x, y))).normalize() * s0_length ) phi = setup["scan"].get_angle_from_array_index(z, deg=False) panel = 0 # Calculate the bounding box bbox = setup["calculate_bbox"](s1, z, panel) z1, z2 = bbox[4], bbox[5] # Calculate the rotation angle for each point phi_dash1 = setup["scan"].get_angle_from_array_index(z1, deg=False) phi_dash2 = setup["scan"].get_angle_from_array_index(z2, deg=False) # Create the XDS coordinate system xcs = CoordinateSystem(m2, s0, s1, phi) # Calculate reciprocal space coordinates at each point e11, e21, e31 = xcs.from_beam_vector_and_rotation_angle(s1, phi_dash1) e12, e22, e32 = xcs.from_beam_vector_and_rotation_angle(s1, phi_dash2) # Check vertical edges for j in range(bbox[2], bbox[3] + 1): xyz1 = setup["detector"][0].get_pixel_lab_coord((bbox[0], j)) xyz2 = setup["detector"][0].get_pixel_lab_coord((bbox[1] + 1, j)) sdash1 = matrix.col(xyz1).normalize() * s0_length sdash2 = matrix.col(xyz2).normalize() * s0_length e11, e21, e3 = xcs.from_beam_vector_and_rotation_angle(sdash1, phi) e12, e22, e3 = xcs.from_beam_vector_and_rotation_angle(sdash2, phi) if bbox[0] > 0 and bbox[1] < width: assert ( abs(e11) >= setup["delta_divergence"] or abs(e21) >= setup["delta_divergence"] ) assert ( abs(e12) >= setup["delta_divergence"] or abs(e22) >= setup["delta_divergence"] ) # Check horizontal edges for i in range(bbox[0], bbox[1] + 1): xyz1 = setup["detector"][0].get_pixel_lab_coord((i, bbox[2])) xyz2 = setup["detector"][0].get_pixel_lab_coord((i, bbox[3] + 1)) sdash1 = matrix.col(xyz1).normalize() * s0_length sdash2 = matrix.col(xyz2).normalize() * s0_length e11, e21, e3 = xcs.from_beam_vector_and_rotation_angle(sdash1, phi) e12, e22, e3 = xcs.from_beam_vector_and_rotation_angle(sdash2, phi) if bbox[2] > 0 and bbox[3] < height: assert ( abs(e11) >= setup["delta_divergence"] or abs(e21) >= setup["delta_divergence"] ) assert ( abs(e12) >= setup["delta_divergence"] or abs(e22) >= setup["delta_divergence"] ) # All e3 coords >= delta_mosaicity if bbox[4] > zrange[0] and bbox[5] < zrange[1]: assert abs(e31) >= setup["delta_mosaicity"] assert abs(e32) >= setup["delta_mosaicity"]
def compute_reference(experiments, reflections): from dials.algorithms.profile_model.modeller import CircleSampler from dials.array_family import flex from dials.algorithms.profile_model.gaussian_rs.transform import TransformForward from dials.algorithms.profile_model.gaussian_rs.transform import TransformSpec from dials.algorithms.profile_model.gaussian_rs import CoordinateSystem reflections = select_strong(reflections) print("Selected %d strong spots" % len(reflections)) sampler = CircleSampler( experiments[0].detector[0].get_image_size(), experiments[0].scan.get_array_range(), 1, ) n_sigma = 4.0 grid_size = 25 spec = TransformSpec( experiments[0].beam, experiments[0].detector, experiments[0].goniometer, experiments[0].scan, experiments[0].profile.sigma_b(deg=False), experiments[0].profile.sigma_m(deg=False), n_sigma, grid_size, ) m2 = experiments[0].goniometer.get_rotation_axis() s0 = experiments[0].beam.get_s0() reference = [ flex.double( flex.grid(1 + 2 * grid_size, 1 + 2 * grid_size, 1 + 2 * grid_size)) for i in range(len(sampler)) ] count = [0] * len(sampler) for r in reflections: s1 = r["s1"] phi = r["xyzcal.mm"][2] xyz = r["xyzcal.px"] bbox = r["bbox"] panel = r["panel"] image = r["shoebox"].data.as_double() mask = r["shoebox"].mask.as_1d() == 5 mask.reshape(image.accessor()) cs = CoordinateSystem(m2, s0, s1, phi) try: transform = TransformForward(spec, cs, bbox, panel, image, mask) d = transform.profile() d /= flex.sum(d) index = sampler.nearest(0, xyz) indices = sampler.nearest_n(0, xyz) for i in indices: w = sampler.weight(i, 0, xyz) reference[i] += w * d count[i] += 1 except Exception: pass for i in range(len(reference)): r = reference[i] if flex.sum(r) > 0: print(flex.max(r)) g = r.accessor() r = r.as_1d() s = r > 0.02 * flex.max(r) r.set_selected(~s, flex.double(len(r), 0)) r = r / flex.sum(r) r.reshape(g) reference[i] = r for i in range(len(reference)): from matplotlib import pylab print(count[i]) r = reference[i] d = r.as_numpy_array()[11, :, :] pylab.imshow(d, interpolation="None") pylab.show() return reference
def integrate_job(block, experiments, reflections, reference, grid_size=5, detector_space=False): from dials.algorithms.profile_model.modeller import CircleSampler from dials.array_family import flex from dials.algorithms.profile_model.gaussian_rs.transform import TransformReverse from dials.algorithms.profile_model.gaussian_rs.transform import TransformForward from dials.algorithms.profile_model.gaussian_rs.transform import ( TransformReverseNoModel, ) from dials.algorithms.profile_model.gaussian_rs.transform import TransformSpec from dials.algorithms.profile_model.gaussian_rs import CoordinateSystem from dials.algorithms.integration.fit import ProfileFitter from dials.array_family import flex from dials.model.data import make_image reflections["shoebox"] = flex.shoebox(reflections["panel"], reflections["bbox"], allocate=True) frame0, frame1 = experiments[0].scan.get_array_range() frame0 = frame0 + block[0] frame1 = frame0 + block[1] reflections["shoebox"] = flex.shoebox(reflections["panel"], reflections["bbox"], allocate=True) extractor = flex.ShoeboxExtractor(reflections, 1, frame0, frame1) iset = experiments[0].imageset[block[0]:block[1]] for i in range(len(iset)): print("Reading image %d" % i) data = iset.get_raw_data(i) mask = iset.get_mask(i) extractor.next(make_image(data, mask)) print("Computing mask") reflections.compute_mask(experiments) print("Computing background") reflections.compute_background(experiments) print("Computing centroid") reflections.compute_centroid(experiments) print("Computing summed intensity") reflections.compute_summed_intensity() assert len(reference) % 9 == 0 num_scan_points = len(reference) // 9 sampler = CircleSampler( experiments[0].detector[0].get_image_size(), experiments[0].scan.get_array_range(), num_scan_points, ) spec = TransformSpec( experiments[0].beam, experiments[0].detector, experiments[0].goniometer, experiments[0].scan, experiments[0].profile.sigma_b(deg=False), experiments[0].profile.sigma_m(deg=False), experiments[0].profile.n_sigma() * 1.5, grid_size, ) m2 = experiments[0].goniometer.get_rotation_axis() s0 = experiments[0].beam.get_s0() Iprf = flex.double(len(reflections)) Vprf = flex.double(len(reflections)) Cprf = flex.double(len(reflections)) Fprf = flex.bool(len(reflections)) Part = reflections["partiality"] reflections["intensity.prf_old.value"] = reflections["intensity.prf.value"] reflections["intensity.prf_old.variance"] = reflections[ "intensity.prf.variance"] selection = reflections.get_flags(reflections.flags.integrated_prf) reflections.unset_flags(~Fprf, reflections.flags.integrated_prf) for i, r in enumerate(reflections): if selection[i] == False: continue s1 = r["s1"] phi = r["xyzcal.mm"][2] xyz = r["xyzcal.px"] bbox = r["bbox"] panel = r["panel"] image = r["shoebox"].data.as_double() background = r["shoebox"].background.as_double() mask = r["shoebox"].mask.as_1d( ) == 5 # | (r['shoebox'].mask.as_1d() == 3) mask.reshape(image.accessor()) cs = CoordinateSystem(m2, s0, s1, phi) index = sampler.nearest(0, xyz) profile, profile_mask = reference[index] # print flex.sum(profile) # print r['partiality'] if detector_space: transform = TransformReverseNoModel(spec, cs, bbox, panel, profile) p = transform.profile() d = image m = mask b = background # print flex.sum(p) Part[i] = flex.sum(p) # ysize, xsize = p.all()[1:3] # p1 = flex.double(flex.grid(1, ysize , xsize)) # d1 = flex.double(flex.grid(1, ysize , xsize)) # b1 = flex.double(flex.grid(1, ysize , xsize)) # m1 = flex.double(flex.grid(1, ysize , xsize)) # for k in range(p.all()[0]): # p1 += p[k:k+1,:,:] # d1 += d[k:k+1,:,:] # b1 += b[k:k+1,:,:] # m1 = m[k:k+1,:,:] try: fit = ProfileFitter(d, b, m, p, 1e-3, 100) assert fit.niter() < 100 Iprf[i] = fit.intensity() Vprf[i] = fit.variance() Cprf[i] = fit.correlation() Fprf[i] = True # if r['intensity.sum.value'] > 10 and abs(fit.intensity()) < 1e-3: print( r["miller_index"], i, fit.intensity(), r["intensity.sum.value"], r["intensity.prf_old.value"], Part[i], fit.niter(), ) # from matplotlib import pylab # pylab.imshow(p1.as_numpy_array()[0,:,:], interpolation='none') # pylab.show() except Exception as e: print(e) pass else: try: transform = TransformForward(spec, cs, bbox, panel, image, background, mask) p = profile d = transform.profile() b = transform.background() m = transform.mask() & profile_mask # if r['miller_index'] == (9, -25, 74): # print list(p) # print list(m) # print list(b) # print list(d) # exit(0) fit = ProfileFitter(d, b, m, p, 1e-3, 100) assert fit.niter() < 100 Iprf[i] = fit.intensity()[0] Vprf[i] = fit.variance()[0] Cprf[i] = fit.correlation() Fprf[i] = True print(r["miller_index"], i, fit.intensity(), r["intensity.prf_old.value"]) # from matplotlib import pylab # pylab.imshow(p1.as_numpy_array()[0,:,:], interpolation='none') # pylab.show() except Exception as e: pass reflections["intensity.prf.value"] = Iprf reflections["intensity.prf.variance"] = Vprf reflections["intensity.prf.correlation"] = Cprf reflections.set_flags(Fprf, reflections.flags.integrated_prf) del reflections["shoebox"] return reflections
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 __call__(self): from scitbx import matrix from random import uniform from dials.algorithms.profile_model.gaussian_rs import CoordinateSystem 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() for i in range(100): # Get random x, y, z x = uniform(0, 2000) y = uniform(0, 2000) 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) x1, x2 = bbox[0], bbox[1] y1, y2 = bbox[2], bbox[3] z1, z2 = bbox[4], bbox[5] # Create the XDS coordinate system xcs = CoordinateSystem(m2, s0, s1, phi) # Calculate the transform fraction fraction = self.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 == False: if curr < last: rev = True else: assert (curr <= last) last = curr # Test passed print 'OK'
def test_forward_panel_edge(dials_data): expt = ExperimentList.from_file( dials_data("centroid_test_data").join( "imported_experiments.json").strpath)[0] # Get the models beam = expt.beam detector = expt.detector gonio = expt.goniometer scan = expt.scan # Set some parameters sigma_divergence = 0.00101229 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) assert len(detector) == 1 s0 = beam.get_s0() m2 = gonio.get_rotation_axis() s0_length = matrix.col(beam.get_s0()).length() image_size = detector[0].get_image_size() refl_xy = [ (0, 0), (2, 3), (4, 1000), (1000, 5), (image_size[0] - 1, image_size[1] - 1), (image_size[0] - 2, 1), (1, image_size[1] - 5), (1000, image_size[1] - 4), (image_size[0] - 3, 1000), ] for x, y in refl_xy: 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) # 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)) # Mask for the foreground pixels refl_mask = image > 1e-3 bg = flex.double(image.accessor()) # Shoebox mask, i.e. mask out pixels that are outside the panel bounds shoebox_mask = flex.bool(image.accessor(), False) for j in range(y1 - y0): for i in range(x1 - x0): if (j + y0 >= 0 and j + y0 < image_size[1] and i + x0 >= 0 and i + x0 < image_size[0]): for k in range(z1 - z0): shoebox_mask[k, j, i] = True mask = refl_mask & shoebox_mask # from matplotlib import pyplot as plt # fig, axes = plt.subplots(ncols=refl_mask.focus()[0], nrows=4) # for i in range(refl_mask.focus()[0]): # axes[0, i].imshow(image.as_numpy_array()[i]) # axes[1, i].imshow(refl_mask.as_numpy_array()[i]) # axes[2, i].imshow(shoebox_mask.as_numpy_array()[i]) # axes[3, i].imshow(mask.as_numpy_array()[i]) # plt.show() # Transform the image to the grid transformed = transform.TransformForward(spec, cs, bbox, 0, image.as_double(), bg, refl_mask) grid = transformed.profile() mask = refl_mask & shoebox_mask # assert only pixels within the panel were transformed assert flex.sum(grid) == pytest.approx(flex.sum( image.select(mask.as_1d())), rel=0.01) # The total transformed counts should be less than the (unmasked) image counts assert flex.sum(grid) < flex.sum(image) # Transform the image to the grid, this time without a background transformed = transform.TransformForward(spec, cs, bbox, 0, image.as_double(), refl_mask) grid = transformed.profile() mask = refl_mask & shoebox_mask # assert only pixels within the panel were transformed assert flex.sum(grid) == pytest.approx(flex.sum( image.select(mask.as_1d())), rel=0.01) # The total transformed counts should be less than the (unmasked) image counts assert flex.sum(grid) < flex.sum(image)
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 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(dials_data): experiment = ExperimentList.from_file( dials_data("centroid_test_data").join("experiments.json")) beam = experiment[0].beam detector = experiment[0].detector goniometer = experiment[0].goniometer scan = experiment[0].scan delta_b = experiment[0].profile.delta_b() delta_m = experiment[0].profile.delta_m() assert len(detector) == 1 # Get the function object to mask the foreground mask_foreground = MaskCalculator3D(beam, detector, goniometer, scan, delta_b, delta_m) s0 = beam.get_s0() m2 = goniometer.get_rotation_axis() s0_length = matrix.col(beam.get_s0()).length() width, height = detector[0].get_image_size() zrange = scan.get_array_range() phi0, dphi = scan.get_oscillation(deg=False) # Generate some reflections reflections = generate_reflections(detector, beam, scan, experiment, 10) # Mask the foreground in each mask_foreground( reflections["shoebox"], reflections["s1"], reflections["xyzcal.px"].parts()[2], reflections["panel"], ) # Loop through all the reflections and check the mask values shoebox = reflections["shoebox"] beam_vector = reflections["s1"] rotation_angle = reflections["xyzcal.mm"].parts()[2] for l in range(len(reflections)): mask = shoebox[l].mask x0, x1, y0, y1, z0, z1 = shoebox[l].bbox s1 = beam_vector[l] phi = rotation_angle[l] cs = CoordinateSystem(m2, s0, s1, phi) def rs_coord(i, j, k): s1d = detector[0].get_pixel_lab_coord((i, j)) s1d = matrix.col(s1d).normalize() * s0_length e1, e2 = cs.from_beam_vector(s1d) e3 = cs.from_rotation_angle_fast(phi0 + (k - zrange[0]) * dphi) return e1, e2, e3 new_mask = flex.int(mask.accessor(), 0) for k in range(z1 - z0): for j in range(y1 - y0): for i in range(x1 - x0): # value1 = mask[k, j, i] e11, e12, e13 = rs_coord(x0 + i, y0 + j, z0 + k) e21, e22, e23 = rs_coord(x0 + i + 1, y0 + j, z0 + k) e31, e32, e33 = rs_coord(x0 + i, y0 + j + 1, z0 + k) e41, e42, e43 = rs_coord(x0 + i, y0 + j, z0 + k + 1) e51, e52, e53 = rs_coord(x0 + i + 1, y0 + j + 1, z0 + k) e61, e62, e63 = rs_coord(x0 + i + 1, y0 + j, z0 + k + 1) e71, e72, e73 = rs_coord(x0 + i, y0 + j + 1, z0 + k + 1) e81, e82, e83 = rs_coord(x0 + i + 1, y0 + j + 1, z0 + k + 1) de1 = (e11 / delta_b)**2 + ( e12 / delta_b)**2 # +(e13/delta_m)**2 de2 = (e21 / delta_b)**2 + ( e22 / delta_b)**2 # +(e23/delta_m)**2 de3 = (e31 / delta_b)**2 + ( e32 / delta_b)**2 # +(e33/delta_m)**2 de4 = (e41 / delta_b)**2 + ( e42 / delta_b)**2 # +(e43/delta_m)**2 de5 = (e51 / delta_b)**2 + ( e52 / delta_b)**2 # +(e53/delta_m)**2 de6 = (e61 / delta_b)**2 + ( e62 / delta_b)**2 # +(e63/delta_m)**2 de7 = (e71 / delta_b)**2 + ( e72 / delta_b)**2 # +(e73/delta_m)**2 de8 = (e81 / delta_b)**2 + ( e82 / delta_b)**2 # +(e83/delta_m)**2 de = math.sqrt( min([de1, de2, de3, de4, de5, de6, de7, de8])) if (x0 + i < 0 or y0 + j < 0 or x0 + i >= width or y0 + j >= height or z0 + k < zrange[0] or z0 + k >= zrange[1]): value2 = MaskCode.Valid else: if de <= 1.0: value2 = MaskCode.Valid | MaskCode.Foreground else: value2 = MaskCode.Valid | MaskCode.Background new_mask[k, j, i] = value2 if not all(m1 == m2 for m1, m2 in zip(mask, new_mask)): np.set_printoptions(threshold=10000) diff = (mask == new_mask).as_numpy_array() print(diff.astype(int)) # print mask.as_numpy_array() # print new_mask.as_numpy_array() # print (new_mask.as_numpy_array()[:,:,:] %2) * (new_mask.as_numpy_array() == 5) assert False
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 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 run(self): from scitbx import matrix from scitbx.array_family import flex from dials.algorithms.shoebox import MaskCode from dials.algorithms.profile_model.gaussian_rs import CoordinateSystem from math import sqrt assert (len(self.detector) == 1) s0 = self.beam.get_s0() m2 = self.goniometer.get_rotation_axis() s0_length = matrix.col(self.beam.get_s0()).length() width, height = self.detector[0].get_image_size() zrange = self.scan.get_array_range() phi0, dphi = self.scan.get_oscillation(deg=False) # Generate some reflections reflections = self.generate_reflections(10) # Mask the foreground in each self.mask_foreground(reflections['shoebox'], reflections['s1'], reflections['xyzcal.px'].parts()[2], reflections['panel']) # Loop through all the reflections and check the mask values shoebox = reflections['shoebox'] beam_vector = reflections['s1'] rotation_angle = reflections['xyzcal.mm'].parts()[2] for l in range(len(reflections)): mask = shoebox[l].mask x0, x1, y0, y1, z0, z1 = shoebox[l].bbox s1 = beam_vector[l] phi = rotation_angle[l] cs = CoordinateSystem(m2, s0, s1, phi) def rs_coord(i, j, k): s1d = self.detector[0].get_pixel_lab_coord((i, j)) s1d = matrix.col(s1d).normalize() * s0_length e1, e2 = cs.from_beam_vector(s1d) e3 = cs.from_rotation_angle_fast(phi0 + (k - zrange[0]) * dphi) return e1, e2, e3 new_mask = flex.int(mask.accessor(), 0) for k in range(z1 - z0): for j in range(y1 - y0): for i in range(x1 - x0): #value1 = mask[k, j, i] e11, e12, e13 = rs_coord(x0 + i, y0 + j, z0 + k) e21, e22, e23 = rs_coord(x0 + i + 1, y0 + j, z0 + k) e31, e32, e33 = rs_coord(x0 + i, y0 + j + 1, z0 + k) e41, e42, e43 = rs_coord(x0 + i, y0 + j, z0 + k + 1) e51, e52, e53 = rs_coord(x0 + i + 1, y0 + j + 1, z0 + k) e61, e62, e63 = rs_coord(x0 + i + 1, y0 + j, z0 + k + 1) e71, e72, e73 = rs_coord(x0 + i, y0 + j + 1, z0 + k + 1) e81, e82, e83 = rs_coord(x0 + i + 1, y0 + j + 1, z0 + k + 1) de1 = (e11 / self.delta_d)**2 + ( e12 / self.delta_d)**2 #+(e13/self.delta_m)**2 de2 = (e21 / self.delta_d)**2 + ( e22 / self.delta_d)**2 #+(e23/self.delta_m)**2 de3 = (e31 / self.delta_d)**2 + ( e32 / self.delta_d)**2 #+(e33/self.delta_m)**2 de4 = (e41 / self.delta_d)**2 + ( e42 / self.delta_d)**2 #+(e43/self.delta_m)**2 de5 = (e51 / self.delta_d)**2 + ( e52 / self.delta_d)**2 #+(e53/self.delta_m)**2 de6 = (e61 / self.delta_d)**2 + ( e62 / self.delta_d)**2 #+(e63/self.delta_m)**2 de7 = (e71 / self.delta_d)**2 + ( e72 / self.delta_d)**2 #+(e73/self.delta_m)**2 de8 = (e81 / self.delta_d)**2 + ( e82 / self.delta_d)**2 #+(e83/self.delta_m)**2 de = sqrt(min([de1, de2, de3, de4, de5, de6, de7, de8])) gx = min([e11, e21, e31, e41, e51, e61, e71, e81]) gy = min([e12, e22, e32, e42, e52, e62, e72, e82]) gz = min([e13, e23, e33, e43, e53, e63, e73, e83]) dee = (gx / self.delta_d)**2 + ( gy / self.delta_d)**2 # + (gz/self.delta_m)**2 #print sqrt(dee), de if (x0 + i < 0 or y0 + j < 0 or x0 + i >= width or y0 + j >= height or z0 + k < zrange[0] or z0 + k >= zrange[1]): value2 = MaskCode.Valid else: if de <= 1.0: value2 = MaskCode.Valid | MaskCode.Foreground else: value2 = MaskCode.Valid | MaskCode.Background new_mask[k, j, i] = value2 try: assert (all(m1 == m2 for m1, m2 in zip(mask, new_mask))) except Exception: import numpy numpy.set_printoptions(threshold=10000) diff = (mask == new_mask).as_numpy_array() print diff.astype(numpy.int) #print mask.as_numpy_array() #print new_mask.as_numpy_array() #print (new_mask.as_numpy_array()[:,:,:] %2) * (new_mask.as_numpy_array() == 5) raise # Test passed print 'OK'
def test_map_frames_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 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 = 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 from scitbx.array_family import flex 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) x1, x2 = bbox[0], bbox[1] y1, y2 = bbox[2], bbox[3] z1, z2 = bbox[4], bbox[5] if x1 == 0 or y1 == 0 or z1 == 0: continue if x2 == 2000 or y2 == 2000 or z2 == 9: continue # 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 and fmax > 0.0 assert fmin >= 0.0 and fmin <= 1.0 # Ensure the fraction for image adds up to 1.0 for # all those images completely within the image for v3 in range(fraction.all()[0]): tot = flex.sum(fraction[v3:v3 + 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 v3 in range(fraction.all()[0]): f = fraction[v3:v3 + 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
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 tst_outer_bounds(self): from scitbx import matrix from random import uniform from dials.algorithms.profile_model.gaussian_rs import CoordinateSystem 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() width, height = self.detector[0].get_image_size() zrange = self.scan.get_array_range() for i in range(1000): # Get random x, y, z x = uniform(0, 2000) y = uniform(0, 2000) 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) x1, x2 = bbox[0], bbox[1] y1, y2 = bbox[2], bbox[3] z1, z2 = bbox[4], bbox[5] # Calculate the rotation angle for each point phi_dash1 = self.scan.get_angle_from_array_index(z1, deg=False) phi_dash2 = self.scan.get_angle_from_array_index(z2, deg=False) # Create the XDS coordinate system xcs = CoordinateSystem(m2, s0, s1, phi) # Calculate reciprocal space coordinates at each point e11, e21, e31 = xcs.from_beam_vector_and_rotation_angle( s1, phi_dash1) e12, e22, e32 = xcs.from_beam_vector_and_rotation_angle( s1, phi_dash2) # Check vertical edges for j in range(bbox[2], bbox[3] + 1): xyz1 = self.detector[0].get_pixel_lab_coord((bbox[0], j)) xyz2 = self.detector[0].get_pixel_lab_coord((bbox[1] + 1, j)) sdash1 = matrix.col(xyz1).normalize() * s0_length sdash2 = matrix.col(xyz2).normalize() * s0_length e11, e21, e3 = xcs.from_beam_vector_and_rotation_angle( sdash1, phi) e12, e22, e3 = xcs.from_beam_vector_and_rotation_angle( sdash2, phi) if bbox[0] > 0 and bbox[1] < width: assert (abs(e11) >= self.delta_divergence or abs(e21) >= self.delta_divergence) assert (abs(e12) >= self.delta_divergence or abs(e22) >= self.delta_divergence) # Check horizontal edges for i in range(bbox[0], bbox[1] + 1): xyz1 = self.detector[0].get_pixel_lab_coord((i, bbox[2])) xyz2 = self.detector[0].get_pixel_lab_coord((i, bbox[3] + 1)) sdash1 = matrix.col(xyz1).normalize() * s0_length sdash2 = matrix.col(xyz2).normalize() * s0_length e11, e21, e3 = xcs.from_beam_vector_and_rotation_angle( sdash1, phi) e12, e22, e3 = xcs.from_beam_vector_and_rotation_angle( sdash2, phi) if bbox[2] > 0 and bbox[3] < height: assert (abs(e11) >= self.delta_divergence or abs(e21) >= self.delta_divergence) assert (abs(e12) >= self.delta_divergence or abs(e22) >= self.delta_divergence) # All e3 coords >= delta_mosaicity if bbox[4] > zrange[0] and bbox[5] < zrange[1]: assert (abs(e31) >= self.delta_mosaicity) assert (abs(e32) >= self.delta_mosaicity) print 'OK'
def test(dials_data): from dxtbx.model.experiment_list import Experiment, ExperimentList from dxtbx.serialize import load from dials.algorithms.profile_model.gaussian_rs import MaskCalculator3D, Model sequence = load.imageset( dials_data("centroid_test_data").join("sweep.json").strpath) crystal = load.crystal( dials_data("centroid_test_data").join("crystal.json").strpath) beam = sequence.get_beam() detector = sequence.get_detector() goniometer = sequence.get_goniometer() scan = sequence.get_scan() delta_d = 3 * beam.get_sigma_divergence(deg=False) try: mosaicity = crystal.get_mosaicity(deg=False) except AttributeError: mosaicity = 0 delta_m = 3 * mosaicity nsigma = 3 profile_model = Model(None, nsigma, beam.get_sigma_divergence(deg=False), mosaicity) experiment = ExperimentList() experiment.append( Experiment( imageset=sequence, beam=beam, detector=detector, goniometer=goniometer, scan=scan, crystal=crystal, profile=profile_model, )) assert len(detector) == 1 # Get the function object to mask the foreground mask_foreground = MaskCalculator3D(beam, detector, goniometer, scan, delta_d, delta_m) from scitbx.array_family import flex from dials.algorithms.profile_model.gaussian_rs import CoordinateSystem from dials.algorithms.shoebox import MaskCode s0 = beam.get_s0() m2 = goniometer.get_rotation_axis() s0_length = matrix.col(beam.get_s0()).length() width, height = detector[0].get_image_size() zrange = scan.get_array_range() phi0, dphi = scan.get_oscillation(deg=False) # Generate some reflections reflections = generate_reflections(detector, beam, scan, experiment, 10) # Mask the foreground in each mask_foreground( reflections["shoebox"], reflections["s1"], reflections["xyzcal.px"].parts()[2], reflections["panel"], ) # Loop through all the reflections and check the mask values shoebox = reflections["shoebox"] beam_vector = reflections["s1"] rotation_angle = reflections["xyzcal.mm"].parts()[2] for l in range(len(reflections)): mask = shoebox[l].mask x0, x1, y0, y1, z0, z1 = shoebox[l].bbox s1 = beam_vector[l] phi = rotation_angle[l] cs = CoordinateSystem(m2, s0, s1, phi) def rs_coord(i, j, k): s1d = detector[0].get_pixel_lab_coord((i, j)) s1d = matrix.col(s1d).normalize() * s0_length e1, e2 = cs.from_beam_vector(s1d) e3 = cs.from_rotation_angle_fast(phi0 + (k - zrange[0]) * dphi) return e1, e2, e3 new_mask = flex.int(mask.accessor(), 0) for k in range(z1 - z0): for j in range(y1 - y0): for i in range(x1 - x0): # value1 = mask[k, j, i] e11, e12, e13 = rs_coord(x0 + i, y0 + j, z0 + k) e21, e22, e23 = rs_coord(x0 + i + 1, y0 + j, z0 + k) e31, e32, e33 = rs_coord(x0 + i, y0 + j + 1, z0 + k) e41, e42, e43 = rs_coord(x0 + i, y0 + j, z0 + k + 1) e51, e52, e53 = rs_coord(x0 + i + 1, y0 + j + 1, z0 + k) e61, e62, e63 = rs_coord(x0 + i + 1, y0 + j, z0 + k + 1) e71, e72, e73 = rs_coord(x0 + i, y0 + j + 1, z0 + k + 1) e81, e82, e83 = rs_coord(x0 + i + 1, y0 + j + 1, z0 + k + 1) de1 = (e11 / delta_d)**2 + ( e12 / delta_d)**2 # +(e13/delta_m)**2 de2 = (e21 / delta_d)**2 + ( e22 / delta_d)**2 # +(e23/delta_m)**2 de3 = (e31 / delta_d)**2 + ( e32 / delta_d)**2 # +(e33/delta_m)**2 de4 = (e41 / delta_d)**2 + ( e42 / delta_d)**2 # +(e43/delta_m)**2 de5 = (e51 / delta_d)**2 + ( e52 / delta_d)**2 # +(e53/delta_m)**2 de6 = (e61 / delta_d)**2 + ( e62 / delta_d)**2 # +(e63/delta_m)**2 de7 = (e71 / delta_d)**2 + ( e72 / delta_d)**2 # +(e73/delta_m)**2 de8 = (e81 / delta_d)**2 + ( e82 / delta_d)**2 # +(e83/delta_m)**2 de = math.sqrt( min([de1, de2, de3, de4, de5, de6, de7, de8])) if (x0 + i < 0 or y0 + j < 0 or x0 + i >= width or y0 + j >= height or z0 + k < zrange[0] or z0 + k >= zrange[1]): value2 = MaskCode.Valid else: if de <= 1.0: value2 = MaskCode.Valid | MaskCode.Foreground else: value2 = MaskCode.Valid | MaskCode.Background new_mask[k, j, i] = value2 if not all(m1 == m2 for m1, m2 in zip(mask, new_mask)): np.set_printoptions(threshold=10000) diff = (mask == new_mask).as_numpy_array() print(diff.astype(np.int)) # print mask.as_numpy_array() # print new_mask.as_numpy_array() # print (new_mask.as_numpy_array()[:,:,:] %2) * (new_mask.as_numpy_array() == 5) assert False
def integrate(experiments, reflections, reference): from dials.algorithms.profile_model.modeller import CircleSampler from dials.array_family import flex from dials.algorithms.profile_model.gaussian_rs.transform import TransformReverse from dials.algorithms.profile_model.gaussian_rs.transform import TransformForward from dials.algorithms.profile_model.gaussian_rs.transform import ( TransformReverseNoModel, ) from dials.algorithms.profile_model.gaussian_rs.transform import TransformSpec from dials.algorithms.profile_model.gaussian_rs import CoordinateSystem selection = reflections.get_flags(reflections.flags.integrated_sum) reflections = reflections.select(selection) print("Selected %d reflections to integrate" % len(reflections)) sampler = CircleSampler( experiments[0].detector[0].get_image_size(), experiments[0].scan.get_array_range(), 1, ) n_sigma = 4.0 grid_size = 25 spec = TransformSpec( experiments[0].beam, experiments[0].detector, experiments[0].goniometer, experiments[0].scan, experiments[0].profile.sigma_b(deg=False), experiments[0].profile.sigma_m(deg=False), n_sigma, grid_size, ) m2 = experiments[0].goniometer.get_rotation_axis() s0 = experiments[0].beam.get_s0() Iprf = flex.double(len(reflections)) Vprf = flex.double(len(reflections)) Cprf = flex.double(len(reflections)) Fprf = flex.bool(len(reflections)) for i, r in enumerate(reflections): s1 = r["s1"] phi = r["xyzcal.mm"][2] xyz = r["xyzcal.px"] bbox = r["bbox"] panel = r["panel"] image = r["shoebox"].data.as_double() background = r["shoebox"].background.as_double() mask = r["shoebox"].mask.as_1d( ) == 5 # | (r['shoebox'].mask.as_1d() == 3) mask.reshape(image.accessor()) cs = CoordinateSystem(m2, s0, s1, phi) index = sampler.nearest(0, xyz) profile = reference[index] # print flex.sum(profile) # print r['partiality'] if False: from dials.algorithms.integration.maximum_likelihood import ( ProfileFittingDouble as ProfileFitting, ) transform = TransformReverseNoModel(spec, cs, bbox, panel, profile) p = transform.profile() d = image m = mask b = background # print flex.sum(p) ysize, xsize = p.all()[1:3] p1 = flex.double(flex.grid(1, ysize, xsize)) d1 = flex.double(flex.grid(1, ysize, xsize)) b1 = flex.double(flex.grid(1, ysize, xsize)) m1 = flex.double(flex.grid(1, ysize, xsize)) for k in range(p.all()[0]): p1 += p[k:k + 1, :, :] d1 += d[k:k + 1, :, :] b1 += b[k:k + 1, :, :] m1 = m[k:k + 1, :, :] try: fit = ProfileFitting(p1, m1, d1, b1, 1e-3, 1000) assert fit.niter() < 1000 Iprf[i] = fit.intensity() Vprf[i] = fit.variance() Cprf[i] = fit.correlation() Fprf[i] = True print(i, fit.intensity(), flex.sum(p1)) # from matplotlib import pylab # pylab.imshow(p1.as_numpy_array()[0,:,:], interpolation='none') # pylab.show() except Exception: pass else: from dials.algorithms.integration.fit import ( ProfileFittingDouble as ProfileFitting, ) try: transform = TransformForward(spec, cs, bbox, panel, image, background, mask) index = sampler.nearest(0, xyz) p = reference[index] d = transform.profile() b = transform.background() m = p > 0 fit = ProfileFitting(p, m, d, b, 1e-3, 1000) assert fit.niter() < 1000 Iprf[i] = fit.intensity() Vprf[i] = fit.variance() Cprf[i] = fit.correlation() Fprf[i] = True print(i, fit.intensity(), flex.sum(p)) # from matplotlib import pylab # pylab.imshow(p1.as_numpy_array()[0,:,:], interpolation='none') # pylab.show() except Exception: pass reflections["intensity.prf.value"] = Iprf reflections["intensity.prf.variance"] = Vprf reflections["intensity.prf.correlation"] = Cprf reflections.set_flags(Fprf, reflections.flags.integrated_prf) return reflections