def get_angles(atom_group, atom, verbose=False): bad_hydrogen_count = 0 corrected_hydrogen_count = [] bonded = get_bonded(atom_group, atom) if not bonded: bad_hydrogen_count += 1 if verbose: print 'not bonded: %s' % atom.format_atom_record() return bad_hydrogen_count, corrected_hydrogen_count for ba in bonded: angled = get_bonded(atom_group, ba, exclude=[atom]) if not angled: bad_hydrogen_count += 1 if verbose: print 'not angled: %s' % atom.format_atom_record() return bad_hydrogen_count, corrected_hydrogen_count if angled[0].element.strip() in ["H", "D", "T"]: return bad_hydrogen_count, corrected_hydrogen_count try: angle = geometry.angle( (atom.xyz, ba.xyz, angled[0].xyz)).angle_model except Exception: print ' Bad angle "%s"' % (atom.format_atom_record()[:26]) bad_hydrogen_count += 1 return bad_hydrogen_count, corrected_hydrogen_count if angle < 85.: xyz = [0, 0, 0] xyz[0] = ba.xyz[0] * 2 - atom.xyz[0] xyz[1] = ba.xyz[1] * 2 - atom.xyz[1] xyz[2] = ba.xyz[2] * 2 - atom.xyz[2] angle = geometry.angle((xyz, ba.xyz, angled[0].xyz)).angle_model if angle > 95.: atom.xyz = tuple(xyz) if verbose: print ' Inverted "%s" ' % (atom.format_atom_record()[:26]) corrected_hydrogen_count.append(atom.i_seq) return bad_hydrogen_count, corrected_hydrogen_count
def get_angles(atom_group, atom, verbose=False): bad_hydrogen_count = 0 corrected_hydrogen_count = [] bonded = get_bonded(atom_group, atom) if not bonded: bad_hydrogen_count+=1 if verbose: print 'not bonded: %s' % atom.format_atom_record() return bad_hydrogen_count, corrected_hydrogen_count for ba in bonded: angled = get_bonded(atom_group, ba, exclude=[atom]) if not angled: bad_hydrogen_count+=1 if verbose: print 'not angled: %s' % atom.format_atom_record() return bad_hydrogen_count, corrected_hydrogen_count if angled[0].element.strip() in ["H", "D", "T"]: return bad_hydrogen_count, corrected_hydrogen_count try: angle = geometry.angle((atom.xyz,ba.xyz,angled[0].xyz)).angle_model except Exception: print ' Bad angle "%s"' % (atom.format_atom_record()[:26]) bad_hydrogen_count +=1 return bad_hydrogen_count, corrected_hydrogen_count if angle<85.: xyz=[0,0,0] xyz[0] = ba.xyz[0]*2-atom.xyz[0] xyz[1] = ba.xyz[1]*2-atom.xyz[1] xyz[2] = ba.xyz[2]*2-atom.xyz[2] angle = geometry.angle((xyz,ba.xyz,angled[0].xyz)).angle_model if angle>95.: atom.xyz = tuple(xyz) if verbose: print ' Inverted "%s" ' % (atom.format_atom_record()[:26]) corrected_hydrogen_count.append(atom.i_seq) return bad_hydrogen_count, corrected_hydrogen_count
def get_i_seqs_from_restraints_manager( hierarchy, restraints_manager, xray_structure = None, sites_cart = None, ): if sites_cart is None and xray_structure: sites_cart = xray_structure.sites_cart() if sites_cart is None: xray_structure = hierarchy.extract_xray_structure() sites_cart = xray_structure.sites_cart() i_seqs=[] xyzs=[] angle_proxies_simple = restraints_manager.geometry.angle_proxies atoms = hierarchy.atoms() for proxy in angle_proxies_simple: i_seq, j_seq, k_seq = proxy.i_seqs if(atoms[i_seq].element.strip() in ["H", "D"] or atoms[k_seq].element.strip() in ["H", "D"] ): if(atoms[i_seq].element.strip() in ["H", "D"] and atoms[k_seq].element.strip() in ["H", "D"] ): continue if(atoms[i_seq].element.strip() in ["H", "D"]): i_h = i_seq site_i = sites_cart[i_seq] site_k = sites_cart[k_seq] else: i_h = k_seq site_i = sites_cart[k_seq] site_k = sites_cart[i_seq] site_j = sites_cart[j_seq] if i_h in i_seqs: continue angle = geometry.angle((site_i, site_j, site_k)).angle_model if angle<85.: xyz=[0,0,0] xyz[0] = site_j[0]*2-site_i[0] xyz[1] = site_j[1]*2-site_i[1] xyz[2] = site_j[2]*2-site_i[2] angle = geometry.angle((xyz, site_j, site_k)).angle_model if angle>95.: xyzs.append(tuple(xyz)) i_seqs.append(i_h) return i_seqs, xyzs
def calc_angle(metrical_matrix=None): xs = quartz_p1(metrical_matrix=metrical_matrix) uc = xs.unit_cell() sites_cart = xs.sites_cart() sites = (sites_cart[4], sites_cart[0], sites_cart[5]) a = geometry.angle(sites) return a.angle_model*(math.pi/180)
def exercise_grad_metrical_matrix(): def calc_distance(metrical_matrix=None): xs = quartz_p1(metrical_matrix=metrical_matrix) uc = xs.unit_cell() sites_cart = xs.sites_cart() sites = (sites_cart[0], sites_cart[5]) d = geometry.distance(sites) return d.distance_model def calc_angle(metrical_matrix=None): xs = quartz_p1(metrical_matrix=metrical_matrix) uc = xs.unit_cell() sites_cart = xs.sites_cart() sites = (sites_cart[4], sites_cart[0], sites_cart[5]) a = geometry.angle(sites) return a.angle_model*(math.pi/180) xs = quartz_p1() uc = xs.unit_cell() sites_cart = xs.sites_cart() # distances sites = (sites_cart[0], sites_cart[5]) d = geometry.distance(sites) grads = d.d_distance_d_metrical_matrix(uc) fd_grads = finite_differences(calc_distance, xs.unit_cell()) assert approx_equal(grads, fd_grads) # angles sites = (sites_cart[4], sites_cart[0], sites_cart[5]) a = geometry.angle(sites) grads = a.d_angle_d_metrical_matrix(uc) fd_grads = finite_differences(calc_angle, xs.unit_cell()) assert approx_equal(grads, fd_grads)
def exercise_geometry(): xs = quartz() uc = xs.unit_cell() flags = xs.scatterer_flags() for f in flags: f.set_grad_site(True) xs.set_scatterer_flags(flags) cov = flex.double( (1e-8, 1e-9, 2e-9, 3e-9, 4e-9, 5e-9, 2e-8, 1e-9, 2e-9, 3e-9, 4e-9, 3e-8, 1e-9, 2e-9, 3e-9, 2e-8, 1e-9, 2e-9, 3e-8, 1e-9, 4e-8)) cell_vcv = flex.double((3e-2, 3e-2, 0, 0, 0, 0, 3e-2, 0, 0, 0, 0, 4e-2, 0, 0, 0, 0, 0, 0, 0, 0, 0)) param_map = xs.parameter_map() cov_cart = covariance.orthogonalize_covariance_matrix(cov, uc, param_map) O = matrix.sqr(uc.orthogonalization_matrix()) F = matrix.sqr(uc.fractionalization_matrix()) sites_cart = xs.sites_cart() sites_frac = xs.sites_frac() # distances rt_mx_ji = sgtbx.rt_mx('-y,x-y,z-1/3') sites = (sites_cart[0], uc.orthogonalize(rt_mx_ji * sites_frac[1])) d = geometry.distance(sites) assert approx_equal(d.distance_model, 1.6159860469110217) v = matrix.col(sites[1]) - matrix.col(sites[0]) r_inv_cart = (O * matrix.sqr(rt_mx_ji.r().inverse().as_double()) * F) g = d.d_distance_d_sites() g = matrix.row(g[0] + tuple(r_inv_cart * matrix.col(g[1]))) f = g * matrix.sqr(cov_cart.matrix_packed_u_as_symmetric()) * g.transpose() assert approx_equal(d.variance(cov_cart, uc, rt_mx_ji), f[0], eps=1e-15) assert approx_equal(0.0018054494791580823, d.variance(cov_cart, cell_vcv, uc, rt_mx_ji)) rt_mx_ji = sgtbx.rt_mx('x+1,y,z') sites = (sites_cart[0], uc.orthogonalize(rt_mx_ji * sites_frac[0])) d = geometry.distance(sites) assert approx_equal(d.distance_model, uc.parameters()[0]) assert approx_equal(cell_vcv.matrix_packed_u_diagonal()[0], d.variance(cov_cart, cell_vcv, uc, rt_mx_ji)) # angles rt_mx_ji = sgtbx.rt_mx('x-y,x,z-2/3') rt_mx_ki = sgtbx.rt_mx('-y,x-y,z-1/3') r_inv_cart_ji = (O * matrix.sqr(rt_mx_ji.r().inverse().as_double()) * F) r_inv_cart_ki = (O * matrix.sqr(rt_mx_ki.r().inverse().as_double()) * F) cov_a = covariance.extract_covariance_matrix_for_sites( flex.size_t([1, 0, 1]), cov_cart, param_map) sites = (uc.orthogonalize(rt_mx_ji * sites_frac[1]), sites_cart[0], uc.orthogonalize(rt_mx_ki * sites_frac[1])) a = geometry.angle(sites) assert approx_equal(a.angle_model, 101.30738566828551) g = a.d_angle_d_sites() g = matrix.row( tuple(r_inv_cart_ji * matrix.col(g[0])) + g[1] + tuple(r_inv_cart_ki * matrix.col(g[2]))) f = g * matrix.sqr(cov_a.matrix_packed_u_as_symmetric()) * g.transpose() assert approx_equal(a.variance(cov_a, uc, (rt_mx_ji, sgtbx.rt_mx(), rt_mx_ki)), f[0], eps=1e-15) assert approx_equal( 0.0042632511984529199, a.variance(cov_a, cell_vcv, uc, (rt_mx_ji, sgtbx.rt_mx(), rt_mx_ki)))
def get_i_seqs_from_restraints_manager( hierarchy, restraints_manager, xray_structure=None, sites_cart=None, ): if sites_cart is None and xray_structure: sites_cart = xray_structure.sites_cart() if sites_cart is None: xray_structure = hierarchy.extract_xray_structure() sites_cart = xray_structure.sites_cart() i_seqs = [] xyzs = [] angle_proxies_simple = restraints_manager.geometry.angle_proxies atoms = hierarchy.atoms() for proxy in angle_proxies_simple: i_seq, j_seq, k_seq = proxy.i_seqs if (atoms[i_seq].element.strip() in ["H", "D"] or atoms[k_seq].element.strip() in ["H", "D"]): if (atoms[i_seq].element.strip() in ["H", "D"] and atoms[k_seq].element.strip() in ["H", "D"]): continue if (atoms[i_seq].element.strip() in ["H", "D"]): i_h = i_seq site_i = sites_cart[i_seq] site_k = sites_cart[k_seq] else: i_h = k_seq site_i = sites_cart[k_seq] site_k = sites_cart[i_seq] site_j = sites_cart[j_seq] if i_h in i_seqs: continue angle = geometry.angle((site_i, site_j, site_k)).angle_model if angle < 85.: xyz = [0, 0, 0] xyz[0] = site_j[0] * 2 - site_i[0] xyz[1] = site_j[1] * 2 - site_i[1] xyz[2] = site_j[2] * 2 - site_i[2] angle = geometry.angle((xyz, site_j, site_k)).angle_model if angle > 95.: xyzs.append(tuple(xyz)) i_seqs.append(i_h) return i_seqs, xyzs
def __init__(self, hbonds, pair_asu_table, site_labels, sites_frac=None, sites_cart=None, min_dha_angle=150, # degrees max_da_distance=2.9, # angstrom covariance_matrix=None, cell_covariance_matrix=None, parameter_map=None, eps=2e-16): assert [sites_frac, sites_cart].count(None) == 1 fmt_a = "%.1f" pair_asu_table = pair_asu_table asu_mappings = pair_asu_table.asu_mappings() space_group_info = sgtbx.space_group_info(group=asu_mappings.space_group()) self.unit_cell = asu_mappings.unit_cell() if sites_cart is not None: sites_frac = self.unit_cell.fractionalize(sites_cart) if sites_frac is not None: sites_cart = self.unit_cell.orthogonalize(sites_frac) if covariance_matrix is not None: assert parameter_map is not None self.covariance_matrix_cart = covariance.orthogonalize_covariance_matrix( covariance_matrix, self.unit_cell, parameter_map) else: self.covariance_matrix_cart = None self.cell_covariance_matrix = cell_covariance_matrix self.eps = eps self.parameter_map = parameter_map self.loop = model.loop(header=( "_geom_hbond_atom_site_label_D", "_geom_hbond_atom_site_label_H", "_geom_hbond_atom_site_label_A", "_geom_hbond_distance_DH", "_geom_hbond_distance_HA", "_geom_hbond_distance_DA", "_geom_hbond_angle_DHA", "_geom_hbond_site_symmetry_A", )) for hbond in hbonds: d_seq, a_seq = hbond.d_seq, hbond.a_seq site_cart_d = sites_cart[d_seq] if hbond.rt_mx is not None: site_frac_a = sites_frac[a_seq] site_frac_a = hbond.rt_mx * site_frac_a site_cart_a = self.unit_cell.orthogonalize(site_frac_a) else: site_cart_a = sites_cart[a_seq] distance_da = geometry.distance((site_cart_d, site_cart_a)) for h_seq, h_sym_groups in pair_asu_table.table()[hbond.d_seq].items(): if site_labels[h_seq][0] not in ('H','D'): # XXX better to pass scattering types instead? continue site_cart_h = sites_cart[h_seq] distance_dh = geometry.distance((site_cart_d, site_cart_h)) distance_ha = geometry.distance((site_cart_h, site_cart_a)) angle_dha = geometry.angle((site_cart_d, site_cart_h, site_cart_a)) if (angle_dha.angle_model < min_dha_angle or distance_da.distance_model > max_da_distance): continue if hbond.rt_mx is not None: sym_code = space_group_info.cif_symmetry_code(hbond.rt_mx) else: sym_code = '.' self.loop.add_row(( site_labels[d_seq], site_labels[h_seq], site_labels[a_seq], self.formatted_distance(d_seq, h_seq, distance_dh, unit_mx), self.formatted_distance(h_seq, a_seq, distance_ha, unit_mx), self.formatted_distance(d_seq, a_seq, distance_da, hbond.rt_mx), self.formatted_angle(d_seq, h_seq, a_seq, angle_dha, hbond.rt_mx), sym_code ))
def predict_protonation(ag, verbose=False): from cctbx import geometry from mmtbx.monomer_library.linking_utils import get_distance2 from math import sqrt # from cctbx_geometry_restraints_ext import * # from cctbx.array_family import flex """ his1 = -37.35*X1 + 15.57*X2 - 0.64*X3 + 0.76*X4 + 17.30 his2 = -2.16*X1 - 6.08*X2 + 0.56*X3 + 0.42*X4 - 94.46 X1 = ND1-CE1 X2 = CE1-NE2 X3 = -ND1- X4 = -NE2- his1<0 ~> ND1 protonated his1>0 his2<0 ~> NE2 protonated his2>0 ~> doubly protonated """ bonds = { ("ND1", "CE1") : None, ("NE2", "CE1") : None, } if verbose: for atom in ag.atoms(): print atom.quote() for i, tmp_atom in enumerate(bonds): atoms = [] for j in range(2): for atom in ag.atoms(): if atom.name.strip()==tmp_atom[j]: atoms.append(atom) break if len(atoms)==2: d2=get_distance2(*atoms) bonds[tmp_atom]=sqrt(d2) angles = { ("CG", "ND1", "CE1") : None, ("CE1","NE2", "CD2") : None, } for i, tmp_atom in enumerate(angles): atoms = [] for j in range(3): for atom in ag.atoms(): if atom.name.strip()==tmp_atom[j]: atoms.append(atom.xyz) break if len(atoms)==3: angle=geometry.angle((atoms)).angle_model angles[tmp_atom]=angle if None in bonds.values() or None in angles.values(): return None his1 = 17.30 - 0.64*angles[("CG", "ND1", "CE1")] his1 += 0.76*angles[("CE1","NE2", "CD2")] his1 -= 37.35*bonds[("ND1", "CE1")] his1 += 15.57*bonds[("NE2", "CE1")] his2 = -94.46 + 0.56*angles[("CG", "ND1", "CE1")] his2 += 0.42*angles[("CE1","NE2", "CD2")] his2 -= 2.61*bonds[("ND1", "CE1")] his2 -= 6.08*bonds[("NE2", "CE1")] if verbose: print 'his1',his1 print 'his2',his2 return (his1, his2)
def predict_protonation(ag, verbose=False): from cctbx import geometry from mmtbx.monomer_library.linking_utils import get_distance2 from math import sqrt # from cctbx_geometry_restraints_ext import * # from cctbx.array_family import flex """ his1 = -37.35*X1 + 15.57*X2 - 0.64*X3 + 0.76*X4 + 17.30 his2 = -2.16*X1 - 6.08*X2 + 0.56*X3 + 0.42*X4 - 94.46 X1 = ND1-CE1 X2 = CE1-NE2 X3 = -ND1- X4 = -NE2- his1<0 ~> ND1 protonated his1>0 his2<0 ~> NE2 protonated his2>0 ~> doubly protonated """ bonds = { ("ND1", "CE1"): None, ("NE2", "CE1"): None, } if verbose: for atom in ag.atoms(): print atom.quote() for i, tmp_atom in enumerate(bonds): atoms = [] for j in range(2): for atom in ag.atoms(): if atom.name.strip() == tmp_atom[j]: atoms.append(atom) break if len(atoms) == 2: d2 = get_distance2(*atoms) bonds[tmp_atom] = sqrt(d2) angles = { ("CG", "ND1", "CE1"): None, ("CE1", "NE2", "CD2"): None, } for i, tmp_atom in enumerate(angles): atoms = [] for j in range(3): for atom in ag.atoms(): if atom.name.strip() == tmp_atom[j]: atoms.append(atom.xyz) break if len(atoms) == 3: angle = geometry.angle((atoms)).angle_model angles[tmp_atom] = angle if None in bonds.values() or None in angles.values(): return None his1 = 17.30 - 0.64 * angles[("CG", "ND1", "CE1")] his1 += 0.76 * angles[("CE1", "NE2", "CD2")] his1 -= 37.35 * bonds[("ND1", "CE1")] his1 += 15.57 * bonds[("NE2", "CE1")] his2 = -94.46 + 0.56 * angles[("CG", "ND1", "CE1")] his2 += 0.42 * angles[("CE1", "NE2", "CD2")] his2 -= 2.61 * bonds[("ND1", "CE1")] his2 -= 6.08 * bonds[("NE2", "CE1")] if verbose: print 'his1', his1 print 'his2', his2 return (his1, his2)
def exercise_geometry(): xs = quartz() uc = xs.unit_cell() flags = xs.scatterer_flags() for f in flags: f.set_grad_site(True) xs.set_scatterer_flags(flags) cov = flex.double((1e-8,1e-9,2e-9,3e-9,4e-9,5e-9, 2e-8,1e-9,2e-9,3e-9,4e-9, 3e-8,1e-9,2e-9,3e-9, 2e-8,1e-9,2e-9, 3e-8,1e-9, 4e-8)) cell_vcv = flex.double((3e-2,3e-2,0,0,0,0, 3e-2,0,0,0,0, 4e-2,0,0,0, 0,0,0, 0,0, 0)) param_map = xs.parameter_map() cov_cart = covariance.orthogonalize_covariance_matrix(cov, uc, param_map) O = matrix.sqr(uc.orthogonalization_matrix()) F = matrix.sqr(uc.fractionalization_matrix()) sites_cart = xs.sites_cart() sites_frac = xs.sites_frac() # distances rt_mx_ji = sgtbx.rt_mx('-y,x-y,z-1/3') sites = (sites_cart[0], uc.orthogonalize(rt_mx_ji*sites_frac[1])) d = geometry.distance(sites) assert approx_equal(d.distance_model, 1.6159860469110217) v = matrix.col(sites[1]) - matrix.col(sites[0]) r_inv_cart = (O * matrix.sqr(rt_mx_ji.r().inverse().as_double()) * F) g = d.d_distance_d_sites() g = matrix.row(g[0] + tuple(r_inv_cart*matrix.col(g[1]))) f = g * matrix.sqr(cov_cart.matrix_packed_u_as_symmetric()) * g.transpose() assert approx_equal(d.variance(cov_cart, uc, rt_mx_ji), f[0], eps=1e-15) assert approx_equal( 0.0018054494791580823, d.variance(cov_cart, cell_vcv, uc, rt_mx_ji)) rt_mx_ji = sgtbx.rt_mx('x+1,y,z') sites = (sites_cart[0], uc.orthogonalize(rt_mx_ji*sites_frac[0])) d = geometry.distance(sites) assert approx_equal(d.distance_model, uc.parameters()[0]) assert approx_equal(cell_vcv.matrix_packed_u_diagonal()[0], d.variance(cov_cart, cell_vcv, uc, rt_mx_ji)) # angles rt_mx_ji = sgtbx.rt_mx('x-y,x,z-2/3') rt_mx_ki = sgtbx.rt_mx('-y,x-y,z-1/3') r_inv_cart_ji = (O * matrix.sqr(rt_mx_ji.r().inverse().as_double()) * F) r_inv_cart_ki = (O * matrix.sqr(rt_mx_ki.r().inverse().as_double()) * F) cov_a = covariance.extract_covariance_matrix_for_sites(flex.size_t([1,0,1]), cov_cart, param_map) sites = (uc.orthogonalize(rt_mx_ji*sites_frac[1]), sites_cart[0], uc.orthogonalize(rt_mx_ki*sites_frac[1])) a = geometry.angle(sites) assert approx_equal(a.angle_model, 101.30738566828551) g = a.d_angle_d_sites() g = matrix.row(tuple(r_inv_cart_ji*matrix.col(g[0])) + g[1] + tuple(r_inv_cart_ki*matrix.col(g[2]))) f = g * matrix.sqr(cov_a.matrix_packed_u_as_symmetric()) * g.transpose() assert approx_equal( a.variance(cov_a, uc, (rt_mx_ji, sgtbx.rt_mx(), rt_mx_ki)), f[0], eps=1e-15) assert approx_equal(0.0042632511984529199, a.variance(cov_a, cell_vcv, uc, (rt_mx_ji, sgtbx.rt_mx(), rt_mx_ki)))
def exercise_high_symmetry_case(): """ BF6 sitting on inversion centre in high symmetry space group. The angles formed between F20, B17 and either F18 or F19 are necessarily exactly equal to 90 degrees, and hence their variance should be exactly zero. The angles formed by F18, B17 and F19 are free to refine, and hence should have an associated variance. """ xs = xray.structure( crystal_symmetry=crystal.symmetry( unit_cell=(22.543, 22.543, 35.5167, 90, 90, 90), space_group_symbol='hall: -I 4bd 2'), scatterers=flex.xray_scatterer(( xray.scatterer( #24 label='F18', site=(0.500000, 0.970584, -0.041027), u=(0.000258, 0.000675, 0.000138, -0.000000, -0.000000, -0.000043), fp=0.017939, fdp=0.010330), xray.scatterer( #25 label='F19', site=(0.500000, 0.933678, 0.021766), u=(0.000178, 0.001046, 0.000158, -0.000000, -0.000000, 0.000144), fp=0.017939, fdp=0.010330), xray.scatterer( #26 label='F20', site=(0.438015, 1.000000, 0.000000), u=(0.000231, 0.000500, 0.000106, -0.000000, -0.000000, 0.000078), fp=0.017939, fdp=0.010330), xray.scatterer( #27 label='B17', site=(0.500000, 1.000000, 0.000000), u=(0.000133, 0.000624, 0.000051, -0.000000, -0.000000, 0.000048), fp=0.001413, fdp=0.000674) ))) flags = xs.scatterer_flags() for f in flags: f.set_grad_site(True) xs.set_scatterer_flags(flags) sites_frac = xs.sites_frac() unit_cell = xs.unit_cell() cov = flex.double([ 0,0,0,0,0,0,0,0,0,0,0,0,5.5895145222321514e-07,-1.7223269587621895e-08,0, -2.0367609296594096e-07,-6.6231210988833185e-08,-2.6525243183929821e-09,0,0, 0,0,0,1.1503438451957222e-07,0,-3.5665932804823073e-08, 7.4165082206213702e-09,-6.8444182449209374e-09,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 9.0344019852871238e-07,1.2109549448751337e-07,-7.4794454124745421e-09,0,0, 0,0,0,1.5840179985755122e-07,9.1193835484941833e-09,0,0,0,0,0, 1.447679091961411e-07,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) cell_cov = flex.double([ 2.4999999999999999e-07,2.4999999999999999e-07,0,0,0,0, 2.4999999999999999e-07,0,0,0,0,1.4399999999999998e-06,0,0,0,0,0,0,0,0,0]) param_map = xs.parameter_map() cov_cart = covariance.orthogonalize_covariance_matrix( cov, unit_cell, param_map) i_seqs = flex.size_t((2,3,1)) cov_i_seqs = covariance.extract_covariance_matrix_for_sites( i_seqs, cov_cart, param_map) for sym_ops in ( (sgtbx.rt_mx(),sgtbx.rt_mx(),sgtbx.rt_mx()), (sgtbx.rt_mx("1-x,2-y,-z"), sgtbx.rt_mx(), sgtbx.rt_mx()), (sgtbx.rt_mx(), sgtbx.rt_mx(), sgtbx.rt_mx("1-x,2-y,-z")), (sgtbx.rt_mx("1-x,2-y,-z"), sgtbx.rt_mx(), sgtbx.rt_mx("1-x,2-y,-z"))): site_frac_ji = sym_ops[0] * sites_frac[i_seqs[0]] site_frac_i = sym_ops[1] * sites_frac[i_seqs[1]] site_frac_ki = sym_ops[2] * sites_frac[i_seqs[2]] a = geometry.angle((unit_cell.orthogonalize(site_frac_ji), unit_cell.orthogonalize(site_frac_i), unit_cell.orthogonalize(site_frac_ki))) var = a.variance(cov_i_seqs, cell_cov, unit_cell, sym_ops) assert approx_equal(var, 0, eps=2e-16) pair_asu_table = xs.pair_asu_table(distance_cutoff=2) import libtbx.load_env if libtbx.env.has_module('iotbx'): import iotbx.cif s = StringIO() print >> s, iotbx.cif.distances_as_cif_loop( pair_asu_table, xs.scatterers().extract_labels(), sites_frac=xs.sites_frac(), covariance_matrix=cov, cell_covariance_matrix=cell_cov, parameter_map=param_map).loop assert not show_diff(s.getvalue(), """\ loop_ _geom_bond_atom_site_label_1 _geom_bond_atom_site_label_2 _geom_bond_distance _geom_bond_site_symmetry_2 F18 B17 1.601(13) 4_575 F19 B17 1.683(18) . F20 B17 1.397(9) . """) s = StringIO() print >> s, iotbx.cif.angles_as_cif_loop( pair_asu_table, xs.scatterers().extract_labels(), sites_frac=xs.sites_frac(), covariance_matrix=cov, cell_covariance_matrix=cell_cov, parameter_map=param_map).loop assert not show_diff(s.getvalue(), """\ loop_ _geom_angle_atom_site_label_1 _geom_angle_atom_site_label_2 _geom_angle_atom_site_label_3 _geom_angle _geom_angle_site_symmetry_1 _geom_angle_site_symmetry_3 F18 B17 F18 180.0 . 4_575 F19 B17 F18 87.1(7) . 4_575 F19 B17 F18 92.9(7) . . F19 B17 F18 92.9(7) 4_575 4_575 F19 B17 F18 87.1(7) 4_575 . F19 B17 F19 180.0 4_575 . F20 B17 F18 90.0 . 4_575 F20 B17 F18 90.0 . . F20 B17 F19 90.0 . . F20 B17 F19 90.0 . 4_575 F20 B17 F18 90.0 9_675 4_575 F20 B17 F18 90.0 9_675 . F20 B17 F19 90.0 9_675 . F20 B17 F19 90.0 9_675 4_575 F20 B17 F20 180.0 9_675 . """)