def centerAndMomentOfInertia(self, conf = None): """ :param conf: a configuration object, or None for the current configuration :type conf: :class:`~MMTK.ParticleProperties.Configuration` or NoneType :returns: the center of mass and the moment of inertia tensor in the given configuration """ from Scientific.Geometry import delta offset = None universe = self.universe() if universe is not None: offset = universe.contiguousObjectOffset([self], conf) m = 0. mr = Vector(0.,0.,0.) t = Tensor(3*[3*[0.]]) for a in self.atomIterator(): ma = a._mass if offset is None: r = a.position(conf) else: r = a.position(conf)+offset[a] m += ma mr += ma*r t += ma*r.dyadicProduct(r) cm = mr/m t -= m*cm.dyadicProduct(cm) t = t.trace()*delta - t return cm, t
def centerAndMomentOfInertia(self, conf=None): """ :param conf: a configuration object, or None for the current configuration :type conf: :class:~MMTK.ParticleProperties.Configuration or NoneType :returns: the center of mass and the moment of inertia tensor in the given configuration """ from Scientific.Geometry import delta offset = None universe = self.universe() if universe is not None: offset = universe.contiguousObjectOffset([self], conf) m = 0. mr = Vector(0., 0., 0.) t = Tensor(3 * [3 * [0.]]) for a in self.atomIterator(): ma = a._mass if offset is None: r = a.position(conf) else: r = a.position(conf) + offset[a] m += ma mr += ma * r t += ma * r.dyadicProduct(r) cm = mr / m t -= m * cm.dyadicProduct(cm) t = t.trace() * delta - t return cm, t
def changeBasis(pt, op, ip, jp, kp): """Returns the coordinates of a point after a change of basis. @param pt: the coordinates of the point in the old basis. @type pt: Scientific Vector @param op: the coordinates of the new origin in the old basis. @type op: Scientific Vector @param ip: the coordinates of the new x axis in the old basis. @type ip: Scientific Vector @param jp: the coordinates of the new y axis in the old basis. @type jp: Scientific Vector @param kp: the coordinates of the new z axis in the old basis. @type kp: Scientific Vector @return: the coordinates of the point in the new basis. @rtype: Scientific Vector """ mat = Tensor(N.array([ip, jp, kp], typecode=N.Float).transpose()) matinv = mat.inverse() # This is the formula of the change of basis. mprim = matinv * (pt - op) return mprim
def __getitem__(self, item): i1, i2 = item if not isinstance(i1, int): i1 = i1.index if not isinstance(i2, int): i2 = i2.index if i1 > i2: i1, i2 = i2, i1 return Tensor(N.transpose(self.array[i1, :, i2, :])) else: return Tensor(self.array[i1, :, i2, :])
def __init__(self, universe, lower, upper, number, initial=None): basis = universe.reciprocalBasisVectors() if basis is None: self.basis = None if initial is None: self._makeRandomKList(lower, upper, number) else: self.klist = [initial] else: self.basis = map(lambda v: 2. * N.pi * v, basis) inverse = N.array(map(list, universe.basisVectors())) self.inverse = Tensor(inverse) / (2. * N.pi) cell_volume = self.basis[0] * (self.basis[1].cross(self.basis[2])) if initial is None: center = 0.5 * (lower + upper) shell_volume = 4. * N.pi * center**2 * (upper - lower) ncells = shell_volume / cell_volume if number > 1.5 * ncells: number = int(1.5 * ncells) if ncells > 500: self._makeRandomKList(lower, upper, number) else: self._makeExplicitKList(lower, upper, number) else: ki = map(round, self.inverse * initial) k = ki[0]*self.basis[0] + ki[1]*self.basis[1] + \ ki[2]*self.basis[2] self.klist = [k]
def zero(self): """ @returns: a tensor of the same rank as the field values with all elements equal to zero @rtype: L{Scientifc.Geometry.Tensor} """ if self.rank == 0: return 0. else: return Tensor(Numeric.zeros(self.rank*(3,), Numeric.Float))
def __call__(self, *points): if len(points) == 1: points = tuple(points[0]) value = apply(Interpolation.InterpolatingFunction.__call__, (self, ) + points) if self.rank == 0: return value elif self.rank == 1: return Vector(value) else: return Tensor(value)
def centerAndMomentOfInertia(self, conf = None): "Returns the center of mass and the moment of inertia tensor." from Scientific.Geometry.TensorModule import delta offset = None universe = self.universe() if universe is not None: offset = universe.contiguousObjectOffset([self], conf) m = 0. mr = Vector(0.,0.,0.) t = Tensor(3*[3*[0.]]) for a in self.atomList(): ma = a._mass if offset is None: r = a.position(conf) else: r = a.position(conf)+offset[a] m = m + ma mr = mr + ma*r t = t + ma*r.dyadicProduct(r) cm = mr/m t = t - m*cm.dyadicProduct(cm) t = t.trace()*delta - t return cm, t
def centerAndMomentOfInertia(self, conf=None): "Returns the center of mass and the moment of inertia tensor." from Scientific.Geometry import delta offset = None universe = self.universe() if universe is not None: offset = universe.contiguousObjectOffset([self], conf) m = 0. mr = Vector(0., 0., 0.) t = Tensor(3 * [3 * [0.]]) for a in self.atomList(): ma = a._mass if offset is None: r = a.position(conf) else: r = a.position(conf) + offset[a] m = m + ma mr = mr + ma * r t = t + ma * r.dyadicProduct(r) cm = mr / m t = t - m * cm.dyadicProduct(cm) t = t.trace() * delta - t return cm, t
def __init__(self, universe, qVectorsDict): if not isinstance(qVectorsDict, dict): raise Error("%s: not a valid python dictionnary." % qVectorsDict) self.qVectorsDict = copy.copy(qVectorsDict) # A copy of the input universe. self.universe = universe if self.universe.reciprocalBasisVectors() is None: # The direct basis. self.dirBasis = None # The reciprocal basis. self.recBasis = None else: # The direct basis. self.dirBasis = Tensor( N.array([N.array(v) for v in self.universe.basisVectors()], typecode=N.Float)) / (2.0 * N.pi) # The reciprocal basis. self.recBasis = (2.0 * N.pi) * Tensor( N.array([ N.array(v) for v in self.universe.reciprocalBasisVectors() ], typecode=N.Float)) self.transRecBasis = self.recBasis.transpose() # These tree qttributes will the "output" for the class. self.qRadii = [] self.qVectors = [] self.hkls = [] self.qGeometry = self.qVectorsDict.get("qgeometry", None) if self.qGeometry in ["spatial", "planar", "axial"]: qShells = self.qVectorsDict.get("qshellvalues", None) self.qShells = Generate_QShells(qShells) try: self.qShellWidth = float(self.qVectorsDict.get("qshellwidth")) except: raise Error("Invalid value for qshellwidth parameter.") try: self.qVectorsPerShell = int( self.qVectorsDict.get("qvectorspershell")) except: raise Error("Invalid value for qvectorspershell parameter.") self.qGeometry = self.qVectorsDict.get("qgeometry", None) if self.qGeometry == "spatial": self._spatial_qvectors() elif self.qGeometry == "planar": self._planar_qvectors() elif self.qGeometry == "axial": self._axial_qvectors() else: raise Error("%s is not a valid Qvector geometry." % self.qGeometry) elif self.qGeometry == "userdefined": self._userdefined_qvectors() else: raise Error("%s is not a valid Qvector geometry." % self.qGeometry) self.qRadii = N.array(self.qRadii, typecode=N.Float) self.qvectors_statistics() self._display_qvectors()
def NeRFinte2cart(self, dihe): # Needs debug """ Reconstructs atomlist positions 2005 Parsons et al - NeRF algorithm :param universe: MMTK universe :type universe: MMTK universe :param dihe: list of dihedrals :type dihe: [[[],[],aval] , [[],[],aval] , dval] where [] is a bond """ known_atoms = [] unknown_atoms = copy.deepcopy(universe.atomList()) C = Vector(0, 0, 0) D = Vector(0, 0, 0) D2 = Vector(0, 0, 0) l = len(dihe) for di in range(l): # Create the START stack dihe.append(self.swap_dihe(dihe[di])) #for i in dihe: # print_zmat_dihe(i) # Assign initial values i = dihe[0] a1 = i[0][0][0] a2 = i[0][0][1] a3 = i[1][1][0] a4 = i[1][1][1] R1 = i[0][0][2] R2 = i[1][1][2] theta1 = i[0][2] phi = i[2] universe.atomList()[a1.index].setPosition(Vector(0, 0, 0)) universe.atomList()[a2.index].setPosition(Vector(R1, 0, 0)) universe.atomList()[a3.index].setPosition( Vector(R1 - R2 * cos(theta1), R2 * sin(theta1), 0)) known_atoms.append(a1) known_atoms.append(a2) known_atoms.append(a3) #print 'initialize at: ', a1, a2, a3 #bPDBprint_atom('HETATM', a1.name, 10*a1.position()) #bPDBprint_atom('HETATM', a2.name, 10*a2.position()) #bPDBprint_atom('HETATM', a3.name, 10*a3.position()) # Main loop cnt = 0 while len(known_atoms) < len(universe.atomList()): cnt += 1 if cnt > 9999: print 'NeRFinte2cart() cnt EXCEEDED: 9999' break ai = -1 for a in unknown_atoms: ai += 1 for i in dihe: # Search if atom a is a4 in any dihe a1 = i[0][0][0] a2 = i[0][0][1] a3 = i[1][0][1] a4 = i[1][1][1] a1known = 0 a2known = 0 a3known = 0 a4known = 0 if a4.index == a.index: for k in known_atoms: # Check if atom is in KNOWN stack if a4.index == k.index: a4known = 1 break if a1.index == k.index: a1known = 1 if a2.index == k.index: a2known = 1 if a3.index == k.index: a3known = 1 if ((a4known == 0) and \ (a1known == 1) and (a2known == 1) and (a3known == 1)): # Move everything so that a3 is in the center M = Translation(-1 * a3.position()) universe.applyTransformation(M) for k in known_atoms: M(k.position()) # Solve a4 #print 'SOLVE: ', a4 print_zmat_dihe(i) A = a1.position() B = a2.position() C = a3.position() #print 'A = ', A, '(', a1.name , ')' #print 'B = ', B, '(', a2.name , ')' #print 'C = ', C, '(', a3.name , ')' R = i[1][1][2] #print 'R = ', R theta = i[1][2] if theta > pi / 2: theta = pi - theta #print 'theta = ', theta, numpy.rad2deg(theta) phi = i[2] if phi < 0: phi = pi - phi #print 'phi = ', phi, numpy.rad2deg(phi) AB = B - A # B - A #print 'AB = ', AB BC = C - B # C - B #print 'BC = ', BC bc = BC.normal() #print 'bc = ', bc n = AB.cross(bc) n = n.normal() #print 'n = ', n Mx = bc #print 'Mx = ', Mx My = n.cross(bc) My = My.normal() #print 'My = ', My Mz = n #print 'Mz = ', Mz M = Tensor([ [Mx.x(), Mx.y(), Mx.z()],\ [My.x(), My.y(), My.z()],\ [Mz.x(), Mz.y(), Mz.z()] ]) #print 'M: ' #print M D2 = Vector(R * cos(theta), R * cos(phi) * sin(theta), R * sin(phi) * sin(theta)) #print 'D2: ' #print D2 D = M * D2 D = D + C #print 'D: ' #print D a.setPosition(D) universe.atomList()[a4.index].setPosition(D) # Add a4 to KNOWN known_atoms.append(a4) unknown_atoms.pop(ai) #print '========================' break for k in known_atoms: bPDBprint_atom('HETATM', k.name, 10 * k.position())
def readLine(self): """Returns the contents of the next non-blank line (= record). The return value is a tuple whose first element (a string) contains the record type. For supported record types (HEADER, ATOM, HETATM, ANISOU, TERM, MODEL, CONECT), the items from the remaining fields are put into a dictionary which is returned as the second tuple element. Most dictionary elements are strings or numbers; atom positions are returned as a vector, and anisotropic temperature factors are returned as a rank-2 tensor, already multiplied by 1.e-4. White space is stripped from all strings except for atom names, whose correct interpretation can depend on an initial space. For unsupported record types, the second tuple element is a string containing the remaining part of the record. """ while 1: line = self.file.readline() if not line: return ('END', '') if line[-1] == '\n': line = line[:-1] line = string.strip(line) if line: break line = string.ljust(line, 80) type = string.strip(line[:6]) if type == 'ATOM' or type == 'HETATM': line = FortranLine(line, atom_format) data = { 'serial_number': line[1], 'name': line[2], 'alternate': string.strip(line[3]), 'residue_name': string.strip(line[4]), 'chain_id': string.strip(line[5]), 'residue_number': line[6], 'insertion_code': string.strip(line[7]), 'position': Vector(line[8:11]), 'occupancy': line[11], 'temperature_factor': line[12], 'segment_id': string.strip(line[13]), 'element': string.strip(line[14]), 'charge': string.strip(line[15]) } return type, data elif type == 'ANISOU': line = FortranLine(line, anisou_format) data = { 'serial_number': line[1], 'name': line[2], 'alternate': string.strip(line[3]), 'residue_name': string.strip(line[4]), 'chain_id': string.strip(line[5]), 'residue_number': line[6], 'insertion_code': string.strip(line[7]), 'u': 1.e-4 * Tensor([[line[8], line[11], line[12]], [line[11], line[9], line[13]], [line[12], line[13], line[10]]]), 'segment_id': string.strip(line[14]), 'element': string.strip(line[15]), 'charge': string.strip(line[16]) } return type, data elif type == 'TER': line = FortranLine(line, ter_format) data = { 'serial_number': line[1], 'residue_name': string.strip(line[2]), 'chain_id': string.strip(line[3]), 'residue_number': line[4], 'insertion_code': string.strip(line[5]) } return type, data elif type == 'CONECT': line = FortranLine(line, conect_format) data = { 'serial_number': line[1], 'bonded': filter(lambda i: i > 0, line[2:6]), 'hydrogen_bonded': filter(lambda i: i > 0, line[6:10]), 'salt_bridged': filter(lambda i: i > 0, line[10:12]) } return type, data elif type == 'MODEL': line = FortranLine(line, model_format) data = {'serial_number': line[1]} return type, data elif type == 'HEADER': line = FortranLine(line, header_format) data = {'compound': line[1], 'date': line[2], 'pdb_code': line[3]} return type, data else: return type, line[6:]
def zero(self): return Tensor(3 * [[0., 0., 0.]])
def sumOverParticles(self): return Tensor(N.add.reduce(self.array, 0))
def zero(self): return Tensor([[0., 0., 0.], [0., 0., 0.], [0., 0., 0.]])
def __getitem__(self, item): if not isinstance(item, int): item = item.index return Tensor(self.array[item])