def get_lattice(self, name): """Get the lattice for a named spacegroup.""" # check that this isn't already a lattice name if name in [ "aP", "mP", "mC", "oP", "oC", "oI", "oF", "tP", "tI", "hR", "hP", "cP", "cI", "cF", ]: return name from cctbx.sgtbx.bravais_types import bravais_lattice if isinstance(name, int): lattice = bravais_lattice(number=name) elif self._int_re.match(name): name = int(name) lattice = bravais_lattice(number=name) else: lattice = bravais_lattice(symbol=str(name)) return str(lattice)
def _setup_target_unit_cell_and_space_group(self, target_unit_cell, target_space_group): target_bravais_t = bravais_lattice( group=target_space_group.info().reference_setting().group()) best_subgroup = None best_angular_difference = 1e8 space_groups = [target_space_group] if target_space_group.conventional_centring_type_symbol() != "P": space_groups.append(sgtbx.space_group()) for target in space_groups: cs = crystal.symmetry( unit_cell=target_unit_cell, space_group=target, assert_is_compatible_unit_cell=False, ) target_best_cell = cs.best_cell().unit_cell() subgroups = lattice_symmetry.metric_subgroups(cs, max_delta=0.1) for subgroup in subgroups.result_groups: bravais_t = bravais_lattice( group=subgroup["ref_subsym"].space_group()) if bravais_t == target_bravais_t: # allow for the cell to be given as best cell, reference setting # primitive settings, or minimum cell best_subsym = subgroup["best_subsym"] ref_subsym = best_subsym.as_reference_setting() if not (best_subsym.unit_cell().is_similar_to( target_unit_cell) or ref_subsym.unit_cell( ).is_similar_to(target_unit_cell) or ref_subsym.primitive_setting().unit_cell( ).is_similar_to(target_unit_cell) or best_subsym.primitive_setting().unit_cell( ).is_similar_to(target_unit_cell) or best_subsym.minimum_cell().unit_cell( ).is_similar_to(target_unit_cell.minimum_cell()) or best_subsym.unit_cell().is_similar_to( target_best_cell)): continue if subgroup[ "max_angular_difference"] < best_angular_difference: best_subgroup = subgroup best_angular_difference = subgroup[ "max_angular_difference"] if best_subgroup is None: raise DialsIndexError("Unit cell incompatible with space group") cb_op_inp_best = best_subgroup["cb_op_inp_best"] best_subsym = best_subgroup["best_subsym"] cb_op_best_ref = best_subsym.change_of_basis_op_to_reference_setting() self.cb_op_inp_ref = cb_op_best_ref * cb_op_inp_best self.target_symmetry_reference_setting = crystal.symmetry( unit_cell=target_unit_cell.change_basis(self.cb_op_inp_ref), space_group=target_space_group.info().as_reference_setting().group( ), )
def apply_symmetry(self, crystal_model): if not (self.target_symmetry_primitive and self.target_symmetry_primitive.space_group()): return crystal, sgtbx.change_of_basis_op() target_space_group = self.target_symmetry_primitive.space_group() A = crystal_model.get_A() max_delta = self._max_delta items = iotbx_converter(crystal_model.get_unit_cell(), max_delta=max_delta) target_sg_ref = target_space_group.info().reference_setting().group() best_angular_difference = 1e8 best_subgroup = None for item in items: if bravais_lattice(group=target_sg_ref) != bravais_lattice( group=item["ref_subsym"].space_group()): continue if item["max_angular_difference"] < best_angular_difference: best_angular_difference = item["max_angular_difference"] best_subgroup = item if best_subgroup is None: return None, None cb_op_inp_best = best_subgroup["cb_op_inp_best"] orient = crystal_orientation(A, True) orient_best = orient.change_basis( scitbx.matrix.sqr( cb_op_inp_best.c().as_double_array()[0:9]).transpose()) constrain_orient = orient_best.constrain(best_subgroup["system"]) best_subsym = best_subgroup["best_subsym"] cb_op_best_ref = best_subsym.change_of_basis_op_to_reference_setting() target_sg_best = target_sg_ref.change_basis(cb_op_best_ref.inverse()) ref_subsym = best_subsym.change_basis(cb_op_best_ref) cb_op_ref_primitive = ref_subsym.change_of_basis_op_to_primitive_setting( ) cb_op_best_primitive = cb_op_ref_primitive * cb_op_best_ref cb_op_inp_primitive = cb_op_ref_primitive * cb_op_best_ref * cb_op_inp_best direct_matrix = constrain_orient.direct_matrix() a = scitbx.matrix.col(direct_matrix[:3]) b = scitbx.matrix.col(direct_matrix[3:6]) c = scitbx.matrix.col(direct_matrix[6:9]) model = Crystal(a, b, c, space_group=target_sg_best) assert target_sg_best.is_compatible_unit_cell(model.get_unit_cell()) model = model.change_basis(cb_op_best_primitive) return model, cb_op_inp_primitive
def _map_space_group_to_input_cell(intensities, space_group): from cctbx.sgtbx.bravais_types import bravais_lattice best_subgroup = find_matching_symmetry( intensities.unit_cell(), space_group, best_monoclinic_beta=str( bravais_lattice(group=space_group)) == "mI", ) cb_op_inp_best = best_subgroup["cb_op_inp_best"] best_subsym = best_subgroup["best_subsym"] cb_op_best_primitive = ( best_subsym.change_of_basis_op_to_primitive_setting()) sg_cb_op_inp_primitive = (space_group.info( ).change_of_basis_op_to_primitive_setting()) sg_primitive = space_group.change_basis(sg_cb_op_inp_primitive) sg_best = sg_primitive.change_basis( cb_op_best_primitive.inverse()) # best_subgroup above is the bravais type, so create thin copy here with the # user-input space group instead best_subsym = best_subsym.customized_copy( space_group_info=sg_best.info()) best_subgroup = { "subsym": best_subsym.change_basis(cb_op_inp_best.inverse()), "best_subsym": best_subsym, "cb_op_inp_best": cb_op_inp_best, } intensities = intensities.customized_copy( space_group_info=sg_best.change_basis( cb_op_inp_best.inverse()).info()) return intensities, best_subgroup
def __init__(self,unit_cell,max_delta,bravais_types_only=True, space_group_symbol="P 1",force_minimum=False,best_monoclinic_beta=True, interest_focus="metric_symmetry",sort=True): # with regard to "force_minimum": when autoindexing, the orientation # matrix may be derived from comparison to a previously indexed case; # the setting may be non-standard; therefore we do not want to # convert to the reduced cell when calculating metric subgroups. if interest_focus=="metric_symmetry": input_symmetry = crystal.symmetry(unit_cell=unit_cell, space_group_symbol=space_group_symbol) elif interest_focus=="input_symmetry": input_symmetry = crystal.symmetry(unit_cell=unit_cell, space_group_symbol=space_group_symbol, force_compatible_unit_cell=False) metric_subgroups.__init__(self,input_symmetry,max_delta, enforce_max_delta_for_generated_two_folds=True, bravais_types_only=bravais_types_only, force_minimum=force_minimum, best_monoclinic_beta=best_monoclinic_beta, interest_focus=interest_focus) for subgroup in self.result_groups: # required keys for subgroup: # max_angular_difference # subsym: the centrosymmetric group, referred to the input_cell basis # cb_op_inp_best: change of basis from the input cell to the best reference cell # derived keys added in other frames: # orient: the orientation matrix, in the reference setting # methods: # to_reference_setting_as_double_array_transpose (formerly 'matrix') # number: the group number of subsym # other attributes: # reduced_group: the acentric group, expressed in input_cell basis # supersym: acentric metric supergroup, input_cell basis group_classification = bravais_lattice(sgtbx.space_group_info( group=subgroup['supersym'].space_group()).type().number()) subgroup['bravais'] = str(group_classification) subgroup['system'] = group_classification.crystal_system.lower() # ad-hoc fix to support the s_minimizer; remove this when # Orientation.constrain() is re-implemented. if subgroup['bravais']=="hR" and subgroup['system']=="trigonal": subgroup['system']="rhombohedral" if subgroup['bravais']=="hP" and subgroup['system']=="trigonal": subgroup['system']="hexagonal" #end of ad-hoc section subgroup['best_group']=subgroup['best_subsym'].space_group() #special procedure to get non-centrosymmetric group subgroup['reduced_group']=\ subgroup['subsym'].space_group().build_derived_acentric_group() subgroup['constraints']=echelon_constraints(subgroup['reduced_group']) self.append(MetricSubgroup().import_iotbx_style(subgroup)) if (sort): self.sort(bestcmp)
def get_observations(set, file_names, params): from libtbx import easy_pickle print "Number of pickle files found:", len(file_names) print returned = 0 from cctbx.sgtbx.bravais_types import bravais_lattice ref_bravais_type = bravais_lattice(set.space_group_info().type().number()) for name in file_names: if name == "stats.pickle": continue full_path = file_name = op.abspath(name) obj = easy_pickle.load(file_name=full_path) if not obj.has_key("observations"): continue unit_cell = obj["observations"][0].unit_cell() result_array = obj["observations"][0] # unit_cell, img_miller_indices = obj print file_name, unit_cell, obj["observations"][0].space_group_info() if not bravais_lattice(obj["observations"][0].space_group_info().type().number()) == ref_bravais_type: print "Skipping cell in different Bravais type" continue if not unit_cell.is_similar_to( other=set.unit_cell(), relative_length_tolerance=0.1, absolute_angle_tolerance=2 ): print "Skipping cell with outlier dimensions" continue obj["observations"][0].show_summary() # Now do manipulate the data to conform to unit cell, asu, and space group of reference # Only works if there is NOT an indexing ambiguity! ref_setting_obs = ( obj["observations"][0] .customized_copy(crystal_symmetry=set.crystal_symmetry()) .resolution_filter(d_min=params.d_min) .map_to_asu() ) returned += 1 yield ref_setting_obs, name print "Only %d of %d obs arrays had the correct cell" % (returned, len(file_names))
def change_of_basis_op_to_best_cell(self, ref_subsym): #plain algorithm for routine work. Triclinic input symmetry is already # in the minimum (reduced) form. Determine the best cell for conventional # monoclinic and orthorhombic crystal systems. subgroup_cb_op_best_cell = ref_subsym.change_of_basis_op_to_best_cell( best_monoclinic_beta=self.best_monoclinic_beta) #fancy algorithm for reindexing work. Triclinic symmetry is aligned # with a reference orientation, but is not necessarily in reduced # form. Guarantee that the best cell # conforms to the one that has already been determined for a reference # dataset collected on the same cystal. This option is only # executed if the reference information is present in a pickled file. if self.reference_subgroups != None: #subsequent code only for reindexing cases import inspect #admittedly this is a private interface. Rely on having this method always # called by derive_result_group_*. Otherwise this breaks. #do not save any frame references, thus avoiding reference circles: current_supersym = inspect.currentframe( ).f_back.f_locals['supersym'] current_bravais = str( bravais_types.bravais_lattice( sgtbx.space_group_info( group=current_supersym.space_group()).type().number())) current_cb_op_minimum_ref = inspect.currentframe( ).f_back.f_locals['cb_op_minimum_ref'] guess1_cb_op_inp_best = subgroup_cb_op_best_cell * current_cb_op_minimum_ref *\ self.cb_op_inp_minimum #assume this frame is called in a very specific way such that four frames # back gives the lepage module, class character. It's the only way to # pull out the current triclinic orientation. guess1_orient = self.current_orientation.change_basis( matrix.sqr(guess1_cb_op_inp_best.c().as_double_array() [0:9]).transpose().elems) for j, refitem in enumerate(self.reference_subgroups): if current_bravais != refitem['bravais']: continue # first guess. test plain algorithm best cell for match to refitem dmsd = guess1_orient.direct_mean_square_difference( refitem['orient']) if dmsd < self.reasonable_cutoff: break #second guess. use the cb_op_best_cell from the reference indexing solution guess2_cb_op_inp_best = refitem['cb_op_best_cell'] * current_cb_op_minimum_ref *\ self.cb_op_inp_minimum guess2_orient = self.current_orientation.change_basis( matrix.sqr(guess2_cb_op_inp_best.c().as_double_array() [0:9]).transpose().elems) dmsd = guess2_orient.direct_mean_square_difference( refitem['orient']) if dmsd < self.reasonable_cutoff: subgroup_cb_op_best_cell = refitem['cb_op_best_cell'] break self.cb_op_best_cell_vector.append(subgroup_cb_op_best_cell) return subgroup_cb_op_best_cell
def get_indexer_lattice(self): """Get the selected lattice as tP form.""" self.index() from cctbx.sgtbx import bravais_types crystal_model = self._indxr_experiment_list[0].crystal return str(bravais_types.bravais_lattice(group=crystal_model.get_space_group()))
def get_indexer_lattice(self): '''Get the selected lattice as tP form.''' self.index() from cctbx.sgtbx import bravais_types crystal_model = self._indxr_experiment_list[0].crystal return str( bravais_types.bravais_lattice(group=crystal_model.get_space_group()))
def spacegroup_to_lattice(input_spacegroup): """This generates a lattice from the imported file but chopping off the first letter of the cell type, changing to lowercase and then prepending it to the first letter of the spacegroup.""" return str( bravais_lattice( group=sgtbx.space_group_info(input_spacegroup).group()))
def bravais_lattice_to_space_groups(chiral_only=True): bravais_lattice_to_sg = collections.defaultdict(list) for sgn in range(230): sg = sgtbx.space_group_info(number=sgn + 1).group() if (not chiral_only) or (sg.is_chiral()): bravais_lattice = bravais_types.bravais_lattice(group=sg) bravais_lattice_to_sg[str(bravais_lattice)].append(sg) bravais_lattice_to_sg["mI"] = [sgtbx.space_group_info("I2").group()] return bravais_lattice_to_sg
def bravais_lattice_to_space_groups(chiral_only=True): bravais_lattice_to_sg = collections.OrderedDict() for sgn in range(230): sg = sgtbx.space_group_info(number=sgn + 1).group() if (not chiral_only) or (sg.is_chiral()): bravais_lattice = bravais_types.bravais_lattice(group=sg) bravais_lattice_to_sg.setdefault(str(bravais_lattice), []) bravais_lattice_to_sg[str(bravais_lattice)].append(sg) return bravais_lattice_to_sg
def get_observations(set, file_names, params): from libtbx import easy_pickle print "Number of pickle files found:", len(file_names) print returned = 0 from cctbx.sgtbx.bravais_types import bravais_lattice ref_bravais_type = bravais_lattice(set.space_group_info().type().number()) for name in file_names: if name == "stats.pickle": continue full_path = file_name = op.abspath(name) obj = easy_pickle.load(file_name=full_path) if "observations" not in obj: continue unit_cell = obj["observations"][0].unit_cell() result_array = obj["observations"][0] #unit_cell, img_miller_indices = obj print file_name, unit_cell, obj["observations"][0].space_group_info() if not bravais_lattice(obj["observations"][0].space_group_info().type( ).number()) == ref_bravais_type: print "Skipping cell in different Bravais type" continue if not unit_cell.is_similar_to(other=set.unit_cell(), relative_length_tolerance=0.1, absolute_angle_tolerance=2): print "Skipping cell with outlier dimensions" continue obj["observations"][0].show_summary() # Now do manipulate the data to conform to unit cell, asu, and space group of reference # Only works if there is NOT an indexing ambiguity! ref_setting_obs = obj["observations"][0].customized_copy( crystal_symmetry=set.crystal_symmetry()).resolution_filter( d_min=params.d_min).map_to_asu() returned += 1 yield ref_setting_obs, name print "Only %d of %d obs arrays had the correct cell" % (returned, len(file_names))
def get_lattice(self, name): '''Get the lattice for a named spacegroup.''' # check that this isn't already a lattice name if name in ['aP', 'mP', 'mC', 'oP', 'oC', 'oI', 'oF', 'tP', 'tI', 'hR', 'hP', 'cP', 'cI', 'cF']: return name from cctbx.sgtbx.bravais_types import bravais_lattice if isinstance(name, int): lattice = bravais_lattice(number=name) elif self._int_re.match(name): name = int(name) lattice = bravais_lattice(number=name) else: lattice = bravais_lattice(symbol=str(name)) return str(lattice)
def change_of_basis_ops_to_minimum_cell( experiments, max_delta, relative_length_tolerance, absolute_angle_tolerance ): """ Compute change of basis ops to map experiments to the minimum cell Map to the minimum cell via the best cell, which appears to guarantee that the resulting minimum cells are consistent. Args: experiments (ExperimentList): a list of experiments. reflections (list): a list of reflection tables Returns: The experiments and reflections mapped to the minimum cell """ median_cell = median_unit_cell(experiments) unit_cells_are_similar = unit_cells_are_similar_to( experiments, median_cell, relative_length_tolerance, absolute_angle_tolerance ) centring_symbols = [ bravais_lattice(group=expt.crystal.get_space_group()).centring_symbol for expt in experiments ] if unit_cells_are_similar and len(set(centring_symbols)) == 1: groups = metric_subgroups( experiments[0] .crystal.get_crystal_symmetry() .customized_copy(unit_cell=median_cell), max_delta, enforce_max_delta_for_generated_two_folds=True, ) group = groups.result_groups[0] cb_op_best_to_min = group["best_subsym"].change_of_basis_op_to_minimum_cell() cb_ops = [cb_op_best_to_min * group["cb_op_inp_best"]] * len(experiments) else: cb_ops = [] for expt in experiments: groups = metric_subgroups( expt.crystal.get_crystal_symmetry(), max_delta, best_monoclinic_beta=False, enforce_max_delta_for_generated_two_folds=True, ) group = groups.result_groups[0] cb_ops.append(group["cb_op_inp_best"]) ref_expts = experiments.change_basis(cb_ops) cb_op_ref_min = ( ref_expts[0] .crystal.get_crystal_symmetry() .customized_copy(unit_cell=median_unit_cell(ref_expts)) .change_of_basis_op_to_minimum_cell() ) cb_ops = [cb_op_ref_min * cb_op for cb_op in cb_ops] return cb_ops
def get_lattice(self, name): '''Get the lattice for a named spacegroup.''' # check that this isn't already a lattice name if name in [ 'aP', 'mP', 'mC', 'oP', 'oC', 'oI', 'oF', 'tP', 'tI', 'hR', 'hP', 'cP', 'cI', 'cF' ]: return name from cctbx.sgtbx.bravais_types import bravais_lattice if isinstance(name, int): lattice = bravais_lattice(number=name) elif self._int_re.match(name): name = int(name) lattice = bravais_lattice(number=name) else: lattice = bravais_lattice(symbol=str(name)) return str(lattice)
def bravais_lattice_to_space_groups(chiral_only=True): from cctbx import sgtbx from cctbx.sgtbx import bravais_types from libtbx.containers import OrderedDict bravais_lattice_to_sg = OrderedDict() for sgn in range(230): sg = sgtbx.space_group_info(number=sgn+1).group() if (not chiral_only) or (sg.is_chiral()): bravais_lattice = bravais_types.bravais_lattice(group=sg) bravais_lattice_to_sg.setdefault(str(bravais_lattice), []) bravais_lattice_to_sg[str(bravais_lattice)].append(sg) return bravais_lattice_to_sg
def change_of_basis_op_to_best_cell(self,ref_subsym): #plain algorithm for routine work. Triclinic input symmetry is already # in the minimum (reduced) form. Determine the best cell for conventional # monoclinic and orthorhombic crystal systems. subgroup_cb_op_best_cell = ref_subsym.change_of_basis_op_to_best_cell( best_monoclinic_beta=self.best_monoclinic_beta) #fancy algorithm for reindexing work. Triclinic symmetry is aligned # with a reference orientation, but is not necessarily in reduced # form. Guarantee that the best cell # conforms to the one that has already been determined for a reference # dataset collected on the same cystal. This option is only # executed if the reference information is present in a pickled file. if self.reference_subgroups != None: #subsequent code only for reindexing cases import inspect #admittedly this is a private interface. Rely on having this method always # called by derive_result_group_*. Otherwise this breaks. #do not save any frame references, thus avoiding reference circles: current_supersym = inspect.currentframe().f_back.f_locals['supersym'] current_bravais = str(bravais_types.bravais_lattice(sgtbx.space_group_info( group=current_supersym.space_group()).type().number())) current_cb_op_minimum_ref = inspect.currentframe().f_back.f_locals['cb_op_minimum_ref'] guess1_cb_op_inp_best = subgroup_cb_op_best_cell * current_cb_op_minimum_ref *\ self.cb_op_inp_minimum #assume this frame is called in a very specific way such that four frames # back gives the lepage module, class character. It's the only way to # pull out the current triclinic orientation. guess1_orient = self.current_orientation.change_basis(matrix.sqr( guess1_cb_op_inp_best.c().as_double_array()[0:9]).transpose().elems) for j,refitem in enumerate(self.reference_subgroups): if current_bravais != refitem['bravais']: continue # first guess. test plain algorithm best cell for match to refitem dmsd = guess1_orient.direct_mean_square_difference(refitem['orient']) if dmsd < self.reasonable_cutoff: break #second guess. use the cb_op_best_cell from the reference indexing solution guess2_cb_op_inp_best = refitem['cb_op_best_cell'] * current_cb_op_minimum_ref *\ self.cb_op_inp_minimum guess2_orient = self.current_orientation.change_basis(matrix.sqr( guess2_cb_op_inp_best.c().as_double_array()[0:9]).transpose().elems) dmsd = guess2_orient.direct_mean_square_difference(refitem['orient']) if dmsd < self.reasonable_cutoff: subgroup_cb_op_best_cell = refitem['cb_op_best_cell'] break self.cb_op_best_cell_vector.append(subgroup_cb_op_best_cell) return subgroup_cb_op_best_cell
def show_indexer_solutions(self): lines = ["All possible indexing solutions:"] for l in self._indxr_helper.repr(): lines.append(l) crystal_model = self._indxr_experiment_list[0].crystal lattice = str( bravais_types.bravais_lattice( group=crystal_model.get_space_group())) lines.append("Indexing solution:") lines.append("%s %s" % ( lattice, "%6.2f %6.2f %6.2f %6.2f %6.2f %6.2f" % crystal_model.get_unit_cell().parameters(), )) return "\n".join(lines)
def show_indexer_solutions(self): lines = [] lines.append('All possible indexing solutions:') for l in self._indxr_helper.repr(): lines.append(l) from cctbx.sgtbx import bravais_types crystal_model = self._indxr_experiment_list[0].crystal lattice = str( bravais_types.bravais_lattice(group=crystal_model.get_space_group())) lines.append('Indexing solution:') lines.append('%s %s' % ( lattice, '%6.2f %6.2f %6.2f %6.2f %6.2f %6.2f' % \ crystal_model.get_unit_cell().parameters())) return '\n'.join(lines)
print "Best cell -> niggli cell" cs.best_cell().niggli_cell().show_summary() print "Reference setting -> minimum cell" cs.as_reference_setting().minimum_cell().show_summary() print "Reference setting -> niggli cell" cs.as_reference_setting().niggli_cell().show_summary() print print "Reference settings (via minimum/niggli cell):" print "Input -> minimum cell -> reference setting" cs.minimum_cell().as_reference_setting().show_summary() print "Input -> niggli cell -> reference setting" cs.niggli_cell().as_reference_setting().show_summary() print "Best cell -> minimum cell -> reference setting" cs.best_cell().minimum_cell().as_reference_setting().show_summary() print "Best cell -> niggli cell -> reference setting" cs.best_cell().niggli_cell().as_reference_setting().show_summary() print "Reference setting -> minimum cell -> reference setting" cs.as_reference_setting().minimum_cell().as_reference_setting().show_summary() print "Reference setting -> niggli cell -> reference setting" cs.as_reference_setting().niggli_cell().as_reference_setting().show_summary() print subgroups = lattice_symmetry.metric_subgroups(cs, max_delta=0.1) for subgroup in subgroups.result_groups: bravais_t = bravais_lattice( group=subgroup['ref_subsym'].space_group()) if bravais_t == 'mC': print subgroup['ref_subsym'].unit_cell() print subgroup['best_subsym'].as_reference_setting().unit_cell()
def run(self): '''Run mosflm indexing''' assert len(self._images) > 0 self._images.sort() self.start() if self._reverse_phi: self.input('detector reversephi') assert self._template is not None and self._directory is not None self.input('template "%s"' % self._template) self.input('directory "%s"' % self._directory) self.input('newmat xiaindex.mat') if self._beam_centre is not None: self.input('beam %f %f' % tuple(self._beam_centre)) if self._wavelength is not None: self.input('wavelength %f' % self._wavelength) if self._distance is not None: self.input('distance %f' % abs(self._distance)) if self._unit_cell is not None: self.input('cell %f %f %f %f %f %f' % self._unit_cell) if self._space_group_number is not None: self.input('symmetry %d' % self._space_group_number) for i in self._images: if self._solution_number > 0: self.input( 'autoindex dps refine image %d thresh %d solu %d' % \ (i, self._threshold, self._solution_number)) else: self.input( 'autoindex dps refine image %d thresh %d' % \ (i, self._threshold)) for i in self._images: self.input('mosaic estimate %d' % i) self.input('go') self.close_wait() #sweep = self.get_indexer_sweep_name() #FileHandler.record_log_file( #'%s INDEX' % (sweep), self.get_log_file()) # check for errors self.check_for_errors() # ok now we're done, let's look through for some useful stuff output = self.get_all_output() self._solutions = _parse_mosflm_index_output(output) self._refined_cell = None self._refined_beam_centre = None self._lattice = None self._mosaic_spreads = [] self._refined_detector_distance = None for o in output: if 'Final cell (after refinement)' in o: self._refined_cell = tuple(map(float, o.split()[-6:])) if 'Beam coordinates of' in o: self._refined_beam_centre = tuple( map(float, o.split()[-2:])) # FIXED this may not be there if this is a repeat indexing! if 'Symmetry:' in o: self._lattice = o.split(':')[1].split()[0] # so we have to resort to this instead... if 'Refining solution #' in o: from cctbx.sgtbx.bravais_types import bravais_lattice self._indexed_space_group_number = int( o.split(')')[0].split()[-1]) self._lattice = str( bravais_lattice( number=self._indexed_space_group_number)) if 'The mosaicity has been estimated' in o: ms = float(o.split('>')[1].split()[0]) self._mosaic_spreads.append(ms) if 'The mosaicity estimation has not worked for some' in o: # this is a problem... in particular with the # mosflm built on linux in CCP4 6.0.1... # FIXME this should be a specific kind of # exception e.g. an IndexError raise IndexingError('mosaicity estimation failed') # mosflm doesn't refine this in autoindexing... if 'Crystal to detector distance of' in o: d = float(o.split()[5].replace('mm', '')) if self._distance is None or self._distance >= 0: self._refined_detector_distance = d else: self._refined_detector_distance = -d # but it does complain if it is different to the header # value - so just use the input value in this case... if 'Input crystal to detector distance' in o \ and 'does NOT agree with' in o: self._refined_detector_distance = self._distance if 'parameters have been set to' in o: self._raster = map(int, o.split()[-5:]) if '(currently SEPARATION' in o: self._separation = map(float, o.replace(')', '').split()[-2:]) # get the resolution estimate out... if '99% have resolution' in o: self._resolution_estimate = float(o.split()[-2])
def run(self): '''Run mosflm indexing''' assert len(self._images) > 0 self._images.sort() self.start() if self._reverse_phi: self.input('detector reversephi') assert self._template is not None and self._directory is not None self.input('template "%s"' %self._template) self.input('directory "%s"' %self._directory) self.input('newmat xiaindex.mat') if self._beam_centre is not None: self.input('beam %f %f' %tuple(self._beam_centre)) if self._wavelength is not None: self.input('wavelength %f' %self._wavelength) if self._distance is not None: self.input('distance %f' %self._distance) if self._unit_cell is not None: self.input('cell %f %f %f %f %f %f' %self._unit_cell) if self._space_group_number is not None: self.input('symmetry %d' %self._space_group_number) for i in self._images: if self._solution_number > 0: self.input( 'autoindex dps refine image %d thresh %d solu %d' % \ (i, self._threshold, self._solution_number)) else: self.input( 'autoindex dps refine image %d thresh %d' % \ (i, self._threshold)) for i in self._images: self.input('mosaic estimate %d' % i) self.input('go') self.close_wait() #sweep = self.get_indexer_sweep_name() #FileHandler.record_log_file( #'%s INDEX' % (sweep), self.get_log_file()) # check for errors self.check_for_errors() # ok now we're done, let's look through for some useful stuff output = self.get_all_output() self._solutions = _parse_mosflm_index_output(output) self._refined_cell = None self._refined_beam_centre = None self._lattice = None self._mosaic_spreads = [] self._refined_detector_distance = None for o in output: if 'Final cell (after refinement)' in o: self._refined_cell = tuple(map(float, o.split()[-6:])) if 'Beam coordinates of' in o: self._refined_beam_centre = tuple(map(float, o.split()[-2:])) # FIXED this may not be there if this is a repeat indexing! if 'Symmetry:' in o: self._lattice = o.split(':')[1].split()[0] # so we have to resort to this instead... if 'Refining solution #' in o: from cctbx.sgtbx.bravais_types import bravais_lattice self._indexed_space_group_number = int(o.split(')')[0].split()[-1]) self._lattice = str(bravais_lattice(number=self._indexed_space_group_number)) if 'The mosaicity has been estimated' in o: ms = float(o.split('>')[1].split()[0]) self._mosaic_spreads.append(ms) if 'The mosaicity estimation has not worked for some' in o: # this is a problem... in particular with the # mosflm built on linux in CCP4 6.0.1... # FIXME this should be a specific kind of # exception e.g. an IndexError # if microcrystal mode, just assume for the moment mosaic # spread is 0.5 degrees... raise IndexingError, 'mosaicity estimation failed' # mosflm doesn't refine this in autoindexing... if 'Crystal to detector distance of' in o: self._refined_detector_distance = float(o.split()[5].replace('mm', '')) # but it does complain if it is different to the header # value - so just use the input value in this case... if 'Input crystal to detector distance' in o \ and 'does NOT agree with' in o: self._refined_detector_distance = self._distance if 'parameters have been set to' in o: self._raster = map(int, o.split()[-5:]) if '(currently SEPARATION' in o: self._separation = map(float, o.replace(')', '').split()[-2:]) # get the resolution estimate out... if '99% have resolution' in o: self._resolution_estimate = float(o.split()[-2])
def change_of_basis_ops_to_minimum_cell(experiments, max_delta, relative_length_tolerance, absolute_angle_tolerance): """ Compute change of basis ops to map experiments to the minimum cell Map to the minimum cell via the best cell, which appears to guarantee that the resulting minimum cells are consistent. Args: experiments (ExperimentList): a list of experiments. reflections (list): a list of reflection tables Returns: The experiments and reflections mapped to the minimum cell """ median_cell = median_unit_cell(experiments) unit_cells_are_similar = unit_cells_are_similar_to( experiments, median_cell, relative_length_tolerance, absolute_angle_tolerance) centring_symbols = [ bravais_lattice(group=expt.crystal.get_space_group()).centring_symbol for expt in experiments ] if unit_cells_are_similar and len(set(centring_symbols)) == 1: groups = metric_subgroups( experiments[0].crystal.get_crystal_symmetry().customized_copy( unit_cell=median_cell), max_delta, enforce_max_delta_for_generated_two_folds=True, ) group = groups.result_groups[0] cb_op_best_to_min = group[ "best_subsym"].change_of_basis_op_to_minimum_cell() cb_ops = [cb_op_best_to_min * group["cb_op_inp_best"] ] * len(experiments) else: groups = [ metric_subgroups( expt.crystal.get_crystal_symmetry(), max_delta, best_monoclinic_beta=False, enforce_max_delta_for_generated_two_folds=True, ) for expt in experiments ] counter = collections.Counter( g.result_groups[0]["best_subsym"].space_group() for g in groups) target_group = counter.most_common()[0][0] cb_ops = [] for expt in experiments: groups = metric_subgroups( expt.crystal.get_crystal_symmetry(), max_delta, best_monoclinic_beta=False, enforce_max_delta_for_generated_two_folds=True, ) group = None for g in groups.result_groups: if g["best_subsym"].space_group() == target_group: group = g if group: cb_ops.append(group["cb_op_inp_best"]) else: cb_ops.append(None) logger.info(f"Couldn't match unit cell to target symmetry:\n" f"{expt.crystal.get_crystal_symmetry()}\n" f"{target_group}") ref_expts = ExperimentList([ expt for expt, cb_op in zip(experiments, cb_ops) if cb_op ]).change_basis(list(filter(None, cb_ops))) cb_op_ref_min = ( ref_expts[0].crystal.get_crystal_symmetry().customized_copy( unit_cell=median_unit_cell( ref_expts)).change_of_basis_op_to_minimum_cell()) cb_ops = [cb_op_ref_min * cb_op if cb_op else None for cb_op in cb_ops] return cb_ops
def refined_settings_factory_from_refined_triclinic(params, experiments, reflections, i_setting=None, lepage_max_delta=5.0, nproc=1, refiner_verbosity=0): assert len(experiments.crystals()) == 1 crystal = experiments.crystals()[0] used_reflections = copy.deepcopy(reflections) UC = crystal.get_unit_cell() from rstbx.dps_core.lepage import iotbx_converter Lfat = refined_settings_list() for item in iotbx_converter(UC, lepage_max_delta): Lfat.append(bravais_setting(item)) supergroup = Lfat.supergroup() triclinic = Lfat.triclinic() triclinic_miller = used_reflections['miller_index'] # assert no transformation between indexing and bravais list assert str(triclinic['cb_op_inp_best']) == "a,b,c" Nset = len(Lfat) for j in xrange(Nset): Lfat[j].setting_number = Nset - j from cctbx.crystal_orientation import crystal_orientation from cctbx import sgtbx from scitbx import matrix for j in xrange(Nset): cb_op = Lfat[j]['cb_op_inp_best'].c().as_double_array()[0:9] orient = crystal_orientation(crystal.get_A(), True) orient_best = orient.change_basis(matrix.sqr(cb_op).transpose()) constrain_orient = orient_best.constrain(Lfat[j]['system']) bravais = Lfat[j]["bravais"] cb_op_best_ref = Lfat[j][ 'best_subsym'].change_of_basis_op_to_reference_setting() space_group = sgtbx.space_group_info( number=bravais_lattice_to_lowest_symmetry_spacegroup_number[ bravais]).group() space_group = space_group.change_basis(cb_op_best_ref.inverse()) bravais = str(bravais_types.bravais_lattice(group=space_group)) Lfat[j]["bravais"] = bravais Lfat[j].unrefined_crystal = dials_crystal_from_orientation( constrain_orient, space_group) args = [] for subgroup in Lfat: args.append((params, subgroup, used_reflections, experiments, refiner_verbosity)) results = easy_mp.parallel_map(func=refine_subgroup, iterable=args, processes=nproc, method="multiprocessing", preserve_order=True, asynchronous=True, preserve_exception_message=True) for i, result in enumerate(results): Lfat[i] = result identify_likely_solutions(Lfat) return Lfat
def apply_symmetry(self, crystal_model): """Apply symmetry constraints to a crystal model. Returns the crystal model (with symmetry constraints applied) in the same setting as provided as input. The cb_op returned by the method is that necessary to transform that model to the user-provided target symmetry. Args: crystal_model (dxtbx.model.Crystal): The input crystal model to which to apply symmetry constraints. Returns: (dxtbx.model.Crystal, cctbx.sgtbx.change_of_basis_op): The crystal model with symmetry constraints applied, and the change_of_basis_op that transforms the returned model to the user-specified target symmetry. """ if not ( self.target_symmetry_primitive and self.target_symmetry_primitive.space_group() ): return crystal, sgtbx.change_of_basis_op() target_space_group = self.target_symmetry_primitive.space_group() A = crystal_model.get_A() max_delta = self._max_delta items = iotbx_converter(crystal_model.get_unit_cell(), max_delta=max_delta) target_sg_ref = target_space_group.info().reference_setting().group() best_angular_difference = 1e8 best_subgroup = None for item in items: if bravais_lattice(group=target_sg_ref) != item["bravais"]: continue if item["max_angular_difference"] < best_angular_difference: best_angular_difference = item["max_angular_difference"] best_subgroup = item if best_subgroup is None: return None, None cb_op_inp_best = best_subgroup["cb_op_inp_best"] best_subsym = best_subgroup["best_subsym"] ref_subsym = best_subgroup["ref_subsym"] cb_op_ref_best = ref_subsym.change_of_basis_op_to_best_cell() cb_op_best_ref = cb_op_ref_best.inverse() cb_op_inp_ref = cb_op_best_ref * cb_op_inp_best cb_op_ref_inp = cb_op_inp_ref.inverse() orient = crystal_orientation(A, True) orient_ref = orient.change_basis( scitbx.matrix.sqr((cb_op_inp_ref).c().as_double_array()[0:9]).transpose() ) constrain_orient = orient_ref.constrain(best_subgroup["system"]) direct_matrix = constrain_orient.direct_matrix() a = scitbx.matrix.col(direct_matrix[:3]) b = scitbx.matrix.col(direct_matrix[3:6]) c = scitbx.matrix.col(direct_matrix[6:9]) model = Crystal(a, b, c, space_group=target_sg_ref) assert target_sg_ref.is_compatible_unit_cell(model.get_unit_cell()) model = model.change_basis(cb_op_ref_inp) if self.cb_op_inp_best is not None: # Then the unit cell has been provided: this is the cb_op to map to the # user-provided input unit cell return model, self.cb_op_inp_best.inverse() * cb_op_inp_best if not self.cb_op_ref_inp.is_identity_op(): if self.target_symmetry_inp.space_group() == best_subsym.space_group(): # Handle where e.g. the user has requested I2 instead of the reference C2 return model, cb_op_inp_best # The user has specified a setting that is not the reference setting return model, self.cb_op_ref_inp * cb_op_inp_ref # Default to reference setting # This change of basis op will ensure that we get the best beta angle without # changing the centring (e.g. from C2 to I2) cb_op_ref_best = ref_subsym.change_of_basis_op_to_best_cell( best_monoclinic_beta=False ) return model, cb_op_ref_best * cb_op_inp_ref
def write(self, experiments, reflections): """ Write the experiments and reflections to file """ # if mmmcif filename is auto, then choose scaled.cif or integrated.cif if self.params.mmcif.hklout in (None, Auto, "auto"): if ("intensity.scale.value" in reflections) and ("intensity.scale.variance" in reflections): filename = "scaled.cif" logger.info( "Data appears to be scaled, setting mmcif.hklout = 'scaled_unmerged.cif'" ) else: filename = "integrated.cif" logger.info( "Data appears to be unscaled, setting mmcif.hklout = 'integrated.cif'" ) # Select reflections selection = reflections.get_flags(reflections.flags.integrated, all=True) reflections = reflections.select(selection) # Filter out bad variances and other issues, but don't filter on ice rings # or alter partialities. ### Assumes you want to apply the lp and dqe corrections to sum and prf ### Do we want to combine partials? reflections = filter_reflection_table( reflections, self.params.intensity, combine_partials=False, partiality_threshold=0.0, d_min=self.params.mtz.d_min, ) # Get the cif block cif_block = iotbx.cif.model.block() # Audit trail dials_version = dials.util.version.dials_version() cif_block["_audit.creation_method"] = dials_version cif_block["_audit.creation_date"] = datetime.date.today().isoformat() cif_block["_computing.data_reduction"] = ( "%s (Winter, G. et al., 2018)" % dials_version) cif_block[ "_publ.section_references"] = "Winter, G. et al. (2018) Acta Cryst. D74, 85-97." # Hard coding X-ray cif_block["_pdbx_diffrn_data_section.id"] = "dials" cif_block["_pdbx_diffrn_data_section.type_scattering"] = "x-ray" cif_block["_pdbx_diffrn_data_section.type_merged"] = "false" cif_block["_pdbx_diffrn_data_section.type_scaled"] = str( "scale" in self.params.intensity).lower() # FIXME Haven't put in any of these bits yet # # Facility/beamline proposal tracking details # # cif_block["_pdbx_diffrn_data_section_experiment.ordinal"] = 1 # cif_block["_pdbx_diffrn_data_section_experiment.data_section_id"] = "dials" # cif_block["_pdbx_diffrn_data_section_experiment.proposal_id"] = "<PROPOSAL ID> # Facility/beamline details for this data collection # # cif_block["_pdbx_diffrn_data_section_site.data_section_id"] = 'dials' # cif_block["_pdbx_diffrn_data_section_site.facility"] = "DIAMOND" # cif_block["_pdbx_diffrn_data_section_site.beamline"] = "VMX-M" # cif_block["_pdbx_diffrn_data_section_site.collection_date"] = scan.epochs()[0] # cif_block["_pdbx_diffrn_data_section_site.detector"] = detector[0].name() # cif_block["_pdbx_diffrn_data_section_site.detector_type"] = detector[0].type() # Write the crystal information cif_loop = iotbx.cif.model.loop(header=( "_pdbx_diffrn_unmerged_cell.ordinal", "_pdbx_diffrn_unmerged_cell.crystal_id", "_pdbx_diffrn_unmerged_cell.wavelength", "_pdbx_diffrn_unmerged_cell.cell_length_a", "_pdbx_diffrn_unmerged_cell.cell_length_b", "_pdbx_diffrn_unmerged_cell.cell_length_c", "_pdbx_diffrn_unmerged_cell.cell_angle_alpha", "_pdbx_diffrn_unmerged_cell.cell_angle_beta", "_pdbx_diffrn_unmerged_cell.cell_angle_gamma", "_pdbx_diffrn_unmerged_cell.Bravais_lattice", )) crystals = experiments.crystals() crystal_to_id = {crystal: i + 1 for i, crystal in enumerate(crystals)} for i, exp in enumerate(experiments): crystal = exp.crystal crystal_id = crystal_to_id[crystal] wavelength = exp.beam.get_wavelength() a, b, c, alpha, beta, gamma = crystal.get_unit_cell().parameters() latt_type = str( bravais_types.bravais_lattice(group=crystal.get_space_group())) cif_loop.add_row((i + 1, crystal_id, wavelength, a, b, c, alpha, beta, gamma, latt_type)) cif_block.add_loop(cif_loop) # Write the scan information cif_loop = iotbx.cif.model.loop(header=( "_pdbx_diffrn_scan.scan_id", "_pdbx_diffrn_scan.crystal_id", "_pdbx_diffrn_scan.image_id_begin", "_pdbx_diffrn_scan.image_id_end", "_pdbx_diffrn_scan.scan_angle_begin", "_pdbx_diffrn_scan.scan_angle_end", )) for i, exp in enumerate(experiments): scan = exp.scan crystal_id = crystal_to_id[exp.crystal] image_range = scan.get_image_range() osc_range = scan.get_oscillation_range(deg=True) cif_loop.add_row(( i + 1, crystal_id, image_range[0], image_range[1], osc_range[0], osc_range[1], )) cif_block.add_loop(cif_loop) # Make a dict of unit_cell parameters unit_cell_parameters = {} if crystal.num_scan_points > 1: for i in range(crystal.num_scan_points): a, b, c, alpha, beta, gamma = crystal.get_unit_cell_at_scan_point( i).parameters() unit_cell_parameters[i] = (a, b, c, alpha, beta, gamma) else: unit_cell_parameters[0] = (a, b, c, alpha, beta, gamma) ### _pdbx_diffrn_image_proc has been removed from the dictionary extension. ### Keeping this section commented out as it may be added back in some ### form in future # # Write the image data # scan = experiments[0].scan # z0 = scan.get_image_range()[0] # # cif_loop = iotbx.cif.model.loop( # header=("_pdbx_diffrn_image_proc.image_id", # "_pdbx_diffrn_image_proc.crystal_id", # "_pdbx_diffrn_image_proc.image_number", # "_pdbx_diffrn_image_proc.phi_value", # "_pdbx_diffrn_image_proc.wavelength", # "_pdbx_diffrn_image_proc.cell_length_a", # "_pdbx_diffrn_image_proc.cell_length_b", # "_pdbx_diffrn_image_proc.cell_length_c", # "_pdbx_diffrn_image_proc.cell_angle_alpha", # "_pdbx_diffrn_image_proc.cell_angle_beta", # "_pdbx_diffrn_image_proc.cell_angle_gamma")) # for i in range(len(scan)): # z = z0 + i # if crystal.num_scan_points > 1: # a, b, c, alpha, beta, gamma = unit_cell_parameters[i] # else: # a, b, c, alpha, beta, gamma = unit_cell_parameters[0] # # phi is the angle at the image centre # phi = scan.get_angle_from_image_index(z + 0.5, deg=True) # cif_loop.add_row((i+1, 1, z, phi, wavelength, # a, b, c, alpha, beta, gamma)) # cif_block.add_loop(cif_loop) # Write reflection data # Required columns header = ( "_pdbx_diffrn_unmerged_refln.reflection_id", "_pdbx_diffrn_unmerged_refln.scan_id", "_pdbx_diffrn_unmerged_refln.image_id_begin", "_pdbx_diffrn_unmerged_refln.image_id_end", "_pdbx_diffrn_unmerged_refln.index_h", "_pdbx_diffrn_unmerged_refln.index_k", "_pdbx_diffrn_unmerged_refln.index_l", ) headernames = { "scales": "_pdbx_diffrn_unmerged_refln.scale_value", "intensity.scale.value": "_pdbx_diffrn_unmerged_refln.intensity_meas", "intensity.scale.sigma": "_pdbx_diffrn_unmerged_refln.intensity_sigma", "intensity.sum.value": "_pdbx_diffrn_unmerged_refln.intensity_sum", "intensity.sum.sigma": "_pdbx_diffrn_unmerged_refln.intensity_sum_sigma", "intensity.prf.value": "_pdbx_diffrn_unmerged_refln.intensity_prf", "intensity.prf.sigma": "_pdbx_diffrn_unmerged_refln.intensity_prf_sigma", "angle": "_pdbx_diffrn_unmerged_refln.scan_angle_reflection", "partiality": "_pdbx_diffrn_unmerged_refln.partiality", } variables_present = [] if "scale" in self.params.intensity: reflections["scales"] = 1.0 / reflections["inverse_scale_factor"] reflections["intensity.scale.sigma"] = ( reflections["intensity.scale.variance"]**0.5) variables_present.extend( ["scales", "intensity.scale.value", "intensity.scale.sigma"]) if "sum" in self.params.intensity: reflections["intensity.sum.sigma"] = ( reflections["intensity.sum.variance"]**0.5) variables_present.extend( ["intensity.sum.value", "intensity.sum.sigma"]) if "profile" in self.params.intensity: reflections["intensity.prf.sigma"] = ( reflections["intensity.prf.variance"]**0.5) variables_present.extend( ["intensity.prf.value", "intensity.prf.sigma"]) # Should always exist reflections["angle"] = reflections["xyzcal.mm"].parts()[2] * RAD2DEG variables_present.extend(["angle"]) if "partiality" in reflections: variables_present.extend(["partiality"]) for name in variables_present: if name in reflections: header += (headernames[name], ) if "scale" in self.params.intensity: # Write dataset_statistics - first make a miller array crystal_symmetry = cctbxcrystal.symmetry( space_group=experiments[0].crystal.get_space_group(), unit_cell=experiments[0].crystal.get_unit_cell(), ) miller_set = miller.set( crystal_symmetry=crystal_symmetry, indices=reflections["miller_index"], anomalous_flag=False, ) i_obs = miller.array(miller_set, data=reflections["intensity.scale.value"]) i_obs.set_observation_type_xray_intensity() i_obs.set_sigmas(reflections["intensity.scale.sigma"]) i_obs.set_info( miller.array_info(source="DIALS", source_type="reflection_tables")) result = dataset_statistics( i_obs=i_obs, crystal_symmetry=crystal_symmetry, use_internal_variance=False, eliminate_sys_absent=False, ) cif_block.update(result.as_cif_block()) cif_loop = iotbx.cif.model.loop(header=header) for i, r in enumerate(reflections.rows()): refl_id = i + 1 scan_id = r["id"] + 1 _, _, _, _, z0, z1 = r["bbox"] h, k, l = r["miller_index"] variable_values = tuple((r[name]) for name in variables_present) cif_loop.add_row((refl_id, scan_id, z0, z1, h, k, l) + variable_values) cif_block.add_loop(cif_loop) # Add the block self._cif["dials"] = cif_block # Print to file with open(filename, "w") as fh: self._cif.show(out=fh) # Log logger.info("Wrote reflections to %s" % filename)
def find_matching_symmetry(unit_cell, target_space_group, max_delta=5): cs = crystal.symmetry(unit_cell=unit_cell, space_group=sgtbx.space_group()) target_bravais_t = bravais_types.bravais_lattice( group=target_space_group.info().reference_setting().group()) best_subgroup = None best_angular_difference = 1e8 # code based on cctbx/sgtbx/lattice_symmetry.py but optimised to only # look at subgroups with the correct bravais type input_symmetry = cs # Get cell reduction operator cb_op_inp_minimum = input_symmetry.change_of_basis_op_to_minimum_cell() # New symmetry object with changed basis minimum_symmetry = input_symmetry.change_basis(cb_op_inp_minimum) # Get highest symmetry compatible with lattice lattice_group = sgtbx.lattice_symmetry_group( minimum_symmetry.unit_cell(), max_delta=max_delta, enforce_max_delta_for_generated_two_folds=True) # Get list of sub-spacegroups subgrs = subgroups.subgroups(lattice_group.info()).groups_parent_setting() # Order sub-groups sort_values = flex.double() for group in subgrs: order_z = group.order_z() space_group_number = sgtbx.space_group_type(group, False).number() assert 1 <= space_group_number <= 230 sort_values.append(order_z*1000+space_group_number) perm = flex.sort_permutation(sort_values, True) for i_subgr in perm: acentric_subgroup = subgrs[i_subgr] acentric_supergroup = metric_supergroup(acentric_subgroup) ## Add centre of inversion to acentric lattice symmetry #centric_group = sgtbx.space_group(acentric_subgroup) #centric_group.expand_inv(sgtbx.tr_vec((0,0,0))) # Make symmetry object: unit-cell + space-group # The unit cell is potentially modified to be exactly compatible # with the space group symmetry. subsym = crystal.symmetry( unit_cell=minimum_symmetry.unit_cell(), space_group=acentric_subgroup, assert_is_compatible_unit_cell=False) #supersym = crystal.symmetry( #unit_cell=minimum_symmetry.unit_cell(), #space_group=acentric_supergroup, #assert_is_compatible_unit_cell=False) # Convert subgroup to reference setting cb_op_minimum_ref = subsym.space_group_info().type().cb_op() ref_subsym = subsym.change_basis(cb_op_minimum_ref) # Ignore unwanted groups bravais_t = bravais_types.bravais_lattice( group=ref_subsym.space_group()) if bravais_t != target_bravais_t: continue # Choose best setting for monoclinic and orthorhombic systems cb_op_best_cell = ref_subsym.change_of_basis_op_to_best_cell( best_monoclinic_beta=True) best_subsym = ref_subsym.change_basis(cb_op_best_cell) # Total basis transformation cb_op_best_cell = change_of_basis_op(str(cb_op_best_cell),stop_chars='',r_den=144,t_den=144) cb_op_minimum_ref=change_of_basis_op(str(cb_op_minimum_ref),stop_chars='',r_den=144,t_den=144) cb_op_inp_minimum=change_of_basis_op(str(cb_op_inp_minimum),stop_chars='',r_den=144,t_den=144) cb_op_inp_best = cb_op_best_cell * cb_op_minimum_ref * cb_op_inp_minimum # Use identity change-of-basis operator if possible if (best_subsym.unit_cell().is_similar_to(input_symmetry.unit_cell())): cb_op_corr = cb_op_inp_best.inverse() try: best_subsym_corr = best_subsym.change_basis(cb_op_corr) except RuntimeError, e: if (str(e).find("Unsuitable value for rational rotation matrix.") < 0): raise else: if (best_subsym_corr.space_group() == best_subsym.space_group()): cb_op_inp_best = cb_op_corr * cb_op_inp_best max_angular_difference = find_max_delta( reduced_cell=minimum_symmetry.unit_cell(), space_group=acentric_supergroup) if max_angular_difference < best_angular_difference: #best_subgroup = subgroup best_angular_difference = max_angular_difference best_subgroup = {'subsym':subsym, #'supersym':supersym, 'ref_subsym':ref_subsym, 'best_subsym':best_subsym, 'cb_op_inp_best':cb_op_inp_best, 'max_angular_difference':max_angular_difference }
def _index(self): if PhilIndex.params.dials.index.method in (libtbx.Auto, None): if self._indxr_input_cell is not None: indexer = self._do_indexing("real_space_grid_search") else: try: indexer_fft3d = self._do_indexing(method="fft3d") nref_3d, rmsd_3d = indexer_fft3d.get_nref_rmsds() except Exception as e: nref_3d = None rmsd_3d = None indexing_failure = e try: indexer_fft1d = self._do_indexing(method="fft1d") nref_1d, rmsd_1d = indexer_fft1d.get_nref_rmsds() except Exception as e: nref_1d = None rmsd_1d = None indexing_failure = e if (nref_1d is not None and nref_3d is None or (nref_1d > nref_3d and rmsd_1d[0] < rmsd_3d[0] and rmsd_1d[1] < rmsd_3d[1] and rmsd_1d[2] < rmsd_3d[2])): indexer = indexer_fft1d elif nref_3d is not None: indexer = indexer_fft3d else: raise RuntimeError(indexing_failure) else: indexer = self._do_indexing( method=PhilIndex.params.dials.index.method) # not strictly the P1 cell, rather the cell that was used in indexing self._p1_cell = indexer._p1_cell self.set_indexer_payload("indexed_filename", indexer.get_indexed_filename()) indexed_file = indexer.get_indexed_filename() indexed_experiments = indexer.get_experiments_filename() fast_mode = PhilIndex.params.dials.fast_mode trust_beam_centre = PhilIndex.params.xia2.settings.trust_beam_centre multi_sweep_indexing = PhilIndex.params.xia2.settings.multi_sweep_indexing check_indexing_symmetry = PhilIndex.params.dials.check_indexing_symmetry if check_indexing_symmetry and not (trust_beam_centre or fast_mode or multi_sweep_indexing): checksym = self.CheckIndexingSymmetry() checksym.set_experiments_filename(indexed_experiments) checksym.set_indexed_filename(indexed_file) checksym.set_grid_search_scope(1) checksym.run() hkl_offset = checksym.get_hkl_offset() logger.debug("hkl_offset: %s", str(hkl_offset)) if hkl_offset is not None and hkl_offset != (0, 0, 0): reindex = self.Reindex() reindex.set_hkl_offset(hkl_offset) reindex.set_indexed_filename(indexed_file) reindex.run() indexed_file = reindex.get_reindexed_reflections_filename() # do some scan-static refinement - run twice, first without outlier # rejection as the model is too far from reality to do a sensible job of # outlier rejection refiner = self.Refine() refiner.set_experiments_filename(indexed_experiments) refiner.set_indexed_filename( reindex.get_reindexed_reflections_filename()) refiner.set_outlier_algorithm(None) refiner.run() indexed_experiments = refiner.get_refined_experiments_filename( ) # now again with outlier rejection (possibly) refiner = self.Refine() refiner.set_experiments_filename(indexed_experiments) refiner.set_indexed_filename(indexed_file) refiner.run() indexed_experiments = refiner.get_refined_experiments_filename( ) if self._indxr_input_lattice is None: # FIXME in here should respect the input unit cell and lattice if provided # FIXME from this (i) populate the helper table, # (ii) try to avoid re-running the indexing # step if we eliminate a solution as we have all of the refined results # already available. rbs = self.RefineBravaisSettings() rbs.set_experiments_filename(indexed_experiments) rbs.set_indexed_filename(indexed_file) if PhilIndex.params.dials.fix_geometry: rbs.set_detector_fix("all") rbs.set_beam_fix("all") elif PhilIndex.params.dials.fix_distance: rbs.set_detector_fix("distance") FileHandler.record_log_file( "%s LATTICE" % self.get_indexer_full_name(), rbs.get_log_file()) rbs.run() for k in sorted(rbs.get_bravais_summary()): summary = rbs.get_bravais_summary()[k] # FIXME need to do this better - for the moment only accept lattices # where R.M.S. deviation is less than twice P1 R.M.S. deviation. if self._indxr_input_lattice is None: if not summary["recommended"]: continue experiments = load.experiment_list(summary["experiments_file"], check_format=False) cryst = experiments.crystals()[0] cs = crystal.symmetry(unit_cell=cryst.get_unit_cell(), space_group=cryst.get_space_group()) lattice = str( bravais_types.bravais_lattice(group=cs.space_group())) cb_op = sgtbx.change_of_basis_op(str(summary["cb_op"])) self._solutions[k] = { "number": k, "mosaic": 0.0, "metric": summary["max_angular_difference"], "rmsd": summary["rmsd"], "nspots": summary["nspots"], "lattice": lattice, "cell": cs.unit_cell().parameters(), "experiments_file": summary["experiments_file"], "cb_op": str(cb_op), } self._solution = self.get_solution() self._indxr_lattice = self._solution["lattice"] for solution in self._solutions: lattice = self._solutions[solution]["lattice"] if (self._indxr_input_lattice is not None and self._indxr_input_lattice != lattice): continue if lattice in self._indxr_other_lattice_cell: if (self._indxr_other_lattice_cell[lattice]["metric"] < self._solutions[solution]["metric"]): continue self._indxr_other_lattice_cell[lattice] = { "metric": self._solutions[solution]["metric"], "cell": self._solutions[solution]["cell"], } self._indxr_mosaic = self._solution["mosaic"] experiments_file = self._solution["experiments_file"] experiment_list = load.experiment_list(experiments_file) self.set_indexer_experiment_list(experiment_list) self.set_indexer_payload("experiments_filename", experiments_file) # reindex the output reflection list to this solution reindex = self.Reindex() reindex.set_indexed_filename(indexed_file) reindex.set_cb_op(self._solution["cb_op"]) reindex.set_space_group( str(lattice_to_spacegroup_number(self._solution["lattice"]))) reindex.run() indexed_file = reindex.get_reindexed_reflections_filename() self.set_indexer_payload("indexed_filename", indexed_file) else: experiment_list = load.experiment_list(indexed_experiments) self.set_indexer_experiment_list(experiment_list) self.set_indexer_payload("experiments_filename", indexed_experiments) cryst = experiment_list.crystals()[0] lattice = str( bravais_types.bravais_lattice(group=cryst.get_space_group())) self._indxr_lattice = lattice self._solutions = {} self._solutions[0] = { "number": 0, "mosaic": 0.0, "metric": -1, "rmsd": -1, "nspots": -1, "lattice": lattice, "cell": cryst.get_unit_cell().parameters(), "experiments_file": indexed_experiments, "cb_op": "a,b,c", } self._indxr_other_lattice_cell[lattice] = { "metric": self._solutions[0]["metric"], "cell": self._solutions[0]["cell"], }
def _refine_prepare(self): for epoch, idxr in self._refinr_indexers.iteritems(): experiments = idxr.get_indexer_experiment_list() assert len(experiments) == 1 # currently only handle one lattice/sweep experiment = experiments[0] crystal_model = experiment.crystal lattice = idxr.get_indexer_lattice() # check if the lattice was user assigned... user_assigned = idxr.get_indexer_user_input_lattice() # hack to figure out if we did indexing with Dials - if so then need to # run XYCORR, INIT, and then dials.export_xds before we are ready to # integrate with XDS from xia2.Modules.Indexer.DialsIndexer import DialsIndexer if isinstance(idxr, DialsIndexer): sweep = idxr.get_indexer_sweep() imageset = idxr._indxr_imagesets[0] scan = imageset.get_scan() first, last = scan.get_image_range() phi_width = scan.get_oscillation()[1] last_background = int(round(5.0 / phi_width)) - 1 + first last_background = min(last, last_background) from xia2.Modules.Indexer.XDSIndexer import XDSIndexer xds_idxr = XDSIndexer() xds_idxr.set_working_directory(self.get_working_directory()) xds_idxr.set_indexer_sweep(sweep) xds_idxr.add_indexer_imageset(imageset) # next start to process these - first xycorr # FIXME run these *afterwards* as then we have a refined detector geometry # so the parallax correction etc. should be slightly better. #self._indxr_images = [(first, last)] xycorr = xds_idxr.Xycorr() xycorr.set_data_range(first, last) xycorr.set_background_range(first, last_background) xycorr.set_working_directory(self.get_working_directory()) xycorr.run() xds_data_files = {} for file in ['X-CORRECTIONS.cbf', 'Y-CORRECTIONS.cbf']: xds_data_files[file] = xycorr.get_output_data_file(file) # next start to process these - then init init = xds_idxr.Init() for file in ['X-CORRECTIONS.cbf', 'Y-CORRECTIONS.cbf']: init.set_input_data_file(file, xds_data_files[file]) init.set_data_range(first, last) init.set_background_range(first, last_background) init.set_working_directory(self.get_working_directory()) init.run() for file in ['BLANK.cbf', 'BKGINIT.cbf', 'GAIN.cbf']: xds_data_files[file] = init.get_output_data_file(file) exporter = self.ExportXDS() exporter.set_experiments_filename( idxr.get_solution()['experiments_file']) exporter.run() for file in ['XPARM.XDS']: xds_data_files[file] = os.path.join( self.get_working_directory(), 'xds', file) for k, v in xds_data_files.items(): idxr.set_indexer_payload(k, v) # check that the indexer is an XDS indexer - if not then # create one... elif not idxr.get_indexer_payload('XPARM.XDS'): Debug.write('Generating an XDS indexer') idxr_old = idxr from xia2.Modules.Indexer.XDSIndexer import XDSIndexer idxr = XDSIndexer() idxr.set_indexer_sweep(idxr_old.get_indexer_sweep()) self._refinr_indexers[epoch] = idxr self.set_refiner_prepare_done(False) # note to self for the future - this set will reset the # integrater prepare done flag - this means that we will # go through this routine all over again. However this # is not a problem as all that will happen is that the # results will be re-got, no additional processing will # be performed... # set the indexer up as per the frameprocessor interface... # this would usually happen within the IndexerFactory. idxr.set_indexer_sweep_name(idxr_old.get_indexer_sweep_name()) idxr.add_indexer_imageset(idxr_old.get_imageset()) idxr.set_working_directory(idxr_old.get_working_directory()) # now copy information from the old indexer to the new # one - lattice, cell, distance etc. # bug # 2434 - providing the correct target cell # may be screwing things up - perhaps it would # be best to allow XDS just to index with a free # cell but target lattice?? cell = crystal_model.get_unit_cell().parameters() check = PhilIndex.params.xia2.settings.xds_check_cell_deviation # FIXME this was changed in #42 but not sure logic is right if not check: Debug.write( 'Inputting target cell: %.2f %.2f %.2f %.2f %.2f %.2f' % \ cell) idxr.set_indexer_input_cell(cell) input_cell = cell from cctbx.sgtbx import bravais_types lattice = str( bravais_types.bravais_lattice(group=crystal_model.get_space_group())) idxr.set_indexer_input_lattice(lattice) if user_assigned: Debug.write('Assigning the user given lattice: %s' % \ lattice) idxr.set_indexer_user_input_lattice(True) idxr.set_detector(experiment.detector) idxr.set_beam(experiment.beam) idxr.set_goniometer(experiment.goniometer) # re-get the unit cell &c. and check that the indexing # worked correctly Debug.write('Rerunning indexing with XDS') experiments = idxr.get_indexer_experiment_list() assert len(experiments) == 1 # currently only handle one lattice/sweep experiment = experiments[0] crystal_model = experiment.crystal
def _index(self): if PhilIndex.params.dials.index.method in (libtbx.Auto, None): if self._indxr_input_cell is not None: indexer = self._do_indexing("real_space_grid_search") else: try: indexer_fft3d = self._do_indexing(method="fft3d") nref_3d, rmsd_3d = indexer_fft3d.get_nref_rmsds() except Exception as e: nref_3d = None rmsd_3d = None try: indexer_fft1d = self._do_indexing(method="fft1d") nref_1d, rmsd_1d = indexer_fft1d.get_nref_rmsds() except Exception as e: nref_1d = None rmsd_1d = None if (nref_1d is not None and nref_3d is None or (nref_1d > nref_3d and rmsd_1d[0] < rmsd_3d[0] and rmsd_1d[1] < rmsd_3d[1] and rmsd_1d[2] < rmsd_3d[2])): indexer = indexer_fft1d elif nref_3d is not None: indexer = indexer_fft3d else: raise RuntimeError(e) else: indexer = self._do_indexing( method=PhilIndex.params.dials.index.method) # not strictly the P1 cell, rather the cell that was used in indexing self._p1_cell = indexer._p1_cell self.set_indexer_payload("indexed_filename", indexer.get_indexed_filename()) from cctbx.sgtbx import bravais_types from dxtbx.serialize import load indexed_file = indexer.get_indexed_filename() indexed_experiments = indexer.get_experiments_filename() fast_mode = PhilIndex.params.dials.fast_mode trust_beam_centre = PhilIndex.params.xia2.settings.trust_beam_centre multi_sweep_indexing = PhilIndex.params.xia2.settings.multi_sweep_indexing == True if not (trust_beam_centre or fast_mode or multi_sweep_indexing): checksym = self.CheckIndexingSymmetry() checksym.set_experiments_filename(indexed_experiments) checksym.set_indexed_filename(indexed_file) checksym.set_grid_search_scope(1) checksym.run() hkl_offset = checksym.get_hkl_offset() Debug.write("hkl_offset: %s" % str(hkl_offset)) if hkl_offset is not None and hkl_offset != (0, 0, 0): reindex = self.Reindex() reindex.set_hkl_offset(hkl_offset) reindex.set_indexed_filename(indexed_file) reindex.run() indexed_file = reindex.get_reindexed_reflections_filename() # do some scan-static refinement - run twice, first without outlier # rejection as the model is too far from reality to do a sensible job of # outlier rejection refiner = self.Refine() refiner.set_experiments_filename(indexed_experiments) refiner.set_indexed_filename( reindex.get_reindexed_reflections_filename()) refiner.set_outlier_algorithm(None) refiner.run() indexed_experiments = refiner.get_refined_experiments_filename( ) # now again with outlier rejection (possibly) refiner = self.Refine() refiner.set_experiments_filename(indexed_experiments) refiner.set_indexed_filename(indexed_file) refiner.run() indexed_experiments = refiner.get_refined_experiments_filename( ) if self._indxr_input_lattice is None: # FIXME in here should respect the input unit cell and lattice if provided # FIXME from this (i) populate the helper table, # (ii) try to avoid re-running the indexing # step if we eliminate a solution as we have all of the refined results # already available. rbs = self.RefineBravaisSettings() rbs.set_experiments_filename(indexed_experiments) rbs.set_indexed_filename(indexed_file) if PhilIndex.params.dials.fix_geometry: rbs.set_detector_fix('all') rbs.set_beam_fix('all') FileHandler.record_log_file( '%s LATTICE' % self.get_indexer_full_name(), rbs.get_log_file()) rbs.run() from cctbx import crystal, sgtbx for k in sorted(rbs.get_bravais_summary()): summary = rbs.get_bravais_summary()[k] # FIXME need to do this better - for the moment only accept lattices # where R.M.S. deviation is less than twice P1 R.M.S. deviation. if self._indxr_input_lattice is None: if not summary['recommended']: continue experiments = load.experiment_list(summary['experiments_file'], check_format=False) cryst = experiments.crystals()[0] cs = crystal.symmetry(unit_cell=cryst.get_unit_cell(), space_group=cryst.get_space_group()) cb_op_best_to_ref = cs.change_of_basis_op_to_reference_setting( ) cs_reference = cs.change_basis(cb_op_best_to_ref) lattice = str( bravais_types.bravais_lattice( group=cs_reference.space_group())) cb_op = cb_op_best_to_ref * sgtbx.change_of_basis_op( str(summary['cb_op'])) self._solutions[k] = { 'number': k, 'mosaic': 0.0, 'metric': summary['max_angular_difference'], 'rmsd': summary['rmsd'], 'nspots': summary['nspots'], 'lattice': lattice, 'cell': cs_reference.unit_cell().parameters(), 'experiments_file': summary['experiments_file'], 'cb_op': str(cb_op) } self._solution = self.get_solution() self._indxr_lattice = self._solution['lattice'] for solution in self._solutions.keys(): lattice = self._solutions[solution]['lattice'] if (self._indxr_input_lattice is not None and self._indxr_input_lattice != lattice): continue if lattice in self._indxr_other_lattice_cell: if self._indxr_other_lattice_cell[lattice]['metric'] < \ self._solutions[solution]['metric']: continue self._indxr_other_lattice_cell[lattice] = { 'metric': self._solutions[solution]['metric'], 'cell': self._solutions[solution]['cell'] } self._indxr_mosaic = self._solution['mosaic'] experiment_list = load.experiment_list( self._solution['experiments_file']) self.set_indexer_experiment_list(experiment_list) # reindex the output experiments list to the reference setting # (from the best cell/conventional setting) cb_op_to_ref = experiment_list.crystals()[0].get_space_group().info()\ .change_of_basis_op_to_reference_setting() reindex = self.Reindex() reindex.set_experiments_filename( self._solution['experiments_file']) reindex.set_cb_op(cb_op_to_ref) reindex.set_space_group( str(lattice_to_spacegroup_number(self._solution['lattice']))) reindex.run() experiments_file = reindex.get_reindexed_experiments_filename() experiment_list = load.experiment_list(experiments_file) self.set_indexer_experiment_list(experiment_list) self.set_indexer_payload("experiments_filename", experiments_file) # reindex the output reflection list to this solution reindex = self.Reindex() reindex.set_indexed_filename(indexed_file) reindex.set_cb_op(self._solution['cb_op']) reindex.set_space_group( str(lattice_to_spacegroup_number(self._solution['lattice']))) reindex.run() indexed_file = reindex.get_reindexed_reflections_filename() self.set_indexer_payload("indexed_filename", indexed_file) else: experiment_list = load.experiment_list(indexed_experiments) self.set_indexer_experiment_list(experiment_list) self.set_indexer_payload("experiments_filename", indexed_experiments) cryst = experiment_list.crystals()[0] lattice = str( bravais_types.bravais_lattice(group=cryst.get_space_group())) self._indxr_lattice = lattice self._solutions = {} self._solutions[0] = { 'number': 0, 'mosaic': 0.0, 'metric': -1, 'rmsd': -1, 'nspots': -1, 'lattice': lattice, 'cell': cryst.get_unit_cell().parameters(), 'experiments_file': indexed_experiments, 'cb_op': 'a,b,c' } self._indxr_other_lattice_cell[lattice] = { 'metric': self._solutions[0]['metric'], 'cell': self._solutions[0]['cell'] } return
F = open(os.path.join(this_directory,"datastore"),"r") #datastore represents all subgroup settings in the labelit reference database. cases = [] bravais_types = [] try: while 1: cases.append(pickle.load(F)) except Exception: assert len(cases)>900 #should be 980 for case in cases: orient,cs,symmetry = case print orient,cs,symmetry.space_group().type().lookup_symbol() S = symmetrize_reduce_enlarge(space_group=symmetry.space_group()) S.set_orientation(orientation=orient,length_unit=1.E-9) S.symmetrize() X = S.forward_independent_parameters() dB_dp = S.forward_gradients() B = S.backward_orientation(independent=X).reciprocal_matrix() #continue if symmetry.space_group().type().lookup_symbol() not in bravais_types: bravais_types.append(symmetry.space_group().type().lookup_symbol()) finite_difference_test(orient) encountered_types = [str(bravais_lattice(i)) for i in bravais_types] reference_types = ["aP","mP","mC","oP","oC","oI","oF","tP","tI","hP","hR","cP","cI","cF"] encountered_types.sort(); reference_types.sort() assert encountered_types == reference_types print "OK"
def find_matching_symmetry(unit_cell, target_space_group, max_delta=5): cs = crystal.symmetry(unit_cell=unit_cell, space_group=sgtbx.space_group()) target_bravais_t = bravais_types.bravais_lattice( group=target_space_group.info().reference_setting().group()) best_subgroup = None best_angular_difference = 1e8 # code based on cctbx/sgtbx/lattice_symmetry.py but optimised to only # look at subgroups with the correct bravais type input_symmetry = cs # Get cell reduction operator cb_op_inp_minimum = input_symmetry.change_of_basis_op_to_minimum_cell() # New symmetry object with changed basis minimum_symmetry = input_symmetry.change_basis(cb_op_inp_minimum) # Get highest symmetry compatible with lattice lattice_group = sgtbx.lattice_symmetry_group( minimum_symmetry.unit_cell(), max_delta=max_delta, enforce_max_delta_for_generated_two_folds=True) # Get list of sub-spacegroups subgrs = subgroups.subgroups(lattice_group.info()).groups_parent_setting() # Order sub-groups sort_values = flex.double() for group in subgrs: order_z = group.order_z() space_group_number = sgtbx.space_group_type(group, False).number() assert 1 <= space_group_number <= 230 sort_values.append(order_z * 1000 + space_group_number) perm = flex.sort_permutation(sort_values, True) for i_subgr in perm: acentric_subgroup = subgrs[i_subgr] acentric_supergroup = metric_supergroup(acentric_subgroup) ## Add centre of inversion to acentric lattice symmetry #centric_group = sgtbx.space_group(acentric_subgroup) #centric_group.expand_inv(sgtbx.tr_vec((0,0,0))) # Make symmetry object: unit-cell + space-group # The unit cell is potentially modified to be exactly compatible # with the space group symmetry. subsym = crystal.symmetry(unit_cell=minimum_symmetry.unit_cell(), space_group=acentric_subgroup, assert_is_compatible_unit_cell=False) #supersym = crystal.symmetry( #unit_cell=minimum_symmetry.unit_cell(), #space_group=acentric_supergroup, #assert_is_compatible_unit_cell=False) # Convert subgroup to reference setting cb_op_minimum_ref = subsym.space_group_info().type().cb_op() ref_subsym = subsym.change_basis(cb_op_minimum_ref) # Ignore unwanted groups bravais_t = bravais_types.bravais_lattice( group=ref_subsym.space_group()) if bravais_t != target_bravais_t: continue # Choose best setting for monoclinic and orthorhombic systems cb_op_best_cell = ref_subsym.change_of_basis_op_to_best_cell( best_monoclinic_beta=True) best_subsym = ref_subsym.change_basis(cb_op_best_cell) # Total basis transformation cb_op_best_cell = change_of_basis_op(str(cb_op_best_cell), stop_chars='', r_den=144, t_den=144) cb_op_minimum_ref = change_of_basis_op(str(cb_op_minimum_ref), stop_chars='', r_den=144, t_den=144) cb_op_inp_minimum = change_of_basis_op(str(cb_op_inp_minimum), stop_chars='', r_den=144, t_den=144) cb_op_inp_best = cb_op_best_cell * cb_op_minimum_ref * cb_op_inp_minimum # Use identity change-of-basis operator if possible if best_subsym.unit_cell().is_similar_to(input_symmetry.unit_cell()): cb_op_corr = cb_op_inp_best.inverse() try: best_subsym_corr = best_subsym.change_basis(cb_op_corr) except RuntimeError as e: if str(e).find( "Unsuitable value for rational rotation matrix.") < 0: raise else: if best_subsym_corr.space_group() == best_subsym.space_group(): cb_op_inp_best = cb_op_corr * cb_op_inp_best max_angular_difference = find_max_delta( reduced_cell=minimum_symmetry.unit_cell(), space_group=acentric_supergroup) if max_angular_difference < best_angular_difference: #best_subgroup = subgroup best_angular_difference = max_angular_difference best_subgroup = { 'subsym': subsym, #'supersym':supersym, 'ref_subsym': ref_subsym, 'best_subsym': best_subsym, 'cb_op_inp_best': cb_op_inp_best, 'max_angular_difference': max_angular_difference } if best_subgroup is not None: return best_subgroup
def _refine_prepare(self): for epoch, idxr in self._refinr_indexers.iteritems(): experiments = idxr.get_indexer_experiment_list() assert len( experiments) == 1 # currently only handle one lattice/sweep experiment = experiments[0] crystal_model = experiment.crystal lattice = idxr.get_indexer_lattice() # check if the lattice was user assigned... user_assigned = idxr.get_indexer_user_input_lattice() # hack to figure out if we did indexing with Dials - if so then need to # run XYCORR, INIT, and then dials.export_xds before we are ready to # integrate with XDS from xia2.Modules.Indexer.DialsIndexer import DialsIndexer if isinstance(idxr, DialsIndexer): sweep = idxr.get_indexer_sweep() imageset = idxr._indxr_imagesets[0] scan = imageset.get_scan() first, last = scan.get_image_range() phi_width = scan.get_oscillation()[1] last_background = int(round(5.0 / phi_width)) - 1 + first last_background = min(last, last_background) from xia2.Modules.Indexer.XDSIndexer import XDSIndexer xds_idxr = XDSIndexer() xds_idxr.set_working_directory(self.get_working_directory()) xds_idxr.set_indexer_sweep(sweep) xds_idxr.add_indexer_imageset(imageset) # next start to process these - first xycorr # FIXME run these *afterwards* as then we have a refined detector geometry # so the parallax correction etc. should be slightly better. #self._indxr_images = [(first, last)] xycorr = xds_idxr.Xycorr() xycorr.set_data_range(first, last) xycorr.set_background_range(first, last_background) xycorr.set_working_directory(self.get_working_directory()) xycorr.run() xds_data_files = {} for file in ['X-CORRECTIONS.cbf', 'Y-CORRECTIONS.cbf']: xds_data_files[file] = xycorr.get_output_data_file(file) # next start to process these - then init init = xds_idxr.Init() for file in ['X-CORRECTIONS.cbf', 'Y-CORRECTIONS.cbf']: init.set_input_data_file(file, xds_data_files[file]) init.set_data_range(first, last) init.set_background_range(first, last_background) init.set_working_directory(self.get_working_directory()) init.run() for file in ['BLANK.cbf', 'BKGINIT.cbf', 'GAIN.cbf']: xds_data_files[file] = init.get_output_data_file(file) exporter = self.ExportXDS() exporter.set_experiments_filename( idxr.get_solution()['experiments_file']) exporter.run() for file in ['XPARM.XDS']: xds_data_files[file] = os.path.join( self.get_working_directory(), 'xds', file) for k, v in xds_data_files.items(): idxr.set_indexer_payload(k, v) # check that the indexer is an XDS indexer - if not then # create one... elif not idxr.get_indexer_payload('XPARM.XDS'): Debug.write('Generating an XDS indexer') idxr_old = idxr from xia2.Modules.Indexer.XDSIndexer import XDSIndexer idxr = XDSIndexer() idxr.set_indexer_sweep(idxr_old.get_indexer_sweep()) self._refinr_indexers[epoch] = idxr self.set_refiner_prepare_done(False) # note to self for the future - this set will reset the # integrater prepare done flag - this means that we will # go through this routine all over again. However this # is not a problem as all that will happen is that the # results will be re-got, no additional processing will # be performed... # set the indexer up as per the frameprocessor interface... # this would usually happen within the IndexerFactory. idxr.set_indexer_sweep_name(idxr_old.get_indexer_sweep_name()) idxr.add_indexer_imageset(idxr_old.get_imageset()) idxr.set_working_directory(idxr_old.get_working_directory()) # now copy information from the old indexer to the new # one - lattice, cell, distance etc. # bug # 2434 - providing the correct target cell # may be screwing things up - perhaps it would # be best to allow XDS just to index with a free # cell but target lattice?? cell = crystal_model.get_unit_cell().parameters() check = PhilIndex.params.xia2.settings.xds_check_cell_deviation # FIXME this was changed in #42 but not sure logic is right if not check: Debug.write( 'Inputting target cell: %.2f %.2f %.2f %.2f %.2f %.2f' % \ cell) idxr.set_indexer_input_cell(cell) input_cell = cell from cctbx.sgtbx import bravais_types lattice = str( bravais_types.bravais_lattice( group=crystal_model.get_space_group())) idxr.set_indexer_input_lattice(lattice) if user_assigned: Debug.write('Assigning the user given lattice: %s' % \ lattice) idxr.set_indexer_user_input_lattice(True) idxr.set_detector(experiment.detector) idxr.set_beam(experiment.beam) idxr.set_goniometer(experiment.goniometer) # re-get the unit cell &c. and check that the indexing # worked correctly Debug.write('Rerunning indexing with XDS') experiments = idxr.get_indexer_experiment_list() assert len(experiments ) == 1 # currently only handle one lattice/sweep experiment = experiments[0] crystal_model = experiment.crystal
def set_best_solution(self, d, best_solution): patterson_group = sgtbx.space_group( str(best_solution["patterson_group"])) if PhilIndex.params.xia2.settings.symmetry.chirality in (None, "chiral"): patterson_group = patterson_group.build_derived_acentric_group( ) cb_op_min_best = sgtbx.change_of_basis_op( str(best_solution["cb_op"])) # This should only be called with multiple sweeps if they're already # consistently indexed, so assert that they all have the same # cb_op_inp_min assert len(set(d["cb_op_inp_min"])) == 1 cb_op_inp_min = sgtbx.change_of_basis_op(str( d["cb_op_inp_min"][0])) min_cell = uctbx.unit_cell(d["min_cell_symmetry"]["unit_cell"]) best_cell = min_cell.change_basis(cb_op=cb_op_min_best) cs = crystal.symmetry( unit_cell=best_cell, space_group=patterson_group, assert_is_compatible_unit_cell=False, ) self._pointgroup = cs.space_group().type().lookup_symbol() self._confidence = best_solution["confidence"] self._totalprob = best_solution["likelihood"] cb_op_inp_best = cb_op_min_best * cb_op_inp_min self._reindex_operator = cb_op_inp_best.as_xyz() self._reindex_matrix = cb_op_inp_best.c().r().as_double() if not self._input_laue_group and not self._hklref: for score in d["subgroup_scores"]: patterson_group = sgtbx.space_group( str(score["patterson_group"])) if PhilIndex.params.xia2.settings.symmetry.chirality in ( None, "chiral", ): patterson_group = patterson_group.build_derived_acentric_group( ) cb_op_inp_this = sgtbx.change_of_basis_op( str(score["cb_op"])) unit_cell = min_cell.change_basis( cb_op=sgtbx.change_of_basis_op(str(cb_op_inp_this))) cs = crystal.symmetry( unit_cell=unit_cell, space_group=patterson_group, assert_is_compatible_unit_cell=False, ) patterson_group = cs.space_group() netzc = score["z_cc_net"] # record this as a possible lattice if its Z score is positive lattice = str( bravais_types.bravais_lattice(group=patterson_group)) if lattice not in self._possible_lattices: if netzc > 0.0: self._possible_lattices.append(lattice) self._lattice_to_laue[lattice] = patterson_group self._likely_spacegroups.append( patterson_group.type().lookup_symbol()) elif self._input_laue_group: self._possible_lattices = [ str(bravais_types.bravais_lattice(group=patterson_group)) ] self._likely_spacegroups = [ patterson_group.type().lookup_symbol() ]
def load_result(file_hash, frame_obj, ref_bravais_type, reference_cell, params, reindex_op, out, get_predictions_to_edge=False, image_info=None, exclude_CSPAD_sensor=None): print >> out, "-" * 80 print >> out, "Step 2. Load pickle file into dictionary obj and filter on lattice & cell with", reindex_op print >> out, file_hash """ Take a pickle file, confirm that it contains the appropriate data, and check the lattice type and unit cell against the reference settings - if rejected, raises an exception (for tracking statistics). """ obj = frame_obj if (not obj.has_key("observations")): return None if params.isoform_name is not None: if not "identified_isoform" in obj: return None if obj["identified_isoform"] != params.isoform_name: return None if reindex_op == "h,k,l": pass #raise WrongBravaisError("Skipping file with h,k,l") else: for idx in xrange(len(obj["observations"])): obj["observations"][idx] = obj["observations"][idx].change_basis( reindex_op) from cctbx.sgtbx import change_of_basis_op cb_op = change_of_basis_op(reindex_op) ORI = obj["current_orientation"][0] Astar = matrix.sqr(ORI.reciprocal_matrix()) CB_OP_sqr = matrix.sqr(cb_op.c().r().as_double()).transpose() from cctbx.crystal_orientation import crystal_orientation ORI_new = crystal_orientation((Astar * CB_OP_sqr).elems, True) obj["current_orientation"][0] = ORI_new # unexpected, first since cxi_merge had a previous postrefinement implementation that # apparently failed to apply the reindex_op (XXX still must be fixed), and secondly # that the crystal_orientation.change basis() implementation fails to work because # it does not use the transpose: obj["current_orientation"][0].change_basis(cb_op) pass #raise WrongBravaisError("Skipping file with alternate indexing %s"%reindex_op) result_array = obj["observations"][0] unit_cell = result_array.unit_cell() sg_info = result_array.space_group_info() print >> out, "" print >> out, sg_info print >> out, unit_cell #Check for pixel size (at this point we are assuming we have square pixels, all experiments described in one #refined_experiments.json file use the same detector, and all panels on the detector have the same pixel size) if params.pixel_size is not None: pixel_size = params.pixel_size elif "pixel_size" in obj: pixel_size = obj["pixel_size"] else: raise Sorry( "Cannot find pixel size. Specify appropriate pixel size in mm for your detector in phil file." ) #Calculate displacements based on pixel size assert obj['mapped_predictions'][0].size() == obj["observations"][0].size() mm_predictions = pixel_size * (obj['mapped_predictions'][0]) mm_displacements = flex.vec3_double() cos_two_polar_angle = flex.double() for pred in mm_predictions: mm_displacements.append( (pred[0] - obj["xbeam"], pred[1] - obj["ybeam"], 0.0)) cos_two_polar_angle.append( math.cos( 2. * math.atan2(pred[1] - obj["ybeam"], pred[0] - obj["xbeam"]))) obj["cos_two_polar_angle"] = cos_two_polar_angle #then convert to polar angle and compute polarization correction if (not bravais_lattice(sg_info.type().number()) == ref_bravais_type): raise WrongBravaisError( "Skipping cell in different Bravais type (%s)" % str(sg_info)) if (not unit_cell.is_similar_to( other=reference_cell, relative_length_tolerance=params.unit_cell_length_tolerance, absolute_angle_tolerance=params.unit_cell_angle_tolerance)): raise OutlierCellError( "Skipping cell with outlier dimensions (%g %g %g %g %g %g" % unit_cell.parameters()) # Illustrate how a unit cell filter would be implemented. #ucparams = unit_cell.parameters() #if not (130.21 < ucparams[2] < 130.61) or not (92.84 < ucparams[0] < 93.24): # print >> out, "DOES NOT PASS ERSATZ UNIT CELL FILTER" # return None print >> out, "Integrated data:" result_array.show_summary(f=out, prefix=" ") # XXX don't force reference setting here, it will be done later, after the # original unit cell is recorded #Remove observations on a selected sensor if requested if exclude_CSPAD_sensor is not None: print >> out, "excluding CSPAD sensor %d" % exclude_CSPAD_sensor fast_min1, slow_min1, fast_max1, slow_max1, \ fast_min2, slow_min2, fast_max2, slow_max2 = \ get_boundaries_from_sensor_ID(exclude_CSPAD_sensor) fast_min = min(fast_min1, fast_min2) slow_min = min(slow_min1, slow_min2) fast_max = max(fast_max1, fast_max2) slow_max = max(slow_max1, slow_max2) accepted = flex.bool() px_preds = obj['mapped_predictions'][0] for idx in xrange(px_preds.size()): pred_fast, pred_slow = px_preds[idx] if (pred_fast < fast_min) or (pred_fast > fast_max) or ( pred_slow < slow_min) or (pred_slow > slow_max): accepted.append(True) else: accepted.append(False) obj['mapped_predictions'][0] = obj['mapped_predictions'][0].select( accepted) obj['observations'][0] = obj['observations'][0].select(accepted) obj['cos_two_polar_angle'] = obj["cos_two_polar_angle"].select( accepted) if not 'indices_to_edge' in obj.keys(): if get_predictions_to_edge: from xfel.merging.predictions_to_edges import extend_predictions extend_predictions(obj, file_name, image_info, dmin=1.5, dump=False) else: obj['indices_to_edge'] = None return obj
def load_result(file_name, ref_bravais_type, reference_cell, params, reindex_op, out): # Pull relevant information from integrated.pickle and refined_experiments.json # files to construct the equivalent of a single integration pickle (frame). try: frame = frame_extractor.ConstructFrameFromFiles( eval_ending(file_name)[2], eval_ending(file_name)[1]).make_frame() except Exception: return None # If @p file_name cannot be read, the load_result() function returns # @c None. print "Step 2. Load frame obj and filter on lattice & cell with", reindex_op """ Take a frame with all expected contents of an integration pickle, confirm that it contains the appropriate data, and check the lattice type and unit cell against the reference settings - if rejected, raises an exception (for tracking statistics). """ # Ignore frames with no integrated reflections. obj = frame if (not obj.has_key("observations")): return None if reindex_op == "h,k,l": pass else: obj["observations"][0].apply_change_of_basis(reindex_op) pass result_array = obj["observations"][0] unit_cell = result_array.unit_cell() sg_info = result_array.space_group_info() print >> out, "" print >> out, "-" * 80 print >> out, file_name print >> out, sg_info print >> out, unit_cell #Check for pixel size (at this point we are assuming we have square pixels, all experiments described in one #refined_experiments.json file use the same detector, and all panels on the detector have the same pixel size) if params.pixel_size is not None: pixel_size = params.pixel_size elif "pixel_size" in obj: pixel_size = obj["pixel_size"] else: raise Sorry( "Cannot find pixel size. Specify appropriate pixel size in mm for your detector in phil file." ) #Calculate displacements based on pixel size assert obj['mapped_predictions'][0].size() == obj["observations"][0].size() mm_predictions = pixel_size * (obj['mapped_predictions'][0]) mm_displacements = flex.vec3_double() cos_two_polar_angle = flex.double() for pred in mm_predictions: mm_displacements.append( (pred[0] - obj["xbeam"], pred[1] - obj["ybeam"], 0.0)) cos_two_polar_angle.append( math.cos( 2. * math.atan2(pred[1] - obj["ybeam"], pred[0] - obj["xbeam"]))) obj["cos_two_polar_angle"] = cos_two_polar_angle #then convert to polar angle and compute polarization correction if (not bravais_lattice(sg_info.type().number()) == ref_bravais_type): raise WrongBravaisError( "Skipping cell in different Bravais type (%s)" % str(sg_info)) if (not unit_cell.is_similar_to( other=reference_cell, relative_length_tolerance=params.unit_cell_length_tolerance, absolute_angle_tolerance=params.unit_cell_angle_tolerance)): raise OutlierCellError( "Skipping cell with outlier dimensions (%g %g %g %g %g %g" % unit_cell.parameters()) print >> out, "Integrated data:" result_array.show_summary(f=out, prefix=" ") # XXX don't force reference setting here, it will be done later, after the # original unit cell is recorded return obj
cs.best_cell().minimum_cell().show_summary() print("Best cell -> niggli cell") cs.best_cell().niggli_cell().show_summary() print("Reference setting -> minimum cell") cs.as_reference_setting().minimum_cell().show_summary() print("Reference setting -> niggli cell") cs.as_reference_setting().niggli_cell().show_summary() print() print("Reference settings (via minimum/niggli cell):") print("Input -> minimum cell -> reference setting") cs.minimum_cell().as_reference_setting().show_summary() print("Input -> niggli cell -> reference setting") cs.niggli_cell().as_reference_setting().show_summary() print("Best cell -> minimum cell -> reference setting") cs.best_cell().minimum_cell().as_reference_setting().show_summary() print("Best cell -> niggli cell -> reference setting") cs.best_cell().niggli_cell().as_reference_setting().show_summary() print("Reference setting -> minimum cell -> reference setting") cs.as_reference_setting().minimum_cell().as_reference_setting().show_summary() print("Reference setting -> niggli cell -> reference setting") cs.as_reference_setting().niggli_cell().as_reference_setting().show_summary() print() subgroups = lattice_symmetry.metric_subgroups(cs, max_delta=0.1) for subgroup in subgroups.result_groups: bravais_t = bravais_lattice(group=subgroup["ref_subsym"].space_group()) if bravais_t == "mC": print(subgroup["ref_subsym"].unit_cell()) print(subgroup["best_subsym"].as_reference_setting().unit_cell())
# FIXME need to do this better - for the moment only accept lattices # where R.M.S. deviation is less than twice P1 R.M.S. deviation. if self._indxr_input_lattice is None: if not summary['recommended']: continue experiments = load.experiment_list( summary['experiments_file'], check_format=False) cryst = experiments.crystals()[0] cs = crystal.symmetry(unit_cell=cryst.get_unit_cell(), space_group=cryst.get_space_group()) cb_op_best_to_ref = cs.change_of_basis_op_to_reference_setting() cs_reference = cs.change_basis(cb_op_best_to_ref) lattice = str(bravais_types.bravais_lattice( group=cs_reference.space_group())) cb_op = cb_op_best_to_ref * sgtbx.change_of_basis_op(str(summary['cb_op'])) self._solutions[k] = { 'number':k, 'mosaic':0.0, 'metric':summary['max_angular_difference'], 'rmsd':summary['rmsd'], 'nspots':summary['nspots'], 'lattice':lattice, 'cell':cs_reference.unit_cell().parameters(), 'experiments_file':summary['experiments_file'], 'cb_op':str(cb_op) } self._solution = self.get_solution()