def rigu_as_cif_loop(xray_structure, proxies): unit_cell = xray_structure.unit_cell() sites_cart = xray_structure.sites_cart() u_cart = xray_structure.scatterers().extract_u_cart(unit_cell) site_labels = xray_structure.scatterers().extract_labels() fmt = "%.6f" loop = model.loop(header=( "_restr_RIGU_atom_site_label_1", "_restr_RIGU_atom_site_label_2", "_restr_RIGU_target_weight_param", "_restr_RIGU_U13_diff", "_restr_RIGU_U23_diff", "_restr_RIGU_U33_diff" )) for proxy in proxies: restraint = adp_restraints.rigu( adp_restraint_params(sites_cart=sites_cart, u_cart=u_cart), proxy=proxy) loop.add_row((site_labels[proxy.i_seqs[0]], site_labels[proxy.i_seqs[1]], fmt % math.sqrt(1/proxy.weight), fmt % restraint.delta_13(), fmt % restraint.delta_23(), fmt % restraint.delta_33() )) return loop
def exercise_rigu(): ins = """ CELL 0.71073 7.772741 8.721603 10.863736 90 102.9832 90 ZERR 2 0.000944 0.001056 0.001068 0 0.0107 0 LATT -1 SYMM -X,0.5+Y,-Z SFAC C H O UNIT 24 44 22 RIGU 0.0001 0.0001 O4 C C12 C12 1 -0.12812 0.06329 -0.17592 11.00000 0.01467 0.02689 0.02780 = -0.00379 0.00441 -0.00377 O4 3 0.08910 0.02721 0.02186 11.00000 0.02001 0.03168 0.03125 = -0.00504 0.00144 -0.00274 C 1 -0.05545 -0.04221 -0.06528 11.00000 0.01560 0.02699 0.02581 = -0.00481 0.00597 -0.00068 HKLF 4 END """ sio = StringIO(ins) import iotbx.shelx as shelx model = shelx.parse_smtbx_refinement_model(file=sio) sites_cart = model.structure.sites_cart() u_cart = model.structure.scatterers().extract_u_cart( model.structure.unit_cell()) arp = adp_restraint_params(sites_cart=sites_cart, u_cart=u_cart) for rp in model._proxies['rigu']: rr = adp_restraints.rigu(arp, rp) U1 = matrix.sym(sym_mat3=u_cart[rp.i_seqs[0]]) U2 = matrix.sym(sym_mat3=u_cart[rp.i_seqs[1]]) vz = matrix.col(sites_cart[rp.i_seqs[1]]) - matrix.col( sites_cart[rp.i_seqs[0]]) vy = vz.ortho() vx = vy.cross(vz) R = matrix.rec( vx.normalize().elems + vy.normalize().elems + vz.normalize().elems, (3, 3)) # with this matrix we can only test Z component as X and Y will differ dU = ((R * U1) * R.transpose() - (R * U2) * R.transpose()).as_sym_mat3() assert approx_equal(dU[2], rr.delta_33()) #with the original matrix all components should match R1 = matrix.rec(rr.RM(), (3, 3)) dU = ((R1 * U1) * R1.transpose() - (R1 * U2) * R1.transpose()).as_sym_mat3() assert approx_equal(dU[2], rr.delta_33()) assert approx_equal(dU[4], rr.delta_13()) assert approx_equal(dU[5], rr.delta_23()) # check the raw gradients against the reference implementation for x, y in zip(rr.reference_gradients(R1), rr.raw_gradients()): for idx in range(0, 6): assert approx_equal(x[idx], y[idx]) for x, y in zip(rigu_finite_diff(R1, U1), rr.raw_gradients()): for idx in range(0, 6): assert approx_equal(x[idx], y[idx])