def __init__(self, with_special_position_pivot): self.with_special_position_pivot = with_special_position_pivot self.uc = uctbx.unit_cell((1, 2, 3)) self.sg = sgtbx.space_group("P 6") self.c0 = xray.scatterer("C0", site=(1e-5, 0., 0.1)) self.site_symm = sgtbx.site_symmetry(self.uc, self.sg, self.c0.site) self.c0.flags.set_grad_site(True) self.c1 = xray.scatterer("C1", site=(0.09, 0.11, 0.)) self.c1.flags.set_grad_site(True) self.h = xray.scatterer("H") self.reparam = constraints.ext.reparametrisation(self.uc) if with_special_position_pivot: x0 = self.reparam.add(constraints.special_position_site_parameter, self.site_symm, self.c0) else: x0 = self.reparam.add(constraints.independent_site_parameter, self.c0) x1 = self.reparam.add(constraints.independent_site_parameter, self.c1) l = self.reparam.add(constraints.independent_scalar_parameter, self.bond_length, variable=False) x_h = self.reparam.add(constraints.terminal_linear_ch_site, pivot=x0, pivot_neighbour=x1, length=l, hydrogen=self.h) self.reparam.finalise() self.x0, self.x1, self.x_h, self.l = [ x.index for x in (x0, x1, x_h, l) ] if self.with_special_position_pivot: self.y0 = x0.independent_params.index
def __init__(self): cs = crystal.symmetry(uctbx.unit_cell((1, 1, 2, 90, 90, 120)), 'R3') sgi = sgtbx.space_group_info('R3(y+z, x+z, x+y+z)') op = sgi.change_of_basis_op_to_reference_setting() self.cs = cs.change_basis(op.inverse()) self.sc = xray.scatterer('C', site=(3/8,)*3, u=(1/2, 1/4, 3/4, -3/2, -3/4, -1/4)) self.sc.flags.set_grad_u_aniso(True) self.site_symm = sgtbx.site_symmetry(self.cs.unit_cell(), self.cs.space_group(), self.sc.site) self.reparam = constraints.ext.reparametrisation(self.cs.unit_cell()) u = self.reparam.add(constraints.special_position_u_star_parameter, self.site_symm, self.sc) self.reparam.finalise() self.u, self.v = u.index, u.independent_params.index
def __init__(self): cs = crystal.symmetry(uctbx.unit_cell((1, 1, 2, 90, 90, 120)), 'R3') sgi = sgtbx.space_group_info('R3(y+z, x+z, x+y+z)') op = sgi.change_of_basis_op_to_reference_setting() self.cs = cs.change_basis(op.inverse()) self.sc = xray.scatterer('C', site=(3 / 8, ) * 3, u=(1 / 2, 1 / 4, 3 / 4, -3 / 2, -3 / 4, -1 / 4)) self.sc.flags.set_grad_u_aniso(True) self.site_symm = sgtbx.site_symmetry(self.cs.unit_cell(), self.cs.space_group(), self.sc.site) self.reparam = constraints.ext.reparametrisation(self.cs.unit_cell()) u = self.reparam.add(constraints.special_position_u_star_parameter, self.site_symm, self.sc) self.reparam.finalise() self.u, self.v = u.index, u.independent_params.index
def apply_symmetry(self, unit_cell, space_group, min_distance_sym_equiv=0.5, u_star_tolerance=0, assert_min_distance_sym_equiv=True): site_symmetry = sgtbx.site_symmetry(unit_cell, space_group, self.site, min_distance_sym_equiv, assert_min_distance_sym_equiv) self.site = site_symmetry.exact_site() self._multiplicity = site_symmetry.multiplicity() self.update_weight(space_group.order_z()) if (self.anisotropic_flag): if (u_star_tolerance > 0.): assert site_symmetry.is_compatible_u_star( self.u_star, u_star_tolerance) self.u_star = site_symmetry.average_u_star(self.u_star) return site_symmetry
def apply_symmetry(self, unit_cell, space_group, min_distance_sym_equiv=0.5, u_star_tolerance=0, assert_min_distance_sym_equiv=True): site_symmetry = sgtbx.site_symmetry( unit_cell, space_group, self.site, min_distance_sym_equiv, assert_min_distance_sym_equiv) self.site = site_symmetry.exact_site() self._multiplicity = site_symmetry.multiplicity() self.update_weight(space_group.order_z()) if (self.anisotropic_flag): if (u_star_tolerance > 0.): assert site_symmetry.is_compatible_u_star(self.u_star,u_star_tolerance) self.u_star = site_symmetry.average_u_star(self.u_star) return site_symmetry
def build_water_hydrogens_from_map2(model, fmodel, params=None, log=None): self = model xs = self.xray_structure unit_cell = xs.unit_cell() scatterers = xs.scatterers() hier = model.pdb_hierarchy() mmtbx.utils.assert_model_is_consistent(model) #assert_water_is_consistent(model) model.reprocess_pdb_hierarchy_inefficient() assert_water_is_consistent(model) if log is None: log = model.log if params is None: params = all_master_params().extract() max_od_dist = params.max_od_dist min_od_dist = params.min_od_dist assert min_od_dist >0.5 assert max_od_dist >min_od_dist and max_od_dist<1.5 keep_max = params.map_next_to_model.max_model_peak_dist keep_min = params.map_next_to_model.min_model_peak_dist params.map_next_to_model.max_model_peak_dist = max_od_dist * 1.8 params.map_next_to_model.min_model_peak_dist = min_od_dist params.peak_search.min_cross_distance = params.min_od_dist # 0.5 if params.peak_search.min_cross_distance < 0.7: params.peak_search.min_cross_distance = 0.7 #if params.map_next_to_model.min_model_peak_dist < 0.7: # params.map_next_to_model.min_model_peak_dist = 0.7 params.map_next_to_model.use_hydrogens = True params.map_next_to_model.min_peak_peak_dist = min_od_dist #if params.map_next_to_model.min_peak_peak_dist <0.7: # params.map_next_to_model.min_peak_peak_dist = 0.7 max_dod_angle = params.max_dod_angle min_dod_angle = params.min_dod_angle assert max_dod_angle<180 and min_dod_angle>30 and max_dod_angle>min_dod_angle peaks = find_hydrogen_peaks( fmodel = fmodel, pdb_atoms = model.pdb_atoms, params = params, log = log) if peaks is None: return model params.map_next_to_model.use_hydrogens = False hs = peaks.heights params.map_next_to_model.max_model_peak_dist = keep_max params.map_next_to_model.min_model_peak_dist = keep_min sol_O = model.solvent_selection().set_selected( model.xray_structure.hd_selection(), False) print >>log, "Number of solvent molecules: ", sol_O.count(True) sol_sel = model.solvent_selection() hd_sel = sol_sel & model.xray_structure.hd_selection() print>>log, "Number of water hydrogens: ", hd_sel.count(True) # pks = distances_to_peaks(xs, peaks.sites, hs, max_od_dist, use_selection=sol_O) obsmap = obs_map(fmodel, map_type=params.secondary_map_type) # filtered_peaks = map_peak_filter(peaks.sites, obsmap) #print>>log, "Number of filtered peaks: ", len(filtered_peaks) # pkss = distances_to_peaks(xs, peaks.sites, hs, max_od_dist*1.7, use_selection=sol_O) #pkss = distances_to_peaks(xs, filtered_peaks, hs, max_od_dist*1.7, # use_selection=sol_O) cutoff2 = params.secondary_map_cutoff assert cutoff2 > 0. and cutoff2 < 100. pkss = make_peak_dict(peaks, sol_O, obsmap, cutoff2) npeaks=0 for pk in pkss.values(): npeaks = npeaks + len(pk) print>>log, "Peaks to consider: ", npeaks water_rgs = self.extract_water_residue_groups() water_rgs.reverse() element='D' next_to_i_seqs = [] for rg in water_rgs: if (rg.atom_groups_size() != 1): raise RuntimeError( "Not implemented: cannot handle water with alt. conf.") ag = rg.only_atom_group() atoms = ag.atoms() h_atoms = [] o_atom=None if atoms.size()>0: for atom in atoms: if (atom.element.strip() == "O"): o_atom = atom else: h_atoms.append(atom) else: assert False o_i = o_atom.i_seq if pkss.has_key(o_i) : o_site = scatterers[o_i].site site_symmetry = sgtbx.site_symmetry(xs.unit_cell(), xs.space_group(), o_site, 0.5, True) if(site_symmetry.n_matrices() != 1): special = True continue # TODO: handle this situation o_u = scatterers[o_i].u_iso_or_equiv(unit_cell) h_sites = pkss[o_i] # print_atom(sys.stdout, o_atom) val = obsmap.eight_point_interpolation(o_site) if val>cutoff2: h_sites.append((0., o_site)) for hatom in h_atoms: hsite = scatterers[hatom.i_seq].site doh = unit_cell.distance(hsite, o_site) assert doh >0.5 and doh < 1.45, "%f\n%s"%(doh,atom_as_str(hatom)) val = obsmap.eight_point_interpolation(hsite) if val>cutoff2: h_sites.append((0., hsite)) dod = match_dod(unit_cell, h_sites, min_od=params.min_od_dist, max_od=params.max_od_dist, min_dod_angle=params.min_dod_angle, max_dod_angle=params.max_dod_angle) if dod is None: od= match_od(unit_cell, h_sites, min_od=params.min_od_dist, max_od=params.max_od_dist) if od is not None: scatterers[o_i].site = od[0] o_atom.xyz = unit_cell.orthogonalize(od[0]) h=od[1] if len(h_atoms)>0: hatom = h_atoms.pop() hatom.xyz = unit_cell.orthogonalize(h) hatom.occ = 1 hatom.b = cctbx.adptbx.u_as_b(o_u) hatom.name = "D1" h_i = hatom.i_seq scatterers[h_i].label = "D1" scatterers[h_i].site = h scatterers[h_i].occupancy = 1 scatterers[h_i].u_iso = o_u if len(h_atoms)>0: # mark for deletion hatom = h_atoms.pop() hatom.name = "D2" hatom.occ = 0. h_i = hatom.i_seq scatterers[h_i].label="D2" scatterers[h_i].occupancy=0. else: insert_atom_into_model(xs, atom=o_atom, atom_name="D1", site_frac=h, occupancy=1, uiso=o_u, element='D') next_to_i_seqs.append(o_atom.i_seq) else: scatterers[o_i].site = dod[1] o_atom.xyz = unit_cell.orthogonalize(dod[1]) ii=1 for h in (dod[0],dod[2]): name = "D"+str(ii) ii=ii+1 if len(h_atoms)>0: hatom = h_atoms.pop() hatom.xyz = unit_cell.orthogonalize(h) hatom.occ = 1 hatom.b = cctbx.adptbx.u_as_b(o_u) hatom.name = name h_i = hatom.i_seq scatterers[h_i].label = name scatterers[h_i].site = h scatterers[h_i].occupancy = 1 scatterers[h_i].u_iso = o_u else: insert_atom_into_model(xs, atom=o_atom, atom_name=name, site_frac=h, occupancy=1, uiso=o_u, element='D') next_to_i_seqs.append(o_atom.i_seq) if( model.refinement_flags is not None and len(next_to_i_seqs)!=0): # TODO: adp_group=True according to params.dod_and_od_group_adp model.refinement_flags.add( next_to_i_seqs=next_to_i_seqs, # [i_seq], # , sites_individual = True, s_occupancies = False, adp_individual_iso=True) print >> log, "Number of H added:", len(next_to_i_seqs) # print "DEBUG! ", dir(model.refinement_flags) #.size() # print "DEBUG! ", dir(model.refinement_flags.sites_individual) #.size() #print "DEBUG! ", model.refinement_flags.sites_individual.size() model.reprocess_pdb_hierarchy_inefficient() if model.refinement_flags.sites_individual is not None: np = model.refinement_flags.sites_individual.size() assert np == model.xray_structure.scatterers().size() assert model.refinement_flags.sites_individual.count(True) == np mmtbx.utils.assert_model_is_consistent(model) sol_sel = model.solvent_selection() hd_sel = sol_sel & model.xray_structure.hd_selection() assert hd_sel.count(True) >= len(next_to_i_seqs) assert_water_is_consistent(model) if False: model.idealize_h() model.pdb_hierarchy(sync_with_xray_structure=True) mmtbx.utils.assert_model_is_consistent(model) assert_water_is_consistent(model) return model
def fit_water(water_and_peaks, xray_structure, params, log): scatterers = xray_structure.scatterers() uc = xray_structure.unit_cell() site_frac_o = scatterers[water_and_peaks.i_seq_o ].site site_frac_h1 = scatterers[water_and_peaks.i_seq_h1].site site_frac_h2 = scatterers[water_and_peaks.i_seq_h2].site peak_sites_frac = water_and_peaks.peaks_sites_frac if(len(peak_sites_frac) == 1): sc1 = scatterers[water_and_peaks.i_seq_h1] sc2 = scatterers[water_and_peaks.i_seq_h2] if(sc1.occupancy < sc2.occupancy and sc2.occupancy > 0.3): site_frac_h2 = sc2.site elif(sc1.occupancy > sc2.occupancy and sc1.occupancy > 0.3): site_frac_h2 = scatterers[water_and_peaks.i_seq_h1].site else: site_frac_h2 = peak_sites_frac[0] result = mmtbx.utils.fit_hoh( site_frac_o = site_frac_o, site_frac_h1 = site_frac_h1, site_frac_h2 = site_frac_h2, site_frac_peak1 = peak_sites_frac[0], site_frac_peak2 = site_frac_h2, angular_shift = params.angular_step, unit_cell = uc) d_best = result.dist_best() o = uc.fractionalize(result.site_cart_o_fitted) h1 = uc.fractionalize(result.site_cart_h1_fitted) h2 = uc.fractionalize(result.site_cart_h2_fitted) else: peak_pairs = [] for i, s1 in enumerate(peak_sites_frac): for j, s2 in enumerate(peak_sites_frac): if i < j: peak_pairs.append([s1,s2]) d_best = 999. for pair in peak_pairs: result = mmtbx.utils.fit_hoh( site_frac_o = site_frac_o, site_frac_h1 = site_frac_h1, site_frac_h2 = site_frac_h2, site_frac_peak1 = pair[0], site_frac_peak2 = pair[1], angular_shift = params.angular_step, unit_cell = uc) if(result.dist_best() < d_best): d_best = result.dist_best() o = uc.fractionalize(result.site_cart_o_fitted) h1 = uc.fractionalize(result.site_cart_h1_fitted) h2 = uc.fractionalize(result.site_cart_h2_fitted) if(d_best < 1.0): # do not move HOH located on special position skip = False sites = [scatterers[water_and_peaks.i_seq_o ].site, scatterers[water_and_peaks.i_seq_h1].site, scatterers[water_and_peaks.i_seq_h2].site] for site in sites: site_symmetry = sgtbx.site_symmetry( xray_structure.unit_cell(), xray_structure.space_group(), site, 0.5, True) if(site_symmetry.n_matrices() != 1): skip = True break # if(not skip): scatterers[water_and_peaks.i_seq_o ].site = o scatterers[water_and_peaks.i_seq_h1].site = h1 scatterers[water_and_peaks.i_seq_h2].site = h2 print >> log, "%6.3f"%d_best
def build_water_hydrogens_from_map2(model, fmodel, params=None, log=None): # self = model xs = model.get_xray_structure() unit_cell = xs.unit_cell() scatterers = xs.scatterers() hier = model.get_hierarchy() mmtbx.utils.assert_model_is_consistent(model) #assert_water_is_consistent(model) model.reprocess_pdb_hierarchy_inefficient() assert_water_is_consistent(model) if log is None: log = model.log if params is None: params = all_master_params().extract() max_od_dist = params.max_od_dist min_od_dist = params.min_od_dist assert min_od_dist > 0.5 assert max_od_dist > min_od_dist and max_od_dist < 1.5 keep_max = params.map_next_to_model.max_model_peak_dist keep_min = params.map_next_to_model.min_model_peak_dist params.map_next_to_model.max_model_peak_dist = max_od_dist * 1.8 params.map_next_to_model.min_model_peak_dist = min_od_dist params.peak_search.min_cross_distance = params.min_od_dist # 0.5 if params.peak_search.min_cross_distance < 0.7: params.peak_search.min_cross_distance = 0.7 #if params.map_next_to_model.min_model_peak_dist < 0.7: # params.map_next_to_model.min_model_peak_dist = 0.7 params.map_next_to_model.use_hydrogens = True params.map_next_to_model.min_peak_peak_dist = min_od_dist #if params.map_next_to_model.min_peak_peak_dist <0.7: # params.map_next_to_model.min_peak_peak_dist = 0.7 max_dod_angle = params.max_dod_angle min_dod_angle = params.min_dod_angle assert max_dod_angle < 180 and min_dod_angle > 30 and max_dod_angle > min_dod_angle peaks = find_hydrogen_peaks(fmodel=fmodel, pdb_atoms=model.get_hierarchy().atoms(), params=params, log=log) if peaks is None: return model params.map_next_to_model.use_hydrogens = False hs = peaks.heights params.map_next_to_model.max_model_peak_dist = keep_max params.map_next_to_model.min_model_peak_dist = keep_min sol_O = model.solvent_selection().set_selected(model.get_hd_selection(), False) print("Number of solvent molecules: ", sol_O.count(True), file=log) sol_sel = model.solvent_selection() hd_sel = sol_sel & model.get_hd_selection() print("Number of water hydrogens: ", hd_sel.count(True), file=log) # pks = distances_to_peaks(xs, peaks.sites, hs, max_od_dist, use_selection=sol_O) obsmap = obs_map(fmodel, map_type=params.secondary_map_type) # filtered_peaks = map_peak_filter(peaks.sites, obsmap) #print>>log, "Number of filtered peaks: ", len(filtered_peaks) # pkss = distances_to_peaks(xs, peaks.sites, hs, max_od_dist*1.7, use_selection=sol_O) #pkss = distances_to_peaks(xs, filtered_peaks, hs, max_od_dist*1.7, # use_selection=sol_O) cutoff2 = params.secondary_map_cutoff assert cutoff2 > 0. and cutoff2 < 100. pkss = make_peak_dict(peaks, sol_O, obsmap, cutoff2) npeaks = 0 for pk in pkss.values(): npeaks = npeaks + len(pk) print("Peaks to consider: ", npeaks, file=log) water_rgs = model.extract_water_residue_groups() water_rgs.reverse() element = 'D' next_to_i_seqs = [] for rg in water_rgs: if (rg.atom_groups_size() != 1): raise RuntimeError( "Not implemented: cannot handle water with alt. conf.") ag = rg.only_atom_group() atoms = ag.atoms() h_atoms = [] o_atom = None if atoms.size() > 0: for atom in atoms: if (atom.element.strip() == "O"): o_atom = atom else: h_atoms.append(atom) else: assert False o_i = o_atom.i_seq if o_i in pkss: o_site = scatterers[o_i].site site_symmetry = sgtbx.site_symmetry(xs.unit_cell(), xs.space_group(), o_site, 0.5, True) if (site_symmetry.n_matrices() != 1): special = True continue # TODO: handle this situation o_u = scatterers[o_i].u_iso_or_equiv(unit_cell) h_sites = pkss[o_i] # print_atom(sys.stdout, o_atom) val = obsmap.eight_point_interpolation(o_site) if val > cutoff2: h_sites.append((0., o_site)) for hatom in h_atoms: hsite = scatterers[hatom.i_seq].site doh = unit_cell.distance(hsite, o_site) assert doh > 0.5 and doh < 1.45, "%f\n%s" % ( doh, atom_as_str(hatom)) val = obsmap.eight_point_interpolation(hsite) if val > cutoff2: h_sites.append((0., hsite)) dod = match_dod(unit_cell, h_sites, min_od=params.min_od_dist, max_od=params.max_od_dist, min_dod_angle=params.min_dod_angle, max_dod_angle=params.max_dod_angle) if dod is None: od = match_od(unit_cell, h_sites, min_od=params.min_od_dist, max_od=params.max_od_dist) if od is not None: scatterers[o_i].site = od[0] o_atom.xyz = unit_cell.orthogonalize(od[0]) h = od[1] if len(h_atoms) > 0: hatom = h_atoms.pop() hatom.xyz = unit_cell.orthogonalize(h) hatom.occ = 1 hatom.b = cctbx.adptbx.u_as_b(o_u) hatom.name = "D1" h_i = hatom.i_seq scatterers[h_i].label = "D1" scatterers[h_i].site = h scatterers[h_i].occupancy = 1 scatterers[h_i].u_iso = o_u if len(h_atoms) > 0: # mark for deletion hatom = h_atoms.pop() hatom.name = "D2" hatom.occ = 0. h_i = hatom.i_seq scatterers[h_i].label = "D2" scatterers[h_i].occupancy = 0. else: insert_atom_into_model(xs, atom=o_atom, atom_name="D1", site_frac=h, occupancy=1, uiso=o_u, element='D') next_to_i_seqs.append(o_atom.i_seq) else: scatterers[o_i].site = dod[1] o_atom.xyz = unit_cell.orthogonalize(dod[1]) ii = 1 for h in (dod[0], dod[2]): name = "D" + str(ii) ii = ii + 1 if len(h_atoms) > 0: hatom = h_atoms.pop() hatom.xyz = unit_cell.orthogonalize(h) hatom.occ = 1 hatom.b = cctbx.adptbx.u_as_b(o_u) hatom.name = name h_i = hatom.i_seq scatterers[h_i].label = name scatterers[h_i].site = h scatterers[h_i].occupancy = 1 scatterers[h_i].u_iso = o_u else: insert_atom_into_model(xs, atom=o_atom, atom_name=name, site_frac=h, occupancy=1, uiso=o_u, element='D') next_to_i_seqs.append(o_atom.i_seq) if (model.refinement_flags is not None and len(next_to_i_seqs) != 0): # TODO: adp_group=True according to params.dod_and_od_group_adp model.refinement_flags.add( next_to_i_seqs=next_to_i_seqs, # [i_seq], # , sites_individual=True, s_occupancies=False, adp_individual_iso=True) print("Number of H added:", len(next_to_i_seqs), file=log) # print "DEBUG! ", dir(model.refinement_flags) #.size() # print "DEBUG! ", dir(model.refinement_flags.sites_individual) #.size() #print "DEBUG! ", model.refinement_flags.sites_individual.size() model.reprocess_pdb_hierarchy_inefficient() if model.refinement_flags.sites_individual is not None: np = model.refinement_flags.sites_individual.size() assert np == model.get_number_of_atoms() assert model.refinement_flags.sites_individual.count(True) == np mmtbx.utils.assert_model_is_consistent(model) sol_sel = model.solvent_selection() hd_sel = sol_sel & model.get_hd_selection() assert hd_sel.count(True) >= len(next_to_i_seqs) assert_water_is_consistent(model) if False: model.idealize_h_minimization() model.get_hierarchy() mmtbx.utils.assert_model_is_consistent(model) assert_water_is_consistent(model) return model
def fit_water(water_and_peaks, xray_structure, params, log): scatterers = xray_structure.scatterers() uc = xray_structure.unit_cell() site_frac_o = scatterers[water_and_peaks.i_seq_o].site site_frac_h1 = scatterers[water_and_peaks.i_seq_h1].site site_frac_h2 = scatterers[water_and_peaks.i_seq_h2].site peak_sites_frac = water_and_peaks.peaks_sites_frac if (len(peak_sites_frac) == 1): sc1 = scatterers[water_and_peaks.i_seq_h1] sc2 = scatterers[water_and_peaks.i_seq_h2] if (sc1.occupancy < sc2.occupancy and sc2.occupancy > 0.3): site_frac_h2 = sc2.site elif (sc1.occupancy > sc2.occupancy and sc1.occupancy > 0.3): site_frac_h2 = scatterers[water_and_peaks.i_seq_h1].site else: site_frac_h2 = peak_sites_frac[0] result = mmtbx.utils.fit_hoh(site_frac_o=site_frac_o, site_frac_h1=site_frac_h1, site_frac_h2=site_frac_h2, site_frac_peak1=peak_sites_frac[0], site_frac_peak2=site_frac_h2, angular_shift=params.angular_step, unit_cell=uc) d_best = result.dist_best() o = uc.fractionalize(result.site_cart_o_fitted) h1 = uc.fractionalize(result.site_cart_h1_fitted) h2 = uc.fractionalize(result.site_cart_h2_fitted) else: peak_pairs = [] for i, s1 in enumerate(peak_sites_frac): for j, s2 in enumerate(peak_sites_frac): if i < j: peak_pairs.append([s1, s2]) d_best = 999. for pair in peak_pairs: result = mmtbx.utils.fit_hoh(site_frac_o=site_frac_o, site_frac_h1=site_frac_h1, site_frac_h2=site_frac_h2, site_frac_peak1=pair[0], site_frac_peak2=pair[1], angular_shift=params.angular_step, unit_cell=uc) if (result.dist_best() < d_best): d_best = result.dist_best() o = uc.fractionalize(result.site_cart_o_fitted) h1 = uc.fractionalize(result.site_cart_h1_fitted) h2 = uc.fractionalize(result.site_cart_h2_fitted) if (d_best < 1.0): # do not move HOH located on special position skip = False sites = [ scatterers[water_and_peaks.i_seq_o].site, scatterers[water_and_peaks.i_seq_h1].site, scatterers[water_and_peaks.i_seq_h2].site ] for site in sites: site_symmetry = sgtbx.site_symmetry(xray_structure.unit_cell(), xray_structure.space_group(), site, 0.5, True) if (site_symmetry.n_matrices() != 1): skip = True break # if (not skip): scatterers[water_and_peaks.i_seq_o].site = o scatterers[water_and_peaks.i_seq_h1].site = h1 scatterers[water_and_peaks.i_seq_h2].site = h2 print("%6.3f" % d_best, file=log)
def demo(): # # define unit cell parameters and a compatible space group # unit_cell = uctbx.unit_cell((10, 10, 15, 90, 90, 120)) space_group = sgtbx.space_group("-P 3 2") # Hall symbol # # define a site_symmetry_table with a few sites # site_symmetry_table = sgtbx.site_symmetry_table() site_symmetry_table.reserve(3) # optional: optimizes memory allocation for site_frac in [(0, 0, 0), (0.5, 0.5, 0.5), (0.25, 0.66, 0.0), (0.75, 0.66, 0.0)]: site_symmetry = sgtbx.site_symmetry(unit_cell=unit_cell, space_group=space_group, original_site=site_frac, min_distance_sym_equiv=0.5, assert_min_distance_sym_equiv=True) site_symmetry_table.process(site_symmetry_ops=site_symmetry) # # there are two sets of indices: # 1. "i_seq" = index into the sequence of sites as passed to # site_symmetry.process(). # 2. The indices of the tabulated special_position_ops instances. # site_symmetry_table.indices() establishes the relation between # these two sets of indices: # site_symmetry_table.indices().size() = number of sites processed # site_symmetry_table.indices()[i_seq] = index of special_position_ops # instance in the internal site_symmetry_table.table() assert list(site_symmetry_table.indices()) == [1, 2, 0, 0] # # table entry 0 is always the general position # assert str(site_symmetry_table.table()[0].special_op()) == "x,y,z" # # all other table entries are special positions # assert str(site_symmetry_table.table()[1].special_op()) == "0,0,0" assert str(site_symmetry_table.table()[2].special_op()) == "1/2,1/2,1/2" # # To obtain the special_position_ops for a certain i_seq: # for i_seq in [0, 1, 2]: print(site_symmetry_table.get(i_seq=i_seq).special_op()) # # Most of the time the (many) general positions don't need a # special treatment, and it is much more convenient to loop # only over the (few) special positions. For example, to # define symmetry constraints for anisotropic displacement # parameters: # for i_seq in site_symmetry_table.special_position_indices(): site_constraints = site_symmetry_table.get( i_seq=i_seq).site_constraints() adp_constraints = site_symmetry_table.get( i_seq=i_seq).adp_constraints() # # See also: # cctbx/examples/site_symmetry_constraints.py # cctbx/examples/adp_symmetry_constraints.py # C++ reference documentation for # cctbx::sgtbx::site_symmetry_ops # cctbx::sgtbx::site_symmetry # print("OK")
def exercise(space_group_info, redundancy_counter=0): n_real = (12, 12, 12) miller_max = (2, 2, 2) gt = maptbx.grid_tags(n_real) uc = space_group_info.any_compatible_unit_cell(volume=1000) fl = sgtbx.search_symmetry_flags(use_space_group_symmetry=True) gt.build(space_group_info.type(), fl) fft = fftpack.real_to_complex_3d(n_real) map0 = flex.double(flex.grid(fft.m_real()).set_focus(fft.n_real()), 0) weight_map = map0.deep_copy() map = map0.deep_copy() ta = gt.tag_array() order_z = space_group_info.group().order_z() problems_expected = (redundancy_counter != 0) for ijk in flex.nested_loop(n_real): t = ta[ijk] if (t < 0): xyz = [i / n for i, n in zip(ijk, n_real)] ss = sgtbx.site_symmetry(unit_cell=uc, space_group=space_group_info.group(), original_site=xyz, min_distance_sym_equiv=1e-5) m = space_group_info.group().multiplicity( site=boost.rational.vector(ijk, n_real)) assert m == ss.multiplicity() w = m / order_z weight_map[ijk] = w map[ijk] = w elif (redundancy_counter != 0): redundancy_counter -= 1 ijk_asu = n_dim_index_from_one_dim(i1d=t, sizes=n_real) assert ta.accessor()(ijk_asu) == t map[ijk] = map[ijk_asu] sf_map = fft.forward(map) del map mi = miller.index_generator(space_group_info.type(), False, miller_max).to_array() assert mi.size() != 0 from_map = maptbx.structure_factors.from_map( space_group=space_group_info.group(), anomalous_flag=False, miller_indices=mi, complex_map=sf_map, conjugate_flag=True) sf = [iround(abs(f)) for f in from_map.data()] if (sf != [0] * len(sf)): assert problems_expected return else: not problems_expected # map_p1 = map0.deep_copy() map_sw = map0.deep_copy() for ijk in flex.nested_loop(n_real): t = ta[ijk] if (t < 0): v = random.random() * 2 - 1 map_p1[ijk] = v map_sw[ijk] = v * weight_map[ijk] else: ijk_asu = n_dim_index_from_one_dim(i1d=t, sizes=n_real) assert ta.accessor()(ijk_asu) == t assert map_p1[ijk_asu] != 0 map_p1[ijk] = map_p1[ijk_asu] # # fft followed by symmetry summation in reciprocal space sf_map_sw = fft.forward(map_sw) del map_sw sf_sw = maptbx.structure_factors.from_map( space_group=space_group_info.group(), anomalous_flag=False, miller_indices=mi, complex_map=sf_map_sw, conjugate_flag=True).data() del sf_map_sw # # symmetry expansion in real space (done above already) followed fft sf_map_p1 = fft.forward(map_p1) del map_p1 sf_p1 = maptbx.structure_factors.from_map(space_group=sgtbx.space_group(), anomalous_flag=False, miller_indices=mi, complex_map=sf_map_p1, conjugate_flag=True).data() del sf_map_p1 # corr = flex.linear_correlation(x=flex.abs(sf_sw), y=flex.abs(sf_p1)) assert corr.is_well_defined assert approx_equal(corr.coefficient(), 1)
def exercise_all_wyckoff(flags, space_group_info): """ Set-up crystal and constraints """ crystal = space_group_info.any_compatible_crystal_symmetry(volume=1000) unit_cell = crystal.unit_cell() wyckoffs = space_group_info.wyckoff_table() for i in xrange(wyckoffs.size()): wyckoff_pos = wyckoffs.position(i) print "%s," % wyckoff_pos.letter(), special_op = wyckoff_pos.special_op() exact_site = eval("(%s)" % special_op, {'x': 0.1, 'y': 0.2, 'z': 0.3}) site_symmetry = sgtbx.site_symmetry(crystal.unit_cell(), crystal.space_group(), exact_site) u_star_constraints = site_symmetry.adp_constraints() u_cart_constraints = site_symmetry.cartesian_adp_constraints(unit_cell) """ Compatibility of all_params for u* and u_cart """ n = u_cart_constraints.n_independent_params() assert n == u_star_constraints.n_independent_params() basis = [] for i in xrange(n): v = [0] * n v[i] = 1 basis.append(v) u_cart_basis = [u_cart_constraints.all_params(v) for v in basis] u_star_basis = [u_star_constraints.all_params(v) for v in basis] u_cart_basis_bis = [ adptbx.u_star_as_u_cart(unit_cell, u) for u in u_star_basis ] a_work = flex.double(u_cart_basis) u_cart_basis_echelon = row_echelon_full_pivoting(a_work=a_work, min_abs_pivot=1e-9) # the vector subspaces spanned respectively by u_cart_basis and # by u_cart_basis_bis should be equal for u in u_cart_basis_bis: assert u_cart_basis_echelon.is_in_row_space(x=flex.double(u), epsilon=1e-9) """ Test the independent gradient computation """ eps = 1e-4 v0 = tuple([random.random() for i in xrange(n)]) u_cart_0 = u_cart_constraints.all_params(v0) grad_f_wrt_independent_u_cart = [] for i in xrange(n): v_up = list(v0) v_up[i] += eps v_down = list(v0) v_down[i] -= eps der = (f(u_cart_constraints.all_params(v_up)) - f(u_cart_constraints.all_params(v_down))) / (2 * eps) grad_f_wrt_independent_u_cart.append(der) grad_f_wrt_u_cart = [] for i in xrange(6): u_cart_up = list(u_cart_0) u_cart_up[i] += eps u_cart_down = list(u_cart_0) u_cart_down[i] -= eps der = (f(u_cart_up) - f(u_cart_down)) / (2 * eps) grad_f_wrt_u_cart.append(der) grad_f_wrt_independent_u_cart_1 = ( u_cart_constraints.independent_gradients(tuple(grad_f_wrt_u_cart))) assert flex.max( flex.abs( flex.double(grad_f_wrt_independent_u_cart_1) - flex.double(grad_f_wrt_independent_u_cart))) < 5 * eps**2 """ Check independent_params """ v = tuple([random.random() for i in xrange(n)]) u_cart = u_cart_constraints.all_params(v) w = u_cart_constraints.independent_params(u_cart) assert approx_equal(v, w, eps=1e-12) print
def run(): # # try these Hall symbols: # "P 1", "P 2", "P 3", "P 3*", "P 4", "P 6", "P 2 2 3" # space_group = sgtbx.space_group("P 3*") # Hall symbol # # initialization of space group symmetry constraints # adp_constraints = sgtbx.tensor_rank_2_constraints( space_group=space_group, reciprocal_space=True) # # number of independent u_star parameters # n_indep = adp_constraints.n_independent_params() # # arbitrary Miller index and u_star tensor # h = (3,1,2) u_star=(0.000004, 0.000004, 0.000007, 0.000002, 0.0000000, 0.0000000) # optional: enforce symmetry at the beginning u_star = space_group.average_u_star(u_star) # # pass u_indep to the minimizer # u_indep = adp_constraints.independent_params(all_params=u_star) assert len(u_indep) == n_indep # # "expand" the independent parameters modified by the minimizer # u_star = adp_constraints.all_params(independent_params=u_indep) assert len(u_star) == 6 # # these calculations are completely independent of the symmetry # dwf = adptbx.debye_waller_factor_u_star(h, u_star) gc = adptbx.debye_waller_factor_u_star_gradient_coefficients(h) # all_gradients is an array of six values all_gradients = [-2*math.pi**2 * dwf * c for c in gc] assert len(all_gradients) == 6 cc = adptbx.debye_waller_factor_u_star_curvature_coefficients(h) # all_curvatures is an array of 21 values (upper triangle of 6x6 matrix) all_curvatures = (-2*math.pi**2)**2 * dwf * cc assert len(all_curvatures) == 6*(6+1)//2 # # here we apply the symmetry constraints to the gradients and curvatures # # g_indep is an array of n_indep values g_indep = adp_constraints.independent_gradients( all_gradients=all_gradients) assert len(g_indep) == n_indep # c_indep is an array of n_indep*(n_indep+1)/2 values (upper triangle) c_indep = adp_constraints.independent_curvatures( all_curvatures=all_curvatures) assert len(c_indep) == n_indep*(n_indep+1)//2 # feed g_indep and c_indep to the minimizer # # initialization of site symmetry constraints # (for sites on special positions) # unit_cell = uctbx.unit_cell((12,12,15,90,90,120)) space_group = sgtbx.space_group_info("P 6").group() site_symmetry = sgtbx.site_symmetry( unit_cell=unit_cell, space_group=space_group, original_site=(1/3.,2/3.,0), # site on 3-fold axis min_distance_sym_equiv=0.5) assert len(site_symmetry.matrices()) == 3 adp_constraints = site_symmetry.adp_constraints() # use adp_constraints as before print "OK"
def demo(): # # define unit cell parameters and a compatible space group # unit_cell = uctbx.unit_cell((10,10,15,90,90,120)) space_group = sgtbx.space_group("-P 3 2") # Hall symbol # # define a site_symmetry_table with a few sites # site_symmetry_table = sgtbx.site_symmetry_table() site_symmetry_table.reserve(3) # optional: optimizes memory allocation for site_frac in [(0,0,0), (0.5,0.5,0.5), (0.25,0.66,0.0), (0.75,0.66,0.0)]: site_symmetry = sgtbx.site_symmetry( unit_cell=unit_cell, space_group=space_group, original_site=site_frac, min_distance_sym_equiv=0.5, assert_min_distance_sym_equiv=True) site_symmetry_table.process(site_symmetry_ops=site_symmetry) # # there are two sets of indices: # 1. "i_seq" = index into the sequence of sites as passed to # site_symmetry.process(). # 2. The indices of the tabulated special_position_ops instances. # site_symmetry_table.indices() establishes the relation between # these two sets of indices: # site_symmetry_table.indices().size() = number of sites processed # site_symmetry_table.indices()[i_seq] = index of special_position_ops # instance in the internal site_symmetry_table.table() assert list(site_symmetry_table.indices()) == [1, 2, 0, 0] # # table entry 0 is always the general position # assert str(site_symmetry_table.table()[0].special_op()) == "x,y,z" # # all other table entries are special positions # assert str(site_symmetry_table.table()[1].special_op()) == "0,0,0" assert str(site_symmetry_table.table()[2].special_op()) == "1/2,1/2,1/2" # # To obtain the special_position_ops for a certain i_seq: # for i_seq in [0,1,2]: print site_symmetry_table.get(i_seq=i_seq).special_op() # # Most of the time the (many) general positions don't need a # special treatment, and it is much more convenient to loop # only over the (few) special positions. For example, to # define symmetry constraints for anisotropic displacement # parameters: # for i_seq in site_symmetry_table.special_position_indices(): site_constraints = site_symmetry_table.get(i_seq=i_seq).site_constraints() adp_constraints = site_symmetry_table.get(i_seq=i_seq).adp_constraints() # # See also: # cctbx/examples/site_symmetry_constraints.py # cctbx/examples/adp_symmetry_constraints.py # C++ reference documentation for # cctbx::sgtbx::site_symmetry_ops # cctbx::sgtbx::site_symmetry # print "OK"
def exercise_all_wyckoff(flags, space_group_info): """ Set-up crystal and constraints """ crystal = space_group_info.any_compatible_crystal_symmetry(volume=1000) unit_cell = crystal.unit_cell() wyckoffs = space_group_info.wyckoff_table() for i in xrange(wyckoffs.size()): wyckoff_pos = wyckoffs.position(i) print "%s," % wyckoff_pos.letter(), special_op = wyckoff_pos.special_op() exact_site = eval("(%s)" % special_op, {"x": 0.1, "y": 0.2, "z": 0.3}) site_symmetry = sgtbx.site_symmetry(crystal.unit_cell(), crystal.space_group(), exact_site) u_star_constraints = site_symmetry.adp_constraints() u_cart_constraints = site_symmetry.cartesian_adp_constraints(unit_cell) """ Compatibility of all_params for u* and u_cart """ n = u_cart_constraints.n_independent_params() assert n == u_star_constraints.n_independent_params() basis = [] for i in xrange(n): v = [0] * n v[i] = 1 basis.append(v) u_cart_basis = [u_cart_constraints.all_params(v) for v in basis] u_star_basis = [u_star_constraints.all_params(v) for v in basis] u_cart_basis_bis = [adptbx.u_star_as_u_cart(unit_cell, u) for u in u_star_basis] a_work = flex.double(u_cart_basis) u_cart_basis_echelon = row_echelon_full_pivoting(a_work=a_work, min_abs_pivot=1e-9) # the vector subspaces spanned respectively by u_cart_basis and # by u_cart_basis_bis should be equal for u in u_cart_basis_bis: assert u_cart_basis_echelon.is_in_row_space(x=flex.double(u), epsilon=1e-9) """ Test the independent gradient computation """ eps = 1e-4 v0 = tuple([random.random() for i in xrange(n)]) u_cart_0 = u_cart_constraints.all_params(v0) grad_f_wrt_independent_u_cart = [] for i in xrange(n): v_up = list(v0) v_up[i] += eps v_down = list(v0) v_down[i] -= eps der = (f(u_cart_constraints.all_params(v_up)) - f(u_cart_constraints.all_params(v_down))) / (2 * eps) grad_f_wrt_independent_u_cart.append(der) grad_f_wrt_u_cart = [] for i in xrange(6): u_cart_up = list(u_cart_0) u_cart_up[i] += eps u_cart_down = list(u_cart_0) u_cart_down[i] -= eps der = (f(u_cart_up) - f(u_cart_down)) / (2 * eps) grad_f_wrt_u_cart.append(der) grad_f_wrt_independent_u_cart_1 = u_cart_constraints.independent_gradients(tuple(grad_f_wrt_u_cart)) assert ( flex.max( flex.abs(flex.double(grad_f_wrt_independent_u_cart_1) - flex.double(grad_f_wrt_independent_u_cart)) ) < 5 * eps ** 2 ) """ Check independent_params """ v = tuple([random.random() for i in xrange(n)]) u_cart = u_cart_constraints.all_params(v) w = u_cart_constraints.independent_params(u_cart) assert approx_equal(v, w, eps=1e-12) print
def exercise(space_group_info, redundancy_counter=0): n_real = (12,12,12) miller_max = (2,2,2) gt = maptbx.grid_tags(n_real) uc = space_group_info.any_compatible_unit_cell(volume=1000) fl = sgtbx.search_symmetry_flags(use_space_group_symmetry=True) gt.build(space_group_info.type(), fl) fft = fftpack.real_to_complex_3d(n_real) map0 = flex.double(flex.grid(fft.m_real()).set_focus(fft.n_real()), 0) weight_map = map0.deep_copy() map = map0.deep_copy() ta = gt.tag_array() order_z = space_group_info.group().order_z() problems_expected = (redundancy_counter != 0) for ijk in flex.nested_loop(n_real): t = ta[ijk] if (t < 0): xyz = [i/n for i,n in zip(ijk, n_real)] ss = sgtbx.site_symmetry( unit_cell=uc, space_group=space_group_info.group(), original_site=xyz, min_distance_sym_equiv=1e-5) m = space_group_info.group().multiplicity( site=boost.rational.vector(ijk, n_real)) assert m == ss.multiplicity() w = m / order_z weight_map[ijk] = w map[ijk] = w elif (redundancy_counter != 0): redundancy_counter -= 1 ijk_asu = n_dim_index_from_one_dim(i1d=t, sizes=n_real) assert ta.accessor()(ijk_asu) == t map[ijk] = map[ijk_asu] sf_map = fft.forward(map) del map mi = miller.index_generator( space_group_info.type(), False, miller_max).to_array() assert mi.size() != 0 from_map = maptbx.structure_factors.from_map( space_group=space_group_info.group(), anomalous_flag=False, miller_indices=mi, complex_map=sf_map, conjugate_flag=True) sf = [iround(abs(f)) for f in from_map.data()] if (sf != [0]*len(sf)): assert problems_expected return else: not problems_expected # map_p1 = map0.deep_copy() map_sw = map0.deep_copy() for ijk in flex.nested_loop(n_real): t = ta[ijk] if (t < 0): v = random.random()*2-1 map_p1[ijk] = v map_sw[ijk] = v * weight_map[ijk] else: ijk_asu = n_dim_index_from_one_dim(i1d=t, sizes=n_real) assert ta.accessor()(ijk_asu) == t assert map_p1[ijk_asu] != 0 map_p1[ijk] = map_p1[ijk_asu] # # fft followed by symmetry summation in reciprocal space sf_map_sw = fft.forward(map_sw) del map_sw sf_sw = maptbx.structure_factors.from_map( space_group=space_group_info.group(), anomalous_flag=False, miller_indices=mi, complex_map=sf_map_sw, conjugate_flag=True).data() del sf_map_sw # # symmetry expansion in real space (done above already) followed fft sf_map_p1 = fft.forward(map_p1) del map_p1 sf_p1 = maptbx.structure_factors.from_map( space_group=sgtbx.space_group(), anomalous_flag=False, miller_indices=mi, complex_map=sf_map_p1, conjugate_flag=True).data() del sf_map_p1 # corr = flex.linear_correlation(x=flex.abs(sf_sw), y=flex.abs(sf_p1)) assert corr.is_well_defined assert approx_equal(corr.coefficient(), 1)
def run(): # # try these Hall symbols: # "P 1", "P 2", "P 3", "P 3*", "P 4", "P 6", "P 2 2 3" # space_group = sgtbx.space_group("P 3*") # Hall symbol # # initialization of space group symmetry constraints # adp_constraints = sgtbx.tensor_rank_2_constraints(space_group=space_group, reciprocal_space=True) # # number of independent u_star parameters # n_indep = adp_constraints.n_independent_params() # # arbitrary Miller index and u_star tensor # h = (3, 1, 2) u_star = (0.000004, 0.000004, 0.000007, 0.000002, 0.0000000, 0.0000000) # optional: enforce symmetry at the beginning u_star = space_group.average_u_star(u_star) # # pass u_indep to the minimizer # u_indep = adp_constraints.independent_params(all_params=u_star) assert len(u_indep) == n_indep # # "expand" the independent parameters modified by the minimizer # u_star = adp_constraints.all_params(independent_params=u_indep) assert len(u_star) == 6 # # these calculations are completely independent of the symmetry # dwf = adptbx.debye_waller_factor_u_star(h, u_star) gc = adptbx.debye_waller_factor_u_star_gradient_coefficients(h) # all_gradients is an array of six values all_gradients = [-2 * math.pi**2 * dwf * c for c in gc] assert len(all_gradients) == 6 cc = adptbx.debye_waller_factor_u_star_curvature_coefficients(h) # all_curvatures is an array of 21 values (upper triangle of 6x6 matrix) all_curvatures = (-2 * math.pi**2)**2 * dwf * cc assert len(all_curvatures) == 6 * (6 + 1) // 2 # # here we apply the symmetry constraints to the gradients and curvatures # # g_indep is an array of n_indep values g_indep = adp_constraints.independent_gradients( all_gradients=all_gradients) assert len(g_indep) == n_indep # c_indep is an array of n_indep*(n_indep+1)/2 values (upper triangle) c_indep = adp_constraints.independent_curvatures( all_curvatures=all_curvatures) assert len(c_indep) == n_indep * (n_indep + 1) // 2 # feed g_indep and c_indep to the minimizer # # initialization of site symmetry constraints # (for sites on special positions) # unit_cell = uctbx.unit_cell((12, 12, 15, 90, 90, 120)) space_group = sgtbx.space_group_info("P 6").group() site_symmetry = sgtbx.site_symmetry( unit_cell=unit_cell, space_group=space_group, original_site=(1 / 3., 2 / 3., 0), # site on 3-fold axis min_distance_sym_equiv=0.5) assert len(site_symmetry.matrices()) == 3 adp_constraints = site_symmetry.adp_constraints() # use adp_constraints as before print("OK")