def constrain(self, constraints): #algorithm 1. Use pre-defined crystal_systems to give hard-coded restraints. # dps_core.constrainment.s_minimizer uses LBFGS minimizer to adapt # all 9 components of the orientation matrix. This gives the best-fit # to the starting matrix (better than algorithm #2), but the disadvantage # is that it is keyed to the crystal_system descriptors. It is therefore # not adapted to all small-molecule space groups (monoclinics), # and will not take into account non-standard settings. if constraints in [ "triclinic", "monoclinic", 'orthorhombic', 'tetragonal', "cubic", "rhombohedral", 'hexagonal' ]: from rstbx.dps_core.constrainment import s_minimizer S = s_minimizer(self, constraint=constraints) return S.newOrientation() #algorithm 2: Tensor_rank_2 symmetrization # Advantages: constraints are calculated directly from the space # group, so will account for non-standard settings. # Disadvantages: drift away from starting orientation is greater than # for algorithm #1. from cctbx.sgtbx import space_group if isinstance(constraints, space_group): from rstbx.symmetry.constraints import AGconvert converter = AGconvert() converter.forward(self) average_cell = constraints.average_unit_cell(self.unit_cell()) converter.validate_and_setG( average_cell.reciprocal().metrical_matrix()) return Orientation(converter.back(), basis_type.reciprocal)
def finite_difference_test(orient): from rstbx.symmetry.constraints import AGconvert as AG from labelit.symmetry.metricsym.a_g_conversion import pp from libtbx.tst_utils import approx_equal adaptor = AG() adaptor.forward(orient) grad = g_gradients(adaptor, symred=None) epsilon = 1.E-10 dAij_dphi = grad.get_all_da()[0] AGback = AG() F = [] for x in [-1., 1.]: AGback.setAngles(adaptor.phi + x * epsilon, adaptor.psi, adaptor.theta) AGback.G = adaptor.G F.append(flex.double(AGback.back())) diff_mat = (F[1] - F[0]) / (2. * epsilon) rule = "dAij_dphi: Analytical gradient vs. finite difference gradient\n"+\ pp(list(dAij_dphi))+"\n"+\ pp(diff_mat) if not (approx_equal(dAij_dphi, diff_mat, 1.E-7)): raise Exception(rule) dAij_dpsi = grad.get_all_da()[1] AGback = AG() F = [] for x in [-1., 1.]: AGback.setAngles(adaptor.phi, adaptor.psi + x * epsilon, adaptor.theta) AGback.G = adaptor.G F.append(flex.double(AGback.back())) diff_mat = (F[1] - F[0]) / (2. * epsilon) rule = "dAij_dpsi: Analytical gradient vs. finite difference gradient\n"+\ pp(list(dAij_dpsi))+"\n"+\ pp(diff_mat) if not (approx_equal(dAij_dpsi, diff_mat, 1.E-7)): raise Exception(rule) dAij_dtheta = grad.get_all_da()[2] AGback = AG() F = [] for x in [-1., 1.]: AGback.setAngles(adaptor.phi, adaptor.psi, adaptor.theta + x * epsilon) AGback.G = adaptor.G F.append(flex.double(AGback.back())) diff_mat = (F[1] - F[0]) / (2. * epsilon) rule = "dAij_dtheta: Analytical gradient vs. finite difference gradient\n"+\ pp(list(dAij_dtheta))+"\n"+\ pp(diff_mat) if not (approx_equal(dAij_dtheta, diff_mat, 1.E-7)): raise Exception(rule) g0, g1, g2, g3, g4, g5 = adaptor.G dAij_dg0 = grad.get_all_da()[3] AGback = AG() F = [] for x in [-1., 1.]: AGback.setAngles(adaptor.phi, adaptor.psi, adaptor.theta) AGback.G = (g0 + x * epsilon, g1, g2, g3, g4, g5) F.append(flex.double(AGback.back())) diff_mat = (F[1] - F[0]) / (2. * epsilon) rule = "dAij_dg0: Analytical gradient vs. finite difference gradient\n"+\ pp(list(dAij_dg0))+"\n"+\ pp(diff_mat) if not (approx_equal(dAij_dg0, diff_mat, 1.E-7)): raise Exception(rule) dAij_dg1 = grad.get_all_da()[4] AGback = AG() F = [] for x in [-1., 1.]: AGback.setAngles(adaptor.phi, adaptor.psi, adaptor.theta) AGback.G = (g0, g1 + x * epsilon, g2, g3, g4, g5) F.append(flex.double(AGback.back())) diff_mat = (F[1] - F[0]) / (2. * epsilon) rule = "dAij_dg1: Analytical gradient vs. finite difference gradient\n"+\ pp(list(dAij_dg1))+"\n"+\ pp(diff_mat) if not (approx_equal(dAij_dg1, diff_mat, 1.E-7)): raise Exception(rule) dAij_dg2 = grad.get_all_da()[5] AGback = AG() F = [] for x in [-1., 1.]: AGback.setAngles(adaptor.phi, adaptor.psi, adaptor.theta) AGback.G = (g0, g1, g2 + x * epsilon, g3, g4, g5) F.append(flex.double(AGback.back())) diff_mat = (F[1] - F[0]) / (2. * epsilon) rule = "dAij_dg2: Analytical gradient vs. finite difference gradient\n"+\ pp(list(dAij_dg2))+"\n"+\ pp(diff_mat) if not (approx_equal(dAij_dg2, diff_mat, 1.E-6)): raise Exception(rule) dAij_dg3 = grad.get_all_da()[6] AGback = AG() F = [] for x in [-1., 1.]: AGback.setAngles(adaptor.phi, adaptor.psi, adaptor.theta) AGback.G = (g0, g1, g2, g3 + x * epsilon, g4, g5) F.append(flex.double(AGback.back())) diff_mat = (F[1] - F[0]) / (2. * epsilon) rule = "dAij_dg3: Analytical gradient vs. finite difference gradient\n"+\ pp(list(dAij_dg3))+"\n"+\ pp(diff_mat) if not (approx_equal(dAij_dg3, diff_mat, 1.E-7)): raise Exception(rule) dAij_dg4 = grad.get_all_da()[7] AGback = AG() F = [] for x in [-1., 1.]: AGback.setAngles(adaptor.phi, adaptor.psi, adaptor.theta) AGback.G = (g0, g1, g2, g3, g4 + x * epsilon, g5) F.append(flex.double(AGback.back())) diff_mat = (F[1] - F[0]) / (2. * epsilon) rule = "dAij_dg4: Analytical gradient vs. finite difference gradient\n"+\ pp(list(dAij_dg4))+"\n"+\ pp(diff_mat) if not (approx_equal(dAij_dg4, diff_mat, 1.E-7)): raise Exception(rule) dAij_dg5 = grad.get_all_da()[8] AGback = AG() F = [] for x in [-1., 1.]: AGback.setAngles(adaptor.phi, adaptor.psi, adaptor.theta) AGback.G = (g0, g1, g2, g3, g4, g5 + x * epsilon) F.append(flex.double(AGback.back())) diff_mat = (F[1] - F[0]) / (2. * epsilon) rule = "dAij_dg5: Analytical gradient vs. finite difference gradient\n"+\ pp(list(dAij_dg5))+"\n"+\ pp(diff_mat) if not (approx_equal(dAij_dg5, diff_mat, 1.E-6)): raise Exception(rule)