def determine_miller_ring_sectors(detector, goniometer, s0, hkl_flex, crystal_A): crystal_R = matrix.sqr(goniometer.get_fixed_rotation()) rotation_axis = goniometer.get_rotation_axis() from dials.algorithms.spot_prediction import ScanStaticRayPredictor from dials.algorithms.spot_prediction import ray_intersection from math import radians PRACTICALLY_INFINITY_BUT_DEFINITELY_LARGER_THAN_2PI = 1000 oscillation = ( -PRACTICALLY_INFINITY_BUT_DEFINITELY_LARGER_THAN_2PI, PRACTICALLY_INFINITY_BUT_DEFINITELY_LARGER_THAN_2PI, ) rays = ScanStaticRayPredictor(s0, rotation_axis, oscillation)(hkl_flex, crystal_R * crystal_A) # ray_intersection could probably be sped up by an is_on_detector() method rays = rays.select(ray_intersection(detector, rays)) divider = radians(10) ray_sectors = [] for s in range(0, 36): ray_sectors.append([]) for (p, m) in zip(rays["phi"], rays["miller_index"]): ray_sectors[int(p / divider)].append(m) return ray_sectors
def test_new_from_array(raypredictor): from dials.algorithms.spot_prediction import IndexGenerator, ScanStaticRayPredictor # Create the index generator raypredictor.generate_indices = IndexGenerator( raypredictor.unit_cell, raypredictor.space_group_type, raypredictor.d_min) s0 = raypredictor.beam.get_s0() m2 = raypredictor.gonio.get_rotation_axis() fixed_rotation = raypredictor.gonio.get_fixed_rotation() setting_rotation = raypredictor.gonio.get_setting_rotation() UB = raypredictor.ub_matrix dphi = raypredictor.scan.get_oscillation_range(deg=False) # Create the ray predictor raypredictor.predict_rays = ScanStaticRayPredictor(s0, m2, fixed_rotation, setting_rotation, dphi) # Predict the spot locations h = raypredictor.generate_indices.to_array() reflections = raypredictor.predict_rays(h, UB) raypredictor.reflections3 = [] for r in reflections.rows(): if r["phi"] >= dphi[0] and r["phi"] <= dphi[1]: raypredictor.reflections3.append(r) assert len(raypredictor.reflections) == len(raypredictor.reflections3) for r1, r2 in zip(raypredictor.reflections.rows(), raypredictor.reflections3): assert all(a == pytest.approx(b, abs=1e-7) for a, b in zip(r1["s1"], r2["s1"])) assert r1["phi"] == pytest.approx(r2["phi"], abs=1e-7) assert r1["entering"] == r2["entering"]
def test_new_from_array(self): from dials.algorithms.spot_prediction import ScanStaticRayPredictor from dials.algorithms.spot_prediction import IndexGenerator # Create the index generator self.generate_indices = IndexGenerator(self.unit_cell, self.space_group_type, self.d_min) s0 = self.beam.get_s0() m2 = self.gonio.get_rotation_axis() fixed_rotation = self.gonio.get_fixed_rotation() setting_rotation = self.gonio.get_setting_rotation() UB = self.ub_matrix dphi = self.scan.get_oscillation_range(deg=False) # Create the ray predictor self.predict_rays = ScanStaticRayPredictor(s0, m2, fixed_rotation, setting_rotation, dphi) # Predict the spot locations h = self.generate_indices.to_array() reflections = self.predict_rays(h, UB) self.reflections3 = [] for r in reflections: if r['phi'] >= dphi[0] and r['phi'] <= dphi[1]: self.reflections3.append(r) eps = 1e-7 assert (len(self.reflections) == len(self.reflections3)) for r1, r2 in zip(self.reflections, self.reflections3): assert (all(abs(a - b) < eps for a, b in zip(r1['s1'], r2['s1']))) assert (abs(r1['phi'] - r2['phi']) < eps) assert (r1['entering'] == r2['entering']) print 'OK'
def test_new(raypredictor): from dials.algorithms.spot_prediction import ScanStaticRayPredictor from dials.algorithms.spot_prediction import IndexGenerator # Create the index generator raypredictor.generate_indices = IndexGenerator(raypredictor.unit_cell, raypredictor.space_group_type, raypredictor.d_min) s0 = raypredictor.beam.get_s0() m2 = raypredictor.gonio.get_rotation_axis() fixed_rotation = raypredictor.gonio.get_fixed_rotation() setting_rotation = raypredictor.gonio.get_setting_rotation() UB = raypredictor.ub_matrix dphi = raypredictor.scan.get_oscillation_range(deg=False) # Create the ray predictor raypredictor.predict_rays = ScanStaticRayPredictor(s0, m2, fixed_rotation, setting_rotation, dphi) # Predict the spot locations raypredictor.reflections2 = [] for h in raypredictor.generate_indices.to_array(): rays = raypredictor.predict_rays(h, UB) for ray in rays: if ray.angle >= dphi[0] and ray.angle <= dphi[1]: raypredictor.reflections2.append(ray) assert len(raypredictor.reflections) == len(raypredictor.reflections2) for r1, r2 in zip(raypredictor.reflections, raypredictor.reflections2): assert all(a == pytest.approx(b, abs=1e-7) for a, b in zip(r1['s1'], r2.s1)) assert r1['phi'] == pytest.approx(r2.angle, abs=1e-7) assert r1['entering'] == r2.entering
def determine_miller_ring_sectors(detector, goniometer, s0, hkl_flex, crystal_A): crystal_R = matrix.sqr(goniometer.get_fixed_rotation()) rotation_axis = goniometer.get_rotation_axis() from dials.algorithms.spot_prediction import ScanStaticRayPredictor from dials.algorithms.spot_prediction import ray_intersection from math import radians PRACTICALLY_INFINITY_BUT_DEFINITELY_LARGER_THAN_2PI = 1000 oscillation = (-PRACTICALLY_INFINITY_BUT_DEFINITELY_LARGER_THAN_2PI, PRACTICALLY_INFINITY_BUT_DEFINITELY_LARGER_THAN_2PI) rays = ScanStaticRayPredictor(s0, rotation_axis, oscillation)(hkl_flex, crystal_R * crystal_A) # ray_intersection could probably be sped up by an is_on_detector() method rays = rays.select(ray_intersection(detector, rays)) divider = radians(10) ray_sectors = [] for s in range(0, 36): ray_sectors.append([]) for (p, m) in zip(rays['phi'], rays['miller_index']): ray_sectors[int(p / divider)].append(m) return ray_sectors
def __call__(self, hkl, experiment_id=0, UB=None): """ Solve the prediction formula for the reflecting angle phi. If UB is given, override the contained crystal model. This is for use in refinement with time-varying crystal parameters """ e = self._experiments[experiment_id] ray_predictor = ScanStaticRayPredictor( e.beam.get_s0(), e.goniometer.get_rotation_axis_datum(), e.goniometer.get_fixed_rotation(), e.goniometer.get_setting_rotation(), self._sweep_range) UB_ = UB if UB else e.crystal.get_A() rays = ray_predictor(hkl, UB_) return rays
def __init__(self): from dials.algorithms.spot_prediction import IndexGenerator from dials.algorithms.spot_prediction import ScanStaticRayPredictor from dials.algorithms.spot_prediction import ray_intersection from iotbx.xds import xparm, integrate_hkl from dials.util import ioutil from math import ceil import dxtbx from rstbx.cftbx.coordinate_frame_converter import \ coordinate_frame_converter from scitbx import matrix # The XDS files to read from integrate_filename = join(dials_regression, 'data/sim_mx/INTEGRATE.HKL') gxparm_filename = join(dials_regression, 'data/sim_mx/GXPARM.XDS') # Read the XDS files self.integrate_handle = integrate_hkl.reader() self.integrate_handle.read_file(integrate_filename) self.gxparm_handle = xparm.reader() self.gxparm_handle.read_file(gxparm_filename) # Get the parameters we need from the GXPARM file models = dxtbx.load(gxparm_filename) self.beam = models.get_beam() self.gonio = models.get_goniometer() self.detector = models.get_detector() self.scan = models.get_scan() assert (len(self.detector) == 1) #print self.detector # Get crystal parameters self.space_group_type = ioutil.get_space_group_type_from_xparm( self.gxparm_handle) cfc = coordinate_frame_converter(gxparm_filename) a_vec = cfc.get('real_space_a') b_vec = cfc.get('real_space_b') c_vec = cfc.get('real_space_c') self.unit_cell = cfc.get_unit_cell() self.ub_matrix = matrix.sqr(a_vec + b_vec + c_vec).inverse() # Get the minimum resolution in the integrate file self.d_min = self.detector[0].get_max_resolution_at_corners( self.beam.get_s0()) # Get the number of frames from the max z value xcal, ycal, zcal = zip(*self.integrate_handle.xyzcal) self.scan.set_image_range( (self.scan.get_image_range()[0], self.scan.get_image_range()[0] + int(ceil(max(zcal))))) # Create the index generator generate_indices = IndexGenerator(self.unit_cell, self.space_group_type, self.d_min) s0 = self.beam.get_s0() m2 = self.gonio.get_rotation_axis() fixed_rotation = self.gonio.get_fixed_rotation() setting_rotation = self.gonio.get_setting_rotation() UB = self.ub_matrix dphi = self.scan.get_oscillation_range(deg=False) # Create the ray predictor self.predict_rays = ScanStaticRayPredictor(s0, m2, fixed_rotation, setting_rotation, dphi) # Predict the spot locations self.reflections = self.predict_rays(generate_indices.to_array(), UB) # Calculate the intersection of the detector and reflection frames success = ray_intersection(self.detector, self.reflections) self.reflections.select(success)
def __init__(self, dials_regression): import dxtbx from iotbx.xds import integrate_hkl, xparm from rstbx.cftbx.coordinate_frame_converter import coordinate_frame_converter from dials.algorithms.spot_prediction import ( IndexGenerator, ScanStaticRayPredictor, ) from dials.util import ioutil # The XDS files to read from integrate_filename = os.path.join(dials_regression, "data", "sim_mx", "INTEGRATE.HKL") gxparm_filename = os.path.join(dials_regression, "data", "sim_mx", "GXPARM.XDS") # Read the XDS files self.integrate_handle = integrate_hkl.reader() self.integrate_handle.read_file(integrate_filename) self.gxparm_handle = xparm.reader() self.gxparm_handle.read_file(gxparm_filename) # Get the parameters we need from the GXPARM file models = dxtbx.load(gxparm_filename) self.beam = models.get_beam() self.gonio = models.get_goniometer() self.detector = models.get_detector() self.scan = models.get_scan() # Get crystal parameters self.space_group_type = ioutil.get_space_group_type_from_xparm( self.gxparm_handle) cfc = coordinate_frame_converter(gxparm_filename) a_vec = cfc.get("real_space_a") b_vec = cfc.get("real_space_b") c_vec = cfc.get("real_space_c") self.unit_cell = cfc.get_unit_cell() self.ub_matrix = matrix.sqr(a_vec + b_vec + c_vec).inverse() # Get the minimum resolution in the integrate file d = [self.unit_cell.d(h) for h in self.integrate_handle.hkl] self.d_min = min(d) # extend the resolution shell by epsilon>0 # to account for rounding artifacts on 32-bit platforms self.d_min = self.d_min - 1e-15 # Get the number of frames from the max z value xcal, ycal, zcal = zip(*self.integrate_handle.xyzcal) self.scan.set_image_range(( self.scan.get_image_range()[0], self.scan.get_image_range()[0] + int(math.ceil(max(zcal))), )) # Print stuff # print self.beam # print self.gonio # print self.detector # print self.scan # Create the index generator self.generate_indices = IndexGenerator(self.unit_cell, self.space_group_type, self.d_min) s0 = self.beam.get_s0() m2 = self.gonio.get_rotation_axis() fixed_rotation = self.gonio.get_fixed_rotation() setting_rotation = self.gonio.get_setting_rotation() UB = self.ub_matrix dphi = self.scan.get_oscillation_range(deg=False) # Create the ray predictor self.predict_rays = ScanStaticRayPredictor(s0, m2, fixed_rotation, setting_rotation, dphi) # Predict the spot locations self.reflections = self.predict_rays(self.generate_indices.to_array(), UB)
def get_reflections(experiments): from dials.algorithms.profile_model.gaussian_rs import zeta_factor from dials.algorithms.spot_prediction import PixelToMillerIndex from collections import defaultdict from dials.algorithms.spot_prediction import ScanStaticRayPredictor from math import floor, sqrt, pi from dials.array_family import flex reflection_pixels = defaultdict(list) transform = PixelToMillerIndex( experiments[0].beam, experiments[0].detector, experiments[0].goniometer, experiments[0].scan, experiments[0].crystal, ) xsize, ysize = experiments[0].detector[0].get_image_size() z0 = experiments[0].scan.get_array_range()[0] image = experiments[0].imageset[0][0] mask = flex.bool(image.accessor()) for j in range(ysize): print(j) for i in range(xsize): h = transform.h(0, i + 0.5, j + 0.5, z0 + 0.5) hkl = tuple(map(lambda x: int(floor(x + 0.5)), h)) d = sqrt(sum(map(lambda a: (a[0] - a[1]) ** 2, zip(h, hkl)))) if d < 0.3: foreground = True else: foreground = False mask[j, i] = foreground reflection_pixels[hkl].append((j, i, foreground)) # from matplotlib import pylab # pylab.imshow(mask.as_numpy_array()) # pylab.show() I = [] V = [] T = [] predictor = ScanStaticRayPredictor( experiments[0].beam.get_s0(), experiments[0].goniometer.get_rotation_axis(), experiments[0].goniometer.get_fixed_rotation(), experiments[0].goniometer.get_setting_rotation(), (-2 * pi, 2 * pi), ) UB = experiments[0].crystal.get_A() phi0 = experiments[0].scan.get_angle_from_array_index(z0 + 0.5, deg=False) m2 = experiments[0].goniometer.get_rotation_axis() s0 = experiments[0].beam.get_s0() for hkl, pixel_list in reflection_pixels.iteritems(): rays = predictor(hkl, UB) if len(rays) == 0: continue elif len(rays) == 1: dphi = rays[0].angle - phi0 else: dphi0 = ((rays[0].angle - phi0) + pi) % (2 * pi) - pi dphi1 = ((rays[1].angle - phi0) + pi) % (2 * pi) - pi if abs(dphi0) < abs(dphi1): dphi = dphi0 s1 = rays[0].s1 else: dphi = dphi1 s1 = rays[1].s1 if abs(dphi) > 5 * pi / 180.0: continue try: zeta = zeta_factor(m2, s0, s1) except Exception: continue dphi *= zeta I_sum = 0 B_sum = 0 I_count = 0 B_count = 0 for j, i, foreground in pixel_list: data = image[j, i] if foreground: I_sum += data I_count += 1 else: B_sum += data B_count += 1 B = B_sum / B_count I.append(I_sum - B * I_count) V.append(I_sum + B * I_count * (1 + I_count / B_count)) T.append(dphi * 180 / pi) print(min(T), max(T)) IOS = [] TN = [] for i, v, t in zip(I, V, T): if i > 0 and v > 0: IOS.append(i / sqrt(v)) TN.append(t) from matplotlib import pylab pylab.hist(TN, bins=20, weights=IOS) pylab.xlabel("DPHI (degrees)") pylab.show()
def simulate_reflection( experiment, reflection, wavelength_spread=0.0, rlp_covariance=None, angular_spread=0.0, beam_divergence=0.0, ): """ Simulate a count from a single reflection """ from scitbx import matrix from dials.algorithms.spot_prediction import ScanStaticRayPredictor from numpy.random import normal, multivariate_normal # Get the models from the experiment beam = experiment.beam detector = experiment.detector goniometer = experiment.goniometer scan = experiment.scan crystal = experiment.crystal # Get some stuff from the models A = matrix.sqr(crystal.get_A()) s0 = matrix.col(beam.get_s0()).normalize() wavelength0 = beam.get_wavelength() m2 = matrix.col(goniometer.get_rotation_axis()) fixed_rotation = matrix.sqr(goniometer.get_fixed_rotation()) setting_rotation = goniometer.get_setting_rotation() dphi = scan.get_oscillation_range(deg=False) # Generate random wavelengths from a normal distribution if wavelength_spread > 0: wavelength = normal(wavelength0, wavelength_spread) else: wavelength = wavelength0 # Create the incident beam vector s0 = s0 / wavelength # draw beam directions from a von mises fisher distriubtion if beam_divergence > 0: s0 = vonmises_fisher(s0, 1.0 / beam_divergence) # Get the miller index and entering flag h = reflection["miller_index"] entering = reflection["entering"] # Get the reciprocal lattice point r0 = fixed_rotation * (A * matrix.col(h)) # Draw reciprocal lattice vectors from a multi variate normal distribution if rlp_covariance is not None: r0 = matrix.col( multivariate_normal(r0, matrix.sqr(rlp_covariance).as_list_of_lists())) # Draw reciprocal lattice vectors from a von mises distribution (spherical cap) if angular_spread > 0: r0 = vonmises_fisher(r0, 1.0 / angular_spread) # Create the ray predictor predictor = ScanStaticRayPredictor(s0, m2, fixed_rotation, setting_rotation, dphi) # Predict the rays for the reciprocal lattice point rays = predictor(r0) # Select the ray that matches the input reflection s1 = None phi = None for ray in rays: if ray.entering == entering: s1 = ray.s1 phi = ray.angle assert s1 != None and phi != None # Get the ray intersection and image number x, y = detector[0].get_ray_intersection_px(s1) z = scan.get_array_index_from_angle(phi, deg=False) return x, y, z