def exercise_zeolite_atlas(distance_cutoff=3.5): atlas_file = libtbx.env.find_in_repositories( relative_path="phenix_regression/misc/strudat_zeolite_atlas", test=os.path.isfile) if (atlas_file is None): print("Skipping exercise_zeolite_atlas(): input file not available") return with open(atlas_file) as f: all_entries = strudat.read_all_entries(f) for i, entry in enumerate(all_entries.entries): structure = entry.as_xray_structure() if ("--full" in sys.argv[1:] or i % 20 == 0): tst_direct_space_asu.exercise_neighbors_pair_generators( structure=structure, verbose="--Verbose" in sys.argv[1:]) asu_mappings = structure.asu_mappings(buffer_thickness=distance_cutoff) pair_generator = crystal.neighbors_fast_pair_generator( asu_mappings=asu_mappings, distance_cutoff=distance_cutoff) bond_counts = flex.size_t(structure.scatterers().size(), 0) for pair in pair_generator: bond_counts[pair.i_seq] += 1 if (pair.j_sym == 0): bond_counts[pair.j_seq] += 1 for atom, bond_count in zip(entry.atoms, bond_counts): assert atom.connectivity is not None assert atom.connectivity == bond_count
def check_distances(sites_cart, point_distance, verbose): asu_mappings = non_crystallographic_asu_mappings(sites_cart=sites_cart) distance_cutoff = point_distance * math.sqrt(2) * 0.99 simple_pair_generator = crystal.neighbors_simple_pair_generator( asu_mappings=asu_mappings, distance_cutoff=distance_cutoff) pair_generator = crystal.neighbors_fast_pair_generator( asu_mappings=asu_mappings, distance_cutoff=distance_cutoff) assert simple_pair_generator.count_pairs() == pair_generator.count_pairs() pair_generator.restart() neighbors = {} for pair in pair_generator: assert pair.j_seq != pair.i_seq assert pair.j_sym == 0 assert approx_equal(pair.dist_sq, point_distance**2) neighbors[pair.i_seq] = neighbors.get(pair.i_seq, 0) + 1 neighbors[pair.j_seq] = neighbors.get(pair.j_seq, 0) + 1 n_dict = {} for n in neighbors.values(): n_dict[n] = n_dict.get(n, 0) + 1 if (verbose): print n_dict if (len(neighbors) > 0): assert max(neighbors.values()) <= 12
def get_crystal_contact_operators(hierarchy, crystal_symmetry, distance_cutoff): """Use an alternate method to identify the symmetry operations required to generate crystal contacts""" # Extract the xray structure from the reference hierarchy struc = hierarchy.extract_xray_structure(crystal_symmetry=crystal_symmetry) atoms = hierarchy.atoms() # Extract the mappings that will tell us the adjacent symmetry copies asu_mappings = struc.asu_mappings(buffer_thickness=distance_cutoff) uc = asu_mappings.unit_cell() # Symmetry operations for each atom mappings = asu_mappings.mappings() # There should be one mappings list per atom assert len(struc.scatterers()) == len(mappings) # Get all atom pairs within distance_cutoff distance pair_generator = crystal.neighbors_fast_pair_generator( asu_mappings, distance_cutoff=distance_cutoff) sym_operations = [] for pair in pair_generator: # obtain rt_mx_ji - symmetry operator that should be applied to j-th atom # to transfer it to i-th atom rt_mx_i = asu_mappings.get_rt_mx_i(pair) rt_mx_j = asu_mappings.get_rt_mx_j(pair) rt_mx_ji = rt_mx_i.inverse().multiply(rt_mx_j) # if it is not a unit matrix, that is symmetry related pair of atoms if not rt_mx_ji.is_unit_mx(): if rt_mx_ji not in sym_operations: sym_operations.append(rt_mx_ji) return sym_operations
def exercise_zeolite_atlas(distance_cutoff=3.5): atlas_file = libtbx.env.find_in_repositories( relative_path="phenix_regression/misc/strudat_zeolite_atlas", test=os.path.isfile) if (atlas_file is None): print "Skipping exercise_zeolite_atlas(): input file not available" return all_entries = strudat.read_all_entries(open(atlas_file)) for i,entry in enumerate(all_entries.entries): structure = entry.as_xray_structure() if ("--full" in sys.argv[1:] or i % 20 == 0): tst_direct_space_asu.exercise_neighbors_pair_generators( structure=structure, verbose="--Verbose" in sys.argv[1:]) asu_mappings = structure.asu_mappings(buffer_thickness=distance_cutoff) pair_generator = crystal.neighbors_fast_pair_generator( asu_mappings=asu_mappings, distance_cutoff=distance_cutoff) bond_counts = flex.size_t(structure.scatterers().size(), 0) for pair in pair_generator: bond_counts[pair.i_seq] += 1 if (pair.j_sym == 0): bond_counts[pair.j_seq] += 1 for atom,bond_count in zip(entry.atoms, bond_counts): assert atom.connectivity is not None assert atom.connectivity == bond_count
def sel_within(self, radius, primary_selection): assert radius > 0 assert self.special_position_settings is not None return crystal.neighbors_fast_pair_generator( asu_mappings=self.special_position_settings.asu_mappings( buffer_thickness=radius, sites_cart=self.root.atoms().extract_xyz()), distance_cutoff=radius).neighbors_of( primary_selection=primary_selection)
def get_pair_generator(crystal_symmetry, buffer_thickness, sites_cart): sst = crystal_symmetry.special_position_settings().site_symmetry_table( sites_cart=sites_cart) from cctbx import crystal conn_asu_mappings = crystal_symmetry.special_position_settings().\ asu_mappings(buffer_thickness = buffer_thickness) conn_asu_mappings.process_sites_cart(original_sites=sites_cart, site_symmetry_table=sst) conn_pair_asu_table = crystal.pair_asu_table( asu_mappings=conn_asu_mappings) conn_pair_asu_table.add_all_pairs(distance_cutoff=buffer_thickness) pair_generator = crystal.neighbors_fast_pair_generator( conn_asu_mappings, distance_cutoff=buffer_thickness) return group_args(pair_generator=pair_generator, conn_asu_mappings=conn_asu_mappings)
def exercise_icosahedron(max_level=2, verbose=0): for level in range(0, max_level + 1): if (0 or verbose): print("level:", level) icosahedron = scitbx.math.icosahedron(level=level) try: distance_cutoff = icosahedron.next_neighbors_distance() * (1 + 1.e-3) estimated_distance_cutoff = False except RuntimeError as e: assert str(e) == "next_neighbors_distance not known." distance_cutoff = 0.4 / (2**(level - 1)) estimated_distance_cutoff = True asu_mappings = crystal.direct_space_asu.non_crystallographic_asu_mappings( sites_cart=icosahedron.sites) pair_asu_table = crystal.pair_asu_table(asu_mappings=asu_mappings) pair_asu_table.add_all_pairs(distance_cutoff=distance_cutoff) if (0 or verbose): ps = pair_asu_table.show_distances(sites_cart=icosahedron.sites) \ .distances_info print("level", level, "min", flex.min(ps.distances)) print(" ", " ", "max", flex.max(ps.distances)) assert ps.pair_counts.all_eq(pair_asu_table.pair_counts()) if (level == 0): for d in ps.distances: assert approx_equal(d, 1.0514622242382672) elif (level < 2): s = StringIO() ps = pair_asu_table.show_distances(sites_cart=icosahedron.sites, out=s) \ .distances_info assert ps.pair_counts.all_eq(pair_asu_table.pair_counts()) assert len(s.getvalue().splitlines()) == [72, 320][level] del s if (level == 0): assert pair_asu_table.pair_counts().all_eq(5) else: assert pair_asu_table.pair_counts().all_eq(3) del pair_asu_table max_distance = crystal.neighbors_fast_pair_generator( asu_mappings=asu_mappings, distance_cutoff=distance_cutoff).max_distance_sq()**.5 if (0 or verbose): print("max_distance:", max_distance) if (not estimated_distance_cutoff): assert approx_equal(max_distance, icosahedron.next_neighbors_distance()) assert approx_equal( max_distance / icosahedron.next_neighbors_distance(), 1)
def exercise_icosahedron(max_level=2, verbose=0): for level in xrange(0,max_level+1): if (0 or verbose): print "level:", level icosahedron = scitbx.math.icosahedron(level=level) try: distance_cutoff = icosahedron.next_neighbors_distance()*(1+1.e-3) estimated_distance_cutoff = False except RuntimeError, e: assert str(e) == "next_neighbors_distance not known." distance_cutoff = 0.4/(2**(level-1)) estimated_distance_cutoff = True asu_mappings = crystal.direct_space_asu.non_crystallographic_asu_mappings( sites_cart=icosahedron.sites) pair_asu_table = crystal.pair_asu_table(asu_mappings=asu_mappings) pair_asu_table.add_all_pairs(distance_cutoff=distance_cutoff) if (0 or verbose): ps = pair_asu_table.show_distances(sites_cart=icosahedron.sites) \ .distances_info print "level", level, "min", flex.min(ps.distances) print " ", " ", "max", flex.max(ps.distances) assert ps.pair_counts.all_eq(pair_asu_table.pair_counts()) if (level == 0): for d in ps.distances: assert approx_equal(d, 1.0514622242382672) elif (level < 2): s = StringIO() ps = pair_asu_table.show_distances(sites_cart=icosahedron.sites, out=s) \ .distances_info assert ps.pair_counts.all_eq(pair_asu_table.pair_counts()) assert len(s.getvalue().splitlines()) == [72,320][level] del s if (level == 0): assert pair_asu_table.pair_counts().all_eq(5) else: assert pair_asu_table.pair_counts().all_eq(3) del pair_asu_table max_distance = crystal.neighbors_fast_pair_generator( asu_mappings=asu_mappings, distance_cutoff=distance_cutoff).max_distance_sq()**.5 if (0 or verbose): print "max_distance:", max_distance if (not estimated_distance_cutoff): assert approx_equal(max_distance, icosahedron.next_neighbors_distance()) assert approx_equal(max_distance/icosahedron.next_neighbors_distance(),1)
def contacts_to_all(self, pdb_hier, symmetry, cutoff=6.0): #finds all contacts within cutoff in an entire pdb_hier xrs = pdb_hier.extract_xray_structure(crystal_symmetry=symmetry) asu_mappings = xrs.asu_mappings(buffer_thickness=cutoff + 1.0) pair_generator = crystal.neighbors_fast_pair_generator( asu_mappings, distance_cutoff=cutoff) natoms = pdb_hier.atoms().size() #distance matrix impractical as we may have multiple contacts to the same atom by symmetry #all of which need to be preserved all_cont = {} for i in range(natoms): all_cont[i] = [] for pair in pair_generator: pi = pair.i_seq pj = pair.j_seq ps = pair.j_sym pd = int(np.sqrt(pair.dist_sq) * 1000) / 1000.0 #avoid base2 float issues for uniquifying all_cont[pi].append( (pj, pd, ps)) #need both from and to (across asu) all_cont[pj].append((pi, pd, ps)) ncont = 0 awl_db = {} # refs to awl objects to pass for awl in pdb_hier.atoms_with_labels(): awl_db[awl.i_seq] = awl all_cont_db = {} for iseq, clist in all_cont.iteritems(): #print "PROTO",iseq,clist ncont = ncont + len(clist) source_at = iseq source_awl = awl_db[source_at] uni_c = set(clist) # for each source awl, generate list of unique tuples (cont awl,distance,sym) cpairs = list( (awl_db[c_at[0]], c_at[1], c_at[2]) for c_at in uni_c) contacts, s_unique_id = self.get_contacts(source_awl, cpairs, cutoff=cutoff) all_cont_db[s_unique_id] = contacts print " Found %d contact pairs" % ncont return all_cont_db
def check_distances(sites_cart, point_distance, verbose): asu_mappings = non_crystallographic_asu_mappings(sites_cart=sites_cart) distance_cutoff = point_distance * math.sqrt(2) * 0.99 simple_pair_generator = crystal.neighbors_simple_pair_generator( asu_mappings=asu_mappings, distance_cutoff=distance_cutoff) pair_generator = crystal.neighbors_fast_pair_generator( asu_mappings=asu_mappings, distance_cutoff=distance_cutoff) assert simple_pair_generator.count_pairs() == pair_generator.count_pairs() pair_generator.restart() neighbors = {} for pair in pair_generator: assert pair.j_seq != pair.i_seq assert pair.j_sym == 0 assert approx_equal(pair.dist_sq, point_distance**2) neighbors[pair.i_seq] = neighbors.get(pair.i_seq, 0) + 1 neighbors[pair.j_seq] = neighbors.get(pair.j_seq, 0) + 1 n_dict = {} for n in neighbors.values(): n_dict[n] = n_dict.get(n, 0) + 1 if (verbose): print(n_dict) if (len(neighbors) > 0): assert max(neighbors.values()) <= 12
def create_super_sphere(pdb_hierarchy, crystal_symmetry, select_within_radius, link_min=1.0, link_max=2.0, r=None): if (r is None): # This is equivalent to (but much faster): # #r = grm.geometry.pair_proxies().nonbonded_proxies.\ # get_symmetry_interacting_indices_unique( # sites_cart = pdb_hierarchy.atoms().extract_xyz()) # sites_cart = pdb_hierarchy.atoms().extract_xyz() sst = crystal_symmetry.special_position_settings().site_symmetry_table( sites_cart=sites_cart) r = {} from cctbx import crystal cutoff = select_within_radius + 1 # +1 is nonbonded buffer conn_asu_mappings = crystal_symmetry.special_position_settings().\ asu_mappings(buffer_thickness=cutoff) conn_asu_mappings.process_sites_cart(original_sites=sites_cart, site_symmetry_table=sst) conn_pair_asu_table = crystal.pair_asu_table( asu_mappings=conn_asu_mappings) conn_pair_asu_table.add_all_pairs(distance_cutoff=cutoff) pair_generator = crystal.neighbors_fast_pair_generator( conn_asu_mappings, distance_cutoff=cutoff) for pair in pair_generator: rt_mx_i = conn_asu_mappings.get_rt_mx_i(pair) rt_mx_j = conn_asu_mappings.get_rt_mx_j(pair) rt_mx_ji = rt_mx_i.inverse().multiply(rt_mx_j) if str(rt_mx_ji) == "x,y,z": continue r.setdefault(pair.j_seq, []).append(rt_mx_ji) for k, v in zip(r.keys(), r.values()): # remove duplicates! r[k] = list(set(v)) c = iotbx.pdb.hierarchy.chain( id="SS") # all symmetry related full residues fm = crystal_symmetry.unit_cell().fractionalization_matrix() om = crystal_symmetry.unit_cell().orthogonalization_matrix() selection = r.keys() for rg in pdb_hierarchy.residue_groups(): keep = False for i in rg.atoms().extract_i_seq(): if (i in selection): keep = True break if (keep): ops = r[i] for op in ops: rg_ = rg.detached_copy() xyz = rg_.atoms().extract_xyz() new_xyz = flex.vec3_double() for xyz_ in xyz: t1 = fm * flex.vec3_double([xyz_]) t2 = op * t1[0] t3 = om * flex.vec3_double([t2]) new_xyz.append(t3[0]) rg_.atoms().set_xyz(new_xyz) rg_.link_to_previous = True c.append_residue_group(rg_) resseq = 0 for rg in c.residue_groups(): rg.resseq = "%4d" % resseq resseq += 1 # Now we need to re-order residues and group by chains so that they can be # linked by pdb interpretation. super_sphere_hierarchy = pdb_hierarchy.deep_copy() # all_chains = iotbx.pdb.utils.all_chain_ids() all_chains = [chid.strip() for chid in all_chains] for cid in list(set([i.id for i in pdb_hierarchy.chains()])): all_chains.remove(cid) all_chains = iter(all_chains) # def get_atom(atoms, name): for a in atoms: if (a.name.strip().lower() == name.strip().lower()): return a.xyz residue_groups_i = list(c.residue_groups()) residue_groups_j = list(c.residue_groups()) residue_groups_k = list() # standard aa residues only # def dist(r1, r2): return math.sqrt((r1[0] - r2[0])**2 + (r1[1] - r2[1])**2 + (r1[2] - r2[2])**2) # def grow_chain(residue_groups_j, chunk, ci): n_linked = 0 for rgj in residue_groups_j: nj = get_atom(atoms=rgj.atoms(), name="N") if (nj is None): continue d_ci_nj = dist(ci, nj) if (d_ci_nj < link_max and d_ci_nj > link_min): n_linked += 1 chunk.append(rgj) residue_groups_j.remove(rgj) break return n_linked, rgj # Find all isolated single residues, and also save starters starters = [] for rgi in residue_groups_i: ci = get_atom(atoms=rgi.atoms(), name="C") ni = get_atom(atoms=rgi.atoms(), name="N") if (ci is None or ni is None): # collect non-proteins c = iotbx.pdb.hierarchy.chain(id=all_chains.next()) c.append_residue_group(rgi) super_sphere_hierarchy.models()[0].append_chain(c) continue residue_groups_k.append(rgi) c_linked = 0 n_linked = 0 for rgj in residue_groups_j: cj = get_atom(atoms=rgj.atoms(), name="C") nj = get_atom(atoms=rgj.atoms(), name="N") if (cj is None or nj is None): continue d_ci_nj = dist(ci, nj) d_ni_cj = dist(ni, cj) if (d_ci_nj < link_max and d_ci_nj > link_min): n_linked += 1 if (d_ni_cj < link_max and d_ni_cj > link_min): c_linked += 1 assert c_linked in [1, 0], c_linked # Either linked or not! assert n_linked in [1, 0], n_linked # Either linked or not! if (c_linked == 0 and n_linked == 0): # isolated single residue c = iotbx.pdb.hierarchy.chain(id=all_chains.next()) rgi.link_to_previous = True c.append_residue_group(rgi) super_sphere_hierarchy.models()[0].append_chain(c) elif (c_linked == 0): # collect c-terminal residues starters.append(rgi) # Grow continuous chains from remaining residues starting from c-terminals for rgi in starters: ci = get_atom(atoms=rgi.atoms(), name="C") chunk = [rgi] n_linked = 1 while n_linked == 1: n_linked, rgj = grow_chain(residue_groups_k, chunk, ci) if (n_linked == 1): ci = get_atom(atoms=rgj.atoms(), name="C") c = iotbx.pdb.hierarchy.chain(id=all_chains.next()) for i, rg in enumerate(chunk): rg.resseq = "%4d" % i c.append_residue_group(rg) super_sphere_hierarchy.models()[0].append_chain(c) # box = uctbx.non_crystallographic_unit_cell_with_the_sites_in_its_center( sites_cart=super_sphere_hierarchy.atoms().extract_xyz(), buffer_layer=10) cs_super_sphere = box.crystal_symmetry() return group_args(hierarchy=super_sphere_hierarchy, crystal_symmetry=cs_super_sphere, selection_r=r)
def compare_ions(hierarchy, reference_hierarchy, reference_xrs, distance_cutoff=2.0, log=None, ignore_elements=(), only_elements=(), sel_str_base="segid ION"): """ Compares two pdb structures to determine the number of ions that appear in the reference structure and are either matched or missing in the other structure. Parameters ---------- hierarchy : iotbx.pdb.hierarchy.root reference_hierarchy : iotbx.pdb.hierarchy.root reference_xrs : ... distance_cutoff : float, optional log : file, optional ignore_element : iterable, optional only_elements : iterable, optional sel_str_base : str, optional Returns ------- int Number of ions in reference_hierarchy that were also found in hierarchy. int Number of ions in reference_hierarchy that were not found in hierarchy. """ if log is None: log = null_out() sel_cache = hierarchy.atom_selection_cache() sel_str = sel_str_base if len(only_elements) > 0: sel_str += " and (%s)" % " or ".join( ["element %s" % e for e in only_elements]) elif len(ignore_elements) > 0: sel_str += " and not (%s)" % " or ".join( ["element %s" % e for e in ignore_elements]) ion_isel = sel_cache.selection(sel_str).iselection() if len(ion_isel) == 0: return [], [] pdb_atoms = hierarchy.atoms() pdb_atoms.reset_i_seq() ions = pdb_atoms.select(ion_isel) asu_mappings = reference_xrs.asu_mappings( buffer_thickness=distance_cutoff + 0.1) unit_cell = reference_xrs.unit_cell() sites_cart = ions.extract_xyz() sites_frac = unit_cell.fractionalize(sites_cart=sites_cart) asu_mappings.process_sites_frac( sites_frac, min_distance_sym_equiv=reference_xrs.min_distance_sym_equiv()) pair_generator = crystal.neighbors_fast_pair_generator( asu_mappings=asu_mappings, distance_cutoff=distance_cutoff) reference_atoms = reference_hierarchy.atoms() n_xray = reference_xrs.scatterers().size() ion_ref_i_seqs = [] for k in range(len(ions)): ion_ref_i_seqs.append([]) for pair in pair_generator: if ((pair.i_seq < n_xray and pair.j_seq < n_xray) or (pair.i_seq >= n_xray and pair.j_seq >= n_xray)): continue if pair.i_seq < n_xray: ion_seq, ref_seq = pair.j_seq, pair.i_seq else: ion_seq, ref_seq = pair.i_seq, pair.j_seq site_frac = sites_frac[ion_seq - n_xray] dxyz = sqrt(pair.dist_sq) j_seq = ion_seq - n_xray ion_ref_i_seqs[j_seq].append(ref_seq) # FIXME better filtering needed - right now we risk double-counting ions in # the reference model, although I haven't found a case of this yet matched = [] missing = [] for i_seq, ref_i_seqs in enumerate(ion_ref_i_seqs): ion = ions[i_seq] if len(ref_i_seqs) == 0: print("No match for %s" % ion.id_str(), file=log) missing.append(ion.id_str()) else: ref_ions = [] for i_seq in ref_i_seqs: ref_atom = reference_atoms[i_seq] if ion.element.upper() == ref_atom.element.upper(): ref_ions.append(ref_atom.id_str()) if len(ref_ions) >= 1: matched.append(ion.id_str()) if len(ref_ions) > 1: print("Multiple matches for %s:" % ion.id_str(), file=log) for ref_ion in ref_ions: print(" %s" % ref_ion, file=log) else: print("Ion %s matches %s" % (ion.id_str(), ref_ions[0]), file=log) else: print("No match for %s" % ion.id_str(), file=log) missing.append(ion.id_str()) return matched, missing
def exercise_with_zeolite(verbose): if (not libtbx.env.has_module("iotbx")): print("Skipping exercise_with_zeolite(): iotbx not available") return from iotbx.kriber import strudat atlas_file = libtbx.env.find_in_repositories( relative_path="phenix_regression/misc/strudat_zeolite_atlas", test=os.path.isfile) if (atlas_file is None): print("Skipping exercise_with_zeolite(): input file not available") return strudat_contents = strudat.read_all_entries(open(atlas_file)) strudat_entry = strudat_contents.get("YUG") si_structure = strudat_entry.as_xray_structure() if (verbose): out = sys.stdout else: out = StringIO() drls = distance_and_repulsion_least_squares( si_structure=si_structure, distance_cutoff=3.5, nonbonded_repulsion_function_type="prolsq", n_macro_cycles=2, out=out) # nbp = drls.geometry_restraints_manager.pair_proxies().nonbonded_proxies assert nbp.n_total() > 50 # expected is 60, but the exact number depends on the minimizer # site_labels = drls.minimized_structure.scatterers().extract_labels() sites_cart = drls.start_structure.sites_cart() pair_proxies = drls.geometry_restraints_manager.pair_proxies() out = StringIO() pair_proxies.bond_proxies.show_sorted(by_value="residual", sites_cart=sites_cart, site_labels=site_labels, f=out) if (verbose): sys.stdout.write(out.getvalue()) assert len(out.getvalue().splitlines()) == 48 * 4 + 2 assert out.getvalue().splitlines()[-1].find("remaining") < 0 out = StringIO() pair_proxies.bond_proxies.show_sorted(by_value="residual", sites_cart=sites_cart, site_labels=site_labels, f=out, prefix="0^", max_items=28) if (verbose): sys.stdout.write(out.getvalue()) assert not show_diff(out.getvalue().replace("e-00", "e-0"), """\ 0^Bond restraints: 48 0^Sorted by residual: 0^bond O3 0^ O4 0^ ideal model delta sigma weight residual 0^ 2.629 2.120 0.509 1.56e+00 4.10e-01 1.06e-01 ... 0^bond SI1 0^ SI1 0^ ideal model delta sigma weight residual sym.op. 0^ 3.071 3.216 -0.145 2.08e+00 2.31e-01 4.83e-03 -x+1/2,-y+1/2,-z+1 0^... (remaining 20 not shown) """, selections=[range(6), range(-5, 0)]) out = StringIO() pair_proxies.bond_proxies.show_sorted(by_value="delta", sites_cart=sites_cart, site_labels=site_labels, f=out, prefix="0^", max_items=28) if (verbose): sys.stdout.write(out.getvalue()) assert not show_diff(out.getvalue().replace("e-00", "e-0"), """\ 0^Bond restraints: 48 0^Sorted by delta: 0^bond O3 0^ O4 0^ ideal model delta sigma weight residual 0^ 2.629 2.120 0.509 1.56e+00 4.10e-01 1.06e-01 ... 0^... (remaining 20 not shown) """, selections=[range(6), [-1]]) site_labels_long = ["abc" + label + "def" for label in site_labels] out = StringIO() pair_proxies.bond_proxies.show_sorted(by_value="residual", sites_cart=sites_cart, site_labels=site_labels_long, f=out, prefix="^0", max_items=28) if (verbose): sys.stdout.write(out.getvalue()) assert not show_diff(out.getvalue().replace("e-00", "e-0"), """\ ^0Bond restraints: 48 ^0Sorted by residual: ^0bond abcO3def ^0 abcO4def ^0 ideal model delta sigma weight residual ^0 2.629 2.120 0.509 1.56e+00 4.10e-01 1.06e-01 ... ^0bond abcSI1def ^0 abcSI1def ^0 ideal model delta sigma weight residual sym.op. ^0 3.071 3.216 -0.145 2.08e+00 2.31e-01 4.83e-03 -x+1/2,-y+1/2,-z+1 ^0... (remaining 20 not shown) """, selections=[range(6), range(-5, 0)]) out = StringIO() pair_proxies.bond_proxies.show_sorted(by_value="residual", sites_cart=sites_cart, f=out, prefix=".=", max_items=28) if (verbose): sys.stdout.write(out.getvalue()) assert not show_diff(out.getvalue().replace("e-00", "e-0"), """\ .=Bond restraints: 48 .=Sorted by residual: .=bond 4 .= 5 .= ideal model delta sigma weight residual .= 2.629 2.120 0.509 1.56e+00 4.10e-01 1.06e-01 ... .=bond 0 .= 0 .= ideal model delta sigma weight residual sym.op. .= 3.071 3.216 -0.145 2.08e+00 2.31e-01 4.83e-03 -x+1/2,-y+1/2,-z+1 .=... (remaining 20 not shown) """, selections=[range(6), range(-5, 0)]) out = StringIO() pair_proxies.bond_proxies.show_sorted(by_value="residual", sites_cart=sites_cart, f=out, prefix="-+", max_items=1) if (verbose): sys.stdout.write(out.getvalue()) assert not show_diff( out.getvalue().replace("e-00", "e-0"), """\ -+Bond restraints: 48 -+Sorted by residual: -+bond 4 -+ 5 -+ ideal model delta sigma weight residual -+ 2.629 2.120 0.509 1.56e+00 4.10e-01 1.06e-01 -+... (remaining 47 not shown) """) out = StringIO() pair_proxies.bond_proxies.show_sorted(by_value="residual", sites_cart=sites_cart, f=out, prefix="=+", max_items=0) if (verbose): sys.stdout.write(out.getvalue()) assert not show_diff( out.getvalue(), """\ =+Bond restraints: 48 =+Sorted by residual: =+... (remaining 48 not shown) """) # sites_cart = si_structure.sites_cart() site_labels = [sc.label for sc in si_structure.scatterers()] asu_mappings = si_structure.asu_mappings(buffer_thickness=3.5) for min_cubicle_edge in [0, 5]: pair_generator = crystal.neighbors_fast_pair_generator( asu_mappings=asu_mappings, distance_cutoff=asu_mappings.buffer_thickness(), minimal=False, min_cubicle_edge=min_cubicle_edge) sorted_asu_proxies = geometry_restraints.nonbonded_sorted_asu_proxies( asu_mappings=asu_mappings) while (not pair_generator.at_end()): p = geometry_restraints.nonbonded_asu_proxy( pair=next(pair_generator), vdw_distance=3) sorted_asu_proxies.process(p) out = StringIO() sorted_asu_proxies.show_sorted(by_value="delta", sites_cart=sites_cart, site_labels=site_labels, f=out, prefix="d%") if (verbose): sys.stdout.write(out.getvalue()) assert not show_diff( out.getvalue(), """\ d%Nonbonded interactions: 7 d%Sorted by model distance: ... d%nonbonded SI2 d% SI2 d% model vdw sym.op. d% 3.092 3.000 -x+1,y,-z ... d%nonbonded SI1 d% SI1 d% model vdw sym.op. d% 3.216 3.000 -x+1/2,-y+1/2,-z+1 """, selections=[range(2), range(10, 14), range(26, 30)]) out = StringIO() sorted_asu_proxies.show_sorted(by_value="delta", sites_cart=sites_cart, f=out, prefix="*j", max_items=5) if (verbose): sys.stdout.write(out.getvalue()) assert not show_diff(out.getvalue(), """\ *jNonbonded interactions: 7 *jSorted by model distance: ... *jnonbonded 0 *j 1 *j model vdw *j 3.107 3.000 *jnonbonded 0 *j 0 *j model vdw sym.op. *j 3.130 3.000 -x+1,y,-z+1 *j... (remaining 2 not shown) """, selections=[range(2), range(-9, 0)]) out = StringIO() sorted_asu_proxies.show_sorted(by_value="delta", sites_cart=sites_cart, f=out, prefix="@r", max_items=0) if (verbose): sys.stdout.write(out.getvalue()) assert not show_diff(out.getvalue(), """\ @rNonbonded interactions: 7 """)
def contacts_to_coord(self, coord, pdb_hier, symmetry, cutoff=6.0): """ Used to use extract map_model, but that caused problems This function takes cartesian coordinate, pdb_hier, and symmetry and returns sorted list of dictionaries, each a particular contact very hacked together, jams pdb strings together create a dummy pdb, put water at the peak site in the original coordinate system then use fast pair generater to get all contacts to our peak atom """ dummy_atom = self.pput.write_atom(1, "O", "", "HOH", "ZZ", 9999, "", coord[0], coord[1], coord[2], 1.0, 35.0, "O", "") #hack to add an atom to a pdb orig_str = pdb_hier.as_pdb_string(write_scale_records=False, append_end=False, interleaved_conf=0, atoms_reset_serial_first_value=1, atom_hetatm=True, sigatm=False, anisou=False, siguij=False, output_break_records=False) nmodels = len(pdb_hier.models()) if nmodels == 1: comb = orig_str + dummy_atom else: newmodel = nmodels + 1 comb = orig_str + "MODEL %s\n" % newmodel comb = comb + dummy_atom comb = comb + "ENDMDL\n" dummy_pdb = iotbx.pdb.input(source_info=None, lines=flex.split_lines(comb)) dummy_hier = dummy_pdb.construct_hierarchy() atsel = "chain ZZ and resid 9999" dummy_select = dummy_hier.atom_selection_cache().selection( string=atsel) atsel_index = np.argwhere(dummy_select.as_numpy_array()) dummy_xrs = dummy_pdb.xray_structure_simple(crystal_symmetry=symmetry) #find neighbors with symmetry -- use pair_finding with asu_mappings #doing this for each peak may be a bad idea, use all_contacts version instead if possible asu_mappings = dummy_xrs.asu_mappings(buffer_thickness=cutoff) pair_generator = crystal.neighbors_fast_pair_generator( asu_mappings, distance_cutoff=cutoff) peak_vector_list = [] #neighbor_mask = pair_generator.neighbors_of(atsel_arr) #neighbors = pair_generator.select(neighbor_mask) for pair in pair_generator: if pair.i_seq == atsel_index: #our peak is first atom, but we want pairs in both directions #to provide exhaustive list of contacts #store index number and difference vector and sym to make unique #we don't care which symop, just how far away rdist = int( np.sqrt(pair.dist_sq) * 1000) / 1000.0 #avoid float error peak_vector_list.append((pair.j_seq, rdist, pair.j_sym)) if pair.j_seq == atsel_index: rdist = int(np.sqrt(pair.dist_sq) * 1000) / 1000.0 peak_vector_list.append((pair.i_seq, rdist, pair.j_sym)) unique = set(peak_vector_list) dummy_atoms = dummy_hier.atoms() #selection is boolean flex array, sizeof no atoms, can be indexed directly #get awl for our dummy atom s_awl = dummy_atoms.select(dummy_select)[0].fetch_labels() #list((awl_db[c_at[0]],c_at[1],c_at[2]) for c_at in uni_c ) #next, get list of contacts (awl,dist) selection = dummy_hier.atom_selection_cache().selection("not all") if len(unique) == 0: return [] cont_list = [] for conti in unique: selection[conti[0]] = True sel_awl = dummy_atoms.select(selection)[0].fetch_labels() cont_list.append( (sel_awl, conti[1], conti[2])) #pass source awl, index for target, distance selection[conti[0]] = False #unselect contacts, s_unal = self.get_contacts(s_awl, cont_list, cutoff=cutoff) return contacts
def exercise_with_zeolite(verbose): if (not libtbx.env.has_module("iotbx")): print "Skipping exercise_with_zeolite(): iotbx not available" return from iotbx.kriber import strudat atlas_file = libtbx.env.find_in_repositories( relative_path="phenix_regression/misc/strudat_zeolite_atlas", test=os.path.isfile) if (atlas_file is None): print "Skipping exercise_with_zeolite(): input file not available" return strudat_contents = strudat.read_all_entries(open(atlas_file)) strudat_entry = strudat_contents.get("YUG") si_structure = strudat_entry.as_xray_structure() if (verbose): out = sys.stdout else: out = StringIO() drls = distance_and_repulsion_least_squares( si_structure=si_structure, distance_cutoff=3.5, nonbonded_repulsion_function_type="prolsq", n_macro_cycles=2, out=out) # nbp = drls.geometry_restraints_manager.pair_proxies().nonbonded_proxies assert nbp.n_total() > 50 # expected is 60, but the exact number depends on the minimizer # site_labels = drls.minimized_structure.scatterers().extract_labels() sites_cart = drls.start_structure.sites_cart() pair_proxies = drls.geometry_restraints_manager.pair_proxies() out = StringIO() pair_proxies.bond_proxies.show_sorted( by_value="residual", sites_cart=sites_cart, site_labels=site_labels, f=out) if (verbose): sys.stdout.write(out.getvalue()) assert len(out.getvalue().splitlines()) == 48*4+2 assert out.getvalue().splitlines()[-1].find("remaining") < 0 out = StringIO() pair_proxies.bond_proxies.show_sorted( by_value="residual", sites_cart=sites_cart, site_labels=site_labels, f=out, prefix="0^", max_items=28) if (verbose): sys.stdout.write(out.getvalue()) assert not show_diff(out.getvalue().replace("e-00", "e-0"), """\ 0^Bond restraints: 48 0^Sorted by residual: 0^bond O3 0^ O4 0^ ideal model delta sigma weight residual 0^ 2.629 2.120 0.509 1.56e+00 4.10e-01 1.06e-01 ... 0^bond SI1 0^ SI1 0^ ideal model delta sigma weight residual sym.op. 0^ 3.071 3.216 -0.145 2.08e+00 2.31e-01 4.83e-03 -x+1/2,-y+1/2,-z+1 0^... (remaining 20 not shown) """, selections=[range(6), range(-5,0)]) out = StringIO() pair_proxies.bond_proxies.show_sorted( by_value="delta", sites_cart=sites_cart, site_labels=site_labels, f=out, prefix="0^", max_items=28) if (verbose): sys.stdout.write(out.getvalue()) assert not show_diff(out.getvalue().replace("e-00", "e-0"), """\ 0^Bond restraints: 48 0^Sorted by delta: 0^bond O3 0^ O4 0^ ideal model delta sigma weight residual 0^ 2.629 2.120 0.509 1.56e+00 4.10e-01 1.06e-01 ... 0^... (remaining 20 not shown) """, selections=[range(6), [-1]]) site_labels_long = ["abc"+label+"def" for label in site_labels] out = StringIO() pair_proxies.bond_proxies.show_sorted( by_value="residual", sites_cart=sites_cart, site_labels=site_labels_long, f=out, prefix="^0", max_items=28) if (verbose): sys.stdout.write(out.getvalue()) assert not show_diff(out.getvalue().replace("e-00", "e-0"), """\ ^0Bond restraints: 48 ^0Sorted by residual: ^0bond abcO3def ^0 abcO4def ^0 ideal model delta sigma weight residual ^0 2.629 2.120 0.509 1.56e+00 4.10e-01 1.06e-01 ... ^0bond abcSI1def ^0 abcSI1def ^0 ideal model delta sigma weight residual sym.op. ^0 3.071 3.216 -0.145 2.08e+00 2.31e-01 4.83e-03 -x+1/2,-y+1/2,-z+1 ^0... (remaining 20 not shown) """, selections=[range(6), range(-5,0)]) out = StringIO() pair_proxies.bond_proxies.show_sorted( by_value="residual", sites_cart=sites_cart, f=out, prefix=".=", max_items=28) if (verbose): sys.stdout.write(out.getvalue()) assert not show_diff(out.getvalue().replace("e-00", "e-0"), """\ .=Bond restraints: 48 .=Sorted by residual: .=bond 4 .= 5 .= ideal model delta sigma weight residual .= 2.629 2.120 0.509 1.56e+00 4.10e-01 1.06e-01 ... .=bond 0 .= 0 .= ideal model delta sigma weight residual sym.op. .= 3.071 3.216 -0.145 2.08e+00 2.31e-01 4.83e-03 -x+1/2,-y+1/2,-z+1 .=... (remaining 20 not shown) """, selections=[range(6), range(-5,0)]) out = StringIO() pair_proxies.bond_proxies.show_sorted( by_value="residual", sites_cart=sites_cart, f=out, prefix="-+", max_items=1) if (verbose): sys.stdout.write(out.getvalue()) assert not show_diff(out.getvalue().replace("e-00", "e-0"), """\ -+Bond restraints: 48 -+Sorted by residual: -+bond 4 -+ 5 -+ ideal model delta sigma weight residual -+ 2.629 2.120 0.509 1.56e+00 4.10e-01 1.06e-01 -+... (remaining 47 not shown) """) out = StringIO() pair_proxies.bond_proxies.show_sorted( by_value="residual", sites_cart=sites_cart, f=out, prefix="=+", max_items=0) if (verbose): sys.stdout.write(out.getvalue()) assert not show_diff(out.getvalue(), """\ =+Bond restraints: 48 =+Sorted by residual: =+... (remaining 48 not shown) """) # sites_cart = si_structure.sites_cart() site_labels = [sc.label for sc in si_structure.scatterers()] asu_mappings = si_structure.asu_mappings(buffer_thickness=3.5) for min_cubicle_edge in [0, 5]: pair_generator = crystal.neighbors_fast_pair_generator( asu_mappings=asu_mappings, distance_cutoff=asu_mappings.buffer_thickness(), minimal=False, min_cubicle_edge=min_cubicle_edge) sorted_asu_proxies = geometry_restraints.nonbonded_sorted_asu_proxies( asu_mappings=asu_mappings) while (not pair_generator.at_end()): p = geometry_restraints.nonbonded_asu_proxy( pair=pair_generator.next(), vdw_distance=3) sorted_asu_proxies.process(p) out = StringIO() sorted_asu_proxies.show_sorted( by_value="delta", sites_cart=sites_cart, site_labels=site_labels, f=out, prefix="d%") if (verbose): sys.stdout.write(out.getvalue()) assert not show_diff(out.getvalue(), """\ d%Nonbonded interactions: 7 d%Sorted by model distance: ... d%nonbonded SI2 d% SI2 d% model vdw sym.op. d% 3.092 3.000 -x+1,y,-z ... d%nonbonded SI1 d% SI1 d% model vdw sym.op. d% 3.216 3.000 -x+1/2,-y+1/2,-z+1 """, selections=[range(2), range(10,14), range(26,30)]) out = StringIO() sorted_asu_proxies.show_sorted( by_value="delta", sites_cart=sites_cart, f=out, prefix="*j", max_items=5) if (verbose): sys.stdout.write(out.getvalue()) assert not show_diff(out.getvalue(), """\ *jNonbonded interactions: 7 *jSorted by model distance: ... *jnonbonded 0 *j 1 *j model vdw *j 3.107 3.000 *jnonbonded 0 *j 0 *j model vdw sym.op. *j 3.130 3.000 -x+1,y,-z+1 *j... (remaining 2 not shown) """, selections=[range(2), range(-9,0)]) out = StringIO() sorted_asu_proxies.show_sorted( by_value="delta", sites_cart=sites_cart, f=out, prefix="@r", max_items=0) if (verbose): sys.stdout.write(out.getvalue()) assert not show_diff(out.getvalue(), """\ @rNonbonded interactions: 7 """)
def compare_ions( hierarchy, reference_hierarchy, reference_xrs, distance_cutoff=2.0, log=None, ignore_elements=(), only_elements=(), sel_str_base="segid ION", ): """ Compares two pdb structures to determine the number of ions that appear in the reference structure and are either matched or missing in the other structure. Parameters ---------- hierarchy : iotbx.pdb.hierarchy.root reference_hierarchy : iotbx.pdb.hierarchy.root reference_xrs : ... distance_cutoff : float, optional log : file, optional ignore_element : iterable, optional only_elements : iterable, optional sel_str_base : str, optional Returns ------- int Number of ions in reference_hierarchy that were also found in hierarchy. int Number of ions in reference_hierarchy that were not found in hierarchy. """ if log is None: log = null_out() sel_cache = hierarchy.atom_selection_cache() sel_str = sel_str_base if len(only_elements) > 0: sel_str += " and (%s)" % " or ".join(["element %s" % e for e in only_elements]) elif len(ignore_elements) > 0: sel_str += " and not (%s)" % " or ".join(["element %s" % e for e in ignore_elements]) ion_isel = sel_cache.selection(sel_str).iselection() if len(ion_isel) == 0: return [], [] pdb_atoms = hierarchy.atoms() pdb_atoms.reset_i_seq() ions = pdb_atoms.select(ion_isel) asu_mappings = reference_xrs.asu_mappings(buffer_thickness=distance_cutoff + 0.1) unit_cell = reference_xrs.unit_cell() sites_cart = ions.extract_xyz() sites_frac = unit_cell.fractionalize(sites_cart=sites_cart) asu_mappings.process_sites_frac(sites_frac, min_distance_sym_equiv=reference_xrs.min_distance_sym_equiv()) pair_generator = crystal.neighbors_fast_pair_generator(asu_mappings=asu_mappings, distance_cutoff=distance_cutoff) reference_atoms = reference_hierarchy.atoms() n_xray = reference_xrs.scatterers().size() ion_ref_i_seqs = [] for k in range(len(ions)): ion_ref_i_seqs.append([]) for pair in pair_generator: if (pair.i_seq < n_xray and pair.j_seq < n_xray) or (pair.i_seq >= n_xray and pair.j_seq >= n_xray): continue if pair.i_seq < n_xray: ion_seq, ref_seq = pair.j_seq, pair.i_seq else: ion_seq, ref_seq = pair.i_seq, pair.j_seq site_frac = sites_frac[ion_seq - n_xray] dxyz = sqrt(pair.dist_sq) j_seq = ion_seq - n_xray ion_ref_i_seqs[j_seq].append(ref_seq) # FIXME better filtering needed - right now we risk double-counting ions in # the reference model, although I haven't found a case of this yet matched = [] missing = [] for i_seq, ref_i_seqs in enumerate(ion_ref_i_seqs): ion = ions[i_seq] if len(ref_i_seqs) == 0: print >> log, "No match for %s" % ion.id_str() missing.append(ion.id_str()) else: ref_ions = [] for i_seq in ref_i_seqs: ref_atom = reference_atoms[i_seq] if ion.element.upper() == ref_atom.element.upper(): ref_ions.append(ref_atom.id_str()) if len(ref_ions) >= 1: matched.append(ion.id_str()) if len(ref_ions) > 1: print >> log, "Multiple matches for %s:" % ion.id_str() for ref_ion in ref_ions: print >> log, " %s" % ref_ion else: print >> log, "Ion %s matches %s" % (ion.id_str(), ref_ions[0]) else: print >> log, "No match for %s" % ion.id_str() missing.append(ion.id_str()) return matched, missing