def exercise_similarity(): model_1 = crystal_model(real_space_a=(10,0,0), real_space_b=(0,11,0), real_space_c=(0,0,12), space_group_symbol="P 1", mosaicity=0.5) model_2 = crystal_model(real_space_a=(10,0,0), real_space_b=(0,11,0), real_space_c=(0,0,12), space_group_symbol="P 1", mosaicity=0.5) assert model_1.is_similar_to(model_2) # mosaicity tests model_1.set_mosaicity(-1) model_2.set_mosaicity(-0.5) assert model_1.is_similar_to(model_2) # test ignores negative mosaicity model_1.set_mosaicity(0.5) model_2.set_mosaicity(0.63) # outside tolerance assert not model_1.is_similar_to(model_2) model_2.set_mosaicity(0.625) #just inside tolerance assert model_1.is_similar_to(model_2) # orientation tests R = model_2.get_U() dr1 = matrix.col((1, 0, 0)).axis_and_angle_as_r3_rotation_matrix(0.0101, deg=True) dr2 = matrix.col((1, 0, 0)).axis_and_angle_as_r3_rotation_matrix(0.0099, deg=True) model_2.set_U(dr1 * R) assert not model_1.is_similar_to(model_2) # outside tolerance model_2.set_U(dr2 * R) assert model_1.is_similar_to(model_2) # inside tolerance # unit_cell.is_similar_to is tested elsewhere return
def exercise(): from dials.algorithms.indexing import compare_orientation_matrices from dxtbx.model.crystal import crystal_model from cctbx import sgtbx from scitbx import matrix from scitbx.math import euler_angles as euler # try and see if we can get back the original rotation matrix and euler angles real_space_a = matrix.col((10,0,0)) real_space_b = matrix.col((0,10,10)) real_space_c = matrix.col((0,0,10)) euler_angles = (1.3, 5.6, 7.8) R = matrix.sqr( euler.xyz_matrix(euler_angles[0], euler_angles[1], euler_angles[2])) crystal_a = crystal_model(real_space_a, real_space_b, real_space_c, space_group=sgtbx.space_group('P 1')) crystal_b = crystal_model(R * real_space_a, R * real_space_b, R * real_space_c, space_group=sgtbx.space_group('P 1')) assert approx_equal(crystal_b.get_U() * crystal_a.get_U().transpose(), R) best_R_ab, best_axis, best_angle, best_cb_op = \ compare_orientation_matrices.difference_rotation_matrix_axis_angle( crystal_a, crystal_b) best_euler_angles = euler.xyz_angles(best_R_ab) assert approx_equal(best_euler_angles, euler_angles) assert best_cb_op.is_identity_op() assert approx_equal(best_R_ab, R) # now see if we can deconvolute the original euler angles after applying # a change of basis to one of the crystals crystal_a = crystal_model(real_space_a, real_space_b, real_space_c, space_group=sgtbx.space_group('I 2 3')) crystal_b = crystal_model(R * real_space_a, R * real_space_b, R * real_space_c, space_group=sgtbx.space_group('I 2 3')) cb_op = sgtbx.change_of_basis_op('z,x,y') crystal_b = crystal_b.change_basis(cb_op) best_R_ab, best_axis, best_angle, best_cb_op = \ compare_orientation_matrices.difference_rotation_matrix_axis_angle( crystal_a, crystal_b) best_euler_angles = euler.xyz_angles(best_R_ab) assert approx_equal(best_euler_angles, euler_angles) assert best_cb_op.c() == cb_op.inverse().c() assert approx_equal(best_R_ab, R)
def tst_dump_empty_sweep(self): from dxtbx.imageset import ImageSweep, NullReader, SweepFileList from dxtbx.model import Beam, Detector, Goniometer, Scan from dxtbx.model.crystal import crystal_model from uuid import uuid4 imageset = ImageSweep(NullReader(SweepFileList("filename%01d.cbf", (0, 3)))) imageset.set_beam(Beam((1, 0, 0))) imageset.set_detector(Detector()) imageset.set_goniometer(Goniometer()) imageset.set_scan(Scan((1, 3), (0.0, 1.0))) crystal = crystal_model((1, 0, 0), (0, 1, 0), (0, 0, 1), space_group_symbol=1) experiments = ExperimentListFactory.from_imageset_and_crystal( imageset, crystal) dump = ExperimentListDumper(experiments) filename = 'temp%s.json' % uuid4().hex dump.as_json(filename) experiments2 = ExperimentListFactory.from_json_file(filename, check_format=False) self.check(experiments, experiments2) print 'OK'
def to_crystal(filename): ''' Get the crystal model from the xparm file Params: filename The xparm/or integrate filename Return: The crystal model ''' from rstbx.cftbx.coordinate_frame_converter import \ coordinate_frame_converter from dxtbx.model.crystal import crystal_model from cctbx.sgtbx import space_group, space_group_symbols # Get the real space coordinate frame cfc = coordinate_frame_converter(filename) real_space_a = cfc.get('real_space_a') real_space_b = cfc.get('real_space_b') real_space_c = cfc.get('real_space_c') sg = cfc.get('space_group_number') space_group = space_group(space_group_symbols(sg).hall()) mosaicity = cfc.get('mosaicity') # Return the crystal model return crystal_model( real_space_a=real_space_a, real_space_b=real_space_b, real_space_c=real_space_c, space_group=space_group, mosaicity=mosaicity)
def tst_from_datablock(self): from dxtbx.imageset import ImageSweep, NullReader, SweepFileList from dxtbx.model import Beam, Detector, Goniometer, Scan from dxtbx.datablock import DataBlockFactory from dxtbx.model.crystal import crystal_model imageset = ImageSweep(NullReader(SweepFileList("filename%01d.cbf", (0, 2)))) imageset.set_beam(Beam()) imageset.set_detector(Detector()) imageset.set_goniometer(Goniometer()) imageset.set_scan(Scan((1, 2), (0, 1))) crystal = crystal_model((1, 0, 0), (0, 1, 0), (0, 0, 1), space_group_symbol=0) datablock = DataBlockFactory.from_imageset(imageset) experiments = ExperimentListFactory.from_datablock_and_crystal( datablock, crystal) assert(len(experiments) == 1) assert(experiments[0].imageset is not None) assert(experiments[0].beam is not None) assert(experiments[0].detector is not None) assert(experiments[0].goniometer is not None) assert(experiments[0].scan is not None) assert(experiments[0].crystal is not None) print 'OK' pass
def __init__(self, obj): from dxtbx.model.crystal import crystal_model import cctbx.uctbx from scitbx import matrix # Get the crystal parameters unit_cell_parameters = list(obj.handle['unit_cell'][0]) unit_cell = cctbx.uctbx.unit_cell(unit_cell_parameters) U = list(obj.handle['orientation_matrix'][0].flatten()) U = matrix.sqr(U) B = matrix.sqr(unit_cell.fractionalization_matrix()).transpose() A = U * B Ai = A.inverse() real_space_a = Ai[0:3] real_space_b = Ai[3:6] real_space_c = Ai[6:9] # Get the space group symbol space_group_symbol = obj.handle['unit_cell_group'][()] # Create the model self.model = crystal_model( real_space_a, real_space_b, real_space_c, space_group_symbol)
def to_crystal(filename): ''' Get the crystal model from the xparm file Params: filename The xparm/or integrate filename Return: The crystal model ''' from rstbx.cftbx.coordinate_frame_converter import \ coordinate_frame_converter from dxtbx.model.crystal import crystal_model from cctbx.sgtbx import space_group, space_group_symbols # Get the real space coordinate frame cfc = coordinate_frame_converter(filename) real_space_a = cfc.get('real_space_a') real_space_b = cfc.get('real_space_b') real_space_c = cfc.get('real_space_c') sg = cfc.get('space_group_number') space_group = space_group(space_group_symbols(sg).hall()) mosaicity = cfc.get('mosaicity') # Return the crystal model return crystal_model(real_space_a=real_space_a, real_space_b=real_space_b, real_space_c=real_space_c, space_group=space_group, mosaicity=mosaicity)
def tst_crystal(self): from dxtbx.serialize.crystal import to_dict, from_dict from dxtbx.model.crystal import crystal_model from scitbx import matrix real_space_a = matrix.col((35.2402102454, -7.60002142787, 22.080026774)) real_space_b = matrix.col((22.659572494, 1.47163505925, -35.6586361881)) real_space_c = matrix.col((5.29417246554, 38.9981792999, 4.97368666613)) c1 = crystal_model( real_space_a=real_space_a, real_space_b=real_space_b, real_space_c=real_space_c, space_group_symbol="P 1 2/m 1", mosaicity=0.1) d = to_dict(c1) c2 = from_dict(d) eps = 1e-7 assert(abs(matrix.col(d['real_space_a']) - real_space_a) <= eps) assert(abs(matrix.col(d['real_space_b']) - real_space_b) <= eps) assert(abs(matrix.col(d['real_space_c']) - real_space_c) <= eps) assert(d['space_group_hall_symbol'] == "-P 2y") assert(d['mosaicity'] == 0.1) assert(c1 == c2) print 'OK'
def predict_once(args): from dxtbx.model.experiment.experiment_list import Experiment U = args[0] A = U * B direct_matrix = A.inverse() cryst_model = crystal_model( direct_matrix[0:3], direct_matrix[3:6], direct_matrix[6:9], space_group=space_group, ) experiment = Experiment( imageset=sweep, beam=sweep.get_beam(), detector=sweep.get_detector(), goniometer=sweep.get_goniometer(), scan=sweep.get_scan(), crystal=cryst_model, ) predicted_reflections = flex.reflection_table.from_predictions(experiment) miller_indices = predicted_reflections["miller_index"] miller_set = miller.set(crystal_symmetry, miller_indices, anomalous_flag=True) if params.d_min is not None: resolution_sel = miller_set.d_spacings().data() > params.d_min predicted_reflections = predicted_reflections.select(resolution_sel) return len(predicted_reflections)
def tst_crystal_with_scan_points(self): from dxtbx.serialize.crystal import to_dict, from_dict from dxtbx.model.crystal import crystal_model from scitbx import matrix real_space_a = matrix.col((35.2402102454, -7.60002142787, 22.080026774)) real_space_b = matrix.col((22.659572494, 1.47163505925, -35.6586361881)) real_space_c = matrix.col((5.29417246554, 38.9981792999, 4.97368666613)) c1 = crystal_model( real_space_a=real_space_a, real_space_b=real_space_b, real_space_c=real_space_c, space_group_symbol="P 1 2/m 1", mosaicity=0.1) A = c1.get_A() c1.set_A_at_scan_points([A for i in range(5)]) d = to_dict(c1) c2 = from_dict(d) eps = 1e-9 for Acomp in (d['A_at_scan_points']): for e1, e2 in zip(A, Acomp): assert(abs(e1 - e2) <= eps) assert(c1 == c2) print 'OK'
def tst_from_datablock(self): from dxtbx.imageset import ImageSweep, NullReader, SweepFileList from dxtbx.model import Beam, Detector, Goniometer, Scan from dxtbx.datablock import DataBlockFactory from dxtbx.model.crystal import crystal_model imageset = ImageSweep(NullReader(SweepFileList("filename%01d.cbf", (0, 2)))) imageset.set_beam(Beam()) imageset.set_detector(Detector()) imageset.set_goniometer(Goniometer()) imageset.set_scan(Scan((1, 2), (0, 1))) crystal = crystal_model((1, 0, 0), (0, 1, 0), (0, 0, 1), space_group_symbol=0) datablock = DataBlockFactory.from_imageset(imageset) experiments = ExperimentListFactory.from_datablock_and_crystal( datablock, crystal) assert(len(experiments) == 1) assert(experiments[0].imageset is not None) assert(experiments[0].beam is not None) assert(experiments[0].detector is not None) assert(experiments[0].goniometer is not None) assert(experiments[0].scan is not None) assert(experiments[0].crystal is not None) print 'OK'
def test_random(self): """Test random initial orientations, random parameter shifts and random times""" attempts = 100 failures = 0 null_mat = matrix.sqr((0., 0., 0., 0., 0., 0., 0., 0., 0.)) for i in range(attempts): # make a new P1 random crystal and parameterise it a = random.uniform(10,50) * \ self.random_direction_close_to(matrix.col((1, 0, 0))) b = random.uniform(10,50) * \ self.random_direction_close_to(matrix.col((0, 1, 0))) c = random.uniform(10,50) * \ self.random_direction_close_to(matrix.col((0, 0, 1))) xl = crystal_model(a, b, c, space_group_symbol="P 1") xl_op = TestOrientationModel(50, xl, self.image_range, 5) # How many parameters? num_param = xl_op.num_free() # apply random parameter shifts to the orientation (2.0 mrad each # checkpoint) p_vals = xl_op.get_param_vals() sigmas = [2.0] * len(p_vals) new_vals = random_param_shift(p_vals, sigmas) xl_op.set_param_vals(new_vals) # select random time point at which to make comparisons t = random.uniform(*self.image_range) xl_op.set_time_point(t) # compare analytical and finite difference derivatives xl_op_an_ds_dp = xl_op.get_ds_dp() xl_op_fd_ds_dp = get_fd_gradients(xl_op, [1.e-6 * pi/180] * \ num_param) for j in range(num_param): try: assert(approx_equal((xl_op_fd_ds_dp[j] - xl_op_an_ds_dp[j]), null_mat, eps = 1.e-6)) except Exception: failures += 1 print "for try", i print "failure for parameter number", j print "of the orientation parameterisation" print "with fd_ds_dp = " print xl_op_fd_ds_dp[j] print "and an_ds_dp = " print xl_op_an_ds_dp[j] print "so that difference fd_ds_dp - an_ds_dp =" print xl_op_fd_ds_dp[j] - xl_op_an_ds_dp[j] if failures == 0: print "OK"
def create_Bmat(): """Create a random crystal model, in P1 for maximum generality. Return the B matrix of this crystal""" from dxtbx.model.crystal import crystal_model vecs = map(random_vector_close_to, [(20, 0, 0), (0, 20, 0), (0, 0, 20)]) return crystal_model(*vecs, space_group_symbol="P 1").get_B()
def build_crystal(self): vecs = map(self._build_cell_vec, [self._params.crystal.a, self._params.crystal.b, self._params.crystal.c]) sg = self._params.crystal.space_group_symbol self.crystal = crystal_model(*vecs, space_group_symbol = sg)
def generate_crystal(unit_cell, space_group): from dxtbx.model.crystal import crystal_model B = matrix.sqr(unit_cell.fractionalization_matrix()).transpose() U = random_rotation() A = U * B direct_matrix = A.inverse() return crystal_model(direct_matrix[0:3], direct_matrix[3:6], direct_matrix[6:9], space_group=space_group)
def dials_crystal_from_orientation(crystal_orientation,space_group): dm = crystal_orientation.direct_matrix() AA = col((dm[0],dm[1],dm[2])) BB = col((dm[3],dm[4],dm[5])) CC = col((dm[6],dm[7],dm[8])) from dxtbx.model.crystal import crystal_model cryst = crystal_model(real_space_a=AA, real_space_b=BB, real_space_c=CC, space_group=space_group) return cryst
def tst_equality(self): from dxtbx.model import Beam, Detector, Goniometer, Scan from dxtbx.model.crystal import crystal_model # Create a load of models b1 = Beam() d1 = Detector() g1 = Goniometer() s1 = Scan() c1 = crystal_model((1, 0, 0), (0, 1, 0), (0, 0, 1), 0) # Create a load of models that look the same but aren't b2 = Beam() d2 = Detector() g2 = Goniometer() s2 = Scan() c2 = crystal_model((1, 0, 0), (0, 1, 0), (0, 0, 1), 0) # Create an experiment e1 = Experiment( beam=b1, detector=d1, goniometer=g1, scan=s1, crystal=c1, imageset=None) # Create an experiment e2 = Experiment( beam=b1, detector=d1, goniometer=g1, scan=s1, crystal=c1, imageset=None) # Create an experiment e3 = Experiment( beam=b2, detector=d2, goniometer=g2, scan=s2, crystal=c2, imageset=None) # Check e1 equals e2 but not e3 assert(e1 == e2) assert(e1 != e3) assert(e2 != e3) # Test passed print 'OK'
def __init__(self,params): import cPickle as pickle from dxtbx.model.beam import beam_factory from dxtbx.model.detector import detector_factory from dxtbx.model.crystal import crystal_model from cctbx.crystal_orientation import crystal_orientation,basis_type from dxtbx.model.experiment.experiment_list import Experiment, ExperimentList from scitbx import matrix self.experiments = ExperimentList() self.unique_file_names = [] self.params = params data = pickle.load(open(self.params.output.prefix+"_frame.pickle","rb")) frames_text = data.split("\n") for item in frames_text: tokens = item.split(' ') wavelength = float(tokens[order_dict["wavelength"]]) beam = beam_factory.simple(wavelength = wavelength) detector = detector_factory.simple( sensor = detector_factory.sensor("PAD"), # XXX shouldn't hard code for XFEL distance = float(tokens[order_dict["distance"]]), beam_centre = [float(tokens[order_dict["beam_x"]]), float(tokens[order_dict["beam_y"]])], fast_direction = "+x", slow_direction = "+y", pixel_size = [self.params.pixel_size,self.params.pixel_size], image_size = [1795,1795], # XXX obviously need to figure this out ) reciprocal_matrix = matrix.sqr([float(tokens[order_dict[k]]) for k in [ 'res_ori_1','res_ori_2','res_ori_3','res_ori_4','res_ori_5','res_ori_6','res_ori_7','res_ori_8','res_ori_9']]) ORI = crystal_orientation(reciprocal_matrix, basis_type.reciprocal) direct = matrix.sqr(ORI.direct_matrix()) crystal = crystal_model( real_space_a = matrix.row(direct[0:3]), real_space_b = matrix.row(direct[3:6]), real_space_c = matrix.row(direct[6:9]), space_group_symbol = "P63", # XXX obviously another gap in the database paradigm mosaicity = float(tokens[order_dict["half_mosaicity_deg"]]), ) crystal.domain_size = float(tokens[order_dict["domain_size_ang"]]) #if isoform is not None: # newB = matrix.sqr(isoform.fractionalization_matrix()).transpose() # crystal.set_B(newB) self.experiments.append(Experiment(beam=beam, detector=None, #dummy for now crystal=crystal)) self.unique_file_names.append(tokens[order_dict["unique_file_name"]]) self.show_summary()
def tst_contains(self): from dxtbx.model import Beam, Detector, Goniometer, Scan from dxtbx.model.crystal import crystal_model # Create a load of models b1 = Beam() d1 = Detector() g1 = Goniometer() s1 = Scan() c1 = crystal_model((1, 0, 0), (0, 1, 0), (0, 0, 1), 0) # Create an experiment e = Experiment( beam=b1, detector=d1, goniometer=g1, scan=s1, crystal=c1, imageset=None) # Check experiment contains model assert(b1 in e) assert(d1 in e) assert(g1 in e) assert(s1 in e) assert(c1 in e) # Create a load of models that look the same but aren't b2 = Beam() d2 = Detector() g2 = Goniometer() s2 = Scan() c2 = crystal_model((1, 0, 0), (0, 1, 0), (0, 0, 1), 0) # Check experiment doesn't contain model assert(b2 not in e) assert(d2 not in e) assert(g2 not in e) assert(s2 not in e) assert(c2 not in e) # Test passed print 'OK'
def __init__(self, test_nave_model = False): # Set up experimental models with regular geometry from dxtbx.model.experiment import beam_factory from dxtbx.model.experiment import goniometer_factory from dxtbx.model.experiment import detector_factory from dxtbx.model.crystal import crystal_model # Beam along the Z axis self.beam = beam_factory.make_beam(unit_s0 = matrix.col((0, 0, 1)), wavelength = 1.0) # Goniometer (used only for index generation) along X axis self.goniometer = goniometer_factory.known_axis(matrix.col((1, 0, 0))) # Detector fast, slow along X, -Y; beam in the centre, 200 mm distance dir1 = matrix.col((1, 0, 0)) dir2 = matrix.col((0, -1, 0)) n = matrix.col((0, 0, 1)) centre = matrix.col((0, 0, 200)) npx_fast = npx_slow = 1000 pix_size = 0.2 origin = centre - (0.5 * npx_fast * pix_size * dir1 + 0.5 * npx_slow * pix_size * dir2) self.detector = detector_factory.make_detector("PAD", dir1, dir2, origin, (pix_size, pix_size), (npx_fast, npx_slow), (0, 1.e6)) # Cubic 100 A^3 crystal a = matrix.col((100, 0, 0)) b = matrix.col((0, 100, 0)) c = matrix.col((0, 0, 100)) self.crystal = crystal_model(a, b, c, space_group_symbol = "P 1") if test_nave_model: self.crystal._ML_half_mosaicity_deg = 500 self.crystal._ML_domain_size_ang = 0.2 # Collect these models in an Experiment (ignoring the goniometer) from dxtbx.model.experiment.experiment_list import Experiment self.experiment = Experiment(beam=self.beam, detector=self.detector, goniometer=None, scan=None, crystal=self.crystal, imageset=None) # Generate some reflections self.reflections = self.generate_reflections() return
def expt_crystal_maker(self): """Construct the crystal object for the experiments file.""" a, b, c = self.ucell.parameters()[0:3] direct_matrix = self.ori.direct_matrix() real_a = direct_matrix[0:3] real_b = direct_matrix[3:6] real_c = direct_matrix[6:9] lattice = self.ucell.lattice_symmetry_group() self.crystal = crystal.crystal_model(real_a, real_b, real_c, space_group=lattice) self.crystal.set_mosaicity(self.data['mosaicity']) self.crystal._ML_half_mosaicity_deg = self.data['ML_half_mosaicity_deg'][0] self.crystal._ML_domain_size_ang = self.data['ML_domain_size_ang'][0] if self.data['identified_isoform'] is not None: self.crystal.identified_isoform = self.data['identified_isoform']
def exercise_similarity(): model_1 = crystal_model(real_space_a=(10, 0, 0), real_space_b=(0, 11, 0), real_space_c=(0, 0, 12), space_group_symbol="P 1", mosaicity=0.5) model_2 = crystal_model(real_space_a=(10, 0, 0), real_space_b=(0, 11, 0), real_space_c=(0, 0, 12), space_group_symbol="P 1", mosaicity=0.5) assert model_1.is_similar_to(model_2) # mosaicity tests model_1.set_mosaicity(-1) model_2.set_mosaicity(-0.5) assert model_1.is_similar_to(model_2) # test ignores negative mosaicity model_1.set_mosaicity(0.5) model_2.set_mosaicity(0.63) # outside tolerance assert not model_1.is_similar_to(model_2) model_2.set_mosaicity(0.625) #just inside tolerance assert model_1.is_similar_to(model_2) # orientation tests R = model_2.get_U() dr1 = matrix.col((1, 0, 0)).axis_and_angle_as_r3_rotation_matrix(0.0101, deg=True) dr2 = matrix.col((1, 0, 0)).axis_and_angle_as_r3_rotation_matrix(0.0099, deg=True) model_2.set_U(dr1 * R) assert not model_1.is_similar_to(model_2) # outside tolerance model_2.set_U(dr2 * R) assert model_1.is_similar_to(model_2) # inside tolerance # unit_cell.is_similar_to is tested elsewhere return
def from_dict(d): ''' Convert the dictionary to a crystal model Params: d The dictionary of parameters Returns: The crystal model ''' from dxtbx.model.crystal import crystal_model # If None, return None if d is None: return None # Check the version and id if str(d['__id__']) != "crystal": raise ValueError("\"__id__\" does not equal \"crystal\"") # Extract from the dictionary real_space_a = d['real_space_a'] real_space_b = d['real_space_b'] real_space_c = d['real_space_c'] # str required to force unicode to ascii conversion space_group = str("Hall:" + d['space_group_hall_symbol']) mosaicity = d['mosaicity'] xl = crystal_model(real_space_a, real_space_b, real_space_c, space_group_symbol=space_group, mosaicity=mosaicity) # New parameters for maximum likelihood values try: xl._ML_half_mosaicity_deg = d['ML_half_mosaicity_deg'] except KeyError: pass try: xl._ML_domain_size_ang = d['ML_domain_size_ang'] except KeyError: pass # Extract scan point setting matrices, if present try: A_at_scan_points = d['A_at_scan_points'] xl.set_A_at_scan_points(A_at_scan_points) except KeyError: pass return xl
def trumpet_wrapper(result, postx, file_name, params, out): from scitbx import matrix from dxtbx.model.beam import beam_factory beam = beam_factory.make_beam(s0=(0, 0, -1. / result["wavelength"])) from dxtbx.model.experiment import experiment_list from dxtbx.model import crystal obs_to_plot = postx.observations_original_index_pair1_selected # XXX uses a private interface HKL = obs_to_plot.indices() i_sigi = obs_to_plot.data() / obs_to_plot.sigmas() direct_matrix = result["current_orientation"][0].direct_matrix() real_a = direct_matrix[0:3] real_b = direct_matrix[3:6] real_c = direct_matrix[6:9] SG = obs_to_plot.space_group() crystal = crystal.crystal_model(real_a, real_b, real_c, space_group=SG) q = experiment_list.Experiment(beam=beam, crystal=crystal) TPL = trumpet_plot() from xfel.cxi.data_utils import reduction RED = reduction(filename=file_name, experiment=q, HKL=HKL, i_sigi=i_sigi, measurements=obs_to_plot, params=params) TPL.set_reduction(RED) # first plot: before postrefinement TPL.reduction.experiment.crystal.set_A( matrix.sqr(result["current_orientation"][0].reciprocal_matrix())) TPL.set_refined( dict(half_mosaic_rotation_deg=result["ML_half_mosaicity_deg"][0], mosaic_domain_size_ang=result["ML_domain_size_ang"][0])) TPL.plot_one_model(nrow=0, out=out) # second plot after postrefinement values = postx.get_parameter_values() TPL.reduction.experiment.crystal.set_A( postx.refined_mini.refinery.get_eff_Astar(values)) TPL.refined["red_curve_domain_size_ang"] = 1 / values.RS TPL.refined[ "partiality_array"] = postx.refined_mini.refinery.get_partiality_array( values) TPL.plot_one_model(nrow=1, out=out) TPL.show()
def __init__(self, plots = False): # Do we make scatterplots? self.do_plots = plots # Let's say we have a scan of 100 images self.image_range = (1, 100) # Make a random P1 crystal a = random.uniform(10,50) * \ self.random_direction_close_to(matrix.col((1, 0, 0))) b = random.uniform(10,50) * \ self.random_direction_close_to(matrix.col((0, 1, 0))) c = random.uniform(10,50) * \ self.random_direction_close_to(matrix.col((0, 0, 1))) self.xl = crystal_model(a, b, c, space_group_symbol = "P 1")
def get_random_predictions(): """ Return a DIALS reflection table representing predictions using the given models. Assumes a Ewald proximity model for mosaicity """ # The U matrix to calculate A* rot = flex.random_double_r3_rotation_matrix() A = sqr(rot) * sqr(uc.reciprocal().orthogonalization_matrix()) A_inv = A.inverse() # Use the matrix to create a crystal model a = col(A_inv[:3]) b = col(A_inv[3:6]) c = col(A_inv[6:]) cm = crystal_model(a, b, c, space_group=spgrp) # This DIALS object has no gonio or scan which will identify it as a still expt = Experiment(beam=beam, detector=detector, goniometer=None, scan=None, crystal=cm) # Predict the reflections return flex.reflection_table.from_predictions(expt)
def prepare_dxtbx_models(self,setting_specific_ai,sg,isoform=None): from dxtbx.model.beam import beam_factory beam = beam_factory.simple(wavelength = self.inputai.wavelength) from dxtbx.model.detector import detector_factory detector = detector_factory.simple( sensor = detector_factory.sensor("PAD"), distance = setting_specific_ai.distance(), beam_centre = [setting_specific_ai.xbeam(), setting_specific_ai.ybeam()], fast_direction = "+x", slow_direction = "+y", pixel_size = [self.pixel_size,self.pixel_size], image_size = [self.inputpd['size1'],self.inputpd['size1']], ) direct = matrix.sqr(setting_specific_ai.getOrientation().direct_matrix()) from dxtbx.model.crystal import crystal_model crystal = crystal_model( real_space_a = matrix.row(direct[0:3]), real_space_b = matrix.row(direct[3:6]), real_space_c = matrix.row(direct[6:9]), space_group_symbol = sg, mosaicity = setting_specific_ai.getMosaicity() ) if isoform is not None: newB = matrix.sqr(isoform.fractionalization_matrix()).transpose() crystal.set_B(newB) from dxtbx.model.experiment.experiment_list import Experiment, ExperimentList experiments = ExperimentList() experiments.append(Experiment(beam=beam, detector=detector, crystal=crystal)) print beam print detector print crystal return experiments
def trumpet_wrapper(result, postx, file_name, params, out): from scitbx import matrix from dxtbx.model.beam import beam_factory beam = beam_factory.make_beam(s0=(0,0,-1./result["wavelength"])) from dxtbx.model.experiment import experiment_list from dxtbx.model import crystal obs_to_plot = postx.observations_original_index_pair1_selected # XXX uses a private interface HKL=obs_to_plot.indices() i_sigi=obs_to_plot.data()/obs_to_plot.sigmas() direct_matrix = result["current_orientation"][0].direct_matrix() real_a = direct_matrix[0:3] real_b = direct_matrix[3:6] real_c = direct_matrix[6:9] SG = obs_to_plot.space_group() crystal = crystal.crystal_model(real_a, real_b, real_c, space_group=SG) q = experiment_list.Experiment(beam=beam, crystal=crystal) TPL = trumpet_plot() from xfel.cxi.data_utils import reduction RED = reduction(filename = file_name, experiment = q, HKL = HKL, i_sigi = i_sigi, measurements = obs_to_plot, params = params) TPL.set_reduction(RED) # first plot: before postrefinement TPL.reduction.experiment.crystal.set_A(matrix.sqr(result["current_orientation"][0].reciprocal_matrix())) TPL.set_refined(dict(half_mosaic_rotation_deg=result["ML_half_mosaicity_deg"][0], mosaic_domain_size_ang=result["ML_domain_size_ang"][0])) TPL.plot_one_model(nrow=0,out=out) # second plot after postrefinement values = postx.get_parameter_values() TPL.reduction.experiment.crystal.set_A(postx.refined_mini.refinery.get_eff_Astar(values)) TPL.refined["red_curve_domain_size_ang"]=1/values.RS TPL.refined["partiality_array"]=postx.refined_mini.refinery.get_partiality_array(values) TPL.plot_one_model(nrow=1,out=out) TPL.show()
def tst_from_imageset(self): from dxtbx.imageset import ImageSet, NullReader from dxtbx.model import Beam, Detector, Goniometer, Scan from dxtbx.model.crystal import crystal_model imageset = ImageSet(NullReader(["filename.cbf"])) imageset.set_beam(Beam(), 0) imageset.set_detector(Detector(), 0) crystal = crystal_model( (1, 0, 0), (0, 1, 0), (0, 0, 1), space_group_symbol=0) experiments = ExperimentListFactory.from_imageset_and_crystal( imageset, crystal) assert(len(experiments) == 1) assert(experiments[0].imageset is not None) assert(experiments[0].beam is not None) assert(experiments[0].detector is not None) assert(experiments[0].crystal is not None) print 'OK'
def get_random_predictions(): """Return a DIALS reflection table representing predictions using the given models. Assumes a Ewald proximity model for mosaicity""" # The U matrix to calculate A* rot = flex.random_double_r3_rotation_matrix() A = sqr(rot) * sqr(uc.reciprocal().orthogonalization_matrix()) A_inv = A.inverse() # Use the matrix to create a crystal model a = col(A_inv[:3]) b = col(A_inv[3:6]) c = col(A_inv[6:]) cm = crystal_model(a, b, c, space_group=spgrp) # This DIALS object has no gonio or scan which will identify it as a still expt = Experiment(beam=beam, detector=detector, goniometer=None, scan=None, crystal=cm) # Predict the reflections return flex.reflection_table.from_predictions(expt)
def __init__(self, obj): from dxtbx.model.crystal import crystal_model import cctbx.uctbx from scitbx import matrix # Get the crystal parameters unit_cell_parameters = list(obj.handle['unit_cell'][0]) unit_cell = cctbx.uctbx.unit_cell(unit_cell_parameters) U = list(obj.handle['orientation_matrix'][0].flatten()) U = matrix.sqr(U) B = matrix.sqr(unit_cell.fractionalization_matrix()).transpose() A = U * B Ai = A.inverse() real_space_a = Ai[0:3] real_space_b = Ai[3:6] real_space_c = Ai[6:9] # Get the space group symbol space_group_symbol = obj.handle['unit_cell_group'][()] # Create the model self.model = crystal_model(real_space_a, real_space_b, real_space_c, space_group_symbol)
def predict_once(args): from dxtbx.model.experiment.experiment_list import Experiment U = args[0] A = U * B direct_matrix = A.inverse() cryst_model = crystal_model(direct_matrix[0:3], direct_matrix[3:6], direct_matrix[6:9], space_group=space_group) experiment = Experiment(imageset=sweep, beam=sweep.get_beam(), detector=sweep.get_detector(), goniometer=sweep.get_goniometer(), scan=sweep.get_scan(), crystal=cryst_model) predicted_reflections = flex.reflection_table.from_predictions( experiment) miller_indices = predicted_reflections['miller_index'] miller_set = miller.set( crystal_symmetry, miller_indices, anomalous_flag=True) if params.d_min is not None: resolution_sel = miller_set.d_spacings().data() > params.d_min predicted_reflections = predicted_reflections.select(resolution_sel) return len(predicted_reflections)
def __init__(self, plots = False): # Do we make scatterplots? self.do_plots = plots # Let's say we have a scan of 100 images self.image_range = (1, 100) # Make a random P1 crystal a = random.uniform(10,50) * \ self.random_direction_close_to(matrix.col((1, 0, 0))) b = random.uniform(10,50) * \ self.random_direction_close_to(matrix.col((0, 1, 0))) c = random.uniform(10,50) * \ self.random_direction_close_to(matrix.col((0, 0, 1))) self.xl = crystal_model(a, b, c, space_group_symbol = "P 1") # Make a beam with wavelength in the range 0.8--1.2 and s0 direction close # to 0,0,1 s0 = random.uniform(0.8, 1.2) * \ self.random_direction_close_to(matrix.col((0, 0, 1))) self.beam = Beam(s0) # Make a standard goniometer model along X self.goniometer = Goniometer((1,0,0)) # Make a simple single panel detector d1 = matrix.col((1, 0, 0)) d2 = matrix.col((0, -1, 0)) npx_fast = 1475 npx_slow = 1679 pix_size_f = pix_size_s = 0.172 from dxtbx.model.experiment import detector_factory self.detector = detector_factory.make_detector("PAD", d1, d2, matrix.col((0, 0, -110)), (pix_size_f, pix_size_s), (npx_fast, npx_slow), (0, 2e20))
def test1(): dials_regression = libtbx.env.find_in_repositories( relative_path="dials_regression", test=os.path.isdir) # use a datablock that contains a CS-PAD detector description data_dir = os.path.join(dials_regression, "refinement_test_data", "hierarchy_test") datablock_path = os.path.join(data_dir, "datablock.json") assert os.path.exists(datablock_path) # load models from dxtbx.datablock import DataBlockFactory datablock = DataBlockFactory.from_serialized_format(datablock_path, check_format=False) im_set = datablock[0].extract_imagesets()[0] from copy import deepcopy detector = deepcopy(im_set.get_detector()) beam = im_set.get_beam() # we'll invent a crystal, goniometer and scan for this test from dxtbx.model.crystal import crystal_model crystal = crystal_model((40., 0., 0.), (0., 40., 0.), (0., 0., 40.), space_group_symbol="P1") from dxtbx.model.experiment import goniometer_factory goniometer = goniometer_factory.known_axis((1., 0., 0.)) # Build a mock scan for a 180 degree sweep from dxtbx.model.scan import scan_factory sf = scan_factory() scan = sf.make_scan(image_range=(1, 1800), exposure_times=0.1, oscillation=(0, 0.1), epochs=range(1800), deg=True) sweep_range = scan.get_oscillation_range(deg=False) im_width = scan.get_oscillation(deg=False)[1] assert sweep_range == (0., pi) assert approx_equal(im_width, 0.1 * pi / 180.) from dxtbx.model.experiment.experiment_list import ExperimentList, Experiment # Build an experiment list experiments = ExperimentList() experiments.append( Experiment(beam=beam, detector=detector, goniometer=goniometer, scan=scan, crystal=crystal, imageset=None)) # simulate some reflections refs, ref_predictor = generate_reflections(experiments) # move the detector quadrants apart by 2mm both horizontally and vertically from dials.algorithms.refinement.parameterisation \ import DetectorParameterisationHierarchical det_param = DetectorParameterisationHierarchical(detector, level=1) det_p_vals = det_param.get_param_vals() p_vals = list(det_p_vals) p_vals[1] += 2 p_vals[2] -= 2 p_vals[7] += 2 p_vals[8] += 2 p_vals[13] -= 2 p_vals[14] += 2 p_vals[19] -= 2 p_vals[20] -= 2 det_param.set_param_vals(p_vals) # reparameterise the detector at the new perturbed geometry det_param = DetectorParameterisationHierarchical(detector, level=1) # parameterise other models from dials.algorithms.refinement.parameterisation.beam_parameters import \ BeamParameterisation from dials.algorithms.refinement.parameterisation.crystal_parameters import \ CrystalOrientationParameterisation, CrystalUnitCellParameterisation beam_param = BeamParameterisation(beam, goniometer) xlo_param = CrystalOrientationParameterisation(crystal) xluc_param = CrystalUnitCellParameterisation(crystal) # fix beam beam_param.set_fixed([True] * 3) # fix crystal xluc_param.set_fixed([True] * 6) xlo_param.set_fixed([True] * 3) # parameterisation of the prediction equation from dials.algorithms.refinement.parameterisation.prediction_parameters import \ XYPhiPredictionParameterisation from dials.algorithms.refinement.parameterisation.parameter_report import \ ParameterReporter pred_param = XYPhiPredictionParameterisation(experiments, [det_param], [beam_param], [xlo_param], [xluc_param]) param_reporter = ParameterReporter([det_param], [beam_param], [xlo_param], [xluc_param]) # reflection manager and target function from dials.algorithms.refinement.target import \ LeastSquaresPositionalResidualWithRmsdCutoff from dials.algorithms.refinement.reflection_manager import ReflectionManager refman = ReflectionManager(refs, experiments, nref_per_degree=20) # set a very tight rmsd target of 1/10000 of a pixel target = LeastSquaresPositionalResidualWithRmsdCutoff( experiments, ref_predictor, refman, pred_param, restraints_parameterisation=None, frac_binsize_cutoff=0.0001) # minimisation engine from dials.algorithms.refinement.engine \ import LevenbergMarquardtIterations as Refinery refinery = Refinery(target=target, prediction_parameterisation=pred_param, log=None, verbosity=0, track_step=False, track_gradient=False, track_parameter_correlation=False, max_iterations=20) # Refiner from dials.algorithms.refinement.refiner import Refiner refiner = Refiner(reflections=refs, experiments=experiments, pred_param=pred_param, param_reporter=param_reporter, refman=refman, target=target, refinery=refinery, verbosity=0) history = refiner.run() assert history.reason_for_termination == "RMSD target achieved" #compare detector with original detector orig_det = im_set.get_detector() refined_det = refiner.get_experiments()[0].detector from scitbx import matrix import math for op, rp in zip(orig_det, refined_det): # compare the origin vectors by... o1 = matrix.col(op.get_origin()) o2 = matrix.col(rp.get_origin()) # ...their relative lengths assert approx_equal(math.fabs(o1.length() - o2.length()) / o1.length(), 0, eps=1e-5) # ...the angle between them assert approx_equal(o1.accute_angle(o2), 0, eps=1e-5) print "OK" return
def from_dict(d): ''' Convert the dictionary to a crystal model Params: d The dictionary of parameters Returns: The crystal model ''' from dxtbx.model.crystal import crystal_model # If None, return None if d is None: return None # Check the version and id if str(d['__id__']) != "crystal": raise ValueError("\"__id__\" does not equal \"crystal\"") # Extract from the dictionary real_space_a = d['real_space_a'] real_space_b = d['real_space_b'] real_space_c = d['real_space_c'] # str required to force unicode to ascii conversion space_group = str("Hall:" + d['space_group_hall_symbol']) mosaicity = d['mosaicity'] xl = crystal_model(real_space_a, real_space_b, real_space_c, space_group_symbol=space_group, mosaicity=mosaicity) # New parameters for maximum likelihood values try: xl._ML_half_mosaicity_deg = d['ML_half_mosaicity_deg'] except KeyError: pass try: xl._ML_domain_size_ang = d['ML_domain_size_ang'] except KeyError: pass # Isoforms used for stills try: xl.identified_isoform = d['identified_isoform'] except KeyError: pass # Extract scan point setting matrices, if present try: A_at_scan_points = d['A_at_scan_points'] xl.set_A_at_scan_points(A_at_scan_points) except KeyError: pass # Extract covariance of B, if present try: cov_B = d['B_covariance'] xl.set_B_covariance(cov_B) except KeyError: pass return xl
def __init__(self, params): import cPickle as pickle from dxtbx.model import BeamFactory from dxtbx.model import DetectorFactory from dxtbx.model.crystal import crystal_model from cctbx.crystal_orientation import crystal_orientation, basis_type from dxtbx.model import Experiment, ExperimentList from scitbx import matrix self.experiments = ExperimentList() self.unique_file_names = [] self.params = params data = pickle.load( open(self.params.output.prefix + "_frame.pickle", "rb")) frames_text = data.split("\n") for item in frames_text: tokens = item.split(' ') wavelength = float(tokens[order_dict["wavelength"]]) beam = BeamFactory.simple(wavelength=wavelength) detector = DetectorFactory.simple( sensor=DetectorFactory.sensor( "PAD"), # XXX shouldn't hard code for XFEL distance=float(tokens[order_dict["distance"]]), beam_centre=[ float(tokens[order_dict["beam_x"]]), float(tokens[order_dict["beam_y"]]) ], fast_direction="+x", slow_direction="+y", pixel_size=[self.params.pixel_size, self.params.pixel_size], image_size=[1795, 1795], # XXX obviously need to figure this out ) reciprocal_matrix = matrix.sqr([ float(tokens[order_dict[k]]) for k in [ 'res_ori_1', 'res_ori_2', 'res_ori_3', 'res_ori_4', 'res_ori_5', 'res_ori_6', 'res_ori_7', 'res_ori_8', 'res_ori_9' ] ]) ORI = crystal_orientation(reciprocal_matrix, basis_type.reciprocal) direct = matrix.sqr(ORI.direct_matrix()) crystal = crystal_model( real_space_a=matrix.row(direct[0:3]), real_space_b=matrix.row(direct[3:6]), real_space_c=matrix.row(direct[6:9]), space_group_symbol=self.params.target_space_group.type(). lookup_symbol(), mosaicity=float(tokens[order_dict["half_mosaicity_deg"]]), ) crystal.domain_size = float(tokens[order_dict["domain_size_ang"]]) #if isoform is not None: # newB = matrix.sqr(isoform.fractionalization_matrix()).transpose() # crystal.set_B(newB) self.experiments.append( Experiment( beam=beam, detector=None, #dummy for now crystal=crystal)) self.unique_file_names.append( tokens[order_dict["unique_file_name"]]) self.show_summary()
from cctbx.uctbx import unit_cell def random_direction_close_to(vector): return vector.rotate_around_origin(matrix.col( (random.random(), random.random(), random.random())).normalize(), random.gauss(0, 1.0), deg=True) # make a random P1 crystal and parameterise it a = random.uniform(10, 50) * random_direction_close_to( matrix.col((1, 0, 0))) b = random.uniform(10, 50) * random_direction_close_to( matrix.col((0, 1, 0))) c = random.uniform(10, 50) * random_direction_close_to( matrix.col((0, 0, 1))) xl = crystal_model(a, b, c, space_group_symbol="P 1") xl_op = CrystalOrientationParameterisation(xl) xl_ucp = CrystalUnitCellParameterisation(xl) null_mat = matrix.sqr((0., 0., 0., 0., 0., 0., 0., 0., 0.)) # compare analytical and finite difference derivatives an_ds_dp = xl_op.get_ds_dp() fd_ds_dp = get_fd_gradients(xl_op, [1.e-6 * pi / 180] * 3) for e, f in zip(an_ds_dp, fd_ds_dp): assert (approx_equal((e - f), null_mat, eps=1.e-6)) an_ds_dp = xl_ucp.get_ds_dp() fd_ds_dp = get_fd_gradients(xl_ucp, [1.e-7] * xl_ucp.num_free()) for e, f in zip(an_ds_dp, fd_ds_dp):
def run(args): import libtbx.load_env from libtbx.utils import Sorry usage = "%s [options] experiments.json indexed.pickle" % libtbx.env.dispatcher_name parser = OptionParser( usage=usage, phil=phil_scope, read_reflections=True, read_experiments=True, check_format=False, epilog=help_message, ) params, options = parser.parse_args(show_diff_phil=True) reflections = flatten_reflections(params.input.reflections) experiments = flatten_experiments(params.input.experiments) if len(experiments) == 0 and len(reflections) == 0: parser.print_help() return elif len(experiments.crystals()) > 1: raise Sorry("Only one crystal can be processed at a time") if params.change_of_basis_op is None: raise Sorry("Please provide a change_of_basis_op.") reference_crystal = None if params.reference is not None: from dxtbx.serialize import load reference_experiments = load.experiment_list(params.reference, check_format=False) assert len(reference_experiments.crystals()) == 1 reference_crystal = reference_experiments.crystals()[0] if len(experiments) and params.change_of_basis_op is libtbx.Auto: if reference_crystal is not None: from dials.algorithms.indexing.compare_orientation_matrices import ( difference_rotation_matrix_and_euler_angles, ) cryst = experiments.crystals()[0] R, euler_angles, change_of_basis_op = difference_rotation_matrix_and_euler_angles(cryst, reference_crystal) print "Change of basis op: %s" % change_of_basis_op print "Rotation matrix to transform input crystal to reference::" print R.mathematica_form(format="%.3f", one_row_per_line=True) print "Euler angles (xyz): %.2f, %.2f, %.2f" % euler_angles elif len(reflections): assert len(reflections) == 1 # always re-map reflections to reciprocal space from dials.algorithms.indexing import indexer refl_copy = flex.reflection_table() for i, imageset in enumerate(experiments.imagesets()): if "imageset_id" in reflections[0]: sel = reflections[0]["imageset_id"] == i else: sel = reflections[0]["id"] == i refl = indexer.indexer_base.map_spots_pixel_to_mm_rad( reflections[0].select(sel), imageset.get_detector(), imageset.get_scan() ) indexer.indexer_base.map_centroids_to_reciprocal_space( refl, imageset.get_detector(), imageset.get_beam(), imageset.get_goniometer() ) refl_copy.extend(refl) # index the reflection list using the input experiments list refl_copy["id"] = flex.int(len(refl_copy), -1) from dials.algorithms.indexing import index_reflections index_reflections(refl_copy, experiments, tolerance=0.2) hkl_expt = refl_copy["miller_index"] hkl_input = reflections[0]["miller_index"] change_of_basis_op = derive_change_of_basis_op(hkl_input, hkl_expt) # reset experiments list since we don't want to reindex this experiments = [] else: change_of_basis_op = sgtbx.change_of_basis_op(params.change_of_basis_op) if len(experiments): experiment = experiments[0] cryst_orig = copy.deepcopy(experiment.crystal) cryst_reindexed = cryst_orig.change_basis(change_of_basis_op) if params.space_group is not None: a, b, c = cryst_reindexed.get_real_space_vectors() cryst_reindexed = crystal_model(a, b, c, space_group=params.space_group.group()) experiment.crystal.update(cryst_reindexed) print "Old crystal:" print cryst_orig print print "New crystal:" print cryst_reindexed print print "Saving reindexed experimental models to %s" % params.output.experiments dump.experiment_list(experiments, params.output.experiments) if len(reflections): assert len(reflections) == 1 reflections = reflections[0] miller_indices = reflections["miller_index"] if params.hkl_offset is not None: h, k, l = miller_indices.as_vec3_double().parts() h += params.hkl_offset[0] k += params.hkl_offset[1] l += params.hkl_offset[2] miller_indices = flex.miller_index(h.iround(), k.iround(), l.iround()) non_integral_indices = change_of_basis_op.apply_results_in_non_integral_indices(miller_indices) if non_integral_indices.size() > 0: print "Removing %i/%i reflections (change of basis results in non-integral indices)" % ( non_integral_indices.size(), miller_indices.size(), ) sel = flex.bool(miller_indices.size(), True) sel.set_selected(non_integral_indices, False) miller_indices_reindexed = change_of_basis_op.apply(miller_indices.select(sel)) reflections["miller_index"].set_selected(sel, miller_indices_reindexed) reflections["miller_index"].set_selected(~sel, (0, 0, 0)) print "Saving reindexed reflections to %s" % params.output.reflections easy_pickle.dump(params.output.reflections, reflections)
def test1(): dials_regression = libtbx.env.find_in_repositories( relative_path="dials_regression", test=os.path.isdir) # use a datablock that contains a CS-PAD detector description data_dir = os.path.join(dials_regression, "refinement_test_data", "hierarchy_test") datablock_path = os.path.join(data_dir, "datablock.json") assert os.path.exists(datablock_path) # load models from dxtbx.datablock import DataBlockFactory datablock = DataBlockFactory.from_serialized_format(datablock_path, check_format=False) im_set = datablock[0].extract_imagesets()[0] from copy import deepcopy detector = deepcopy(im_set.get_detector()) beam = im_set.get_beam() # we'll invent a crystal, goniometer and scan for this test from dxtbx.model.crystal import crystal_model crystal = crystal_model((40.,0.,0.) ,(0.,40.,0.), (0.,0.,40.), space_group_symbol = "P1") from dxtbx.model.experiment import goniometer_factory goniometer = goniometer_factory.known_axis((1., 0., 0.)) # Build a mock scan for a 180 degree sweep from dxtbx.model.scan import scan_factory sf = scan_factory() scan = sf.make_scan(image_range = (1,1800), exposure_times = 0.1, oscillation = (0, 0.1), epochs = range(1800), deg = True) sweep_range = scan.get_oscillation_range(deg=False) im_width = scan.get_oscillation(deg=False)[1] assert sweep_range == (0., pi) assert approx_equal(im_width, 0.1 * pi / 180.) from dxtbx.model.experiment.experiment_list import ExperimentList, Experiment # Build an experiment list experiments = ExperimentList() experiments.append(Experiment( beam=beam, detector=detector, goniometer=goniometer, scan=scan, crystal=crystal, imageset=None)) # simulate some reflections refs, ref_predictor = generate_reflections(experiments) # move the detector quadrants apart by 2mm both horizontally and vertically from dials.algorithms.refinement.parameterisation \ import DetectorParameterisationHierarchical det_param = DetectorParameterisationHierarchical(detector, level=1) det_p_vals = det_param.get_param_vals() p_vals = list(det_p_vals) p_vals[1] += 2 p_vals[2] -= 2 p_vals[7] += 2 p_vals[8] += 2 p_vals[13] -= 2 p_vals[14] += 2 p_vals[19] -= 2 p_vals[20] -= 2 det_param.set_param_vals(p_vals) # reparameterise the detector at the new perturbed geometry det_param = DetectorParameterisationHierarchical(detector, level=1) # parameterise other models from dials.algorithms.refinement.parameterisation.beam_parameters import \ BeamParameterisation from dials.algorithms.refinement.parameterisation.crystal_parameters import \ CrystalOrientationParameterisation, CrystalUnitCellParameterisation beam_param = BeamParameterisation(beam, goniometer) xlo_param = CrystalOrientationParameterisation(crystal) xluc_param = CrystalUnitCellParameterisation(crystal) # fix beam beam_param.set_fixed([True]*3) # fix crystal xluc_param.set_fixed([True]*6) xlo_param.set_fixed([True]*3) # parameterisation of the prediction equation from dials.algorithms.refinement.parameterisation.prediction_parameters import \ XYPhiPredictionParameterisation from dials.algorithms.refinement.parameterisation.parameter_report import \ ParameterReporter pred_param = XYPhiPredictionParameterisation(experiments, [det_param], [beam_param], [xlo_param], [xluc_param]) param_reporter = ParameterReporter([det_param], [beam_param], [xlo_param], [xluc_param]) # reflection manager and target function from dials.algorithms.refinement.target import \ LeastSquaresPositionalResidualWithRmsdCutoff from dials.algorithms.refinement.reflection_manager import ReflectionManager refman = ReflectionManager(refs, experiments, nref_per_degree=20) # set a very tight rmsd target of 1/10000 of a pixel target = LeastSquaresPositionalResidualWithRmsdCutoff(experiments, ref_predictor, refman, pred_param, restraints_parameterisation=None, frac_binsize_cutoff=0.0001) # minimisation engine from dials.algorithms.refinement.engine \ import LevenbergMarquardtIterations as Refinery refinery = Refinery(target = target, prediction_parameterisation = pred_param, log = None, verbosity = 0, track_step = False, track_gradient = False, track_parameter_correlation = False, max_iterations = 20) # Refiner from dials.algorithms.refinement.refiner import Refiner refiner = Refiner(reflections=refs, experiments=experiments, pred_param=pred_param, param_reporter=param_reporter, refman=refman, target=target, refinery=refinery, verbosity=0) history = refiner.run() assert history.reason_for_termination == "RMSD target achieved" #compare detector with original detector orig_det = im_set.get_detector() refined_det = refiner.get_experiments()[0].detector from scitbx import matrix import math for op, rp in zip(orig_det, refined_det): # compare the origin vectors by... o1 = matrix.col(op.get_origin()) o2 = matrix.col(rp.get_origin()) # ...their relative lengths assert approx_equal( math.fabs(o1.length() - o2.length()) / o1.length(), 0, eps=1e-5) # ...the angle between them assert approx_equal(o1.accute_angle(o2), 0, eps=1e-5) print "OK" return
def run(space_group_info): datablock_json = os.path.join(dials_regression, "indexing_test_data", "i04_weak_data", "datablock_orig.json") datablock = load.datablock(datablock_json, check_format=False)[0] sweep = datablock.extract_imagesets()[0] sweep._indices = sweep._indices[:20] sweep.set_scan(sweep.get_scan()[:20]) import random space_group = space_group_info.group() unit_cell = space_group_info.any_compatible_unit_cell( volume=random.uniform(1e4, 1e6)) crystal_symmetry = crystal.symmetry(unit_cell=unit_cell, space_group=space_group) crystal_symmetry.show_summary() # the reciprocal matrix B = matrix.sqr(unit_cell.fractionalization_matrix()).transpose() U = random_rotation() A = U * B direct_matrix = A.inverse() cryst_model = crystal_model(direct_matrix[0:3], direct_matrix[3:6], direct_matrix[6:9], space_group=space_group) experiment = Experiment(imageset=sweep, beam=sweep.get_beam(), detector=sweep.get_detector(), goniometer=sweep.get_goniometer(), scan=sweep.get_scan(), crystal=cryst_model) predicted_reflections = flex.reflection_table.from_predictions(experiment) use_fraction = 0.3 use_sel = flex.random_selection( len(predicted_reflections), int(use_fraction * len(predicted_reflections))) predicted_reflections = predicted_reflections.select(use_sel) miller_indices = predicted_reflections['miller_index'] miller_set = miller.set(crystal_symmetry, miller_indices, anomalous_flag=True) predicted_reflections['xyzobs.mm.value'] = predicted_reflections[ 'xyzcal.mm'] predicted_reflections['id'] = flex.int(len(predicted_reflections), 0) from dials.algorithms.indexing.indexer import indexer_base indexer_base.map_centroids_to_reciprocal_space(predicted_reflections, sweep.get_detector(), sweep.get_beam(), sweep.get_goniometer()) # check that local and global indexing worked equally well in absence of errors result = compare_global_local(experiment, predicted_reflections, miller_indices) assert result.misindexed_local == 0 assert result.misindexed_global == 0 a, b, c = cryst_model.get_real_space_vectors() relative_error = 0.02 a *= (1 + relative_error) b *= (1 + relative_error) c *= (1 + relative_error) cryst_model2 = crystal_model(a, b, c, space_group=space_group) experiment.crystal = cryst_model2 result = compare_global_local(experiment, predicted_reflections, miller_indices) # check that the local indexing did a better job given the errors in the basis vectors #assert result.misindexed_local < result.misindexed_global assert result.misindexed_local == 0 assert result.correct_local > result.correct_global # usually the number misindexed is much smaller than this assert result.misindexed_local < (0.001 * len(result.reflections_local)) # the reciprocal matrix A = cryst_model.get_A() A = random_rotation(angle_max=0.03) * A direct_matrix = A.inverse() cryst_model2 = crystal_model(direct_matrix[0:3], direct_matrix[3:6], direct_matrix[6:9], space_group=space_group) experiment.crystal = cryst_model2 result = compare_global_local(experiment, predicted_reflections, miller_indices) # check that the local indexing did a better job given the errors in the basis vectors assert result.misindexed_local <= result.misindexed_global, ( result.misindexed_local, result.misindexed_global) assert result.misindexed_local < 0.01 * result.correct_local assert result.correct_local > result.correct_global # usually the number misindexed is much smaller than this assert result.misindexed_local < (0.001 * len(result.reflections_local))
def exercise_crystal_model(): real_space_a = matrix.col((10,0,0)) real_space_b = matrix.col((0,11,0)) real_space_c = matrix.col((0,0,12)) model = crystal_model(real_space_a=(10,0,0), real_space_b=(0,11,0), real_space_c=(0,0,12), space_group_symbol="P 1") assert isinstance(model.get_unit_cell(), uctbx.unit_cell) assert model.get_unit_cell().parameters() == ( 10.0, 11.0, 12.0, 90.0, 90.0, 90.0) assert approx_equal(model.get_A(), (1/10, 0, 0, 0, 1/11, 0, 0, 0, 1/12)) assert approx_equal(model.get_A().inverse(), (10, 0, 0, 0, 11, 0, 0, 0, 12)) assert approx_equal(model.get_B(), model.get_A()) assert approx_equal(model.get_U(), (1, 0, 0, 0, 1, 0, 0, 0, 1)) assert approx_equal(model.get_real_space_vectors(), (real_space_a, real_space_b, real_space_c)) assert approx_equal(model.get_mosaicity(), 0) model2 = crystal_model(real_space_a=(10,0,0), real_space_b=(0,11,0), real_space_c=(0,0,12), space_group_symbol="P 1") assert model == model2 model2.set_mosaicity(0.01) assert model != model2 # rotate 45 degrees about x-axis R1 = matrix.sqr((1, 0, 0, 0, math.cos(math.pi/4), -math.sin(math.pi/4), 0, math.sin(math.pi/4), math.cos(math.pi/4))) # rotate 30 degrees about y-axis R2 = matrix.sqr((math.cos(math.pi/6), 0, math.sin(math.pi/6), 0, 1, 0, -math.sin(math.pi/6), 0, math.cos(math.pi/6))) # rotate 60 degrees about z-axis R3 = matrix.sqr((math.cos(math.pi/3), -math.sin(math.pi/3), 0, math.sin(math.pi/3), math.cos(math.pi/3), 0, 0, 0, 1)) R = R1 * R2 * R3 model.set_U(R) # B is unchanged assert approx_equal(model.get_B(), (1/10, 0, 0, 0, 1/11, 0, 0, 0, 1/12)) assert approx_equal(model.get_U(), R) assert approx_equal(model.get_A(), model.get_U() * model.get_B()) a_, b_, c_ = model.get_real_space_vectors() assert approx_equal(a_, R * real_space_a) assert approx_equal(b_, R * real_space_b) assert approx_equal(c_, R * real_space_c) s = StringIO() print >> s, model assert not show_diff(s.getvalue().replace("-0.0000", " 0.0000"), """\ Crystal: Unit cell: (10.000, 11.000, 12.000, 90.000, 90.000, 90.000) Space group: P 1 U matrix: {{ 0.4330, -0.7500, 0.5000}, { 0.7891, 0.0474, -0.6124}, { 0.4356, 0.6597, 0.6124}} B matrix: {{ 0.1000, 0.0000, 0.0000}, { 0.0000, 0.0909, 0.0000}, { 0.0000, 0.0000, 0.0833}} A = UB: {{ 0.0433, -0.0682, 0.0417}, { 0.0789, 0.0043, -0.0510}, { 0.0436, 0.0600, 0.0510}} """) model.set_B((1/12, 0, 0, 0, 1/12, 0, 0, 0, 1/12)) assert approx_equal(model.get_unit_cell().parameters(), (12, 12, 12, 90, 90, 90)) U = matrix.sqr(( 0.3455, -0.2589, -0.9020, 0.8914, 0.3909, 0.2293, 0.2933, -0.8833, 0.3658)) B = matrix.sqr((1/13, 0, 0, 0, 1/13, 0, 0, 0, 1/13)) model.set_A(U * B) assert approx_equal(model.get_A(), U * B) assert approx_equal(model.get_U(), U, 1e-4) assert approx_equal(model.get_B(), B, 1e-5) model3 = crystal_model( real_space_a=(10,0,0), real_space_b=(0,11,0), real_space_c=(0,0,12), space_group=sgtbx.space_group_info("P 222").group(), mosaicity=0.01) assert model3.get_space_group().type().hall_symbol() == " P 2 2" assert model != model3 # sgi_ref = sgtbx.space_group_info(number=230) model_ref = crystal_model( real_space_a=(44,0,0), real_space_b=(0,44,0), real_space_c=(0,0,44), space_group=sgi_ref.group()) assert approx_equal(model_ref.get_U(), (1,0,0,0,1,0,0,0,1)) assert approx_equal(model_ref.get_B(), (1/44,0,0,0,1/44,0,0,0,1/44)) assert approx_equal(model_ref.get_A(), model_ref.get_B()) assert approx_equal(model_ref.get_unit_cell().parameters(), (44,44,44,90,90,90)) a_ref, b_ref, c_ref = model_ref.get_real_space_vectors() cb_op_to_primitive = sgi_ref.change_of_basis_op_to_primitive_setting() model_primitive = model_ref.change_basis(cb_op_to_primitive) cb_op_to_reference = model_primitive.get_space_group().info()\ .change_of_basis_op_to_reference_setting() a_prim, b_prim, c_prim = model_primitive.get_real_space_vectors() #print cb_op_to_primitive.as_abc() ##'-1/2*a+1/2*b+1/2*c,1/2*a-1/2*b+1/2*c,1/2*a+1/2*b-1/2*c' assert approx_equal(a_prim, -1/2 * a_ref + 1/2 * b_ref + 1/2 * c_ref) assert approx_equal(b_prim, 1/2 * a_ref - 1/2 * b_ref + 1/2 * c_ref) assert approx_equal(c_prim, 1/2 * a_ref + 1/2 * b_ref - 1/2 * c_ref) #print cb_op_to_reference.as_abc() ##b+c,a+c,a+b assert approx_equal(a_ref, b_prim + c_prim) assert approx_equal(b_ref, a_prim + c_prim) assert approx_equal(c_ref, a_prim + b_prim) assert approx_equal( model_primitive.get_U(), [-0.5773502691896258, 0.40824829046386285, 0.7071067811865476, 0.5773502691896257, -0.4082482904638631, 0.7071067811865476, 0.5773502691896257, 0.8164965809277259, 0.0]) assert approx_equal( model_primitive.get_B(), [0.0262431940540739, 0.0, 0.0, 0.00927837023781507, 0.02783511071344521, 0.0, 0.01607060866333063, 0.01607060866333063, 0.03214121732666125]) assert approx_equal( model_primitive.get_A(), (0, 1/44, 1/44, 1/44, 0, 1/44, 1/44, 1/44, 0)) assert approx_equal( model_primitive.get_unit_cell().parameters(), [38.1051177665153, 38.1051177665153, 38.1051177665153, 109.47122063449069, 109.47122063449069, 109.47122063449069]) assert model_ref != model_primitive model_ref_recycled = model_primitive.change_basis(cb_op_to_reference) assert approx_equal(model_ref.get_U(), model_ref_recycled.get_U()) assert approx_equal(model_ref.get_B(), model_ref_recycled.get_B()) assert approx_equal(model_ref.get_A(), model_ref_recycled.get_A()) assert approx_equal(model_ref.get_unit_cell().parameters(), model_ref_recycled.get_unit_cell().parameters()) assert model_ref == model_ref_recycled # uc = uctbx.unit_cell((58.2567, 58.1264, 39.7093, 46.9077, 46.8612, 62.1055)) sg = sgtbx.space_group_info(symbol="P1").group() cs = crystal.symmetry(unit_cell=uc, space_group=sg) cb_op_to_minimum = cs.change_of_basis_op_to_minimum_cell() # the reciprocal matrix B = matrix.sqr(uc.fractionalization_matrix()).transpose() U = random_rotation() direct_matrix = (U * B).inverse() model = crystal_model(direct_matrix[:3], direct_matrix[3:6], direct_matrix[6:9], space_group=sg) assert uc.is_similar_to(model.get_unit_cell()) uc_minimum = uc.change_basis(cb_op_to_minimum) model_minimum = model.change_basis(cb_op_to_minimum) assert uc_minimum.is_similar_to(model_minimum.get_unit_cell()) assert model_minimum != model model_minimum.update(model) assert model_minimum == model # from scitbx.math import euler_angles A_static = model.get_A() A_as_scan_points = [A_static] num_scan_points = 11 for i in range(num_scan_points-1): A_as_scan_points.append( A_as_scan_points[-1] * matrix.sqr(euler_angles.xyz_matrix(0.1,0.2,0.3))) model.set_A_at_scan_points(A_as_scan_points) model_minimum = model.change_basis(cb_op_to_minimum) assert model.num_scan_points == model_minimum.num_scan_points == num_scan_points M = matrix.sqr(cb_op_to_minimum.c_inv().r().transpose().as_double()) M_inv = M.inverse() for i in range(num_scan_points): A_orig = model.get_A_at_scan_point(i) A_min = model_minimum.get_A_at_scan_point(i) assert A_min == A_orig * M_inv
def write_par_file(file_name, experiment): from scitbx import matrix from dxtbx.model.crystal import crystal_model from rstbx.cftbx.coordinate_frame_helpers import align_reference_frame from dials.command_line.refine_bravais_settings import short_space_group_name imageset = experiment.imageset detector = imageset.get_detector() goniometer = imageset.get_goniometer() beam = imageset.get_beam() scan = imageset.get_scan() R_to_mosflm = align_reference_frame(beam.get_s0(), (1.0, 0.0, 0.0), goniometer.get_rotation_axis(), (0.0, 0.0, 1.0)) cryst = experiment.crystal cryst = cryst.change_basis( cryst.get_space_group().info()\ .change_of_basis_op_to_reference_setting()) A = cryst.get_A() A_inv = A.inverse() real_space_a = R_to_mosflm * A_inv.elems[:3] real_space_b = R_to_mosflm * A_inv.elems[3:6] real_space_c = R_to_mosflm * A_inv.elems[6:9] cryst_mosflm = crystal_model(real_space_a, real_space_b, real_space_c, space_group=cryst.get_space_group(), mosaicity=cryst.get_mosaicity()) A_mosflm = cryst_mosflm.get_A() U_mosflm = cryst_mosflm.get_U() B_mosflm = cryst_mosflm.get_B() UB_mosflm = U_mosflm * B_mosflm uc_params = cryst_mosflm.get_unit_cell().parameters() assert U_mosflm.is_r3_rotation_matrix(), U_mosflm symmetry = cryst_mosflm.get_space_group().type().number() beam_centre = tuple(reversed(detector[0].get_beam_centre(beam.get_s0()))) distance = detector[0].get_directed_distance() polarization = R_to_mosflm * matrix.col(beam.get_polarization_normal()) rotation = matrix.col(goniometer.get_rotation_axis()) if (rotation.angle(matrix.col(detector[0].get_fast_axis())) < rotation.angle(matrix.col(detector[0].get_slow_axis()))): direction = 'FAST' else: direction = 'SLOW' rotation = R_to_mosflm * rotation with open(file_name, 'wb') as f: # print >> f, '# parameter file for BEST' print >> f, 'TITLE From DIALS' print >> f, 'DETECTOR PILA' print >> f, 'SITE Not set' print >> f, 'DIAMETER %6.2f' % (max( detector[0].get_image_size()) * detector[0].get_pixel_size()[0]) print >> f, 'PIXEL %s' % detector[0].get_pixel_size()[0] print >> f, 'ROTAXIS %4.2f %4.2f %4.2f' % rotation.elems, direction print >> f, 'POLAXIS %4.2f %4.2f %4.2f' % polarization.elems print >> f, 'GAIN 1.00' # correct for Pilatus images print >> f, 'CMOSAIC %.2f' % experiment.profile.sigma_m() print >> f, 'PHISTART %.2f' % scan.get_oscillation_range()[0] print >> f, 'PHIWIDTH %.2f' % scan.get_oscillation()[1] print >> f, 'DISTANCE %7.2f' % distance print >> f, 'WAVELENGTH %.5f' % beam.get_wavelength() print >> f, 'POLARISATION %7.5f' % beam.get_polarization_fraction() print >> f, 'SYMMETRY %s' % short_space_group_name( cryst.get_space_group()) print >> f, 'UB %9.2f %9.2f %9.2f' % UB_mosflm[:3] print >> f, ' %9.2f %9.2f %9.2f' % UB_mosflm[3:6] print >> f, ' %9.2f %9.2f %9.2f' % UB_mosflm[6:] print >> f, 'CELL %8.2f %8.2f %8.2f %6.2f %6.2f %6.2f' % uc_params print >> f, 'RASTER 13 13 7 3 4' print >> f, 'SEPARATION 2.960 2.960' print >> f, 'BEAM %8.3f %8.3f' % beam_centre print >> f, '# end of parameter file for BEST'
def extract_varying_crystal(integrate_lp, experiments): '''Extract a varying crystal model from an INTEGRATE.LP file (static in blocks with step changes) and write it to the provided experiments ''' if len(experiments) > 1: print "Can only read a varying crystal model for a single " +\ "experiment. Skipping." return experiment = experiments[0] # read required records from the file. Relies on them being in the # right order as we read through once xds_axis = None xds_beam = None blocks, a_axis, b_axis, c_axis = [], [], [], [] with open(integrate_lp) as f: for record in f: if record.lstrip().startswith("ROTATION_AXIS="): xds_axis = record.split("ROTATION_AXIS=")[1].split() break for record in f: if record.lstrip().startswith("INCIDENT_BEAM_DIRECTION="): xds_beam = record.split("INCIDENT_BEAM_DIRECTION=")[1].split() break for record in f: if record.lstrip().startswith("PROCESSING OF IMAGES"): blocks.append(record.split("PROCESSING OF IMAGES")[1]) continue if record.lstrip().startswith("COORDINATES OF UNIT CELL A-AXIS"): a_axis.append(record.split("COORDINATES OF UNIT CELL A-AXIS")[1]) continue if record.lstrip().startswith("COORDINATES OF UNIT CELL B-AXIS"): b_axis.append(record.split("COORDINATES OF UNIT CELL B-AXIS")[1]) continue if record.lstrip().startswith("COORDINATES OF UNIT CELL C-AXIS"): c_axis.append(record.split("COORDINATES OF UNIT CELL C-AXIS")[1]) continue # sanity checks msg = "INTEGRATE.LP is not in the expected format" nblocks = len(blocks) try: assert len(a_axis) == len(b_axis) == len(c_axis) == nblocks assert (xds_axis, xds_beam).count(None) == 0 except AssertionError: print msg return # conversions to numeric try: blocks = [map(int, block.split("...")) for block in blocks] a_axis = [map(float, axis.split()) for axis in a_axis] b_axis = [map(float, axis.split()) for axis in b_axis] c_axis = [map(float, axis.split()) for axis in c_axis] xds_beam = [float(e) for e in xds_beam] xds_axis = [float(e) for e in xds_axis] except ValueError: print msg return # coordinate frame conversions from scitbx import matrix dbeam = matrix.col(experiment.beam.get_direction()) daxis = matrix.col(experiment.goniometer.get_rotation_axis()) xbeam = matrix.col(xds_beam).normalize() xaxis = matrix.col(xds_axis).normalize() # want to align XDS -s0 vector... from rstbx.cftbx.coordinate_frame_helpers import align_reference_frame R = align_reference_frame(- xbeam, dbeam, xaxis, daxis) # Make a static crystal for each block from dxtbx.model.crystal import crystal_model crystals = [] sg = experiment.crystal.get_space_group() for a, b, c in zip(a_axis, b_axis, c_axis): a = R * matrix.col(a) b = R * matrix.col(b) c = R * matrix.col(c) crystals.append(crystal_model(a, b, c, space_group=sg)) # construct a list of scan points A_list = [] for block, crystal in zip(blocks, crystals): A = crystal.get_A() for im in range(block[0], block[1] + 1): A_list.append(A) # Need a final scan point at the end of the final image A_list.append(A) # set the scan-varying crystal experiment.crystal.set_A_at_scan_points(A_list) return
def test_refinement(): '''Test a refinement run''' dials_regression = libtbx.env.find_in_repositories( relative_path="dials_regression", test=os.path.isdir) # Get a beam and detector from a datablock. This one has a CS-PAD, but that # is irrelevant data_dir = os.path.join(dials_regression, "refinement_test_data", "hierarchy_test") datablock_path = os.path.join(data_dir, "datablock.json") assert os.path.exists(datablock_path) # load models from dxtbx.datablock import DataBlockFactory datablock = DataBlockFactory.from_serialized_format(datablock_path, check_format=False) im_set = datablock[0].extract_imagesets()[0] from copy import deepcopy detector = deepcopy(im_set.get_detector()) beam = im_set.get_beam() # Invent a crystal, goniometer and scan for this test from dxtbx.model.crystal import crystal_model crystal = crystal_model((40.,0.,0.) ,(0.,40.,0.), (0.,0.,40.), space_group_symbol = "P1") orig_xl = deepcopy(crystal) from dxtbx.model.experiment import goniometer_factory goniometer = goniometer_factory.known_axis((1., 0., 0.)) # Build a mock scan for a 180 degree sweep from dxtbx.model.scan import scan_factory sf = scan_factory() scan = sf.make_scan(image_range = (1,1800), exposure_times = 0.1, oscillation = (0, 0.1), epochs = range(1800), deg = True) sweep_range = scan.get_oscillation_range(deg=False) im_width = scan.get_oscillation(deg=False)[1] assert sweep_range == (0., pi) assert approx_equal(im_width, 0.1 * pi / 180.) from dxtbx.model.experiment.experiment_list import ExperimentList, Experiment # Build an experiment list experiments = ExperimentList() experiments.append(Experiment( beam=beam, detector=detector, goniometer=goniometer, scan=scan, crystal=crystal, imageset=None)) # simulate some reflections refs, _ = generate_reflections(experiments) # change unit cell a bit (=0.1 Angstrom length upsets, 0.1 degree of # alpha and beta angles) from dials.algorithms.refinement.parameterisation.crystal_parameters import \ CrystalUnitCellParameterisation xluc_param = CrystalUnitCellParameterisation(crystal) xluc_p_vals = xluc_param.get_param_vals() cell_params = crystal.get_unit_cell().parameters() cell_params = [a + b for a, b in zip(cell_params, [0.1, -0.1, 0.1, 0.1, -0.1, 0.0])] from cctbx.uctbx import unit_cell from rstbx.symmetry.constraints.parameter_reduction import \ symmetrize_reduce_enlarge from scitbx import matrix new_uc = unit_cell(cell_params) newB = matrix.sqr(new_uc.fractionalization_matrix()).transpose() S = symmetrize_reduce_enlarge(crystal.get_space_group()) S.set_orientation(orientation=newB) X = tuple([e * 1.e5 for e in S.forward_independent_parameters()]) xluc_param.set_param_vals(X) # reparameterise the crystal at the perturbed geometry xluc_param = CrystalUnitCellParameterisation(crystal) # Dummy parameterisations for other models beam_param = None xlo_param = None det_param = None # parameterisation of the prediction equation from dials.algorithms.refinement.parameterisation.parameter_report import \ ParameterReporter pred_param = TwoThetaPredictionParameterisation(experiments, det_param, beam_param, xlo_param, [xluc_param]) param_reporter = ParameterReporter(det_param, beam_param, xlo_param, [xluc_param]) # reflection manager refman = TwoThetaReflectionManager(refs, experiments, nref_per_degree=20, verbosity=2) # reflection predictor ref_predictor = TwoThetaExperimentsPredictor(experiments) # target function target = TwoThetaTarget(experiments, ref_predictor, refman, pred_param) # minimisation engine from dials.algorithms.refinement.engine \ import LevenbergMarquardtIterations as Refinery refinery = Refinery(target = target, prediction_parameterisation = pred_param, log = None, verbosity = 0, track_step = False, track_gradient = False, track_parameter_correlation = False, max_iterations = 20) # Refiner from dials.algorithms.refinement.refiner import Refiner refiner = Refiner(reflections=refs, experiments=experiments, pred_param=pred_param, param_reporter=param_reporter, refman=refman, target=target, refinery=refinery, verbosity=1) history = refiner.run() # compare crystal with original crystal refined_xl = refiner.get_experiments()[0].crystal #print refined_xl assert refined_xl.is_similar_to(orig_xl, uc_rel_length_tolerance=0.001, uc_abs_angle_tolerance=0.01) #print "Unit cell esds:" #print refined_xl.get_cell_parameter_sd() return
def dump(experiments, directory): ''' Dump the experiments in mosflm format :param experiments: The experiments to dump :param directory: The directory to write to ''' for i, experiment in enumerate(experiments): suffix = "" if len(experiments) > 1: suffix = "_%i" % (i + 1) sub_dir = "%s%s" % (directory, suffix) if not os.path.isdir(sub_dir): os.makedirs(sub_dir) detector = experiment.detector beam = experiment.beam scan = experiment.scan goniometer = experiment.goniometer # XXX imageset is getting the experimental geometry from the image files # rather than the input experiments.json file imageset = experiment.imageset from rstbx.cftbx.coordinate_frame_helpers import align_reference_frame R_to_mosflm = align_reference_frame(beam.get_s0(), (1.0, 0.0, 0.0), goniometer.get_rotation_axis(), (0.0, 0.0, 1.0)) #print R_to_mosflm cryst = experiment.crystal cryst = cryst.change_basis( cryst.get_space_group().info()\ .change_of_basis_op_to_reference_setting()) A = cryst.get_A() A_inv = A.inverse() real_space_a = R_to_mosflm * A_inv.elems[:3] real_space_b = R_to_mosflm * A_inv.elems[3:6] real_space_c = R_to_mosflm * A_inv.elems[6:9] cryst_mosflm = crystal_model(real_space_a, real_space_b, real_space_c, space_group=cryst.get_space_group(), mosaicity=cryst.get_mosaicity()) A_mosflm = cryst_mosflm.get_A() U_mosflm = cryst_mosflm.get_U() assert U_mosflm.is_r3_rotation_matrix(), U_mosflm w = beam.get_wavelength() index_mat = os.path.join(sub_dir, "index.mat") mosflm_in = os.path.join(sub_dir, "mosflm.in") print "Exporting experiment to %s and %s" % (index_mat, mosflm_in) with open(index_mat, "wb") as f: print >> f, format_mosflm_mat(w * A_mosflm, U_mosflm, cryst.get_unit_cell()) directory, template = os.path.split(imageset.get_template()) symmetry = cryst_mosflm.get_space_group().type().number() beam_centre = tuple( reversed(detector[0].get_beam_centre(beam.get_s0()))) distance = detector[0].get_directed_distance() with open(mosflm_in, "wb") as f: print >> f, write_mosflm_input(directory=directory, template=template, symmetry=symmetry, beam_centre=beam_centre, distance=distance, mat_file="index.mat") return
def run(space_group_info): datablock_json = os.path.join( dials_regression, "indexing_test_data", "i04_weak_data", "datablock_orig.json") datablock = load.datablock(datablock_json, check_format=False)[0] sweep = datablock.extract_imagesets()[0] sweep._indices = sweep._indices[:20] sweep.set_scan(sweep.get_scan()[:20]) import random space_group = space_group_info.group() unit_cell = space_group_info.any_compatible_unit_cell(volume=random.uniform(1e4,1e6)) crystal_symmetry = crystal.symmetry(unit_cell=unit_cell, space_group=space_group) crystal_symmetry.show_summary() # the reciprocal matrix B = matrix.sqr(unit_cell.fractionalization_matrix()).transpose() U = random_rotation() A = U * B direct_matrix = A.inverse() cryst_model = crystal_model(direct_matrix[0:3], direct_matrix[3:6], direct_matrix[6:9], space_group=space_group) experiment = Experiment(imageset=sweep, beam=sweep.get_beam(), detector=sweep.get_detector(), goniometer=sweep.get_goniometer(), scan=sweep.get_scan(), crystal=cryst_model) predicted_reflections = flex.reflection_table.from_predictions( experiment) use_fraction = 0.3 use_sel = flex.random_selection( len(predicted_reflections), int(use_fraction*len(predicted_reflections))) predicted_reflections = predicted_reflections.select(use_sel) miller_indices = predicted_reflections['miller_index'] miller_set = miller.set( crystal_symmetry, miller_indices, anomalous_flag=True) predicted_reflections['xyzobs.mm.value'] = predicted_reflections['xyzcal.mm'] predicted_reflections['id'] = flex.int(len(predicted_reflections), 0) from dials.algorithms.indexing.indexer import indexer_base indexer_base.map_centroids_to_reciprocal_space( predicted_reflections, sweep.get_detector(), sweep.get_beam(), sweep.get_goniometer()) # check that local and global indexing worked equally well in absence of errors result = compare_global_local(experiment, predicted_reflections, miller_indices) assert result.misindexed_local == 0 assert result.misindexed_global == 0 a, b, c = cryst_model.get_real_space_vectors() relative_error = 0.02 a *= (1+relative_error) b *= (1+relative_error) c *= (1+relative_error) cryst_model2 = crystal_model(a, b, c, space_group=space_group) experiment.crystal = cryst_model2 result = compare_global_local(experiment, predicted_reflections, miller_indices) # check that the local indexing did a better job given the errors in the basis vectors #assert result.misindexed_local < result.misindexed_global assert result.misindexed_local == 0 assert result.correct_local > result.correct_global # usually the number misindexed is much smaller than this assert result.misindexed_local < (0.001 * len(result.reflections_local)) # the reciprocal matrix A = cryst_model.get_A() A = random_rotation(angle_max=0.03) * A direct_matrix = A.inverse() cryst_model2 = crystal_model(direct_matrix[0:3], direct_matrix[3:6], direct_matrix[6:9], space_group=space_group) experiment.crystal = cryst_model2 result = compare_global_local(experiment, predicted_reflections, miller_indices) # check that the local indexing did a better job given the errors in the basis vectors assert result.misindexed_local <= result.misindexed_global, ( result.misindexed_local, result.misindexed_global) assert result.misindexed_local < 0.01 * result.correct_local assert result.correct_local > result.correct_global # usually the number misindexed is much smaller than this assert result.misindexed_local < (0.001 * len(result.reflections_local))