def rotMatrixFromCrystalVectors(cvs1=None, cvs2=None, cvs3=None): """\ Make a rotation matrix in the RotationParameterization convention from components of crystal vectors that are along given sample directions """ mat = zeros([3,3], dtype='float64') if cvs1 == None: if ((cvs2 == None) or (cvs3 == None)): print >> sys.stderr, "need more inputs" raise RuntimeError, "unrecoverable error" cvs1 = cross(cvs2,cvs3) cvs1 = normalized(cvs1) if cvs2 == None: if ((cvs1 == None) or (cvs3 == None)): print >> sys.stderr, "need more inputs" raise RuntimeError, "unrecoverable error" cvs2 = cross(cvs1,cvs3) cvs2 = normalized(cvs2) if cvs3 == None: if ((cvs1 == None) or (cvs2 == None)): print >> sys.stderr, "need more inputs" raise RuntimeError, "unrecoverable error" cvs3 = cross(cvs1,cvs2) cvs3 = normalized(cvs3) mat[0,:] = cvs1[:] mat[1,:] = cvs2[:] mat[2,:] = cvs3[:] det = determinant3(mat) if (abs(det-1.0) < 1e-12): return mat elif (abs(det+1.0) < 1e-12): mat = -mat return mat else: print >> sys.stderr, "vectors not close enough to orthonormal" raise RuntimeError, "unrecoverable error"
def __init__(self, *args): if isinstance(args[0], str): a = args[0] if a == 'rand': if len(args) > 1: if hasattr(args[1], '__len__'): thetaScale = args[1] if len(thetaScale) == 3: self.n = zeros(3, dtype='float64') self.n[0] = RotInv.__rvNorm() * thetaScale[0] self.n[1] = RotInv.__rvNorm() * thetaScale[1] self.n[2] = RotInv.__rvNorm() * thetaScale[2] mag = normvec3(self.n) if mag > 0.: self.n[:] = self.n[:] / mag self.theta = mag else: newInv = Quat('rand').toInv() self.n[:] = newInv.n[:] self.theta = mag else: raise RuntimeError, "unrecoverable error: bad thetaScale length" else: newInv = Quat('rand').toInv() self.n = newInv.n thetaScale = float(args[1]) self.theta = RotInv.__rvNorm() * thetaScale else: newInv = Quat('rand').toInv() self.n = newInv.n self.theta = newInv.theta elif a == 'align': # align given crystal vector with given sample vector vl = num.array(args[1]) vs = num.array(args[2]) # normalize mag = normvec3(vl) vl /= mag mag = normvec3(vs) vs /= mag self.theta = math.acos(num.dot(vs,vl)) # arccosine w = cross(vl,vs) mag = normvec3(w) if mag > 1e-14: self.n = w / mag else: sqr3i = 1./sqrt(3.) self.n = num.array([sqr3i, sqr3i, sqr3i]) else: print >> sys.stderr, "bad string" raise RuntimeError, "unrecoverable error" elif len(args) == 1: a = args[0] if (hasattr(a,"toInv")): "use direct conversion, assuming it is more efficient" newInv = a.toInv() self.theta = newInv.theta self.n = newInv.n elif isinstance(a,RotationParameterization): "from 3x3 matrix of components" (self.theta, self.n) = matToThetaN(a.toMatrix()) else: a = num.atleast_1d(args[0]) if size(shape(a)) == 2: "from 3x3 matrix of components" assert a.shape[0] == 3 and a.shape[1] == 3, 'wrong shape for matrix' (self.theta, self.n) = matToThetaN(a) elif size(shape(a)) == 1: "exponential map parameters" assert a.shape[0] == 3, 'wrong shape for exp map parameters' self.n = a self.theta = sqrt(sum(self.n[:] * self.n[:])) if self.theta > 0.: self.n = self.n / self.theta else: self.n = num.array([1.,0.,0.]) # n not really well defined else: print >> sys.stderr, "wrong shape of args[0]", shape(a) raise RuntimeError, "unrecoverable error" elif len(args) == 2: "from theta and normal vector (not necessarily normalized)" self.theta = float(args[0]) self.n = zeros(3, dtype='float64') self.n[:] = args[1] mag = sqrt(sum(self.n[:] * self.n[:])) self.n[:] = self.n[:] / mag elif len(args) == 4: "from theta and normal vector (not necessarily normalized)" self.theta = float(args[0]) self.n = zeros(3, dtype='float64') self.n[:] = args[1:4] mag = sqrt(sum(self.n[:] * self.n[:])) self.n[:] = self.n[:] / mag else: print >> sys.stderr, "wrong number of args %g" % len(args) raise RuntimeError, "unrecoverable error"