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 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 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 __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 ))