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_covariance(): xs = xray.structure( crystal_symmetry=crystal.symmetry( (5.01,5.01,5.47,90,90,120), "P6222"), scatterers=flex.xray_scatterer([ xray.scatterer("Si", (1/2.,1/2.,1/3.)), xray.scatterer("O", (0.197,-0.197,0.83333))])) 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)) param_map = xs.parameter_map() assert approx_equal(cov, covariance.extract_covariance_matrix_for_sites(flex.size_t([0,1]), cov, param_map)) cov_cart = covariance.orthogonalize_covariance_matrix(cov, uc, param_map) O = matrix.sqr(uc.orthogonalization_matrix()) for i in range(param_map.n_scatterers): cov_i = covariance.extract_covariance_matrix_for_sites(flex.size_t([i]), cov, param_map) cov_i_cart = covariance.extract_covariance_matrix_for_sites(flex.size_t([i]), cov_cart, param_map) assert approx_equal( O * matrix.sym(sym_mat3=cov_i) * O.transpose(), matrix.sym(sym_mat3=cov_i_cart).as_mat3()) for f in flags: f.set_grads(False) flags[0].set_grad_u_aniso(True) flags[0].set_use_u_aniso(True) flags[1].set_grad_u_iso(True) flags[1].set_use_u_iso(True) xs.set_scatterer_flags(flags) param_map = xs.parameter_map() cov = flex.double(7*7, 0) cov.reshape(flex.grid(7,7)) cov.matrix_diagonal_set_in_place(flex.double([i for i in range(7)])) cov = cov.matrix_symmetric_as_packed_u() assert approx_equal([i for i in range(6)], covariance.extract_covariance_matrix_for_u_aniso( 0, cov, param_map).matrix_packed_u_diagonal()) assert covariance.variance_for_u_iso(1, cov, param_map) == 6 try: covariance.variance_for_u_iso(0, cov, param_map) except RuntimeError: pass else: raise Exception_expected try: covariance.extract_covariance_matrix_for_u_aniso(1, cov, param_map) except RuntimeError: pass else: raise Exception_expected approx_equal(covariance.extract_covariance_matrix_for_sites( flex.size_t([1]), cov, param_map), (0,0,0,0,0,0))
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 exercise_floating_origin_dynamic_weighting(verbose=False): from cctbx import covariance import scitbx.math worst_condition_number_acceptable = 10 # light elements only xs0 = random_structure.xray_structure(elements=['C', 'C', 'C', 'O', 'N'], use_u_aniso=True) msg = "light elements in %s ..." % ( xs0.space_group_info().type().hall_symbol()) if verbose: print(msg, end=' ') fo_sq = xs0.structure_factors(d_min=0.8).f_calc().norm() fo_sq = fo_sq.customized_copy(sigmas=flex.double(fo_sq.size(), 1.)) xs = xs0.deep_copy_scatterers() xs.shake_adp() xs.shake_sites_in_place(rms_difference=0.1) for sc in xs.scatterers(): sc.flags.set_grad_site(True).set_grad_u_aniso(True) ls = least_squares.crystallographic_ls( fo_sq.as_xray_observations(), constraints.reparametrisation( structure=xs, constraints=[], connectivity_table=smtbx.utils.connectivity_table(xs)), weighting_scheme=least_squares.unit_weighting(), origin_fixing_restraints_type= origin_fixing_restraints.atomic_number_weighting) ls.build_up() lambdas = eigensystem.real_symmetric( ls.normal_matrix_packed_u().matrix_packed_u_as_symmetric()).values() # assert the restrained L.S. problem is not too ill-conditionned cond = math.log10(lambdas[0]/lambdas[-1]) if verbose: print("normal matrix condition: %.1f" % cond) assert cond < worst_condition_number_acceptable, msg # one heavy element xs0 = random_structure.xray_structure( space_group_info=sgtbx.space_group_info('hall: P 2yb'), elements=['Zn', 'C', 'C', 'C', 'O', 'N'], use_u_aniso=True) msg = "one heavy element + light elements (synthetic data) in %s ..." % ( xs0.space_group_info().type().hall_symbol()) if verbose: print(msg, end=' ') fo_sq = xs0.structure_factors(d_min=0.8).f_calc().norm() fo_sq = fo_sq.customized_copy(sigmas=flex.double(fo_sq.size(), 1.)) xs = xs0.deep_copy_scatterers() xs.shake_adp() xs.shake_sites_in_place(rms_difference=0.1) for sc in xs.scatterers(): sc.flags.set_grad_site(True).set_grad_u_aniso(True) ls = least_squares.crystallographic_ls( fo_sq.as_xray_observations(), constraints.reparametrisation( structure=xs, constraints=[], connectivity_table=smtbx.utils.connectivity_table(xs)), weighting_scheme=least_squares.mainstream_shelx_weighting(), origin_fixing_restraints_type= origin_fixing_restraints.atomic_number_weighting) ls.build_up() lambdas = eigensystem.real_symmetric( ls.normal_matrix_packed_u().matrix_packed_u_as_symmetric()).values() # assert the restrained L.S. problem is not too ill-conditionned cond = math.log10(lambdas[0]/lambdas[-1]) if verbose: print("normal matrix condition: %.1f" % cond) assert cond < worst_condition_number_acceptable, msg # are esd's for x,y,z coordinates of the same order of magnitude? var_cart = covariance.orthogonalize_covariance_matrix( ls.covariance_matrix(), xs.unit_cell(), xs.parameter_map()) var_site_cart = covariance.extract_covariance_matrix_for_sites( flex.size_t_range(len(xs.scatterers())), var_cart, xs.parameter_map()) site_esds = var_site_cart.matrix_packed_u_diagonal() indicators = flex.double() for i in xrange(0, len(site_esds), 3): stats = scitbx.math.basic_statistics(site_esds[i:i+3]) indicators.append(stats.bias_corrected_standard_deviation/stats.mean) assert indicators.all_lt(2) # especially troublesome structure with one heavy element # (contributed by Jonathan Coome) xs0 = xray.structure( crystal_symmetry=crystal.symmetry( unit_cell=(8.4519, 8.4632, 18.7887, 90, 96.921, 90), space_group_symbol="hall: P 2yb"), scatterers=flex.xray_scatterer([ xray.scatterer( #0 label="ZN1", site=(-0.736683, -0.313978, -0.246902), u=(0.000302, 0.000323, 0.000054, 0.000011, 0.000015, -0.000004)), xray.scatterer( #1 label="N3B", site=(-0.721014, -0.313583, -0.134277), u=(0.000268, 0.000237, 0.000055, -0.000027, 0.000005, 0.000006)), xray.scatterer( #2 label="N3A", site=(-0.733619, -0.290423, -0.357921), u=(0.000229, 0.000313, 0.000053, 0.000022, 0.000018, -0.000018)), xray.scatterer( #3 label="C9B", site=(-1.101537, -0.120157, -0.138063), u=(0.000315, 0.000345, 0.000103, 0.000050, 0.000055, -0.000017)), xray.scatterer( #4 label="N5B", site=(-0.962032, -0.220345, -0.222045), u=(0.000274, 0.000392, 0.000060, -0.000011, -0.000001, -0.000002)), xray.scatterer( #5 label="N1B", site=(-0.498153, -0.402742, -0.208698), u=(0.000252, 0.000306, 0.000063, 0.000000, 0.000007, 0.000018)), xray.scatterer( #6 label="C3B", site=(-0.322492, -0.472610, -0.114594), u=(0.000302, 0.000331, 0.000085, 0.000016, -0.000013, 0.000037)), xray.scatterer( #7 label="C4B", site=(-0.591851, -0.368163, -0.094677), u=(0.000262, 0.000255, 0.000073, -0.000034, 0.000027, -0.000004)), xray.scatterer( #8 label="N4B", site=(-0.969383, -0.204624, -0.150014), u=(0.000279, 0.000259, 0.000070, -0.000009, 0.000039, 0.000000)), xray.scatterer( #9 label="N2B", site=(-0.470538, -0.414572, -0.135526), u=(0.000277, 0.000282, 0.000065, 0.000003, 0.000021, -0.000006)), xray.scatterer( #10 label="C8A", site=(-0.679889, -0.158646, -0.385629), u=(0.000209, 0.000290, 0.000078, 0.000060, 0.000006, 0.000016)), xray.scatterer( #11 label="N5A", site=(-0.649210, -0.075518, -0.263412), u=(0.000307, 0.000335, 0.000057, -0.000002, 0.000016, -0.000012)), xray.scatterer( #12 label="C6B", site=(-0.708620, -0.325965, 0.011657), u=(0.000503, 0.000318, 0.000053, -0.000058, 0.000032, -0.000019)), xray.scatterer( #13 label="C10B", site=(-1.179332, -0.083184, -0.202815), u=(0.000280, 0.000424, 0.000136, 0.000094, 0.000006, 0.000013)), xray.scatterer( #14 label="N1A", site=(-0.838363, -0.532191, -0.293213), u=(0.000312, 0.000323, 0.000060, 0.000018, 0.000011, -0.000008)), xray.scatterer( #15 label="C3A", site=(-0.915414, -0.671031, -0.393826), u=(0.000319, 0.000384, 0.000078, -0.000052, -0.000001, -0.000020)), xray.scatterer( #16 label="C1A", site=(-0.907466, -0.665419, -0.276011), u=(0.000371, 0.000315, 0.000079, 0.000006, 0.000036, 0.000033)), xray.scatterer( #17 label="C1B", site=(-0.365085, -0.452753, -0.231927), u=(0.000321, 0.000253, 0.000087, -0.000024, 0.000047, -0.000034)), xray.scatterer( #18 label="C11A", site=(-0.598622, 0.053343, -0.227354), u=(0.000265, 0.000409, 0.000084, 0.000088, -0.000018, -0.000030)), xray.scatterer( #19 label="C2A", site=(-0.958694, -0.755645, -0.337016), u=(0.000394, 0.000350, 0.000106, -0.000057, 0.000027, -0.000005)), xray.scatterer( #20 label="C4A", site=(-0.784860, -0.407601, -0.402050), u=(0.000238, 0.000296, 0.000064, 0.000002, 0.000011, -0.000016)), xray.scatterer( #21 label="C5A", site=(-0.784185, -0.399716, -0.475491), u=(0.000310, 0.000364, 0.000062, 0.000044, -0.000011, -0.000017)), xray.scatterer( #22 label="N4A", site=(-0.630284, -0.043981, -0.333143), u=(0.000290, 0.000275, 0.000074, 0.000021, 0.000027, 0.000013)), xray.scatterer( #23 label="C10A", site=(-0.545465, 0.166922, -0.272829), u=(0.000369, 0.000253, 0.000117, 0.000015, -0.000002, -0.000008)), xray.scatterer( #24 label="C9A", site=(-0.567548, 0.102272, -0.339923), u=(0.000346, 0.000335, 0.000103, -0.000016, 0.000037, 0.000023)), xray.scatterer( #25 label="C11B", site=(-1.089943, -0.146930, -0.253779), u=(0.000262, 0.000422, 0.000102, -0.000018, -0.000002, 0.000029)), xray.scatterer( #26 label="N2A", site=(-0.843385, -0.537780, -0.366515), u=(0.000273, 0.000309, 0.000055, -0.000012, -0.000005, -0.000018)), xray.scatterer( #27 label="C7A", site=(-0.674021, -0.136086, -0.457790), u=(0.000362, 0.000378, 0.000074, 0.000043, 0.000034, 0.000016)), xray.scatterer( #28 label="C8B", site=(-0.843625, -0.264182, -0.102023), u=(0.000264, 0.000275, 0.000072, -0.000025, 0.000019, -0.000005)), xray.scatterer( #29 label="C6A", site=(-0.726731, -0.261702, -0.502366), u=(0.000339, 0.000472, 0.000064, 0.000062, -0.000003, 0.000028)), xray.scatterer( #30 label="C5B", site=(-0.577197, -0.376753, -0.020800), u=(0.000349, 0.000353, 0.000066, -0.000082, -0.000022, 0.000014)), xray.scatterer( #31 label="C2B", site=(-0.252088, -0.497338, -0.175057), u=(0.000251, 0.000342, 0.000119, 0.000020, 0.000034, -0.000018)), xray.scatterer( #32 label="C7B", site=(-0.843956, -0.268811, -0.028080), u=(0.000344, 0.000377, 0.000078, -0.000029, 0.000059, -0.000007)), xray.scatterer( #33 label="F4B", site=(-0.680814, -0.696808, -0.115056), u=(0.000670, 0.000408, 0.000109, -0.000099, 0.000139, -0.000031)), xray.scatterer( #34 label="F1B", site=(-0.780326, -0.921249, -0.073962), u=(0.000687, 0.000357, 0.000128, -0.000152, -0.000011, 0.000021)), xray.scatterer( #35 label="B1B", site=(-0.795220, -0.758128, -0.075955), u=(0.000413, 0.000418, 0.000075, 0.000054, 0.000045, 0.000023)), xray.scatterer( #36 label="F2B", site=(-0.945140, -0.714626, -0.105820), u=(0.000584, 0.001371, 0.000108, 0.000420, 0.000067, 0.000134)), xray.scatterer( #37 label="F3B", site=(-0.768914, -0.701660, -0.005161), u=(0.000678, 0.000544, 0.000079, -0.000000, 0.000090, -0.000021)), xray.scatterer( #38 label="F1A", site=(-0.109283, -0.252334, -0.429288), u=(0.000427, 0.001704, 0.000125, 0.000407, 0.000041, 0.000035)), xray.scatterer( #39 label="F4A", site=(-0.341552, -0.262864, -0.502023), u=(0.000640, 0.000557, 0.000081, -0.000074, 0.000042, -0.000052)), xray.scatterer( #40 label="F3A", site=(-0.324533, -0.142292, -0.393215), u=(0.000471, 0.001203, 0.000134, 0.000333, -0.000057, -0.000220)), xray.scatterer( #41 label="F2A", site=(-0.312838, -0.405405, -0.400231), u=(0.002822, 0.000831, 0.000092, -0.000648, 0.000115, 0.000027)), xray.scatterer( #42 label="B1A", site=(-0.271589, -0.268874, -0.430724), u=(0.000643, 0.000443, 0.000079, 0.000040, 0.000052, -0.000034)), xray.scatterer( #43 label="H5B", site=(-0.475808, -0.413802, 0.004402), u=0.005270), xray.scatterer( #44 label="H6B", site=(-0.699519, -0.326233, 0.062781), u=0.019940), xray.scatterer( #45 label="H3B", site=(-0.283410, -0.484757, -0.063922), u=0.029990), xray.scatterer( #46 label="H1B", site=(-0.357103, -0.451819, -0.284911), u=0.031070), xray.scatterer( #47 label="H10A", site=(-0.495517, 0.268296, -0.256187), u=0.027610), xray.scatterer( #48 label="H2B", site=(-0.147129, -0.535141, -0.174699), u=0.017930), xray.scatterer( #49 label="H7A", site=(-0.643658, -0.031387, -0.475357), u=0.020200), xray.scatterer( #50 label="H1A", site=(-0.912757, -0.691043, -0.227554), u=0.033320), xray.scatterer( #51 label="H7B", site=(-0.933670, -0.241189, -0.010263), u=0.021310), xray.scatterer( #52 label="H11B", site=(-1.107736, -0.155470, -0.311996), u=0.041500), xray.scatterer( #53 label="H9A", site=(-0.539908, 0.139753, -0.382281), u=0.007130), xray.scatterer( #54 label="H10B", site=(-1.265944, -0.029610, -0.212398), u=0.030910), xray.scatterer( #55 label="H3A", site=(-0.934728, -0.691149, -0.450551), u=0.038950), xray.scatterer( #56 label="H5A", site=(-0.833654, -0.487479, -0.508239), u=0.031150), xray.scatterer( #57 label="H6A", site=(-0.742871, -0.242269, -0.558157), u=0.050490), xray.scatterer( #58 label="H9B", site=(-1.120150, -0.093752, -0.090706), u=0.039310), xray.scatterer( #59 label="H11A", site=(-0.593074, 0.054973, -0.180370), u=0.055810), xray.scatterer( #60 label="H2A", site=(-0.999576, -0.842158, -0.340837), u=0.057030) ])) fo_sq = xs0.structure_factors(d_min=0.8).f_calc().norm() fo_sq = fo_sq.customized_copy(sigmas=flex.double(fo_sq.size(), 1.)) for hydrogen_flag in (True, False): xs = xs0.deep_copy_scatterers() if not hydrogen_flag: xs.select_inplace(~xs.element_selection('H')) xs.shake_adp() xs.shake_sites_in_place(rms_difference=0.1) for sc in xs.scatterers(): sc.flags.set_grad_site(True).set_grad_u_aniso(False) ls = least_squares.crystallographic_ls( fo_sq.as_xray_observations(), constraints.reparametrisation( structure=xs, constraints=[], connectivity_table=smtbx.utils.connectivity_table(xs)), weighting_scheme=least_squares.unit_weighting(), origin_fixing_restraints_type= origin_fixing_restraints.atomic_number_weighting) ls.build_up() lambdas = eigensystem.real_symmetric( ls.normal_matrix_packed_u().matrix_packed_u_as_symmetric()).values() # assert the restrained L.S. problem is not too ill-conditionned cond = math.log10(lambdas[0]/lambdas[-1]) msg = ("one heavy element + light elements (real data) %s Hydrogens: %.1f" % (['without', 'with'][hydrogen_flag], cond)) if verbose: print(msg) assert cond < worst_condition_number_acceptable, msg # are esd's for x,y,z coordinates of the same order of magnitude? var_cart = covariance.orthogonalize_covariance_matrix( ls.covariance_matrix(), xs.unit_cell(), xs.parameter_map()) var_site_cart = covariance.extract_covariance_matrix_for_sites( flex.size_t_range(len(xs.scatterers())), var_cart, xs.parameter_map()) site_esds = var_site_cart.matrix_packed_u_diagonal() indicators = flex.double() for i in xrange(0, len(site_esds), 3): stats = scitbx.math.basic_statistics(site_esds[i:i+3]) indicators.append(stats.bias_corrected_standard_deviation/stats.mean) assert indicators.all_lt(1)
def exercise_covariance(): xs = xray.structure(crystal_symmetry=crystal.symmetry( (5.01, 5.01, 5.47, 90, 90, 120), "P6222"), scatterers=flex.xray_scatterer([ xray.scatterer("Si", (1 / 2., 1 / 2., 1 / 3.)), xray.scatterer("O", (0.197, -0.197, 0.83333)) ])) 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)) param_map = xs.parameter_map() assert approx_equal( cov, covariance.extract_covariance_matrix_for_sites(flex.size_t([0, 1]), cov, param_map)) cov_cart = covariance.orthogonalize_covariance_matrix(cov, uc, param_map) O = matrix.sqr(uc.orthogonalization_matrix()) for i in range(param_map.n_scatterers): cov_i = covariance.extract_covariance_matrix_for_sites( flex.size_t([i]), cov, param_map) cov_i_cart = covariance.extract_covariance_matrix_for_sites( flex.size_t([i]), cov_cart, param_map) assert approx_equal(O * matrix.sym(sym_mat3=cov_i) * O.transpose(), matrix.sym(sym_mat3=cov_i_cart).as_mat3()) for f in flags: f.set_grads(False) flags[0].set_grad_u_aniso(True) flags[0].set_use_u_aniso(True) flags[1].set_grad_u_iso(True) flags[1].set_use_u_iso(True) xs.set_scatterer_flags(flags) param_map = xs.parameter_map() cov = flex.double(7 * 7, 0) cov.reshape(flex.grid(7, 7)) cov.matrix_diagonal_set_in_place(flex.double([i for i in range(7)])) cov = cov.matrix_symmetric_as_packed_u() assert approx_equal([i for i in range(6)], covariance.extract_covariance_matrix_for_u_aniso( 0, cov, param_map).matrix_packed_u_diagonal()) assert covariance.variance_for_u_iso(1, cov, param_map) == 6 try: covariance.variance_for_u_iso(0, cov, param_map) except RuntimeError: pass else: raise Exception_expected try: covariance.extract_covariance_matrix_for_u_aniso(1, cov, param_map) except RuntimeError: pass else: raise Exception_expected approx_equal( covariance.extract_covariance_matrix_for_sites(flex.size_t([1]), cov, param_map), (0, 0, 0, 0, 0, 0))
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 . """)
def exercise_floating_origin_dynamic_weighting(verbose=False): from cctbx import covariance import scitbx.math worst_condition_number_acceptable = 10 # light elements only xs0 = random_structure.xray_structure(elements=['C', 'C', 'C', 'O', 'N'], use_u_aniso=True) fo_sq = xs0.structure_factors(d_min=0.8).f_calc().norm() fo_sq = fo_sq.customized_copy(sigmas=flex.double(fo_sq.size(), 1.)) xs = xs0.deep_copy_scatterers() xs.shake_adp() xs.shake_sites_in_place(rms_difference=0.1) for sc in xs.scatterers(): sc.flags.set_grad_site(True).set_grad_u_aniso(True) ls = least_squares.crystallographic_ls( fo_sq.as_xray_observations(), constraints.reparametrisation( structure=xs, constraints=[], connectivity_table=smtbx.utils.connectivity_table(xs)), weighting_scheme=least_squares.unit_weighting(), origin_fixing_restraints_type= origin_fixing_restraints.atomic_number_weighting) ls.build_up() lambdas = eigensystem.real_symmetric( ls.normal_matrix_packed_u().matrix_packed_u_as_symmetric()).values() # assert the restrained L.S. problem is not too ill-conditionned cond = math.log10(lambdas[0]/lambdas[-1]) msg = "light elements: %.1f" % cond if verbose: print msg assert cond < worst_condition_number_acceptable, msg # one heavy element xs0 = random_structure.xray_structure( space_group_info=sgtbx.space_group_info('hall: P 2yb'), elements=['Zn', 'C', 'C', 'C', 'O', 'N'], use_u_aniso=True) fo_sq = xs0.structure_factors(d_min=0.8).f_calc().norm() fo_sq = fo_sq.customized_copy(sigmas=flex.double(fo_sq.size(), 1.)) xs = xs0.deep_copy_scatterers() xs.shake_adp() xs.shake_sites_in_place(rms_difference=0.1) for sc in xs.scatterers(): sc.flags.set_grad_site(True).set_grad_u_aniso(True) ls = least_squares.crystallographic_ls( fo_sq.as_xray_observations(), constraints.reparametrisation( structure=xs, constraints=[], connectivity_table=smtbx.utils.connectivity_table(xs)), weighting_scheme=least_squares.mainstream_shelx_weighting(), origin_fixing_restraints_type= origin_fixing_restraints.atomic_number_weighting) ls.build_up() lambdas = eigensystem.real_symmetric( ls.normal_matrix_packed_u().matrix_packed_u_as_symmetric()).values() # assert the restrained L.S. problem is not too ill-conditionned cond = math.log10(lambdas[0]/lambdas[-1]) msg = "one heavy element + light elements (synthetic data): %.1f" % cond if verbose: print msg assert cond < worst_condition_number_acceptable, msg # are esd's for x,y,z coordinates of the same order of magnitude? var_cart = covariance.orthogonalize_covariance_matrix( ls.covariance_matrix(), xs.unit_cell(), xs.parameter_map()) var_site_cart = covariance.extract_covariance_matrix_for_sites( flex.size_t_range(len(xs.scatterers())), var_cart, xs.parameter_map()) site_esds = var_site_cart.matrix_packed_u_diagonal() indicators = flex.double() for i in xrange(0, len(site_esds), 3): stats = scitbx.math.basic_statistics(site_esds[i:i+3]) indicators.append(stats.bias_corrected_standard_deviation/stats.mean) assert indicators.all_lt(1) # especially troublesome structure with one heavy element # (contributed by Jonathan Coome) xs0 = xray.structure( crystal_symmetry=crystal.symmetry( unit_cell=(8.4519, 8.4632, 18.7887, 90, 96.921, 90), space_group_symbol="hall: P 2yb"), scatterers=flex.xray_scatterer([ xray.scatterer( #0 label="ZN1", site=(-0.736683, -0.313978, -0.246902), u=(0.000302, 0.000323, 0.000054, 0.000011, 0.000015, -0.000004)), xray.scatterer( #1 label="N3B", site=(-0.721014, -0.313583, -0.134277), u=(0.000268, 0.000237, 0.000055, -0.000027, 0.000005, 0.000006)), xray.scatterer( #2 label="N3A", site=(-0.733619, -0.290423, -0.357921), u=(0.000229, 0.000313, 0.000053, 0.000022, 0.000018, -0.000018)), xray.scatterer( #3 label="C9B", site=(-1.101537, -0.120157, -0.138063), u=(0.000315, 0.000345, 0.000103, 0.000050, 0.000055, -0.000017)), xray.scatterer( #4 label="N5B", site=(-0.962032, -0.220345, -0.222045), u=(0.000274, 0.000392, 0.000060, -0.000011, -0.000001, -0.000002)), xray.scatterer( #5 label="N1B", site=(-0.498153, -0.402742, -0.208698), u=(0.000252, 0.000306, 0.000063, 0.000000, 0.000007, 0.000018)), xray.scatterer( #6 label="C3B", site=(-0.322492, -0.472610, -0.114594), u=(0.000302, 0.000331, 0.000085, 0.000016, -0.000013, 0.000037)), xray.scatterer( #7 label="C4B", site=(-0.591851, -0.368163, -0.094677), u=(0.000262, 0.000255, 0.000073, -0.000034, 0.000027, -0.000004)), xray.scatterer( #8 label="N4B", site=(-0.969383, -0.204624, -0.150014), u=(0.000279, 0.000259, 0.000070, -0.000009, 0.000039, 0.000000)), xray.scatterer( #9 label="N2B", site=(-0.470538, -0.414572, -0.135526), u=(0.000277, 0.000282, 0.000065, 0.000003, 0.000021, -0.000006)), xray.scatterer( #10 label="C8A", site=(-0.679889, -0.158646, -0.385629), u=(0.000209, 0.000290, 0.000078, 0.000060, 0.000006, 0.000016)), xray.scatterer( #11 label="N5A", site=(-0.649210, -0.075518, -0.263412), u=(0.000307, 0.000335, 0.000057, -0.000002, 0.000016, -0.000012)), xray.scatterer( #12 label="C6B", site=(-0.708620, -0.325965, 0.011657), u=(0.000503, 0.000318, 0.000053, -0.000058, 0.000032, -0.000019)), xray.scatterer( #13 label="C10B", site=(-1.179332, -0.083184, -0.202815), u=(0.000280, 0.000424, 0.000136, 0.000094, 0.000006, 0.000013)), xray.scatterer( #14 label="N1A", site=(-0.838363, -0.532191, -0.293213), u=(0.000312, 0.000323, 0.000060, 0.000018, 0.000011, -0.000008)), xray.scatterer( #15 label="C3A", site=(-0.915414, -0.671031, -0.393826), u=(0.000319, 0.000384, 0.000078, -0.000052, -0.000001, -0.000020)), xray.scatterer( #16 label="C1A", site=(-0.907466, -0.665419, -0.276011), u=(0.000371, 0.000315, 0.000079, 0.000006, 0.000036, 0.000033)), xray.scatterer( #17 label="C1B", site=(-0.365085, -0.452753, -0.231927), u=(0.000321, 0.000253, 0.000087, -0.000024, 0.000047, -0.000034)), xray.scatterer( #18 label="C11A", site=(-0.598622, 0.053343, -0.227354), u=(0.000265, 0.000409, 0.000084, 0.000088, -0.000018, -0.000030)), xray.scatterer( #19 label="C2A", site=(-0.958694, -0.755645, -0.337016), u=(0.000394, 0.000350, 0.000106, -0.000057, 0.000027, -0.000005)), xray.scatterer( #20 label="C4A", site=(-0.784860, -0.407601, -0.402050), u=(0.000238, 0.000296, 0.000064, 0.000002, 0.000011, -0.000016)), xray.scatterer( #21 label="C5A", site=(-0.784185, -0.399716, -0.475491), u=(0.000310, 0.000364, 0.000062, 0.000044, -0.000011, -0.000017)), xray.scatterer( #22 label="N4A", site=(-0.630284, -0.043981, -0.333143), u=(0.000290, 0.000275, 0.000074, 0.000021, 0.000027, 0.000013)), xray.scatterer( #23 label="C10A", site=(-0.545465, 0.166922, -0.272829), u=(0.000369, 0.000253, 0.000117, 0.000015, -0.000002, -0.000008)), xray.scatterer( #24 label="C9A", site=(-0.567548, 0.102272, -0.339923), u=(0.000346, 0.000335, 0.000103, -0.000016, 0.000037, 0.000023)), xray.scatterer( #25 label="C11B", site=(-1.089943, -0.146930, -0.253779), u=(0.000262, 0.000422, 0.000102, -0.000018, -0.000002, 0.000029)), xray.scatterer( #26 label="N2A", site=(-0.843385, -0.537780, -0.366515), u=(0.000273, 0.000309, 0.000055, -0.000012, -0.000005, -0.000018)), xray.scatterer( #27 label="C7A", site=(-0.674021, -0.136086, -0.457790), u=(0.000362, 0.000378, 0.000074, 0.000043, 0.000034, 0.000016)), xray.scatterer( #28 label="C8B", site=(-0.843625, -0.264182, -0.102023), u=(0.000264, 0.000275, 0.000072, -0.000025, 0.000019, -0.000005)), xray.scatterer( #29 label="C6A", site=(-0.726731, -0.261702, -0.502366), u=(0.000339, 0.000472, 0.000064, 0.000062, -0.000003, 0.000028)), xray.scatterer( #30 label="C5B", site=(-0.577197, -0.376753, -0.020800), u=(0.000349, 0.000353, 0.000066, -0.000082, -0.000022, 0.000014)), xray.scatterer( #31 label="C2B", site=(-0.252088, -0.497338, -0.175057), u=(0.000251, 0.000342, 0.000119, 0.000020, 0.000034, -0.000018)), xray.scatterer( #32 label="C7B", site=(-0.843956, -0.268811, -0.028080), u=(0.000344, 0.000377, 0.000078, -0.000029, 0.000059, -0.000007)), xray.scatterer( #33 label="F4B", site=(-0.680814, -0.696808, -0.115056), u=(0.000670, 0.000408, 0.000109, -0.000099, 0.000139, -0.000031)), xray.scatterer( #34 label="F1B", site=(-0.780326, -0.921249, -0.073962), u=(0.000687, 0.000357, 0.000128, -0.000152, -0.000011, 0.000021)), xray.scatterer( #35 label="B1B", site=(-0.795220, -0.758128, -0.075955), u=(0.000413, 0.000418, 0.000075, 0.000054, 0.000045, 0.000023)), xray.scatterer( #36 label="F2B", site=(-0.945140, -0.714626, -0.105820), u=(0.000584, 0.001371, 0.000108, 0.000420, 0.000067, 0.000134)), xray.scatterer( #37 label="F3B", site=(-0.768914, -0.701660, -0.005161), u=(0.000678, 0.000544, 0.000079, -0.000000, 0.000090, -0.000021)), xray.scatterer( #38 label="F1A", site=(-0.109283, -0.252334, -0.429288), u=(0.000427, 0.001704, 0.000125, 0.000407, 0.000041, 0.000035)), xray.scatterer( #39 label="F4A", site=(-0.341552, -0.262864, -0.502023), u=(0.000640, 0.000557, 0.000081, -0.000074, 0.000042, -0.000052)), xray.scatterer( #40 label="F3A", site=(-0.324533, -0.142292, -0.393215), u=(0.000471, 0.001203, 0.000134, 0.000333, -0.000057, -0.000220)), xray.scatterer( #41 label="F2A", site=(-0.312838, -0.405405, -0.400231), u=(0.002822, 0.000831, 0.000092, -0.000648, 0.000115, 0.000027)), xray.scatterer( #42 label="B1A", site=(-0.271589, -0.268874, -0.430724), u=(0.000643, 0.000443, 0.000079, 0.000040, 0.000052, -0.000034)), xray.scatterer( #43 label="H5B", site=(-0.475808, -0.413802, 0.004402), u=0.005270), xray.scatterer( #44 label="H6B", site=(-0.699519, -0.326233, 0.062781), u=0.019940), xray.scatterer( #45 label="H3B", site=(-0.283410, -0.484757, -0.063922), u=0.029990), xray.scatterer( #46 label="H1B", site=(-0.357103, -0.451819, -0.284911), u=0.031070), xray.scatterer( #47 label="H10A", site=(-0.495517, 0.268296, -0.256187), u=0.027610), xray.scatterer( #48 label="H2B", site=(-0.147129, -0.535141, -0.174699), u=0.017930), xray.scatterer( #49 label="H7A", site=(-0.643658, -0.031387, -0.475357), u=0.020200), xray.scatterer( #50 label="H1A", site=(-0.912757, -0.691043, -0.227554), u=0.033320), xray.scatterer( #51 label="H7B", site=(-0.933670, -0.241189, -0.010263), u=0.021310), xray.scatterer( #52 label="H11B", site=(-1.107736, -0.155470, -0.311996), u=0.041500), xray.scatterer( #53 label="H9A", site=(-0.539908, 0.139753, -0.382281), u=0.007130), xray.scatterer( #54 label="H10B", site=(-1.265944, -0.029610, -0.212398), u=0.030910), xray.scatterer( #55 label="H3A", site=(-0.934728, -0.691149, -0.450551), u=0.038950), xray.scatterer( #56 label="H5A", site=(-0.833654, -0.487479, -0.508239), u=0.031150), xray.scatterer( #57 label="H6A", site=(-0.742871, -0.242269, -0.558157), u=0.050490), xray.scatterer( #58 label="H9B", site=(-1.120150, -0.093752, -0.090706), u=0.039310), xray.scatterer( #59 label="H11A", site=(-0.593074, 0.054973, -0.180370), u=0.055810), xray.scatterer( #60 label="H2A", site=(-0.999576, -0.842158, -0.340837), u=0.057030) ])) fo_sq = xs0.structure_factors(d_min=0.8).f_calc().norm() fo_sq = fo_sq.customized_copy(sigmas=flex.double(fo_sq.size(), 1.)) for hydrogen_flag in (True, False): xs = xs0.deep_copy_scatterers() if not hydrogen_flag: xs.select_inplace(~xs.element_selection('H')) xs.shake_adp() xs.shake_sites_in_place(rms_difference=0.1) for sc in xs.scatterers(): sc.flags.set_grad_site(True).set_grad_u_aniso(False) ls = least_squares.crystallographic_ls( fo_sq.as_xray_observations(), constraints.reparametrisation( structure=xs, constraints=[], connectivity_table=smtbx.utils.connectivity_table(xs)), weighting_scheme=least_squares.unit_weighting(), origin_fixing_restraints_type= origin_fixing_restraints.atomic_number_weighting) ls.build_up() lambdas = eigensystem.real_symmetric( ls.normal_matrix_packed_u().matrix_packed_u_as_symmetric()).values() # assert the restrained L.S. problem is not too ill-conditionned cond = math.log10(lambdas[0]/lambdas[-1]) msg = ("one heavy element + light elements (real data) %s Hydrogens: %.1f" % (['without', 'with'][hydrogen_flag], cond)) if verbose: print msg assert cond < worst_condition_number_acceptable, msg # are esd's for x,y,z coordinates of the same order of magnitude? var_cart = covariance.orthogonalize_covariance_matrix( ls.covariance_matrix(), xs.unit_cell(), xs.parameter_map()) var_site_cart = covariance.extract_covariance_matrix_for_sites( flex.size_t_range(len(xs.scatterers())), var_cart, xs.parameter_map()) site_esds = var_site_cart.matrix_packed_u_diagonal() indicators = flex.double() for i in xrange(0, len(site_esds), 3): stats = scitbx.math.basic_statistics(site_esds[i:i+3]) indicators.append(stats.bias_corrected_standard_deviation/stats.mean) assert indicators.all_lt(1)