def regression_test(): """Perform a regression test by comparing to indices generating by the brute force method used in the Use Case.""" from rstbx.diffraction import rotation_angles from rstbx.diffraction import full_sphere_indices from cctbx.sgtbx import space_group, space_group_symbols from cctbx.uctbx import unit_cell # 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( scitbx.math.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 indices = full_sphere_indices(unit_cell=uc, resolution_limit=dmin, space_group=sg) 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 * pi / 180.0, phi_end_rad=1.0 * pi / 180.0, indices=indices) r = reeke_model(ub_beg, ub_end, axis, s0, dmin, 1.0) reeke_indices = r.generate_indices() #r.visualize_with_rgl() for oi in obs_indices: assert (tuple(map(int, oi)) in reeke_indices) #TODO Tests for an oblique cell print "OK"
def regression_test(): """Perform a regression test by comparing to indices generating by the brute force method used in the Use Case.""" from rstbx.diffraction import rotation_angles from rstbx.diffraction import full_sphere_indices from cctbx.sgtbx import space_group, space_group_symbols from cctbx.uctbx import unit_cell # 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(scitbx.math.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 indices = full_sphere_indices(unit_cell=uc, resolution_limit=dmin, space_group=sg) 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 * pi / 180.0, phi_end_rad=1.0 * pi / 180.0, indices=indices ) r = reeke_model(ub_beg, ub_end, axis, s0, dmin, 1.0) reeke_indices = r.generate_indices() # r.visualize_with_rgl() for oi in obs_indices: assert tuple(map(int, oi)) in reeke_indices # TODO Tests for an oblique cell print "OK"
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 predict_observations(self): '''Actually perform the prediction calculations.''' d2r = math.pi / 180.0 cfc = coordinate_frame_converter(self._configuration_file) self.img_start, self.osc_start, self.osc_range = parse_xds_xparm_scan_info( self._configuration_file) if self._dmin is None: self._dmin = cfc.derive_detector_highest_resolution() phi_start = ((self._img_range[0] - self.img_start) * self.osc_range + \ self.osc_start) * d2r phi_end = ((self._img_range[1] - self.img_start + 1) * self.osc_range + \ self.osc_start) * d2r self.phi_start_rad = phi_start self.phi_end_rad = phi_end # in principle this should come from the crystal model - should that # crystal model record the cell parameters or derive them from the # axis directions? A = cfc.get_c('real_space_a') B = cfc.get_c('real_space_b') C = cfc.get_c('real_space_c') cell = (A.length(), B.length(), C.length(), B.angle(C, deg = True), C.angle(A, deg = True), A.angle(B, deg = True)) self.uc = unit_cell(cell) # generate all of the possible indices, then pull out those which should # be systematically absent sg = cfc.get('space_group_number') indices = full_sphere_indices( unit_cell = self.uc, resolution_limit = self._dmin, space_group = space_group(space_group_symbols(sg).hall())) # then get the UB matrix according to the Rossmann convention which # is used within the Labelit code. u, b = cfc.get_u_b(convention = cfc.ROSSMANN) axis = cfc.get('rotation_axis', convention = cfc.ROSSMANN) ub = u * b wavelength = cfc.get('wavelength') self.wavelength = wavelength # work out which reflections should be observed (i.e. pass through the # Ewald sphere) ra = rotation_angles(self._dmin, ub, wavelength, axis) obs_indices, obs_angles = ra.observed_indices_and_angles_from_angle_range( phi_start_rad = phi_start, phi_end_rad = phi_end, indices = indices) # convert all of these to full scattering vectors in a laboratory frame # (for which I will use the CBF coordinate frame) and calculate which # will intersect with the detector u, b = cfc.get_u_b() axis = cfc.get_c('rotation_axis') # must guarantee that sample_to_source vector is normalized so that # s0 has length of 1/wavelength. sample_to_source_vec = cfc.get_c('sample_to_source').normalize() s0 = (- 1.0 / wavelength) * sample_to_source_vec ub = u * b # need some detector properties for this as well... starting to # abstract these to a detector model. df = detector_factory_from_cfc(cfc) d = df.build() # the Use Case assumes the detector consists of a single sensor sensor = d.sensors()[0] self.pixel_size_fast, self.pixel_size_slow = d.px_size_fast(), \ d.px_size_slow() # used for polarization correction self.distance = sensor.distance rp = reflection_prediction(axis, s0, ub, sensor) if self._rocking_curve is not None: assert self._rocking_curve != "none" rp.set_rocking_curve(self._rocking_curve) rp.set_mosaicity(self._mosaicity_deg, degrees = True) return rp.predict(obs_indices, obs_angles)
def regenerate_predictions_brute(xds_integrate_hkl_file, phi_range): from rstbx.cftbx.coordinate_frame_converter import coordinate_frame_converter from rstbx.diffraction import rotation_angles from rstbx.diffraction import full_sphere_indices from cctbx.sgtbx import space_group, space_group_symbols from cctbx.uctbx import unit_cell import math cfc = coordinate_frame_converter(xds_integrate_hkl_file) d2r = math.pi / 180.0 dmin = cfc.derive_detector_highest_resolution() A = cfc.get_c('real_space_a') B = cfc.get_c('real_space_b') C = cfc.get_c('real_space_c') cell = (A.length(), B.length(), C.length(), B.angle(C, deg = True), C.angle(A, deg = True), A.angle(B, deg = True)) uc = unit_cell(cell) sg = cfc.get('space_group_number') indices = full_sphere_indices( unit_cell = uc, resolution_limit = dmin, space_group = space_group(space_group_symbols(sg).hall())) u, b = cfc.get_u_b(convention = cfc.ROSSMANN) axis = cfc.get('rotation_axis', convention = cfc.ROSSMANN) ub = u * b wavelength = cfc.get('wavelength') ra = rotation_angles(dmin, ub, wavelength, axis) obs_indices, obs_angles = ra.observed_indices_and_angles_from_angle_range( phi_start_rad = phi_range[0] * d2r, phi_end_rad = phi_range[1] * d2r, indices = indices) # in here work in internal (i.e. not Rossmann) coordinate frame u, b = cfc.get_u_b() axis = cfc.get_c('rotation_axis') sample_to_source_vec = cfc.get_c('sample_to_source').normalize() s0 = (- 1.0 / wavelength) * sample_to_source_vec ub = u * b detector_origin = cfc.get_c('detector_origin') detector_fast = cfc.get_c('detector_fast') detector_slow = cfc.get_c('detector_slow') detector_normal = detector_fast.cross(detector_slow) distance = detector_origin.dot(detector_normal.normalize()) nx, ny = cfc.get('detector_size_fast_slow') px, py = cfc.get('detector_pixel_size_fast_slow') limits = [0, nx * px, 0, ny * py] xyz_to_hkl = { } for hkl, angle in zip(obs_indices, obs_angles): s = (ub * hkl).rotate(axis, angle) q = (s + s0).normalize() # check if diffracted ray parallel to detector face q_dot_n = q.dot(detector_normal) if q_dot_n == 0: continue r = (q * distance / q_dot_n) - detector_origin x = r.dot(detector_fast) y = r.dot(detector_slow) if x < limits[0] or y < limits[2]: continue if x > limits[1] or y > limits[3]: continue xyz = (x, y, angle / d2r) xyz_to_hkl[xyz] = map(int, hkl) return xyz_to_hkl
mybeam = beam_factory.make_beam(direction, 1.5) # make a random P1 crystal a = random.uniform(10, 20) * random_direction_close_to(matrix.col((1, 0, 0))) b = random.uniform(10, 20) * random_direction_close_to(matrix.col((0, 1, 0))) c = random.uniform(10, 20) * random_direction_close_to(matrix.col((0, 0, 1))) crystal_model(a, b, c, space_group_symbol="P 1") # make a dumb goniometer that rotates around X mygonio = goniometer_factory.known_axis((1, 0, 0)) # generate some indices resolution = 2.0 indices = full_sphere_indices( unit_cell=mycrystal.get_unit_cell(), resolution_limit=resolution, space_group=space_group(space_group_symbols(1).hall()), ) # generate list of phi values R_to_rossmann = align_reference_frame( mybeam.get_unit_s0(), (0.0, 0.0, 1.0), mygonio.get_rotation_axis(), (0.0, 1.0, 0.0) ) ra = rotation_angles( resolution, R_to_rossmann * mycrystal.get_U() * mycrystal.get_B(), mybeam.get_wavelength(), R_to_rossmann * matrix.col(mygonio.get_rotation_axis()), )
direction = random_direction_close_to(matrix.col((0, 0, 1))) mybeam = beam_factory.make_beam(direction, 1.5) # make a random P1 crystal a = random.uniform(10,20) * random_direction_close_to(matrix.col((1, 0, 0))) b = random.uniform(10,20) * random_direction_close_to(matrix.col((0, 1, 0))) c = random.uniform(10,20) * random_direction_close_to(matrix.col((0, 0, 1))) crystal_model(a, b, c, space_group_symbol="P 1") # make a dumb goniometer that rotates around X mygonio = goniometer_factory.known_axis((1, 0, 0)) # generate some indices resolution = 2.0 indices = full_sphere_indices( unit_cell = mycrystal.get_unit_cell(), resolution_limit = resolution, space_group = space_group(space_group_symbols(1).hall())) # generate list of phi values R_to_rossmann = align_reference_frame( mybeam.get_unit_s0(), (0.0, 0.0, 1.0), mygonio.get_rotation_axis(), (0.0, 1.0, 0.0)) ra = rotation_angles(resolution, R_to_rossmann * mycrystal.get_U() * mycrystal.get_B(), mybeam.get_wavelength(), R_to_rossmann * matrix.col(mygonio.get_rotation_axis())) obs_indices_rstbx, obs_angles_rstbx = \ ra.observed_indices_and_angles_from_angle_range( phi_start_rad = 0.0, phi_end_rad = math.pi, indices = indices)