def reciprocal(cell): cell = Numeric.array(cell) sa, sb, sg = Numeric.sin(cell[3:6]/r2d) ca, cb, cg = Numeric.cos(cell[3:6]/r2d) v = cell[0]*cell[1]*cell[2]*(1-ca**2-cb**2-cg**2+2*ca*cb*cg)**0.5 rc = Numeric.zeros(6, Numeric.Float) rc[0] = cell[1]*cell[2]*sa/v rc[1] = cell[2]*cell[0]*sb/v rc[2] = cell[0]*cell[1]*sg/v rc[3] = Numeric.arccos((cb*cg-ca)/(sb*sg)) * r2d rc[4] = Numeric.arccos((ca*cg-cb)/(sa*sg)) * r2d rc[5] = Numeric.arccos((ca*cb-cg)/(sa*sb)) * r2d return rc
def reciprocal(cell): cell = Numeric.array(cell) sa, sb, sg = Numeric.sin(cell[3:6] / r2d) ca, cb, cg = Numeric.cos(cell[3:6] / r2d) v = cell[0] * cell[1] * cell[2] * (1 - ca**2 - cb**2 - cg**2 + 2 * ca * cb * cg)**0.5 rc = Numeric.zeros(6, Numeric.Float) rc[0] = cell[1] * cell[2] * sa / v rc[1] = cell[2] * cell[0] * sb / v rc[2] = cell[0] * cell[1] * sg / v rc[3] = Numeric.arccos((cb * cg - ca) / (sb * sg)) * r2d rc[4] = Numeric.arccos((ca * cg - cb) / (sa * sg)) * r2d rc[5] = Numeric.arccos((ca * cb - cg) / (sa * sb)) * r2d return rc
def angle(self, other): "Returns the angle to vector |other|." if not isVector(other): raise TypeError, "Angle between vector and non-vector" cosa = Numeric.add.reduce(self.array*other.array) / \ Numeric.sqrt(Numeric.add.reduce(self.array*self.array) * \ Numeric.add.reduce(other.array*other.array)) cosa = max(-1.,min(1.,cosa)) return Numeric.arccos(cosa)
def angle(self, other): "Returns the angle to vector |other|." if not isVector(other): raise TypeError, "Angle between vector and non-vector" cosa = Numeric.add.reduce(self.array*other.array) / \ Numeric.sqrt(Numeric.add.reduce(self.array*self.array) * \ Numeric.add.reduce(other.array*other.array)) cosa = max(-1., min(1., cosa)) return Numeric.arccos(cosa)
def testTrig (self): "Test sin, cos, tan, and their inverses" assert_eq(Numeric.arccos(-1.0), Numeric.pi) assert_eq(Numeric.sin(self.a), map(math.sin, self.a)) assert_eq(Numeric.cos(self.a), map(math.cos, self.a)) assert_eq(Numeric.tan(self.a), map(math.tan, self.a)) assert_eq(Numeric.arccos(self.a), map(math.acos, self.a)) assert_eq(Numeric.arcsin(self.a), map(math.asin, self.a)) assert_eq(Numeric.arctan(self.a), map(math.atan, self.a)) assert Numeric.sin(self.m).shape == self.m.shape assert Numeric.cos(self.m).shape == self.m.shape assert Numeric.tan(self.m).shape == self.m.shape assert Numeric.arcsin(self.m).shape == self.m.shape assert Numeric.arccos(self.m).shape == self.m.shape assert Numeric.arctan(self.m).shape == self.m.shape assert_eq(Numeric.sin(self.m).flat, map(math.sin, self.m.flat)) assert_eq(Numeric.cos(self.m).flat, map(math.cos, self.m.flat)) assert_eq(Numeric.tan(self.m).flat, map(math.tan, self.m.flat)) assert_eq(Numeric.arcsin(self.m).flat, map(math.asin, self.m.flat)) assert_eq(Numeric.arccos(self.m).flat, map(math.acos, self.m.flat)) assert_eq(Numeric.arctan(self.m).flat, map(math.atan, self.m.flat))
def angle(x,y,z): d1 = dist3(x,y) d2 = dist3(z,y) if (d1 <= 0 or d2 <= 0): return 0.0 acc = Numeric.add.reduce((y-x) * (y-z)) / (d1*d2) if (acc > 1): acc = 1. elif (acc < -1): acc = -1. return Numeric.arccos(acc)
def _intersectCirclePlane(circle, plane): if abs(abs(circle.normal*plane.normal)-1.) < _eps: if plane.hasPoint(circle.center): return circle else: return None else: line = plane.intersectWith(Plane(circle.center, circle.normal)) x = line.distanceFrom(circle.center) if x > circle.radius: return None else: angle = Numeric.arccos(x/circle.radius) along_line = Numeric.sin(angle)*circle.radius normal = circle.normal.cross(line.direction) if line.distanceFrom(circle.center+normal) > x: normal = -normal return (circle.center+x*normal-along_line*line.direction, circle.center+x*normal+along_line*line.direction)
def _tetrahedralH(self, atom, known, unknown, bond): r = atom.position() n = (known[0].position()-r).normal() cone = Objects3D.Cone(r, n, Numeric.arccos(-1./3.)) sphere = Objects3D.Sphere(r, bond) circle = sphere.intersectWith(cone) others = filter(lambda a: a.symbol != 'H', known[0].bondedTo()) others.remove(atom) other = others[0] ref = (Objects3D.Plane(circle.center, circle.normal) \ .projectionOf(other.position())-circle.center).normal() p0 = circle.center + circle.radius*ref p0 = Objects3D.rotatePoint(p0, Objects3D.Line(circle.center, circle.normal), 60.*Units.deg) p1 = Objects3D.rotatePoint(p0, Objects3D.Line(circle.center, circle.normal), 120.*Units.deg) p2 = Objects3D.rotatePoint(p1, Objects3D.Line(circle.center, circle.normal), 120.*Units.deg) unknown[0].setPosition(p0) unknown[1].setPosition(p1) unknown[2].setPosition(p2)
def arccos(self): v = Numeric.arccos(self.value) d = -1./Numeric.sqrt(1.-pow(self.value,2)) return DerivVar(v, map(lambda x,f=d: f*x, self.deriv))
def test1(*s): "Test of basic array creation and arithmetic." x=Numeric.array([1.,1.,1.,-2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.]) y=Numeric.array([5.,0.,3., 2., -1., -4., 0., -10., 10., 1., 0., 3.]) a10 = 10. m1 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0] m2 = [0, 0, 1, 0, 0, 1, 1, 0, 0, 0 ,0, 1] xm = array(x, mask=m1) ym = array(y, mask=m2) z = Numeric.array([-.5, 0., .5, .8]) zm = array(z, mask=[0,1,0,0]) xf = Numeric.where(m1, 1.e+20, x) xm.set_fill_value(1.e+20) for item in [x, y, xm, ym, xf]: item.shape = s assert isMaskedArray(x) == 0 assert isMaskedArray(xm) == 1 assert shape(xm) == s assert xm.shape == s assert size(xm) == reduce(lambda x,y:x*y, s) assert xm.size() == size(xm) assert size(xm,0) == s[0] assert xm.size(0) == size(xm,0) assert count(xm) == len(m1) - reduce(lambda x,y:x+y, m1) if rank(xm) > 1: assert count(xm,0) == size(xm,0) - reduce(lambda x,y:x+y, xm.mask()[0]) alltest(xm, xf) alltest(filled(xm, 1.e20), xf) alltest(x, xm) alltest(-x, -xm) alltest(x + y, xm + ym) alltest(x - y, xm - ym) alltest(x * y, xm * ym) alltest(x / y, xm / ym) alltest(a10 + y, a10 + ym) alltest(a10 - y, a10 - ym) alltest(a10 * y, a10 * ym) alltest(a10 / y, a10 / ym) alltest(x + a10, xm + a10) alltest(x - a10, xm - a10) alltest(x * a10, xm * a10) alltest(x / a10, xm / a10) a2d = array([[1,2],[0,4]], Float) a2dm = masked_array(a2d, [[0,0],[1,0]]) alltest (a2d * a2d, a2d * a2dm) alltest (a2d + a2d, a2d + a2dm) alltest (a2d - a2d, a2d - a2dm) alltest(x**2, xm**2) alltest(abs(x)**2.5, abs(xm) **2.5) alltest(x**y, xm**ym) alltest(Numeric.add(x,y), add(xm, ym)) alltest(Numeric.subtract(x,y), subtract(xm, ym)) alltest(Numeric.multiply(x,y), multiply(xm, ym)) alltest(Numeric.divide(x,y), divide(xm, ym)) alltest(Numeric.cos(x), cos(xm)) alltest(Numeric.cosh(x), cosh(xm)) alltest(Numeric.sin(x), sin(xm)) alltest(Numeric.sinh(x), sinh(xm)) alltest(Numeric.tan(x), tan(xm)) alltest(Numeric.tanh(x), tanh(xm)) alltest(Numeric.sqrt(abs(x)), sqrt(xm)) alltest(Numeric.log(abs(x)), log(xm)) alltest(Numeric.log10(abs(x)), log10(xm)) alltest(Numeric.exp(x), exp(xm)) alltest(Numeric.arcsin(z), arcsin(zm)) alltest(Numeric.arccos(z), arccos(zm)) alltest(Numeric.arctan(z), arctan(zm)) alltest(Numeric.arctan2(x, y), arctan2(xm, ym)) alltest(Numeric.absolute(x), absolute(xm)) alltest(Numeric.equal(x,y), equal(xm, ym)) alltest(Numeric.not_equal(x,y), not_equal(xm, ym)) alltest(Numeric.less(x,y), less(xm, ym)) alltest(Numeric.greater(x,y), greater(xm, ym)) alltest(Numeric.less_equal(x,y), less_equal(xm, ym)) alltest(Numeric.greater_equal(x,y), greater_equal(xm, ym)) alltest(Numeric.conjugate(x), conjugate(xm)) alltest(Numeric.concatenate((x,y)), concatenate((xm,ym))) alltest(Numeric.concatenate((x,y)), concatenate((x,y))) alltest(Numeric.concatenate((x,y)), concatenate((xm,y))) alltest(Numeric.concatenate((x,y,x)), concatenate((x,ym,x))) ott = array([0.,1.,2.,3.], mask=[1,0,0,0]) assert isinstance(count(ott), types.IntType) alltest(3, count(ott)) alltest(1, count(1)) alltest(0, array(1,mask=[1])) ott.shape = (2,2) assert isMaskedArray(count(ott,0)) assert isinstance(count(ott), types.IntType) alltest(3, count(ott)) assert getmask(count(ott,0)) is None alltest([1,2],count(ott,0)) xr = Numeric.ravel(x) #max doesn't work if shaped xmr = ravel(xm) alltest(max(xr), maximum(xmr)) #true because of careful selection of data alltest(min(xr), minimum(xmr)) #true because of careful selection of data alltest(Numeric.add.reduce(x), add.reduce(x)) alltest(Numeric.add.accumulate(x), add.accumulate(x)) alltest(4, sum(array(4))) alltest(4, sum(array(4), axis=0)) alltest(Numeric.sum(x), sum(x)) alltest(Numeric.sum(filled(xm,0)), sum(xm)) alltest(Numeric.sum(x,0), sum(x,0)) alltest(Numeric.product(x), product(x)) alltest(Numeric.product(x,0), product(x,0)) alltest(Numeric.product(filled(xm,1)), product(xm)) if len(s) > 1: alltest(Numeric.concatenate((x,y),1), concatenate((xm,ym),1)) alltest(Numeric.add.reduce(x,1), add.reduce(x,1)) alltest(Numeric.sum(x,1), sum(x,1)) alltest(Numeric.product(x,1), product(x,1))
def threeAngles(self, e1, e2, e3, tolerance=1e-7): """Find three angles a1, a2, a3 such that Rotation(a1*|e1|)*Rotation(a2*|e2|)*Rotation(a3*|e3|) is equal to the rotation object. |e1|, |e2|, and |e3| are non-zero vectors. The result is a list of the two possible solutions.""" # Written by Pierre Legrand ([email protected]) # # Basically this is a reimplementation of the David # Thomas's algorithm [1] described by Gerard Bricogne in [2]: # # [1] "Modern Equations of Diffractometry. Goniometry." D.J. Thomas # Acta Cryst. (1990) A46 Page 321-343. # # [2] "The ECC Cooperative Programming Workshop on Position-Sensitive # Detector Software." G. Bricogne, # Computational aspect of Protein Crystal Data Analysis, # Proceedings of the Daresbury Study Weekend (23-24/01/1987) # Page 122-126 e1 = e1.normal() e2 = e2.normal() e3 = e3.normal() # We are searching for the three angles a1, a2, a3 # If 2 consecutive axes are parallel: decomposition is not meaningful if (e1.cross(e2)).length() < tolerance or \ (e2.cross(e3)).length() < tolerance : raise ValueError, 'Consecutive parallel axes. Too many solutions' w = self(e3) # Solve the equation : _a.cosx + _b.sinx = _c _a = e1*e3 - (e1*e2)*(e2*e3) _b = e1*(e2.cross(e3)) _c = e1*w - (e1*e2)*(e2*e3) _norm = (_a**2 + _b**2)**0.5 # Checking for possible errors in initial Rot matrix if _norm == 0: raise ValueError, 'FAILURE 1, norm = 0' if abs(_c/_norm) > 1+tolerance: raise ValueError, 'FAILURE 2' + \ 'malformed rotation Tensor (non orthogonal?) %.8f' \ % (_c/_norm) #if _c/_norm > 1: raise ValueError, 'Step1: No solution' _th = angleFromSineAndCosine(_b/_norm, _a/_norm) _xmth = Numeric.arccos(_c/_norm) # a2a and a2b are the two possible solutions to the equation. a2a = mod_angle((_th + _xmth), 2*Numeric.pi) a2b = mod_angle((_th - _xmth), 2*Numeric.pi) solutions = [] # for each solution, find the two other angles (a1, a3). for a2 in (a2a, a2b): R2 = Rotation(e2, a2) v = R2(e3) v1 = v - (v*e1)*e1 w1 = w - (w*e1)*e1 norm = ((v1*v1)*(w1*w1))**0.5 if norm == 0: # in that case rotation 1 and 3 are about the same axis # so any solution for rotation 1 is OK a1 = 0. else: cosa1 = (v1*w1)/norm sina1 = v1*(w1.cross(e1))/norm a1 = mod_angle(angleFromSineAndCosine(sina1, cosa1), 2*Numeric.pi) R3 = Rotation(e2, -1*a2)*Rotation(e1, -1*a1)*self # u = normalized test vector perpendicular to e3 # if e2 and e3 are // we have an exception before. # if we take u = e1^e3 then it will not work for # Euler and Kappa axes. u = (e2.cross(e3)).normal() cosa3 = u*R3(u) sina3 = u*(R3(u).cross(e3)) a3 = mod_angle(angleFromSineAndCosine(sina3, cosa3), 2*Numeric.pi) solutions.append(Numeric.array([a1, a2, a3])) # Gives the closest solution to 0,0,0 first if Numeric.add.reduce(solutions[0]**2) > \ Numeric.add.reduce(solutions[1]**2): solutions = [solutions[1], solutions[0]] return solutions