def from_abc(klass, a, b, c, alpha, beta, gamma): """ Create 3 vectors from six parameters """ sin_gamma = sin(gamma) cos_gamma = cos(gamma) tan_gamma = tan(gamma) cos_beta = cos(beta) cos_alpha = cos(alpha) v1 = Vec(a, 0, 0) v2 = Vec(b * cos_gamma, b * sin_gamma, 0) v3 = Vec( c * cos_beta, -(c * cos_beta / tan_gamma) + c * cos_alpha / sin_gamma, sqrt(c**2 - (c * cos_beta)**2 - (-(c * cos_beta / tan_gamma) + c * cos_alpha / sin_gamma)**2)) return Reper(v1, v2, v3)
def __init__( self, *args, **kargs ): if len( args ) == 6: a,b,c, alpha, beta, gamma = args if kargs.get( 'indeg', False ): self.rep = Reper.from_abc( a,b,c, alpha * math.pi / 180.0, beta * math.pi / 180.0, gamma * math.pi / 180.0 ) else: self.rep = Reper.from_abc( a,b,c, alpha, beta, gamma ) elif len( args ) == 9: self.rep = Reper( Vec( *args[0:3] ), Vec( *args[3:6] ), Vec( *args[6:9] ) ) else: assert type( args[ 0 ] ) is Reper self.rep = args[ 0 ] self.atoms = {} self.decart = kargs.get( 'decart', False ) ## by default assume that all coordinates of atoms in fractional coordinates
def norm(self): """ Reduce & make all zelling args negative. """ vs = [self.v1, self.v2, self.v3, (self.v1 + self.v2 + self.v3) * -1] f = True while f: f = False for i, v1 in enumerate(vs): for j, v2 in enumerate(vs): if i != j and v1 * v2 > 0.0001: for k in xrange(4): if k != i and k != j: vs[k] += v1 ## add v1 to all, except v1 and v2 vs[i] *= -1 ## v1 --> -v1 v1 *= -1 ## also correct cycle var f = True return Reper(vs[0], vs[1], vs[2])
def minimize(self): """ Reduce reper to 3 minimal vector. """ vs = [self.v1, self.v2, self.v3] f = True while f: f = False vts = [t for t in vs] abc = ( (i,j,k) for i in xrange( -1, 2 )\ for j in xrange( -1, 2 )\ for k in xrange( -1, 2 ) ) for a, b, c in abc: vnew = a * vs[0] + b * vs[1] + c * vs[2] for i, v in enumerate(vts): if v.vlen2() > vnew.vlen2(): vo, vts[i] = vts[i], vnew if abs(vts[0] * vts[1].vcross(vts[2])) > 0.0001: f = True else: vts[i] = vo #print vs, vts, f vs = vts return Reper(*vs)