def reference_setting_choices(space_group): # we used to have cyclic_permutations = ['x,y,z', 'y,z,x', 'z,x,y' ] adams_group = sgtbx.space_group_info( group=space_group.build_derived_group(False, False)) space_group = sgtbx.space_group_info(group=space_group) # please check that we have something in reference setting # just to make sure that thne thing is used for it's original purpose assert space_group.is_reference_setting() info = [] identity_op = sgtbx.change_of_basis_op('x,y,z').c().r() for cyclic_permutation in cyclic_permutations: cob_op = sgtbx.change_of_basis_op(cyclic_permutation) transformed_adams_group = adams_group.change_basis(cob_op) transformed_space_group = space_group.change_basis(cob_op) cob_to_ref_sg = transformed_space_group.\ change_of_basis_op_to_reference_setting() cob_to_ref_pg = transformed_adams_group.\ change_of_basis_op_to_reference_setting() adams_norm = False space_norm = False # check if the rotation part of the cb_op to ref is # the identity operator # if hall symbols are equal, sg's are equal if (identity_op == cob_to_ref_pg.c().r()): adams_norm=True if (identity_op == cob_to_ref_sg.c().r()): space_norm=True info_tuple = (cob_op, cob_to_ref_sg, adams_norm, space_norm) info.append(info_tuple) possible_additional_transforms = [] # we have to of course take into account the identity operator possible_additional_transforms.append(info[0][0]*info[0][1]) for ii in info: if ii[2]: # should fall in the adams normalizer if not ii[3]: # should NOT fall in the space normalizer # cob should ONLY be applied on unit cell, not to the sg. possible_additional_transforms.append(ii[0]) return possible_additional_transforms
def exercise_double_coset_decomposition( crystal_symmetry_ri, lattice_group, miller_array_subs, miller_array_sub_as, miller_array_sub_bs, coset_decompositions, i, j, verbose, ): group_a = miller_array_subs[i].space_group_info().group() group_b = miller_array_subs[j].space_group_info().group() miller_array_sub_a = miller_array_sub_as[i] miller_array_sub_b = miller_array_sub_bs[j] single_coset_ccs = {} for partition in coset_decompositions[i].partitions: cb_op = sgtbx.change_of_basis_op(partition[0]) cb = miller_array_sub_a.change_basis(cb_op).map_to_asu() cc = cb.correlation(other=miller_array_sub_b).coefficient() key = "%.6f" % cc single_coset_ccs.setdefault(key, []).append(str(partition[0])) double_coset_ccs = {} for c in sgtbx.cosets.double_unique(lattice_group, group_a, group_b): cb_op = sgtbx.change_of_basis_op(c) cb = miller_array_sub_b.change_basis(cb_op).map_to_asu() cc = cb.correlation(other=miller_array_sub_a).coefficient() key = "%.6f" % cc double_coset_ccs.setdefault(key, []).append(str(c)) double_coset_repetitions = [len(v) for v in double_coset_ccs.values()] failure = max(double_coset_repetitions) > 1 if failure or verbose: print [str(sgtbx.space_group_info(group=g)) for g in (group_a, group_b)]
def construct_nice_cb_op(coset, sym_transform_1_to_2, to_niggli_1, to_niggli_2): best_choice = None best_choice_as_hkl = None to_niggli_2 = to_niggli_2.new_denominators( to_niggli_1 ) sym_transform_1_to_2 = sym_transform_1_to_2.new_denominators( to_niggli_1 ) for coset_element in coset: tmp_coset_element = sgtbx.change_of_basis_op(coset_element) tmp_coset_element = tmp_coset_element.new_denominators( to_niggli_1 ) tmp_op = to_niggli_1.inverse() \ * (tmp_coset_element * sym_transform_1_to_2) \ * to_niggli_2 if (best_choice_as_hkl is None or sgtbx.compare_cb_op_as_hkl( best_choice_as_hkl, tmp_op.as_hkl()) > 0): best_choice = tmp_op best_choice_as_hkl = tmp_op.as_hkl() assert best_choice is not None tmptmp = sgtbx.change_of_basis_op(coset[0]) return best_choice
def exercise_monoclinic_cell_choices_core(space_group_number, verbose): # transformation matrices for cell choices # columns are basis vectors "new in terms of old" # see Int. Tab. Vol. A, p. 22, Fig. 2.2.6.4. b1 = (1, 0, 0, 0, 1, 0, 0, 0, 1) b2 = (-1, 0, 1, 0, 1, 0, -1, 0, 0) b3 = (0, 0, -1, 0, 1, 0, 1, 0, -1) flip = (0, 0, 1, 0, -1, 0, 1, 0, 0) p3s = sgtbx.space_group("P 3*") done = {} ref = sgtbx.space_group_info(number=space_group_number) ref_uhm = ref.type().universal_hermann_mauguin_symbol() for i_fl,fl in enumerate([b1, flip]): rfl = sgtbx.rot_mx(fl) cfl = sgtbx.change_of_basis_op(sgtbx.rt_mx(rfl)) for i_rt,rt in enumerate(p3s): rp3 = rt.r() cp3 = sgtbx.change_of_basis_op(sgtbx.rt_mx(rp3)) for i_cs,cs in enumerate([b1,b2,b3]): rcs = sgtbx.rot_mx(cs).inverse() ccs = sgtbx.change_of_basis_op(sgtbx.rt_mx(rcs)) cb_all = cp3 * cfl * ccs refcb = ref.change_basis(cb_all) refcb2 = sgtbx.space_group_info(symbol=ref_uhm+"("+str(cb_all.c())+")") assert refcb2.group() == refcb.group() s = sgtbx.space_group_symbols(str(refcb)) q = s.qualifier() hm = str(refcb) if (0 or verbose): print hm, q, cb_all.c() if (i_fl == 0): assert q[0] == "bca"[i_rt] if (len(q) == 2): assert q[1] == "123"[i_cs] elif (q[0] == "-"): assert q[1] == "bca"[i_rt] if (len(q) == 3): assert q[2] == "123"[i_cs] else: assert q[0] == "bca"[i_rt] if (len(q) == 2 and q[1] != "123"[i_cs]): assert done[hm] == 1 done.setdefault(hm, 0) done[hm] += 1 assert len(done) in [3, 9, 18] assert done.values() == [18/len(done)]*len(done) if (0 or verbose): print return done
def exercise_orthorhombic_hm_qualifier_as_cb_symbol(): cb_symbols = { "cab": ["c,a,b", "z,x,y"], "a-cb": ["a,-c,b", "x,-z,y"], "-cba": ["-c,b,a", "-z,y,x"], "bca": ["b,c,a", "y,z,x"], "ba-c": ["b,a,-c", "y,x,-z"]} for sgsyms1 in sgtbx.space_group_symbol_iterator(): n = sgsyms1.number() if (n < 16 or n > 74): continue q = sgsyms1.qualifier() if (len(q) == 0): continue e = sgsyms1.extension() if (e == "\0"): e = "" ehm = sgtbx.space_group_symbols( space_group_number=n, extension=e).universal_hermann_mauguin() cabc, cxyz = cb_symbols[q] assert sgtbx.change_of_basis_op(cxyz).as_abc() == cabc assert sgtbx.change_of_basis_op(cabc).as_xyz() == cxyz uhm_xyz = ehm + " ("+cxyz+")" sgsyms2 = sgtbx.space_group_symbols(symbol=uhm_xyz) assert sgsyms2.change_of_basis_symbol() == cxyz assert sgsyms2.extension() == sgsyms1.extension() assert sgsyms2.universal_hermann_mauguin() == uhm_xyz g1 = sgtbx.space_group(space_group_symbols=sgsyms1) g2 = sgtbx.space_group(space_group_symbols=sgsyms2) assert g2 == g1 g2 = sgtbx.space_group( sgtbx.space_group_symbols(symbol=ehm)).change_basis( sgtbx.change_of_basis_op(sgtbx.rt_mx(cxyz))) assert g2 == g1 for c in [cxyz, cabc]: g2 = sgtbx.space_group_info( group=sgtbx.space_group( sgtbx.space_group_symbols(symbol=ehm))).change_basis(c).group() assert g2 == g1 cit = sgtbx.rt_mx(cxyz).r().inverse().transpose() cit_xyz = cit.as_xyz() g2 = sgtbx.space_group_info( group=sgtbx.space_group( sgtbx.space_group_symbols(symbol=ehm))).change_basis(cit_xyz).group() assert g2 == g1 assert cit.as_xyz(False, "abc") == cabc uhm_abc = ehm + " ("+cabc+")" sgsyms2 = sgtbx.space_group_symbols(symbol=uhm_abc) assert sgsyms2.change_of_basis_symbol() == cxyz assert sgsyms2.extension() == sgsyms1.extension() assert sgsyms2.universal_hermann_mauguin() == uhm_xyz g2 = sgtbx.space_group(space_group_symbols=sgsyms2) assert g2 == g1
def show_rfactors_targets_scales_overall(self, header = None, out=None): from cctbx import sgtbx if(out is None): out = sys.stdout out.flush() p = " " self._header_resolutions_nreflections(header=header, out=out) print("| "+" "*38+"|", file=out) self._rfactors_and_bulk_solvent_and_scale_params(out=out) line7="| normalized target function (%s) (work): %s"% ( self.target_name, n_as_s("%15.6f",self.target_work)) np = 79 - (len(line7) + 1) line7 = line7 + " "*np + "|" print(line7, file=out) # no norm - work line71="| target function (%s) not normalized (work): %s"% ( self.target_name, n_as_s("%15.6f",self.target_work_no_norm)) np = 79 - (len(line71) + 1) line71 = line71 + " "*np + "|" print(line71, file=out) # no norm - free line71="| target function (%s) not normalized (free): %s"% ( self.target_name, n_as_s("%15.6f",self.target_free_no_norm)) np = 79 - (len(line71) + 1) line71 = line71 + " "*np + "|" print(line71, file=out) # if(self.twin_fraction is not None): line8="| twin fraction: "+format_value("%-4.2f",self.twin_fraction)+\ " twin operator: "+\ format_value("%-s",sgtbx.change_of_basis_op(self.twin_law).as_hkl()) np = 79 - (len(line8) + 1) line8 = line8 + " "*np + "|" print(line8, file=out) print("|"+"-"*77+"|", file=out) out.flush()
def _apply_reindexing_operators(self, reindexing_ops, subgroup=None): """Apply the reindexing operators to the reflections and experiments.""" unique_ids = set(self.cosym_analysis.dataset_ids) for cb_op, dataset_id in zip(reindexing_ops, unique_ids): cb_op = sgtbx.change_of_basis_op(cb_op) logger.debug("Applying reindexing op %s to dataset %i", cb_op.as_xyz(), dataset_id) expt = self._experiments[dataset_id] refl = self._reflections[dataset_id] expt.crystal = expt.crystal.change_basis(cb_op) if subgroup is not None: cb_op = subgroup["cb_op_inp_best"] * cb_op expt.crystal = expt.crystal.change_basis(cb_op) expt.crystal.set_space_group( subgroup["best_subsym"].space_group( ).build_derived_acentric_group()) else: expt.crystal = expt.crystal.change_basis(cb_op) expt.crystal.set_unit_cell( expt.crystal.get_space_group().average_unit_cell( expt.crystal.get_unit_cell())) refl["miller_index"] = cb_op.apply(refl["miller_index"]) # Allow for the case where some datasets are filtered out. if len(reindexing_ops) < len(self._experiments): to_delete = [ i for i in range(len(self._experiments)) if i not in unique_ids ] for idx in sorted(to_delete, reverse=True): logger.info( f"Removing dataset {idx} as unable to determine reindexing operator" ) del self._experiments[idx] del self._reflections[idx]
def run(): settings = [0] for i in xrange(1, 231): settings.append({}) list_cb_op = [] for xyz in ("x,y,z", "z,x,y", "y,z,x"): list_cb_op.append(sgtbx.change_of_basis_op(sgtbx.rt_mx(xyz))) n_built = 0 for i in sgtbx.space_group_symbol_iterator(): hall_symbol = i.hall() for z in "PABCIRHF": hall_z = hall_symbol[0] + z + hall_symbol[2:] for cb_op in list_cb_op: group = sgtbx.space_group(hall_z).change_basis(cb_op) sg_type = group.type() settings[sg_type.number()][sg_type.lookup_symbol()] = 0 n_built += 1 print "# n_built =", n_built n_non_redundant = 0 print "settings = (" for i in xrange(1, 231): print "#", i symbols = settings[i].keys() symbols.sort() for s in symbols: print "'" + s + "'," n_non_redundant += 1 print ")" print "# n_non_redundant =", n_non_redundant
def show_rfactors_targets_scales_overall(self, header = None, out=None): from cctbx import sgtbx if(out is None): out = sys.stdout out.flush() p = " " self._header_resolutions_nreflections(header=header, out=out) print >> out, "| "+" "*38+"|" self._rfactors_and_bulk_solvent_and_scale_params(out=out) line7="| normalized target function (%s) (work): %s"% ( self.target_name, n_as_s("%15.6f",self.target_work)) np = 79 - (len(line7) + 1) line7 = line7 + " "*np + "|" print >> out, line7 # no norm - work line71="| target function (%s) not normalized (work): %s"% ( self.target_name, n_as_s("%15.6f",self.target_work_no_norm)) np = 79 - (len(line71) + 1) line71 = line71 + " "*np + "|" print >> out, line71 # no norm - free line71="| target function (%s) not normalized (free): %s"% ( self.target_name, n_as_s("%15.6f",self.target_free_no_norm)) np = 79 - (len(line71) + 1) line71 = line71 + " "*np + "|" print >> out, line71 # if(self.twin_fraction is not None): line8="| twin fraction: "+format_value("%-4.2f",self.twin_fraction)+\ " twin operator: "+\ format_value("%-s",sgtbx.change_of_basis_op(self.twin_law).as_hkl()) np = 79 - (len(line8) + 1) line8 = line8 + " "*np + "|" print >> out, line8 print >> out, "|"+"-"*77+"|" out.flush()
def difference_rotation_matrix_axis_angle(crystal_a, crystal_b): from cctbx import sgtbx #assert crystal_a.get_space_group() == crystal_b.get_space_group() space_group = crystal_b.get_space_group() best_R_ab = None best_cb_op = None best_axis = None best_angle = 1e8 # iterate over space group ops to find smallest differences for i_op, op in enumerate( space_group.build_derived_laue_group().all_ops()): if op.r().determinant() < 0: continue elif not op.t().is_zero(): continue cb_op = sgtbx.change_of_basis_op(op.inverse()) crystal_b_sym = crystal_b.change_basis(cb_op) U_a = crystal_a.get_U() U_b = crystal_b_sym.get_U() assert U_a.is_r3_rotation_matrix() assert U_b.is_r3_rotation_matrix() # the rotation matrix to transform from U_a to U_b R_ab = U_b * U_a.transpose() axis_angle = r3_rotation_axis_and_angle_from_matrix(R_ab) axis = axis_angle.axis angle = axis_angle.angle() * 180.0 / math.pi if abs(angle) < abs(best_angle): best_angle = angle best_axis = axis best_R_ab = R_ab best_cb_op = cb_op return best_R_ab, best_axis, best_angle, best_cb_op
def generate_twin_operators(self, lattice_symmetry_max_delta=3.0): # see also mmtbx.scaling.twin_analyses.twin_laws cb_op_to_niggli_cell = \ self._data.change_of_basis_op_to_niggli_cell() if self._lattice_group is None: minimum_cell_symmetry = self._data.crystal_symmetry().change_basis( cb_op=cb_op_to_niggli_cell) self._lattice_group = sgtbx.lattice_symmetry.group( reduced_cell=minimum_cell_symmetry.unit_cell(), max_delta=lattice_symmetry_max_delta) intensity_symmetry = minimum_cell_symmetry.reflection_intensity_symmetry( anomalous_flag=self._data.anomalous_flag()) cb_op = cb_op_to_niggli_cell.inverse() else: cb_op = sgtbx.change_of_basis_op() intensity_symmetry = self._data.reflection_intensity_symmetry() operators = [] for partition in sgtbx.cosets.left_decomposition( g = self._lattice_group, h = intensity_symmetry.space_group() .build_derived_acentric_group() .make_tidy()).partitions[1:] : if (partition[0].r().determinant() > 0): operators.append(cb_op.apply(partition[0])) return operators
def __init__(self, f_in_p1, **kwds): isinstance(f_in_p1, miller.array) assert f_in_p1.space_group().type().hall_symbol() == ' P 1' self.f_in_p1 = f_in_p1 adopt_optional_init_args(self, kwds) self.search_parameters = maptbx.peak_search_parameters( peak_search_level=3, interpolate=True, min_distance_sym_equiv=0.25, ) self.space_group = sgtbx.space_group('P 1', t_den=sg_t_den) self.origin = None self.symmetry_pool = [] self.find_centring_translations() if self.space_group.order_z() > 1: f_in_centered = self.f_in_p1.customized_copy( space_group_info=sgtbx.space_group_info(group=self.space_group) ).eliminate_sys_absent().merge_equivalents().array() self.cb_op_to_primitive = \ f_in_centered.change_of_basis_op_to_primitive_setting() self.f_in_p1 = f_in_centered.change_basis(self.cb_op_to_primitive) self.space_group = self.f_in_p1.space_group() else: self.cb_op_to_primitive = sgtbx.change_of_basis_op() self.f_in_p1 = self.f_in_p1.generate_bijvoet_mates() self.find_space_group() self.space_group = sgtbx.space_group(self.space_group.type().hall_symbol(), t_den=sgtbx.sg_t_den) self.space_group_info = sgtbx.space_group_info(group=self.space_group)
def find_space_group(self): decorated_symmetry_pool = [] denominator = 12**3 for i, (r, d) in enumerate(self.cross_correlation_peaks()): t = sgtbx.tr_vec((d*denominator).as_int(), tr_den=denominator) cb_op = sgtbx.change_of_basis_op(sgtbx.rt_mx(r, t)) phi_sym = self.f_in_p1.symmetry_agreement_factor( cb_op, assert_is_similar_symmetry=False) if phi_sym < self.phi_sym_acceptance_cutoff: status = possible_symmetry.accepted elif phi_sym < self.phi_sym_rejection_cutoff: status = possible_symmetry.unsure else: status = possible_symmetry.rejected decorated_symmetry_pool.append( (-status, i, possible_symmetry(r, d, phi_sym, status))) decorated_symmetry_pool.sort() self.symmetry_pool = [ item[-1] for item in decorated_symmetry_pool ] self.origin = mat.mutable_zeros(3) for symm in self.symmetry_pool: if symm.status != symm.accepted: continue symm.set_components_of_global_origin(self.origin) if self.origin.elems.count(0) == 0: break for symm in self.symmetry_pool: if symm.status != symm.accepted: continue symm.change_origin(self.origin) self.space_group.expand_smx(symm.rt)
def subgroups_table(d): header = ( "Patterson group", "", "Likelihood", "NetZcc", "Zcc+", "Zcc-", "delta", "Reindex operator", ) rows = [header] for score in d["subgroup_scores"]: rows.append(( str( sgtbx.space_group( hall_symbol=str(score["patterson_group"])).info()), score["stars"], "%.3f" % score["likelihood"], "% .2f" % score["z_cc_net"], "% .2f" % score["z_cc_for"], "% .2f" % score["z_cc_against"], "%.1f" % score["max_angular_difference"], str(sgtbx.change_of_basis_op(str(score["cb_op"]))), )) return rows
def test_experimentlist_change_basis(dials_data): experiments = ExperimentList() for i in range(4): experiments.extend( ExperimentList.from_file( dials_data("vmxi_proteinase_k_sweeps") / ("experiments_%i.expt" % i), check_format=False, )) reindexed_uc = (68.368, 103.968, 68.368, 90.000, 90.000, 90.000) reindexed_sg = sgtbx.space_group_info("P 4 2 2 (b,c,a)").group() cb_op = sgtbx.change_of_basis_op("-a,-c,-b") for cb_op in (cb_op, [cb_op] * len(experiments)): expts_rdx = experiments.change_basis(cb_op) for expt in expts_rdx: assert expt.crystal.get_unit_cell().parameters() == pytest.approx( reindexed_uc, abs=0.1) assert expt.crystal.get_space_group() == reindexed_sg experiments.change_basis(cb_op, in_place=True) for expt in experiments: assert expt.crystal.get_unit_cell().parameters() == pytest.approx( reindexed_uc, abs=0.1) assert expt.crystal.get_space_group() == reindexed_sg with pytest.raises(AssertionError): experiments.change_basis([cb_op, cb_op])
def assign_operators(self, reidx_ops=None): arrays = self.arrays self.best_operators = None if reidx_ops is None: reidx_ops = self.find_reindex_ops() print >>self.log_out, "Reindex operators:", map(lambda x: str(x.as_hkl()), reidx_ops) print >>self.log_out, "" reidx_ops.sort(key=lambda x: not x.is_identity_op()) # identity op to first data = None latt_id = flex.int([]) for i, a in enumerate(arrays): if data is None: data = a else: data = data.concatenate(a, assert_is_similar_symmetry=False) latt_id.extend(flex.int(a.size(), i)) latt_id = data.customized_copy(data=latt_id.as_double()) result = brehm_diederichs.run(L=[data, latt_id], nproc=self.nproc, verbose=True) self.best_operators = map(lambda x: None, xrange(len(arrays))) for op in result: idxes = map(int, result[op]) print >>self.log_out, " %s num=%3d idxes= %s" %(op, len(result[op]), idxes) for idx in idxes: self.best_operators[idx] = sgtbx.change_of_basis_op(op)
def __init__(self, crystal_symmetry, symmetry_flags): self.cb_op_original_to_sampling = crystal_symmetry \ .change_of_basis_op_to_reference_setting() point_group_type = crystal_symmetry.space_group().point_group_type() add_cb_op = {"2": "z,x,y", "m": "y,z,x"}.get(point_group_type, None) if (add_cb_op is not None): self.cb_op_original_to_sampling = sgtbx.change_of_basis_op(add_cb_op) \ * self.cb_op_original_to_sampling sampling_symmetry = crystal_symmetry.change_basis( self.cb_op_original_to_sampling) search_symmetry = sgtbx.search_symmetry( flags=symmetry_flags, space_group_type=sampling_symmetry.space_group_info().type(), seminvariant=sampling_symmetry.space_group_info() .structure_seminvariants()) expanded_symmetry = crystal.symmetry( unit_cell=sampling_symmetry.unit_cell(), space_group=search_symmetry.projected_subgroup()) self.rational_asu = expanded_symmetry.space_group_info().direct_space_asu() self.rational_asu.add_planes( normal_directions=search_symmetry.continuous_shifts(), both_directions=True) self.float_asu=self.rational_asu.define_metric( unit_cell=expanded_symmetry.unit_cell()).as_float_asu() self.continuous_shift_flags=search_symmetry.continuous_shift_flags()
def difference_rotation_matrix_and_euler_angles(crystal_a, crystal_b): from cctbx import sgtbx #assert crystal_a.get_space_group() == crystal_b.get_space_group() space_group = crystal_b.get_space_group() min_sum_euler_angles = 1e8 best_R_ab = None best_cb_op = None # iterate over space group ops to find smallest differences for i_op, op in enumerate(space_group.build_derived_laue_group().all_ops()): if op.r().determinant() < 0: continue elif not op.t().is_zero(): continue cb_op = sgtbx.change_of_basis_op(op.inverse()) crystal_b_sym = crystal_b.change_basis(cb_op) U_a = crystal_a.get_U() U_b = crystal_b_sym.get_U() assert U_a.is_r3_rotation_matrix() assert U_b.is_r3_rotation_matrix() # the rotation matrix to transform from U_a to U_b R_ab = U_b * U_a.transpose() euler_angles = euler.xyz_angles(R_ab) sum_euler_angles = sum(abs(ea) for ea in euler_angles) if sum_euler_angles < min_sum_euler_angles: min_sum_euler_angles = sum_euler_angles best_R_ab = R_ab best_cb_op = cb_op best_euler_angles = euler.xyz_angles(best_R_ab) return best_R_ab, best_euler_angles, best_cb_op
def exercise(): ma = miller.array( miller.set(crystal.symmetry(unit_cell=(5,5,5, 90, 90, 90), space_group=sgtbx.space_group('P 2x')), indices=flex.miller_index( [(1,0,0), (0,1,0), (0,0,1), (-1,0,0), (0,-1,0), (0,0,-1), (1,1,0), (1,0,1), (0,1,1), (-1,-1,0), (-1,0,-1), (0,-1,-1), (1,-1,0), (1,0,-1), (0,1,-1), (-1,1,0), (-1,0,1), (0,-1,1), (1,1,1), (-1,1,1), (1,-1,1), (1,1,-1), (-1,-1,-1), (1,-1,-1), (-1,1,-1), (-1,-1,1)])), data=flex.complex_double(flex.random_double(26), flex.random_double(26))) f_at_h = dict(zip(ma.indices(), ma.data())) for op in ("-x, y+1/2, -z", "x+1/2, -y, z-1/2"): op = sgtbx.rt_mx(op) original, transformed = ma.common_sets( ma.change_basis(sgtbx.change_of_basis_op(op.inverse()))) for h, f in original: assert f == f_at_h[h] for h, op_f in transformed: assert approx_equal( op_f, f_at_h[h*op.r()]*exp(1j*2*pi*row(h).dot(col(op.t().as_double()))))
def reindex(self, reflections, experiments, solution): ''' Reindex with newly-determined space group / unit cell ''' # Update space group / unit cell experiment = experiments[0] print "Old crystal:" print experiment.crystal print experiment.crystal.update(solution.refined_crystal) print "New crystal:" print experiment.crystal print # Change basis cb_op = solution['cb_op_inp_best'].as_abc() change_of_basis_op = sgtbx.change_of_basis_op(cb_op) miller_indices = reflections['miller_index'] non_integral_indices = change_of_basis_op.apply_results_in_non_integral_indices( miller_indices) if non_integral_indices.size() > 0: print "Removing {}/{} reflections (change of basis results in non-integral indices)" \ "".format(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)) return experiments, reflections
def loop_over_super_cells(max_index, all_subgroups, subgroup): assert subgroup.n_ltr() == 1 for ia in xrange(1,max_index+1): for ib in xrange(1,max_index+1): for ic in xrange(1,max_index+1): cb_op = sgtbx.change_of_basis_op("x/%d,y/%d,z/%d" % (ia,ib,ic)) try: scsubgroup = subgroup.change_basis(cb_op=cb_op) except RuntimeError, e: if (str(e).endswith( "Unsuitable value for rational rotation matrix.")): all_subgroups["incompatible_rotation_denominator"] += 1 elif (str(e).endswith( "Unsuitable value for rational translation vector.")): all_subgroups["incompatible_translation_denominator"] += 1 else: raise RuntimeError else: def remove_lattice_translations(g): result = sgtbx.space_group( hall_symbol="P1", t_den=subgroup.t_den()) for i_inv in xrange(g.f_inv()): for i_smx in xrange(g.n_smx()): result.expand_smx(g(0, i_inv, i_smx)) return result subsubgroup = remove_lattice_translations(scsubgroup) uhm = sgtbx.space_group_type(group=subsubgroup) \ .universal_hermann_mauguin_symbol() all_subgroups[uhm] += 1
def test_twin_r_value(twin_operator): miller_array = random_data(35).map_to_asu() miller_array = miller_array.f_as_f_sq() for twin_fraction, expected_r_abs,expected_r_sq in zip( [0,0.1,0.2,0.3,0.4,0.5], [0.50,0.40,0.30,0.20,0.10,0.0], [0.333,0.213,0.120,0.0533,0.0133,0.00]): cb_op = sgtbx.change_of_basis_op( twin_operator ) miller_array_mod, miller_array_twin = miller_array.common_sets( miller_array.change_basis( cb_op ).map_to_asu() ) twinned_miller = miller_array_mod.customized_copy( data = (1.0-twin_fraction)*miller_array_mod.data() + twin_fraction*miller_array_twin.data(), sigmas = flex.sqrt( flex.pow( ((1.0-twin_fraction)*miller_array_mod.sigmas()),2.0)+\ flex.pow( ((twin_fraction)*miller_array_twin.sigmas()),2.0)) ) twinned_miller.set_observation_type( miller_array.observation_type()) twin_r = scaling.twin_r( twinned_miller.indices(), twinned_miller.data(), twinned_miller.space_group(), twinned_miller.anomalous_flag(), cb_op.c().r().as_double()[0:9] ) assert approx_equal(twin_r.r_abs_value(), expected_r_abs, 0.08) assert approx_equal(twin_r.r_sq_value(), expected_r_sq, 0.08)
def run(args): if "--full" in args: to_do = range(1, 230 + 1) elif "--special" in args: to_do = sorted(special.keys()) else: to_do = [75, 151] for space_group_number in to_do: sgi = sgtbx.space_group_info(number=space_group_number) sgi.show_summary(prefix="") sys.stdout.flush() n_special = 0 for m in scitbx.math.unimodular_generator(range=1).all(): cb_op = sgtbx.change_of_basis_op(sgtbx.rt_mx(sgtbx.rot_mx(m, 1), 1)).new_denominators(12, 144) cb_sgi = sgi.change_basis(cb_op=cb_op) cb_op_ref = cb_sgi.change_of_basis_op_to_reference_setting() ref_sgi = cb_sgi.change_basis(cb_op=cb_op_ref) assert ref_sgi.group() == sgi.group() c = cb_op_ref.c() if c.r().is_unit_mx() and c.t().num() != (0, 0, 0): n_special += 1 cb_ref_sgi = sgi.change_basis(cb_op=cb_op_ref) print " cb_op=%s -> %s" % (str(cb_op.c()), cb_ref_sgi.type().universal_hermann_mauguin_symbol()) sys.stdout.flush() # verify that c.t() is not an allowed origin shift assert cb_ref_sgi.group() != sgi.group() assert special.get(space_group_number, 0) == n_special print format_cpu_times()
def get_symop_correlation_coefficients(miller_array, use_binning=False): from copy import deepcopy from scitbx.array_family import flex from cctbx import miller corr_coeffs = flex.double() n_refs = flex.int() space_group = miller_array.space_group() for smx in space_group.smx(): reindexed_array = miller_array.change_basis(sgtbx.change_of_basis_op(smx)) intensity, intensity_rdx = reindexed_array.common_sets(miller_array) if use_binning: intensity.use_binning_of(miller_array) intensity_rdx.use_binning_of(miller_array) cc = intensity.correlation(intensity_rdx, use_binning=use_binning) corr_coeffs.append( flex.mean_weighted( flex.double(i for i in cc.data if i is not None), flex.double(j for i, j in zip(cc.data, cc.binner.counts()) if i is not None), ) ) else: corr_coeffs.append(intensity.correlation(intensity_rdx, use_binning=use_binning).coefficient()) n_refs.append(intensity.size()) return corr_coeffs, n_refs
def difference_rotation_matrix_axis_angle(crystal_a, crystal_b, target_angle=0): from cctbx import sgtbx # assert crystal_a.get_space_group() == crystal_b.get_space_group() space_group = crystal_b.get_space_group() best_R_ab = None best_cb_op = None best_axis = None best_angle = 1e8 # iterate over space group ops to find smallest differences for i_op, op in enumerate(space_group.build_derived_laue_group().all_ops()): if op.r().determinant() < 0: continue elif not op.t().is_zero(): continue cb_op = sgtbx.change_of_basis_op(op.inverse()) crystal_b_sym = crystal_b.change_basis(cb_op) U_a = crystal_a.get_U() U_b = crystal_b_sym.get_U() assert U_a.is_r3_rotation_matrix() assert U_b.is_r3_rotation_matrix() # the rotation matrix to transform from U_a to U_b R_ab = U_b * U_a.transpose() axis_angle = r3_rotation_axis_and_angle_from_matrix(R_ab) axis = axis_angle.axis angle = axis_angle.angle() * 180.0 / math.pi for sign in (+1, -1): if abs(sign * angle - target_angle) < abs(best_angle - target_angle): best_angle = sign * angle best_axis = tuple(sign * a for a in axis) best_R_ab = R_ab if sign > 0 else R_ab.inverse() best_cb_op = cb_op if sign > 0 else cb_op.inverse() return best_R_ab, best_axis, best_angle, best_cb_op
def detwin_miller_array(miller_obs, twin_law, twin_fraction): # for the moment, ignore incompleten twin pairs please cb_op = sgtbx.change_of_basis_op( twin_law ) twin_related_miller = miller_obs.change_basis( cb_op ).set_observation_type( miller_obs ) set1, set2 = miller_obs.common_sets( twin_related_miller )\ .set_observation_type(miller_obs ) assert miller_obs.observation_type() is not None assert miller_obs.sigmas() is not None if set1.is_xray_amplitude_array(): set1 = set1.f_as_f_sq() set2 = set1.f_as_f_sq() detwinned_f = flex.double() detwinned_sigma = flex.double() if set1.is_xray_intensity_array(): if set2.is_xray_intensity_array(): for i1,s1,i2,s2 in zip( set1.data(), set1.sigmas(), set2.data(), set2.sigmas() ): tmp_detwinner = detwin(i1,s1,i2,s2) # we do some double work here actually ni1 = tmp_detwinner.xm ns1 = math.sqrt( math.abs(self.vcv[0]) ) detwinned_f.append( ni1 ) detwinned_s.append( ns1 ) set1 = set1.f_sq_as_f() new_f = set1.customized_copy
def assign_operators(self, reidx_ops=None): arrays = self.arrays self.best_operators = None if reidx_ops is None: reidx_ops = self.find_reindex_ops() print >>self.log_out, "Reindex operators:", map(lambda x: str(x.as_hkl()), reidx_ops) print >>self.log_out, "" reidx_ops.sort(key=lambda x: not x.is_identity_op()) # identity op to first data = None latt_id = flex.int([]) for i, a in enumerate(arrays): if data is None: data = a else: data = data.concatenate(a, assert_is_similar_symmetry=False) latt_id.extend(flex.int(a.size(), i)) latt_id = data.customized_copy(data=latt_id.as_double()) result = brehm_diederichs.run(L=[data, latt_id], nproc=self.nproc, plot=True, verbose=True) self.best_operators = map(lambda x: None, xrange(len(arrays))) for op in result: idxes = map(int, result[op]) print >>self.log_out, " %s num=%3d idxes= %s" %(op, len(result[op]), idxes) for idx in idxes: self.best_operators[idx] = sgtbx.change_of_basis_op(op)
def exercise_space_group_contains(): g = sgtbx.space_group("P 2") for s in ["x,y,z", "-x,-y,z", "-x+1,-y-2,z+3"]: assert g.contains(sgtbx.rt_mx(s)) for s in ["x,y,-z", "x+1/2,y,z"]: assert not g.contains(sgtbx.rt_mx(s)) for symbols in sgtbx.space_group_symbol_iterator(): g = sgtbx.space_group(symbols.hall()) for s in g: assert g.contains(s) rnd = flex.mersenne_twister(seed=0) n_c = 0 n_nc = 0 for symbol in sgtbx.bravais_types.centric: g = sgtbx.space_group_info(symbol=symbol, space_group_t_den=144).group() for s in g.change_basis(sgtbx.change_of_basis_op("x+1/12,y-1/12,z+1/12")): if (rnd.random_double() < 0.9): continue # avoid long runtime gc = sgtbx.space_group(g) gc.expand_smx(s) if (gc.order_z() == g.order_z()): assert g.contains(s) n_c += 1 else: assert not g.contains(s) n_nc += 1 assert n_c == 11, n_c assert n_nc == 53, n_nc
def exercise_double_coset_decomposition(crystal_symmetry_ri, lattice_group, miller_array_subs, miller_array_sub_as, miller_array_sub_bs, coset_decompositions, i, j, verbose): group_a = miller_array_subs[i].space_group_info().group() group_b = miller_array_subs[j].space_group_info().group() miller_array_sub_a = miller_array_sub_as[i] miller_array_sub_b = miller_array_sub_bs[j] single_coset_ccs = {} for partition in coset_decompositions[i].partitions: cb_op = sgtbx.change_of_basis_op(partition[0]) cb = miller_array_sub_a.change_basis(cb_op).map_to_asu() cc = cb.correlation(other=miller_array_sub_b).coefficient() key = "%.6f" % cc single_coset_ccs.setdefault(key, []).append(str(partition[0])) double_coset_ccs = {} for c in sgtbx.cosets.double_unique(lattice_group, group_a, group_b): cb_op = sgtbx.change_of_basis_op(c) cb = miller_array_sub_b.change_basis(cb_op).map_to_asu() cc = cb.correlation(other=miller_array_sub_a).coefficient() key = "%.6f" % cc double_coset_ccs.setdefault(key, []).append(str(c)) double_coset_repetitions = [len(v) for v in double_coset_ccs.values()] failure = (max(double_coset_repetitions) > 1) if (failure or verbose): print( [str(sgtbx.space_group_info(group=g)) for g in (group_a, group_b)]) print("single_coset ops:", list(single_coset_ccs.values())) print("double_coset ops:", list(double_coset_ccs.values())) if (failure): for cc, ops in double_coset_ccs.items(): if (len(ops) > 1): print(cc, ops) for op in ops: ri = sgtbx.rt_mx(op).r().info() print(" ", ri.type(), ri.sense(), ri.ev()) raise RuntimeError("max(double_coset_repetitions) > 1") single_coset_ccs = list(single_coset_ccs.keys()) double_coset_ccs = list(double_coset_ccs.keys()) single_coset_ccs.sort() double_coset_ccs.sort() failure = (double_coset_ccs != single_coset_ccs) if (failure or verbose): print("single_coset_ccs:", single_coset_ccs) print("double_coset_ccs:", double_coset_ccs) if (failure): raise RuntimeError("double_coset_ccs != single_coset_ccs")
def exercise_find_matching_symmetry(): from cctbx import crystal, sgtbx, uctbx from dials.algorithms.indexing import symmetry def run_once(crystal_symmetry): cs = crystal_symmetry #print cs.show_summary() from cctbx.sgtbx import lattice_symmetry subgroups = lattice_symmetry.metric_subgroups(cs, max_delta=5) for op in ('x,y,z', 'z,x,y', 'y,z,x', '-x,z,y', 'y,x,-z', 'z,-y,x')[:]: cb_op = sgtbx.change_of_basis_op(op) uc_inp = cs.unit_cell().change_basis(cb_op) for ref_uc, ref_sg in [(cs.unit_cell(), cs.space_group()), (None, cs.space_group())][:]: best_subgroup = symmetry.find_matching_symmetry( uc_inp, target_space_group=ref_sg) cb_op_inp_best = best_subgroup['cb_op_inp_best'] assert uc_inp.change_basis(cb_op_inp_best).is_similar_to( cs.as_reference_setting().best_cell().unit_cell()) # 1) known unit cell and space group # -> cb op for test unit cell to best match for reference symmetry # 2) known unit cell # -> cb op for test unit cell to best match for given unit cell # 3) known space group # -> cb op for test unit cell to best match for given space group # Assumptions: # 1) test unit cell is minimum cell uc = uctbx.unit_cell("76, 115, 134, 90, 99.07, 90") sgi = sgtbx.space_group_info(symbol="I2") cs = crystal.symmetry(unit_cell=uc, space_group_info=sgi) uc_inp = uc.minimum_cell() cs_min = crystal.symmetry(unit_cell=cs.minimum_cell().unit_cell(), space_group=sgtbx.space_group()) uc = uctbx.unit_cell("42,42,40,90,90,90") sgi = sgtbx.space_group_info(symbol="P41212") cs = crystal.symmetry(unit_cell=uc, space_group_info=sgi) cb_op = sgtbx.change_of_basis_op("c,a,b") uc_inp = uc.change_basis(cb_op) run_once(cs.change_basis(cb_op)) from cctbx.sgtbx import bravais_types for symbol in bravais_types.acentric: sgi = sgtbx.space_group_info(symbol=symbol) uc = sgi.any_compatible_unit_cell(volume=1000) cs = crystal.symmetry(unit_cell=uc, space_group_info=sgi) cs = cs.niggli_cell().as_reference_setting().primitive_setting() run_once(cs)
def show_remark_3(self, out=None): from cctbx import sgtbx if (out is None): out = sys.stdout pr = "REMARK 3 " print >> out, pr + "REFINEMENT TARGET : %s" % self.target_name.upper() print >> out, pr print >> out, pr + "DATA USED IN REFINEMENT." print >> out, pr + " RESOLUTION RANGE HIGH (ANGSTROMS) : %s" % format_value( "%-8.3f", self.d_min) print >> out, pr + " RESOLUTION RANGE LOW (ANGSTROMS) : %s" % format_value( "%-8.3f", self.d_max) print >> out, pr + " MIN(FOBS/SIGMA_FOBS) : %s" % format_value( "%-6.2f", self.min_f_obs_over_sigma) print >> out,pr+" COMPLETENESS FOR RANGE (%s) : %-6.2f"%\ ("%", self.completeness_in_range*100.0) print >> out, pr + " NUMBER OF REFLECTIONS : %-10d" % self.number_of_reflections print >> out, pr + " NUMBER OF REFLECTIONS (NON-ANOMALOUS) : %-10d" % self.number_of_reflections_merged print >> out, pr print >> out, pr + "FIT TO DATA USED IN REFINEMENT." print >> out, pr + " R VALUE (WORKING + TEST SET) : %s" % format_value( "%-6.4f", self.r_all) print >> out, pr + " R VALUE (WORKING SET) : %s" % format_value( "%-6.4f", self.r_work) print >> out, pr + " FREE R VALUE : %s" % format_value( "%-6.4f", self.r_free) print >> out, pr + " FREE R VALUE TEST SET SIZE (%s) : %-6.2f" % ( "%", float(self.number_of_test_reflections) / self.number_of_reflections * 100.) print >> out, pr + " FREE R VALUE TEST SET COUNT : %-10d" % self.number_of_test_reflections print >> out, pr self.show_rwork_rfree_number_completeness( prefix=pr, title="FIT TO DATA USED IN REFINEMENT (IN BINS).", out=out) print >> out, pr print >> out, pr + "BULK SOLVENT MODELLING." print >> out, pr + " METHOD USED : FLAT BULK SOLVENT MODEL" print >> out, pr + " SOLVENT RADIUS : %s" % format_value( "%-8.2f", self.mask_solvent_radius) print >> out, pr + " SHRINKAGE RADIUS : %s" % format_value( "%-8.2f", self.mask_shrink_radius) print >> out, pr + " GRID STEP FACTOR : %s" % format_value( "%-8.2f", self.mask_grid_step_factor) print >> out, pr if (self.twin_fraction is not None): print >> out, pr + "TWINNING INFORMATION." print >> out, pr + " FRACTION: %s" % format_value( "%-8.3f", self.twin_fraction) print >> out,pr+" OPERATOR: %s"%\ format_value("%-s", sgtbx.change_of_basis_op(self.twin_law).as_hkl()) print >> out, pr + "ERROR ESTIMATES." print >> out,pr+" COORDINATE ERROR (MAXIMUM-LIKELIHOOD BASED) : %s"%\ format_value("%-8.2f", self.ml_coordinate_error) print >> out,pr+" PHASE ERROR (DEGREES, MAXIMUM-LIKELIHOOD BASED) : %s"%\ format_value("%-8.2f", self.ml_phase_error) print >> out, pr print >> out,pr+"STRUCTURE FACTORS CALCULATION ALGORITHM : %-s"%\ self.sf_algorithm.upper() out.flush()
def get_hkl_offset_correlation_coefficients( dials_reflections, dials_crystal, map_to_asu=False, grid_h=0, grid_k=0, grid_l=0, reference=None): # N.B. deliberately ignoring d_min, d_max as these are inconsistent with # changing the miller indices from dials.array_family import flex from cctbx.miller import set as miller_set from cctbx import sgtbx cs = cctbx_crystal_from_dials(dials_crystal) ms = cctbx_i_over_sigi_ms_from_dials_data(dials_reflections, cs) if reference: reference_ms = cctbx_i_over_sigi_ms_from_dials_data(reference, cs) else: reference_ms = None ccs = flex.double() offsets = flex.vec3_int() nref = flex.size_t() if reference: cb_op = sgtbx.change_of_basis_op('x,y,z') else: cb_op = sgtbx.change_of_basis_op('-x,-y,-z') hkl_test = [(h, k, l) for h in range(-grid_h, grid_h + 1) \ for k in range(-grid_k, grid_k + 1) \ for l in range(-grid_l, grid_l + 1)] for hkl in hkl_test: indices = offset_miller_indices(ms.indices(), hkl) reindexed_indices = cb_op.apply(indices) rms = miller_set(cs, reindexed_indices).array(ms.data()) if reference_ms: _ms = reference_ms else: _ms = miller_set(cs, indices).array(ms.data()) n, cc = compute_miller_set_correlation(_ms, rms, map_to_asu=map_to_asu) ccs.append(cc) offsets.append(hkl) nref.append(n) return offsets, ccs, nref
def convert_operator(change_of_basis): from cctbx import sgtbx try: c_o_b = sgtbx.change_of_basis_op(change_of_basis) except RuntimeError as e: raise Sorry(str(e)) else: return c_o_b
def exercise_monoclinic_cell_choices_core(space_group_number, verbose): # transformation matrices for cell choices # columns are basis vectors "new in terms of old" # see Int. Tab. Vol. A, p. 22, Fig. 2.2.6.4. b1 = (1, 0, 0, 0, 1, 0, 0, 0, 1) b2 = (-1, 0, 1, 0, 1, 0, -1, 0, 0) b3 = (0, 0, -1, 0, 1, 0, 1, 0, -1) flip = (0, 0, 1, 0, -1, 0, 1, 0, 0) p3s = sgtbx.space_group("P 3*") done = {} ref = sgtbx.space_group_info(number=space_group_number) ref_uhm = ref.type().universal_hermann_mauguin_symbol() for i_fl, fl in enumerate([b1, flip]): rfl = sgtbx.rot_mx(fl) cfl = sgtbx.change_of_basis_op(sgtbx.rt_mx(rfl)) for i_rt, rt in enumerate(p3s): rp3 = rt.r() cp3 = sgtbx.change_of_basis_op(sgtbx.rt_mx(rp3)) for i_cs, cs in enumerate([b1, b2, b3]): rcs = sgtbx.rot_mx(cs).inverse() ccs = sgtbx.change_of_basis_op(sgtbx.rt_mx(rcs)) cb_all = cp3 * cfl * ccs refcb = ref.change_basis(cb_all) refcb2 = sgtbx.space_group_info(symbol=ref_uhm + "(" + str(cb_all.c()) + ")") assert refcb2.group() == refcb.group() s = sgtbx.space_group_symbols(str(refcb)) q = s.qualifier() hm = str(refcb) if (0 or verbose): print(hm, q, cb_all.c()) if (i_fl == 0): assert q[0] == "bca"[i_rt] if (len(q) == 2): assert q[1] == "123"[i_cs] elif (q[0] == "-"): assert q[1] == "bca"[i_rt] if (len(q) == 3): assert q[2] == "123"[i_cs] else: assert q[0] == "bca"[i_rt] if (len(q) == 2 and q[1] != "123"[i_cs]): assert done[hm] == 1 done.setdefault(hm, 0) done[hm] += 1 assert len(done) in [3, 9, 18] assert list(done.values()) == [18 / len(done)] * len(done) if (0 or verbose): print() return done
def generate_unimodular_cells(cell): Amat = sqr(cell.orthogonalization_matrix()).transpose() for m in unimodular_generator(range=1).all(): c_inv = sgtbx.rt_mx(sgtbx.rot_mx(m)) orientation_similarity_cb_op = sgtbx.change_of_basis_op(c_inv).inverse() new_cell = cell.change_basis(orientation_similarity_cb_op) yield new_cell,orientation_similarity_cb_op
def _reindexing_ops( self, coords: np.ndarray, sym_ops: List[sgtbx.rt_mx], cosets: sgtbx.cosets.left_decomposition, ) -> List[sgtbx.change_of_basis_op]: """Identify the reindexing operator for each dataset. Args: coords (np.ndarray): A flattened list of the N-dimensional vectors, i.e. coordinates in the first dimension are stored first, followed by the coordinates in the second dimension, etc. sym_ops (List[sgtbx.rt_mx]): List of cctbx.sgtbx.rt_mx used for the cosym symmetry analysis cosets (sgtbx.cosets.left_decomposition): The left coset decomposition of the lattice group with respect to the proposed Patterson group Returns: List[sgtbx.change_of_basis_op]: A list of reindexing operators corresponding to each dataset. """ reindexing_ops = [] n_datasets = len(self.input_intensities) n_sym_ops = len(sym_ops) coord_ids = np.arange(n_datasets * n_sym_ops) dataset_ids = coord_ids % n_datasets # choose a high density point as seed X = coords nbrs = NearestNeighbors(n_neighbors=min(11, len(X)), algorithm="brute", metric="cosine").fit(X) distances, indices = nbrs.kneighbors(X) average_distance = np.array([dist[1:].mean() for dist in distances]) i = average_distance.argmin() xis = np.array([X[i]]) for j in range(n_datasets): sel = np.where(dataset_ids == j) X = coords[sel] # Find nearest neighbour in cosine-space to the current cluster centroid nbrs = NearestNeighbors(n_neighbors=min(1, len(X)), algorithm="brute", metric="cosine").fit(X) distances, indices = nbrs.kneighbors([xis.mean(axis=0)]) k = indices[0][0] xis = np.append(xis, [X[k]], axis=0) for partition in cosets.partitions: if sym_ops[k] in partition: cb_op = sgtbx.change_of_basis_op( partition[0]).new_denominators(self.cb_op_inp_min) reindexing_ops.append( (self.cb_op_inp_min.inverse() * cb_op * self.cb_op_inp_min).as_xyz()) break return reindexing_ops
def test_symmetry_basis_changes_for_C2(tmpdir): """Test the correctness of change of basis operations in dials.symmetry Supply the unit cell of beta-lactamase, which triggers a change of basis from input to minimum during symmetry analysis.""" os.chdir(tmpdir.strpath) unit_cell = (53.173, 61.245, 69.292, 90.0, 93.04675, 90.0) space_group = sgtbx.space_group_info("C 2").group() experiments, reflections, _ = generate_experiments_reflections( space_group=space_group, unit_cell=unit_cell, sample_size=1, map_to_minimum=False, ) experiments.as_json("tmp.expt") expt_file = tmpdir.join("tmp.expt").strpath joint_table = flex.reflection_table() for r in reflections: joint_table.extend(r) joint_table.as_file("tmp.refl") refl_file = tmpdir.join("tmp.refl").strpath command = ["dials.symmetry", expt_file, refl_file, "json=symmetry.json"] result = procrunner.run(command, working_directory=tmpdir.strpath) assert not result.returncode and not result.stderr assert tmpdir.join("symmetrized.refl").check(file=1) assert tmpdir.join("symmetrized.expt").check(file=1) expts = load.experiment_list(tmpdir.join("symmetrized.expt").strpath, check_format=False) for v, expected in zip(expts[0].crystal.get_unit_cell().parameters(), unit_cell): assert v == pytest.approx(expected) # Using the change of basis ops from the json output we should be able to # reindex the input experiments to match the output experiments with tmpdir.join("symmetry.json").open() as f: d = json.load(f) cs = experiments[0].crystal.get_crystal_symmetry() cb_op_inp_min = sgtbx.change_of_basis_op(str(d["cb_op_inp_min"][0])) cb_op_min_best = sgtbx.change_of_basis_op( str(d["subgroup_scores"][0]["cb_op"])) assert cs.change_basis(cb_op_min_best * cb_op_inp_min).is_similar_symmetry( expts[0].crystal.get_crystal_symmetry())
def get_indexing_offset_correlation_coefficients( reflections, crystal, grid_search_scope, d_min=None, d_max=None, map_to_asu=False ): from copy import deepcopy from dials.array_family import flex space_group = crystal.get_space_group() unit_cell = crystal.get_unit_cell() from cctbx.crystal import symmetry as crystal_symmetry cs = crystal_symmetry(unit_cell, space_group.type().lookup_symbol()) from cctbx.miller import set as miller_set data = reflections["intensity.sum.value"] / flex.sqrt(reflections["intensity.sum.variance"]) ccs = flex.double() offsets = flex.vec3_int() nref = flex.size_t() original_miller_indices = reflections["miller_index"] ms = miller_set(cs, original_miller_indices) ms = ms.array(data) if d_min is not None or d_max is not None: ms = ms.resolution_filter(d_min=d_min, d_max=d_max) if map_to_asu: ms = ms.map_to_asu() g = grid_search_scope for h in range(-g, g + 1): for k in range(-g, g + 1): for l in range(-g, g + 1): for smx in ["-x,-y,-z"]: # reindexed = deepcopy(reflections) # hkl offset doubled as equivalent of h0 + 1, hI - 1 miller_indices = offset_miller_indices(ms.indices(), (2 * h, 2 * k, 2 * l)) reindexed_miller_indices = sgtbx.change_of_basis_op(smx).apply(miller_indices) rms = miller_set(cs, reindexed_miller_indices) rms = rms.array(data) # if params.d_min or params.d_max: # rms = rms.resolution_filter(d_min=params.d_min, d_max=params.d_max) # if map_to_asu: # rms = rms.map_to_asu() intensity, intensity_rdx = rms.common_sets(ms) cc = intensity.correlation(intensity_rdx).coefficient() ccs.append(cc) offsets.append((h, k, l)) nref.append(intensity.size()) return offsets, ccs, nref
def generate_reindex_sets(self, obs_in): ops = self.generate_twin_operators(obs_in) alternates = {'h,k,l': obs_in} for op in ops: hkl = obs_in.indices() cb_op = sgtbx.change_of_basis_op(op.operator.r().as_hkl()) hklrev = cb_op.apply(hkl) alternates[op.operator.r().as_hkl()] = obs_in.customized_copy(indices = hklrev).map_to_asu() return alternates
def generate_reindex_sets(self): ops = self.generate_twin_operators() alternates = {} for op in ops: hkl = self.data.indices() cb_op = sgtbx.change_of_basis_op(op.operator.r().as_hkl()) hklrev = cb_op.apply(hkl) alternates[op.operator.r().as_hkl()] = self.data.customized_copy(indices = hklrev).map_to_asu() return alternates
def create_shelx_reflection_data_source(self, format, indices_transform=None, change_of_basis_op=None, data_scale=1): """ format is one of 3, 4, 5, etc. data_scale scales the data and their standard deviations """ assert [indices_transform, change_of_basis_op].count(None) == 1 if change_of_basis_op is None: if indices_transform.is_unit_mx(): change_of_basis_op = sgtbx.change_of_basis_op() else: r = sgtbx.rt_mx(indices_transform.new_denominator(24).transpose()) change_of_basis_op = sgtbx.change_of_basis_op(r).inverse() self.reflection_file_format = "hklf%i" % format self.data_change_of_basis_op = change_of_basis_op self.data_scale = data_scale
def __call__(self, params, options): ''' Import the integrate.hkl file. ''' from iotbx.xds import integrate_hkl from dials.array_family import flex from dials.util.command_line import Command from cctbx import sgtbx # Get the unit cell to calculate the resolution uc = self._experiment.crystal.get_unit_cell() # Read the INTEGRATE.HKL file Command.start('Reading INTEGRATE.HKL') handle = integrate_hkl.reader() handle.read_file(self._integrate_hkl) hkl = flex.miller_index(handle.hkl) xyzcal = flex.vec3_double(handle.xyzcal) xyzobs = flex.vec3_double(handle.xyzobs) iobs = flex.double(handle.iobs) sigma = flex.double(handle.sigma) rlp = flex.double(handle.rlp) peak = flex.double(handle.peak) * 0.01 Command.end('Read %d reflections from INTEGRATE.HKL file.' % len(hkl)) # Derive the reindex matrix rdx = self.derive_reindex_matrix(handle) print 'Reindex matrix:\n%d %d %d\n%d %d %d\n%d %d %d' % (rdx.elems) # Reindex the reflections Command.start('Reindexing reflections') cb_op = sgtbx.change_of_basis_op(sgtbx.rt_mx(sgtbx.rot_mx(rdx.elems))) hkl = cb_op.apply(hkl) Command.end('Reindexed %d reflections' % len(hkl)) # Create the reflection list Command.start('Creating reflection table') table = flex.reflection_table() table['id'] = flex.int(len(hkl), 0) table['panel'] = flex.size_t(len(hkl), 0) table['miller_index'] = hkl table['xyzcal.px'] = xyzcal table['xyzobs.px.value'] = xyzobs table['intensity.cor.value'] = iobs table['intensity.cor.variance'] = sigma**2 table['intensity.prf.value'] = iobs * peak / rlp table['intensity.prf.variance'] = (sigma * peak / rlp)**2 table['lp'] = 1.0 / rlp table['d'] = flex.double(uc.d(h) for h in hkl) Command.end('Created table with {0} reflections'.format(len(table))) # Output the table to pickle file if params.output.filename is None: params.output.filename = 'integrate_hkl.pickle' Command.start('Saving reflection table to %s' % params.output.filename) table.as_pickle(params.output.filename) Command.end('Saved reflection table to %s' % params.output.filename)
def _change_of_basis(self): if(self.params.change_of_basis is not None): print("Applying change-of-basis operator '%s'" % \ self.params.change_of_basis, file=self.log) from cctbx import sgtbx cb_op = sgtbx.change_of_basis_op(self.params.change_of_basis) self.xray_structure = self.xray_structure.change_basis(cb_op) self.pdb_hierarchy.atoms().set_xyz(self.xray_structure.sites_cart()) print("New symmetry:", file=self.log) self.xray_structure.crystal_symmetry().show_summary(f=self.log, prefix=" ") self.crystal_symmetry = self.xray_structure.crystal_symmetry()
def exercise(): from dials.algorithms.indexing import compare_orientation_matrices from dxtbx.model import Crystal 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(real_space_a, real_space_b, real_space_c, space_group=sgtbx.space_group('P 1')) crystal_b = Crystal(R * real_space_a, R * real_space_b, R * real_space_c, space_group=sgtbx.space_group('P 1')) assert approx_equal( matrix.sqr(crystal_b.get_U()) * matrix.sqr(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(real_space_a, real_space_b, real_space_c, space_group=sgtbx.space_group('I 2 3')) crystal_b = Crystal(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 get_observations_non_polar(self, observations_original, pickle_filename, iparams): #return observations with correct polarity if iparams.indexing_ambiguity.index_basis_in is None: return observations_original.map_to_asu(), 'h,k,l' ind_pickle = pickle.load(open(iparams.indexing_ambiguity.index_basis_in, "rb")) if pickle_filename not in ind_pickle: return observations_original.map_to_asu(), 'Not Found' from cctbx import sgtbx cb_op = sgtbx.change_of_basis_op(ind_pickle[pickle_filename]) observations_alt = observations_original.map_to_asu().change_basis(cb_op).map_to_asu() return observations_alt, ind_pickle[pickle_filename]
def construct_rational_point_group( space_group, cb_op=None ): gr = rat_rot_group() if cb_op is None: cb_op = sgtbx.change_of_basis_op( "a,b,c" ) cb_op = cb_op_as_rational( cb_op ) for s in space_group: tmp_r = rt_mx_as_rational( s.r() ) gr.expand( tmp_r ) gr.change_basis( cb_op ) gr.expand(show=False) return gr
def construct_rational_point_group(space_group, cb_op=None): gr = rat_rot_group() if cb_op is None: cb_op = sgtbx.change_of_basis_op("a,b,c") cb_op = cb_op_as_rational(cb_op) for s in space_group: tmp_r = rt_mx_as_rational(s.r()) gr.expand(tmp_r) gr.change_basis(cb_op) gr.expand(show=False) return gr
def combined_cb_op(self, other, cb_op): sc = self.change_of_basis_op_to_minimum_cell oc = other.change_of_basis_op_to_minimum_cell cb_op = cb_op.new_denominators(sc) best_choice = None best_choice_as_hkl = None for s_symop in self.minimum_cell_symmetry.space_group(): s_symop = sgtbx.change_of_basis_op(sgtbx.rt_mx( s_symop.r())).new_denominators(sc) for o_symop in other.minimum_cell_symmetry.space_group(): o_symop = sgtbx.change_of_basis_op(sgtbx.rt_mx( o_symop.r())).new_denominators(sc) possible_choice = sc.inverse() * s_symop * cb_op * o_symop * oc possible_choice_as_hkl = possible_choice.as_hkl() if (best_choice_as_hkl is None or sgtbx.compare_cb_op_as_hkl( best_choice_as_hkl, possible_choice_as_hkl) > 0): best_choice = possible_choice best_choice_as_hkl = possible_choice_as_hkl assert best_choice is not None return best_choice
def main(mtz, index_basis): # read in mtz reflection_file = reflection_file_reader.any_reflection_file(mtz) miller_arrays = reflection_file.as_miller_arrays() # apply new basis cb_op = sgtbx.change_of_basis_op(index_basis) miller_array_new = miller_arrays[0].change_basis(cb_op) # write out new mtz hklout = os.path.splitext(mtz)[0] + "_modified.mtz" mtz_dataset = miller_array_new.as_mtz_dataset(column_root_label="IOBS") mtz_dataset.mtz_object().write(file_name=hklout) print("Output file saved to", hklout)
def combined_cb_op(self, other, cb_op): sc = self.change_of_basis_op_to_minimum_cell oc = other.change_of_basis_op_to_minimum_cell cb_op = cb_op.new_denominators(sc) best_choice = None best_choice_as_hkl = None for s_symop in self.minimum_cell_symmetry.space_group(): s_symop = sgtbx.change_of_basis_op(sgtbx.rt_mx(s_symop.r())).new_denominators(sc) for o_symop in other.minimum_cell_symmetry.space_group(): o_symop = sgtbx.change_of_basis_op(sgtbx.rt_mx(o_symop.r())).new_denominators(sc) possible_choice = sc.inverse() * s_symop * cb_op * o_symop * oc possible_choice_as_hkl = possible_choice.as_hkl() if ( best_choice_as_hkl is None or sgtbx.compare_cb_op_as_hkl(best_choice_as_hkl, possible_choice_as_hkl) > 0 ): best_choice = possible_choice best_choice_as_hkl = possible_choice_as_hkl assert best_choice is not None return best_choice
def change_basis(self, cb_op): if (not isinstance(cb_op, sgtbx.change_of_basis_op)): cb_op = sgtbx.change_of_basis_op(cb_op) cb_hall_symbol = None if (self.hall_symbol is not None): space_group_info = sgtbx.space_group_info("Hall: " + self.hall_symbol) cb_space_group_info = space_group_info.change_basis(cb_op) cb_hall_symbol = cb_space_group_info.type().hall_symbol() cb_asu = direct_space_asu(cb_hall_symbol) for cut in self.cuts: cb_asu.cuts.append(cut.change_basis(cb_op)) return cb_asu
def exercise_inversion_centring(): cb = sgtbx.change_of_basis_op("x+1/12,y+1/12,z-1/12") for symb in sgtbx.space_group_symbol_iterator(): sg = sgtbx.space_group(space_group_symbols=symb) sg1 = sg.change_basis(cb) icb = sg1.change_of_origin_realising_origin_centricity() if sg1.is_centric(): assert not sg1.is_origin_centric() sg2 = sg1.change_basis(icb) assert sg2.is_origin_centric() else: assert str(icb) == "a,b,c"