def generate_reflections(self): """Use reeke_model to generate indices of reflections near to the Ewald sphere that might be observed on a still image. Build a reflection_table of these.""" from cctbx.sgtbx import space_group_info space_group_type = space_group_info("P 1").group().type() # create a ReekeIndexGenerator UB = self.crystal.get_A() axis = self.goniometer.get_rotation_axis() s0 = self.beam.get_s0() dmin = 1.5 # use the same UB at the beginning and end - the margin parameter ensures # we still have indices close to the Ewald sphere generated from dials.algorithms.spot_prediction import ReekeIndexGenerator r = ReekeIndexGenerator(UB, UB, space_group_type, axis, s0, dmin=1.5, margin=1) # generate indices hkl = r.to_array() nref = len(hkl) # create a reflection table from dials.array_family import flex table = flex.reflection_table() table['flags'] = flex.size_t(nref, 0) table['id'] = flex.int(nref, 0) table['panel'] = flex.size_t(nref, 0) table['miller_index'] = flex.miller_index(hkl) table['entering'] = flex.bool(nref, True) table['s1'] = flex.vec3_double(nref) table['xyzcal.mm'] = flex.vec3_double(nref) table['xyzcal.px'] = flex.vec3_double(nref) return table
def generate_reflections(self): """Use reeke_model to generate indices of reflections near to the Ewald sphere that might be observed on a still image. Build a reflection_table of these.""" from cctbx.sgtbx import space_group_info space_group_type = space_group_info("P 1").group().type() # create a ReekeIndexGenerator UB = self.crystal.get_U() * self.crystal.get_B() axis = self.goniometer.get_rotation_axis() s0 = self.beam.get_s0() dmin = 1.5 # use the same UB at the beginning and end - the margin parameter ensures # we still have indices close to the Ewald sphere generated from dials.algorithms.spot_prediction import ReekeIndexGenerator r = ReekeIndexGenerator(UB, UB, space_group_type, axis, s0, dmin=1.5, margin=1) # generate indices hkl = r.to_array() nref = len(hkl) # create a reflection table from dials.array_family import flex table = flex.reflection_table() table['flags'] = flex.size_t(nref, 0) table['id'] = flex.int(nref, 0) table['panel'] = flex.size_t(nref, 0) table['miller_index'] = flex.miller_index(hkl) table['entering'] = flex.bool(nref, True) table['s1'] = flex.vec3_double(nref) table['xyzcal.mm'] = flex.vec3_double(nref) table['xyzcal.px'] = flex.vec3_double(nref) return table
def test_scan_varying(raypredictor): from dials.algorithms.spot_prediction import ScanVaryingRayPredictor from dials.algorithms.spot_prediction import ReekeIndexGenerator from scitbx import matrix import scitbx.math s0 = raypredictor.beam.get_s0() m2 = raypredictor.gonio.get_rotation_axis() UB = raypredictor.ub_matrix dphi = raypredictor.scan.get_oscillation_range(deg=False) # For quick comparison look at reflections on one frame only frame = 0 angle_beg = raypredictor.scan.get_angle_from_array_index(frame, deg=False) angle_end = raypredictor.scan.get_angle_from_array_index(frame+1, deg=False) frame0_refs = raypredictor.reflections.select( (raypredictor.reflections['phi'] >= angle_beg) & (raypredictor.reflections['phi'] <= angle_end)) # Get UB matrices at beginning and end of frame r_osc_beg = matrix.sqr( scitbx.math.r3_rotation_axis_and_angle_as_matrix( axis = m2, angle = angle_beg, deg=False)) UB_beg = r_osc_beg * raypredictor.ub_matrix r_osc_end = matrix.sqr( scitbx.math.r3_rotation_axis_and_angle_as_matrix( axis = m2, angle = angle_end, deg=False)) UB_end = r_osc_end * raypredictor.ub_matrix # Get indices r = ReekeIndexGenerator(UB_beg, UB_end, raypredictor.space_group_type, m2, s0, raypredictor.d_min, margin=1) h = r.to_array() # Fn to loop through hkl applying a prediction function to each and testing # the results are the same as those from the ScanStaticRayPredictor def test_each_hkl(hkl_list, predict_fn): DEG2RAD = math.pi/180. count = 0 for hkl in hkl_list: ray = predict_fn(hkl) if ray is not None: count += 1 ref = frame0_refs.select(frame0_refs['miller_index']==hkl)[0] assert ref['entering'] == ray.entering assert ref['phi'] == pytest.approx(ray.angle * DEG2RAD, abs=1e-6) # ray angle is in degrees (!) assert ref['s1'] == pytest.approx(ray.s1, abs=1e-6) # ensure all reflections were matched assert count == len(frame0_refs) # Create the ray predictor sv_predict_rays = ScanVaryingRayPredictor(s0, m2, raypredictor.scan.get_array_range()[0], raypredictor.scan.get_oscillation(), raypredictor.d_min) # Test with the method that allows only differing UB matrices test_each_hkl(h, lambda x: sv_predict_rays(x, UB_beg, UB_end, frame)) # Now repeat prediction using the overload that allows for different s0 # at the beginning and end of the frame. Here, pass in the same s0 each time # and the result should be the same as before test_each_hkl(h, lambda x: sv_predict_rays(x, UB_beg, UB_end, s0, s0, frame))
def generate_cpp(self, frame): from dials.algorithms.spot_prediction import ReekeIndexGenerator from cctbx.sgtbx import space_group_info space_group_type = space_group_info("P 1").group().type() ub_beg, ub_end = self.get_ub(frame) r = ReekeIndexGenerator(ub_beg, ub_end, space_group_type, self.axis, self.s0, self.dmin, self.margin) hkl = r.to_array() return sorted(list(hkl))
def test_varying_s0(self): from dials.algorithms.spot_prediction import ReekeIndexGenerator from cctbx.sgtbx import space_group_info space_group_type = space_group_info("P 1").group().type() ub_beg, ub_end = self._get_ub(0) hkl_sets = [] # loop over random beam changes and ensure we can generate indices us0 = self.s0.normalize() for i in range(100): # find a random axis orthogonal to the beam about which to rotate it axis = (us0.ortho()).rotate_around_origin(axis=us0, angle=random.uniform( 0, 2 * math.pi)) # apply small angle of rotation (up to ~1mrad) to perturb the beam direction s0_2 = self.s0.rotate_around_origin(axis=axis, angle=random.uniform(0, 0.057), deg=True) # alter the wavelength by up to about 0.1% s0_2 = s0_2 * random.uniform(0.999, 1.001) # now try to generate indices r = ReekeIndexGenerator( ub_beg, ub_end, space_group_type, self.axis, self.s0, s0_2, self.dmin, self.margin, ) hkl = r.to_array() hkl_sets.append(set(list(hkl))) # count common reflections in every set. For this example let's say we are # satisfied if 98% of the smallest set of generated indices are common # to every set. It is unclear how optimal this requirement is, but it at # least shows that beam changes across one image that are much larger than # we'd expect in normal processing do not hugely alter the generated list # of HKLs. min_set_len = min(len(e) for e in hkl_sets) common = set.intersection(*hkl_sets) # print "{0:.3f}% common".format(len(common) / min_set_len) assert len(common) >= 0.98 * min_set_len
def test_versus_brute_force(): """Perform a regression test by comparing to indices generated by the brute force method""" # cubic, 50A cell, 1A radiation, 1 deg osciillation, everything ideal a = 50.0 ub_beg = matrix.sqr( (1.0 / a, 0.0, 0.0, 0.0, 1.0 / a, 0.0, 0.0, 0.0, 1.0 / a)) axis = matrix.col((0, 1, 0)) r_osc = matrix.sqr( r3_rotation_axis_and_angle_as_matrix(axis=axis, angle=1.0, deg=True)) ub_end = r_osc * ub_beg uc = unit_cell((a, a, a, 90, 90, 90)) sg = space_group(space_group_symbols("P23").hall()) s0 = matrix.col((0, 0, 1)) wavelength = 1.0 dmin = 1.5 # get the full set of indices indices = full_sphere_indices(unit_cell=uc, resolution_limit=dmin, space_group=sg) # find the observed indices ra = rotation_angles(dmin, ub_beg, wavelength, axis) obs_indices, obs_angles = ra.observed_indices_and_angles_from_angle_range( phi_start_rad=0.0 * math.pi / 180.0, phi_end_rad=1.0 * math.pi / 180.0, indices=indices, ) # r = reeke_model(ub_beg, ub_end, axis, s0, dmin, 1.0) # reeke_indices = r.generate_indices() # now try the Reeke method to generate indices r = ReekeIndexGenerator(ub_beg, ub_end, sg.type(), axis, s0, dmin, margin=1) reeke_indices = r.to_array() for oi in obs_indices: assert tuple(map(int, oi)) in reeke_indices
def _search_on_image(self, t): from cctbx.sgtbx import space_group_info space_group_type = space_group_info("P 1").group().type() self._predictor.prepare(t) A1 = self._predictor.get_A1() A2 = self._predictor.get_A2() index_generator = ReekeIndexGenerator(A1, A2, space_group_type, self._axis, self._s0, self._dmin, margin = 1) indices = index_generator.to_array() reflections = [] for hkl in indices: r = self._predictor.predict(hkl) if r: reflections.append(r) return reflections
def _search_on_image(self, t): from cctbx.sgtbx import space_group_info space_group_type = space_group_info("P 1").group().type() self._predictor.prepare(t) A1 = self._predictor.get_A1() A2 = self._predictor.get_A2() index_generator = ReekeIndexGenerator( A1, A2, space_group_type, self._axis, self._s0, self._dmin, margin=1 ) indices = index_generator.to_array() reflections = [] for hkl in indices: r = self._predictor.predict(hkl) if r: reflections.append(r) return reflections