def calc(self, frameIndex, trajectory): """Calculates the contribution for one frame. @param frameIndex: the index of the frame. @type frameIndex: integer. @param trajectory: the trajectory. @type trajectory: MMTK.Trajectory.Trajectory object """ orderedAtoms = sorted(trajectory.universe.atomList(), key = operator.attrgetter('index')) selectedAtoms = Collection([orderedAtoms[ind] for ind in self.subset]) targetAtoms = Collection([orderedAtoms[ind] for ind in self.target]) initialConf = Configuration(trajectory.universe, self.initialConfArray) # First frame, nothing to do because the initialConf already stores the initial transformation. if frameIndex == self.firstFrame: trajectory.universe.setConfiguration(initialConf) else: trajectory.universe.setFromTrajectory(trajectory, frameIndex) # Find and apply the linear transformation that will minimize the RMS with the configuration # resulting from the principal axes transformation. tr, rms = selectedAtoms.findTransformation(initialConf) #selectedAtoms.applyTransformation(tr) trajectory.universe.applyTransformation(tr) globalMotionFilteredFrame = {} for at in targetAtoms: globalMotionFilteredFrame[at.index] = at.position() return frameIndex, globalMotionFilteredFrame
def getChemicalObjects(types, var_list): """ processing atom selections """ myCollection = Collection() for k in types.keys(): if var_list[k] == '*': # 'All' for molecule in types[k]: myCollection.addObject(molecule) elif var_list[k] == 'None': pass elif var_list[k] == 'BackBone': for molecule in types[k]: myCollection.addObject(molecule.backbone()) elif var_list[k] == 'SideChain': for molecule in types[k]: reslist = molecule.sidechains() for res in reslist: myCollection.addObject(res) elif var_list[k] == 'Methyl': al = types[k].atomList() for atom in al: if atom.symbol == 'C': h = 0 al2 = atom.bondedTo() for at2 in al2: if at2.symbol == 'H': h = h + 1 if h == 3: meth = Collection() meth.addObject(atom) for at2 in al2: if at2.symbol == 'H': meth.addObject(at2) myCollection.addObject(meth) elif var_list[k] == 'C_alpha': al = types[k].atomList() for atom in al: if atom.name == 'C_alpha': myCollection.addObject(atom) elif var_list[k] == 'Carbon' or var_list[k] == 'Phosphorus' or \ var_list[k] == 'Oxygen' or var_list[k] == 'Nitrogen' or \ var_list[k] == 'Hydrogen' or var_list[k] == 'Sulfur': al = types[k].atomList() # This test is tricky: the second line compares only the # first letter, so calcium is treated like carbon! # Perhaps this should be rewritten to use chemical element # symbols only. for atom in al: if atom.type.name == lower(var_list[k]) or \ upper(atom.type.name[0]) == var_list[k][0]: myCollection.addObject(atom) return myCollection
def _get_heavy_atoms(self, universe, restrained_molecule_index): molecule = universe[restrained_molecule_index] col = Collection() for atom in molecule.atomList(): if atom.type.name != "hydrogen": col.addObject(atom) return col
def interpreteInputParameters(self): """Parse the input parameters for the analysis. """ # Parses the parameters that are common to different analysis. Analysis.interpreteInputParameters(self) self.buildTimeInfo() self.subset = self.selectAtoms(self.subsetDefinition) self.nSelectedAtoms = len(self.subset) self.target = self.selectAtoms(self.targetDefinition) self.trajectory.universe.setFromTrajectory(self.trajectory, self.firstFrame) orderedAtoms = sorted(self.trajectory.universe.atomList(), key = operator.attrgetter('index')) selectedAtoms = Collection([orderedAtoms[ind] for ind in self.subset]) # For the fist frame, defines principal axes transformation. tr = selectedAtoms.normalizingTransformation() # And apply it to the system. self.trajectory.universe.applyTransformation(tr) # selectedAtoms.applyTransformation(tr) self.initialConfArray = copy.deepcopy(self.trajectory.universe.configuration().array) if self.architecture != 'monoprocessor': # The attribute trajectory is removed because it can not be pickled by Pyro. delattr(self, 'trajectory')
def getReference(gr, atom_list, verbose=0): """ for given group of atoms construct Configuration object containing reference posiotion for each atom in the group """ verbose = 1 universe = gr.universe() # update in group make-up reference = Configuration(universe, cell=universe.cellParameters()) group = Collection() for atom in gr.atomList(): try: idx = atom_list.index(atom) reference[atom] = atom_list[idx].position() group.addObject(atom) except ValueError: # not in list if verbose > 0: print 'Warning: nMoldyn.misc.getReference' print 'Matching problem' print atom if group.numberOfAtoms() == 0: print 'Error: No reference atoms found' reference = None group = gr return group, reference
def parsePDBAtomSelection(filename, traj): univ = traj.universe pdb = PDBConfiguration(filename) # find objects in UNIV and PDB with the same number of atoms total = 0 pdb_index = 0 pdb_collection = {} for object in range(len(univ)): natom = len(univ[object].atomList()) pdb_natom = 0 while pdb_natom < natom: pdb_object = pdb.objects[pdb_index] if dir(pdb_object).count('atom_list') == 1: # no groups try: pdb_collection[object].append(pdb_object) except KeyError: pdb_collection[object] = [pdb_object] pdb_natom = pdb_natom + len(pdb_object.atom_list) # chains ? elif dir(pdb_object).count('residues') == 1: # biopolymers for residue in pdb_object.residues: try: pdb_collection[object].append(residue) except KeyError: pdb_collection[object] = [residue] pdb_natom = pdb_natom + len(residue.atom_list) pdb_index = pdb_index + 1 if pdb_natom != natom: return None ######### ERROR # match PDBMAP names from UNIV against PDB atom names # and add selected atoms to the collection selection = [] for object in range(len(univ)): pdbmap = [] if univ[object].__class__.__name__ == 'Protein': for chain in univ[object].chains: for residue in chain[0]: pdbmap.append(residue) elif univ[object].__class__.__name__ == 'Molecule': pdbmap.append(univ[object]) for item in range(len(pdbmap)): pdb_item = pdb_collection[object][item] atom_list = pdbmap[item].atomList() if upper(pdbmap[item].pdbmap[0][0]) != upper(pdb_item.name): return None ######### ERROR for ia in pdb_item.atoms.keys(): atom = pdb_item.atoms[ia] if atom.properties['element'] == '*': anum = pdbmap[item].pdbmap[0][1][ia].number atra = atom_list[anum] selection.append(atra) return Collection(selection)
def finalize(self): """Finalizes the calculations (e.g. averaging the total term, output files creations ...). """ if self.architecture == 'monoprocessor': t = self.trajectory else: # Load the whole trajectory set. t = Trajectory(None, self.trajectoryFilename, 'r') comsUniverse = t.universe.__copy__() comsUniverse.removeObject(comsUniverse.objectList()[:]) orderedAtoms = sorted(t.universe.atomList(), key = operator.attrgetter('index')) groups = [Collection([orderedAtoms[ind] for ind in g]) for g in self.group] comp = 1 for g in groups: comAtom = Atom('H', name = 'COM'+str(comp)) comAtom._mass = g.mass() comsUniverse.addObject(comAtom) comp += 1 # traj_new is the filtered trajectory outputFile = Trajectory(comsUniverse, self.output, "w") outputFile.jobinfo = self.information + '\nOutput file written on: %s\n\n' % asctime() # Each time |snapshot| is called, the universe contents i flushed into the output file. snapshot = SnapshotGenerator(comsUniverse,\ actions = [TrajectoryOutput(outputFile, ["configuration","time"], 0, None, 1)]) # Loop over the output frames. for comp in range(self.nFrames): frameIndex = self.frameIndexes[comp] t.universe.setFromTrajectory(t, frameIndex) comsUniverse.setCellParameters(t.universe.cellParameters()) aComp = 0 for at in comsUniverse.atomList(): at.setPosition(self.comsTrajectory[frameIndex][aComp]) aComp += 1 snapshot(data = {'time': self.times[comp]}) # The output COM trajectory is closed. outputFile.close() self.toPlot = None
def selectAtoms(self, condition): """ Return a collection containing all atoms a for which condition(property[a]) is True. :param condition: a test function :type condition: callable """ from MMTK.Collections import Collection return Collection( [a for a in self.universe.atomList() if condition(self[a])])
def finalize(self): """Finalizes the calculations (e.g. averaging the total term, output files creations ...). """ if self.architecture == 'monoprocessor': t = self.trajectory else: # Load the whole trajectory set. t = Trajectory(None, self.trajectoryFilename, 'r') orderedAtoms = sorted(t.universe.atomList(), key = operator.attrgetter('index')) selectedAtoms = Collection([orderedAtoms[ind] for ind in self.subset]) targetAtoms = Collection([orderedAtoms[ind] for ind in self.target]) # traj_new is the filtered trajectory outputFile = Trajectory(targetAtoms, self.output, "w") outputFile.jobinfo = self.information + '\nOutput file written on: %s\n\n' % asctime() # Create the snapshot generator snapshot = SnapshotGenerator(t.universe, actions = [TrajectoryOutput(outputFile, ["configuration"], 0, None, 1)]) # Loop over the output frames. for comp in range(self.nFrames): frameIndex = self.frameIndexes[comp] t.universe.setFromTrajectory(t, frameIndex) for at in targetAtoms: at.setPosition(Vector(self.filteredTrajectory[frameIndex][at.index])) snapshot(data = {'time': self.times[comp]}) outputFile.close() t.close() self.toPlot = None
def getMethyls(molecule): al = molecule.atomList() result = [] for atom in al: if atom.symbol == 'C': h = 0 al2 = atom.bondedTo() for at2 in al2: if at2.symbol == 'H': h = h + 1 if h == 3: # find a complete pdbmap within a one of parent groups object = atom.parent try: res_name = object.pdbmap[0][0] except AttributeError: res_name = '' # an atom can belong only to one residue while len(res_name) == 0: object = object.parent try: res_name = object.pdbmap[0] except AttributeError: pass atom_number = object.atomList().index(atom) aindex = 0 pdbmap = {} for key in object.pdbmap[0][1].keys(): if object.pdbmap[0][1][key].number == atom_number: pdbmap[key] = AtomReference(aindex) break aindex = aindex + 1 meth = [atom] for at2 in al2: if at2.symbol == 'H': meth.append(at2) atom_number = object.atomList().index(at2) for key in object.pdbmap[0][1].keys(): if object.pdbmap[0][1][key].number == atom_number: pdbmap[key] = AtomReference(aindex) break aindex = aindex + 1 myCollection = Collection(meth) myCollection.pdbmap = [(res_name, pdbmap)] result.append(myCollection) return result
def getTypes(universe): types = {} for io in range(len(universe)): object = universe[io] if object.__class__.__name__ == 'Protein': name = 'Protein.' + str(io) elif object.__class__.__name__ == 'AtomCluster': name = object.name else: name = object.type.name try: collection = types[name] except KeyError: collection = Collection() collection.addObject(object) types[name] = collection return types
def calc(self, frameIndex, trajectory): """Calculates the contribution for one frame. @param frameIndex: the index of the frame. @type frameIndex: integer. @param trajectory: the trajectory. @type trajectory: MMTK.Trajectory.Trajectory object """ trajectory.universe.setFromTrajectory(trajectory, frameIndex) orderedAtoms = sorted(trajectory.universe.atomList(), key = operator.attrgetter('index')) groups = [Collection([orderedAtoms[ind] for ind in g]) for g in self.group] centersOfMass = [g.centerOfMass() for g in groups] return frameIndex, centersOfMass
def ghostBusters(atoms): """ apply filtering to an atom List and return collection having no repetitions of atoms using a histogram-like approach """ unique = {} ghost = 'No' for atom in atoms.atomList(): try: unique[atom] = unique[atom] + 1 ghost = 'Yes' except: unique[atom] = 1 if ghost == 'Yes': atsel = [] for atom in unique.keys(): if unique[atom] > 1: atsel.append(atom) else: atsel = unique.keys() atomsNew = Collection(atsel) return atomsNew
def getProteinBackbone(protein): result = [] for chain in protein.chains: for residue in chain[0]: if dir(residue).count('peptide') > 0: # terminal NHE... resmap = residue.pdbmap res_name = resmap[0][0] bb = residue.backbone().atomList() pdbmap = {} for atom in range(len(bb)): atom_number = residue.atomList().index(bb[atom]) ikey = (map(lambda x: x.number, resmap[0][1].values()))\ .index(atom_number) pdbmap[resmap[0][1].keys()[ikey]] = AtomReference(atom) myCollection = Collection(bb) myCollection.pdbmap = [(res_name, pdbmap)] result.append(myCollection) return result
def interpreteInputParameters(self): """Parse the input parameters for the analysis. """ # Parses the parameters that are common to different analysis. Analysis.interpreteInputParameters(self) self.buildTimeInfo() self.subset = self.selectAtoms(self.subsetDefinition) self.nSelectedAtoms = len(self.subset) orderedAtoms = sorted(self.trajectory.universe.atomList(), key = operator.attrgetter('index')) selectedAtoms = Collection([orderedAtoms[ind] for ind in self.subset]) # traj_new is the filtered trajectory self.outputFile = Trajectory(selectedAtoms, self.output, "w") # Create the snapshot generator self.snapshot = SnapshotGenerator(self.trajectory.universe, actions = [TrajectoryOutput(self.outputFile, ["all"], 0, None, 1)])
def calc(self, atomIndexes, trajectory): """Calculates the contribution for one group. @param atomIndexes: the index of the atoms of the group. @type atomIndexes: list of integers. @param trajectory: the trajectory. @type trajectory: MMTK.Trajectory.Trajectory object """ orderedAtoms = sorted(trajectory.universe.atomList(), key=operator.attrgetter('index')) group = Collection([orderedAtoms[ind] for ind in atomIndexes]) angvel = getAngularVelocity(trajectory,\ group,\ self.frameIndexes,\ self.dt,\ self.stepwiseRBT,\ self.referenceFrame,\ self.differentiation) return atomIndexes, angvel
def parseGroupSelection(types, group_dict, refer_dict, verbose=0): if len(group_dict) == 2: groups = [{}, {}] reference = [{}, {}] else: groups = [{}] reference = [{}] for ngr in range(len(group_dict)): for title in group_dict[ngr].keys(): master = split(title) if len(master) == 2: # Proteins mol = types[master[0]][0] if master[1] == 'All': groups[ngr][title] = [types[master[0]]] try: filename = refer_dict[ngr][title]['*'] # possible extension here: define a RE pattern # (instead of '*') to make sub-selection (res-numbers, etc.) if filename: info = parsePDBReference(filename, [mol], verbose=verbose) reference[ngr][title] = \ Collection(info['PDB']).atomList() else: reference[ngr][title] = None except: reference[ngr][title] = None elif master[1] == 'SideChain': # SideChain selection was intentionaly made more flexible: # we're picking whole residues (not sidechain attribute) # to be able to define either parts of real sidechains # (aromatic rings,...), # or, for example, select also C_alpha atoms # This means that after entering real calculations # atoms in a group has to be filtered out according to # make-up of the reference structure (if the latter one is # set to None, then use sidechain attribute and use first # configuration as a reference) pat = getResidues(mol) groups[ngr][title] = [] for ia in group_dict[ngr][title]: if ia == '*': for g in pat.values(): groups[ngr][title] = groups[ngr][title] + g break else: groups[ngr][title] = groups[ngr][title] + pat[ia] reference[ngr][title] = [] try: for ia in refer_dict[ngr][title].keys(): filename = refer_dict[ngr][title][ia] if filename: info = parsePDBReference(filename, pat[ia], verbose=verbose) reference[ngr][title] = reference[ngr][title]+\ Collection(info['PDB']).atomList() except: reference[ngr][title] = None elif master[1] == 'BackBone': pat = getProteinBackbone(mol) groups[ngr][title] = pat try: filename = refer_dict[ngr][title]['*'] if filename: info = parsePDBReference(filename, pat, verbose=verbose) reference[ngr][title] = \ Collection(info['PDB']).atomList() else: reference[ngr][title] = None except: reference[ngr][title] = None elif master[1] == 'Methyl': pat = getMethyls(mol) groups[ngr][title] = pat try: filename = refer_dict[ngr][title]['*'] if filename: info = parsePDBReference(filename, pat, verbose=verbose) reference[ngr][title] = \ Collection(info['PDB']).atomList() else: reference[ngr][title] = None except: reference[ngr][title] = None else: # Molecules groups[ngr][title] = types[master[0]].objects try: filename = refer_dict[ngr][title]['*'] if filename: info = parsePDBReference(filename, groups[ngr][title], verbose=verbose) reference[ngr][title] = \ Collection(info['PDB']).atomList() else: reference[ngr][title] = None except: reference[ngr][title] = None return groups, reference
def calc(self, frameIndex, trajectory): """Calculates the contribution for one group. @param frameIndex: the index of the frame in |self.frameIndexes| array. @type frameIndex: integer. @param trajectory: the trajectory. @type trajectory: MMTK.Trajectory.Trajectory object """ trajectory.universe.setFromTrajectory(trajectory, frameIndex) directCell = N.ravel( N.array([v for v in trajectory.universe.basisVectors()], typecode=N.Float)) reverseCell = N.ravel( N.transpose( N.array( [v for v in trajectory.universe.reciprocalBasisVectors()], typecode=N.Float))) S2 = {} chemicalObjects = trajectory.universe.objectList() for comp in range(self.nChemicalObjects): obj = chemicalObjects[comp] objName = self.chemicalObjectNames[comp] if self.chemicalObjectInfo[objName]['objectclass'] in [ 'PeptideChain', 'Protein' ]: S2[objName] = N.zeros((53, ), typecode=N.Float) S2[objName] = N.zeros((len(self.sequence[objName]), ), typecode=N.Float) for v in range(len(self.hnLookup[objName])): aa_no = self.hnLookup[objName][v] aa_no_minus = aa_no - 1 H = obj.backbone()[aa_no].H O = obj.backbone()[aa_no_minus].O heavyAtoms = Collection() for m in range(len(obj.residues())): if (m != aa_no) and (m != aa_no_minus): for atom in obj.residues()[m].atomList(): if atom.symbol != 'H': heavyAtoms.addObject(atom) # The indexes of the selected atoms. indexes = N.zeros((heavyAtoms.numberOfAtoms(), ), typecode=N.Int32) comp = 0 for at in heavyAtoms.atomList(): indexes[comp] = at.index comp += 1 scaleconfig = N.zeros((3 * heavyAtoms.numberOfAtoms(), ), typecode=N.Float) val = order_parameter(trajectory.universe.contiguousObjectConfiguration().array,\ H.index, O.index, directCell, reverseCell, indexes,\ scaleconfig, self.scaleHydrogenPos, self.scaleOxygenPos,\ Units.Ang) S2[objName][v] = val return frameIndex, S2
chains = pdb_conf1.createNucleotideChains() molecule_names = [] if len(chains) >= 2: clist = findContacts(chains[0], chains[1]) else: molecule_names = [] for (key, mol) in pdb_conf1.molecules.items(): for o in mol: molecule_names.append(o.name) targets = pdb_conf1.createAll(molecule_names=molecule_names) if len(molecule_names) > 1: clist = findContacts(targets[0], targets[1]) else: atoms = targets.atomList() mid = len(atoms) / 2 clist = findContacts(Collection(atoms[:mid]), Collection(atoms[mid:])) print len(clist), 'contacts' for c in clist[:8]: print '%-64s %6.2f' % (c, c.dist / Units.Ang) else: target = pdb_conf1.createAll() if sys.argv[1][:2] == '-v': (a, v) = target.surfaceAndVolume() print 'surface area %.2f volume %.2f' \ % (a/(Units.Ang**2), v/(Units.Ang**3)) elif sys.argv[1][:2] == '-a': smap = target.surfaceAtoms(probe_radius=1.4 * Units.Ang) print len(smap.keys()), 'of', len( target.atomList()), 'atoms on surface' elif sys.argv[1][:2] == '-p':
def calc(self, atomIndexes, trajectory): """Calculates the contribution for one group. @param atomIndexes: the index of the atoms of the group. @type atomIndexes: list of integers. @param trajectory: the trajectory. @type trajectory: MMTK.Trajectory.Trajectory object """ orderedAtoms = sorted(trajectory.universe.atomList(), key=operator.attrgetter('index')) group = Collection([orderedAtoms[ind] for ind in atomIndexes]) rbtPerGroup = {} # Those matrix will store the quaternions and the CMS coming from the RBT trajectory. rbtPerGroup['quaternions'] = N.zeros((self.nFrames, 4), typecode=N.Float) rbtPerGroup['com'] = N.zeros((self.nFrames, 3), typecode=N.Float) rbtPerGroup['fit'] = N.zeros((self.nFrames, ), typecode=N.Float) rbtPerGroup['trajectory'] = {} # Case of a moving reference. if self.stepwiseRBT: # The reference configuration is always the one of the previous frame excepted for the first frame # where it is set by definition to the first frame (could we think about a cyclic alternative way ?). for comp in range(self.nFrames): frameIndex = self.frameIndexes[comp] if comp == 0: previousFrame = self.firstFrame else: previousFrame = self.frameIndexes[comp - 1] refConfig = trajectory.configuration[previousFrame] # The RBT is created just for the current step. rbt = trajectory.readRigidBodyTrajectory(group,\ first = frameIndex,\ last = frameIndex + 1,\ skip = 1,\ reference = refConfig) # The corresponding quaternions and cms are stored in their corresponding matrix. rbtPerGroup['quaternions'][comp, :] = copy.copy( rbt.quaternions) rbtPerGroup['com'][comp, :] = copy.copy(rbt.cms) rbtPerGroup['fit'][comp] = copy.copy(rbt.fit) # The simplest case, the reference frame is fixed. # A unique RBT is performed from first to last skipping skip steps and using refConfig as the reference. else: # If a fixed reference has been set. We can already set the reference configuration here. refConfig = trajectory.configuration[self.referenceFrame] # The RBT is created. rbt = trajectory.readRigidBodyTrajectory(group,\ first = self.first,\ last = self.last,\ skip = self.skip,\ reference = refConfig) # The corresponding quaternions and cms are stored in their corresponding matrix. rbtPerGroup['quaternions'] = copy.copy(rbt.quaternions) rbtPerGroup['com'] = copy.copy(rbt.cms) rbtPerGroup['fit'] = copy.copy(rbt.fit) # I can not use the centers of mass defined by rbt.cms because the reference frame # selected can be out of the selected frames for the Rigid Body Trajectory. centerOfMass = group.centerOfMass(refConfig) # Loop over the atoms of the group to set the RBT trajectory. for atom in group: rbtPerGroup['trajectory'][atom.index] = N.zeros((self.nFrames, 3), typecode=N.Float) # The coordinates of the atoms are centered around the center of mass of the group. xyz = refConfig[atom] - centerOfMass # Loop over the selected frames. for comp in range(self.nFrames): # The rotation matrix corresponding to the selected frame in the RBT. transfo = Quaternion( rbtPerGroup['quaternions'][comp, :]).asRotation() if self.removeTranslation: # The transformation matrix corresponding to the selected frame in the RBT. transfo = Translation(centerOfMass) * transfo # Compose with the CMS translation if the removeTranslation flag is set off. else: # The transformation matrix corresponding to the selected frame in the RBT. transfo = Translation(Vector( rbtPerGroup['com'][comp, :])) * transfo # The RBT is performed on the CMS centered coordinates of atom at. rbtPerGroup['trajectory'][atom.index][comp, :] = transfo( Vector(xyz)) return atomIndexes, rbtPerGroup
def finalize(self): """Finalizes the calculations (e.g. averaging the total term, output files creations ...). """ if self.architecture == 'monoprocessor': t = self.trajectory else: # Load the whole trajectory set. t = Trajectory(None, self.trajectoryFilename, 'r') selectedAtoms = Collection() orderedAtoms = sorted(t.universe.atomList(), key=operator.attrgetter('index')) groups = [[ selectedAtoms.addObject(orderedAtoms[index]) for index in atomIndexes ] for atomIndexes in self.group] # Create trajectory outputFile = Trajectory(selectedAtoms, self.output, 'w') # Create the snapshot generator snapshot = SnapshotGenerator( t.universe, actions=[ TrajectoryOutput(outputFile, ["configuration", "time"], 0, None, 1) ]) # The output is written for comp in range(self.nFrames): frameIndex = self.frameIndexes[comp] t.universe.setFromTrajectory(t, frameIndex) for atom in selectedAtoms: atom.setPosition(self.RBT['trajectory'][atom.index][comp, :]) snapshot(data={'time': self.times[comp]}) outputFile.close() outputFile = NetCDFFile(self.output, 'a') outputFile.title = self.__class__.__name__ outputFile.jobinfo = self.information + '\nOutput file written on: %s\n\n' % asctime( ) outputFile.jobinfo += 'Input trajectory: %s\n\n' % self.trajectoryFilename outputFile.createDimension('NFRAMES', self.nFrames) outputFile.createDimension('NGROUPS', self.nGroups) outputFile.createDimension('QUATERNIONLENGTH', 4) # The NetCDF variable that stores the quaternions. QUATERNIONS = outputFile.createVariable( 'quaternion', N.Float, ('NGROUPS', 'NFRAMES', 'QUATERNIONLENGTH')) # The NetCDF variable that stores the centers of mass. COM = outputFile.createVariable('com', N.Float, ('NGROUPS', 'NFRAMES', 'xyz')) # The NetCDF variable that stores the rigid-body fit. FIT = outputFile.createVariable('fit', N.Float, ('NGROUPS', 'NFRAMES')) # Loop over the groups. for comp in range(self.nGroups): aIndexes = self.group[comp] outputFile.jobinfo += 'Group %s: %s\n' % ( comp + 1, [index for index in aIndexes]) QUATERNIONS[comp, :, :] = self.RBT[comp]['quaternions'][:, :] COM[comp, :, :] = self.RBT[comp]['com'][:, :] FIT[comp, :] = self.RBT[comp]['fit'][:] outputFile.close() self.toPlot = None
def calc(self, atomIndexes, trajectory): """Calculates the contribution for one group. @param atomIndexes: the index of the atoms of the group. @type atomIndexes: list of integers. @param trajectory: the trajectory. @type trajectory: MMTK.Trajectory.Trajectory object """ orderedAtoms = sorted(trajectory.universe.atomList(), key=operator.attrgetter('index')) group = Collection([orderedAtoms[ind] for ind in atomIndexes]) j, m, n = self.wignerIndexes # Those matrix will store the quaternions and the CMS coming from the RBT trajectory. quaternions = N.zeros((self.nFrames, 4), typecode=N.Float) # Case of a moving reference. if self.stepwiseRBT: # The reference configuration is always the one of the previous frame excepted for the first frame # where it is set by definition to the first frame (could we think about a cyclic alternative way ?). for comp in range(self.nFrames): frameIndex = self.frameIndexes[comp] if comp == 0: previousFrame = self.firstFrame else: previousFrame = self.frameIndexes[comp - 1] refConfig = trajectory.configuration[previousFrame] # The RBT is created just for the current step. rbt = trajectory.readRigidBodyTrajectory(group,\ first = frameIndex,\ last = frameIndex + 1,\ skip = 1,\ reference = refConfig) # The corresponding quaternions and cms are stored in their corresponding matrix. quaternions[comp, :] = copy.copy(rbt.quaternions) # The simplest case, the reference frame is fixed. # A unique RBT is performed from first to last skipping skip steps and using refConfig as the reference. else: # If a fixed reference has been set. We can already set the reference configuration here. refConfig = trajectory.configuration[self.referenceFrame] # The RBT is created. rbt = trajectory.readRigidBodyTrajectory(group,\ first = self.first,\ last = self.last,\ skip = self.skip,\ reference = refConfig) quaternions = rbt.quaternions # c1 is the scaling factor converting Wigner function into spherical harmonics. It depends only on j. c1 = N.sqrt(((2.0 * j + 1) / (4.0 * N.pi))) quat2 = N.zeros(quaternions.shape, typecode=N.Complex) # quat2[:,0] refers to the (q0+iq3) of equation 3.55 quat2[:, 0] = quaternions[:, 0] + 1j * quaternions[:, 3] # quat2[:,2] refers to the (q2+iq1) of equation 3.55 quat2[:, 2] = quaternions[:, 2] + 1j * quaternions[:, 1] # quat2[:,1] refers to the (q0-iq3) of equation 3.55 quat2[:, 1] = N.conjugate(quat2[:, 0]) # quat2[:,3] refers to the (q2-iq1) of equation 3.55 quat2[:, 3] = N.conjugate(quat2[:, 2]) pp = self.preparePP(j, m, n) Djmn = N.add.reduce( N.multiply.reduce(quat2[:, N.NewAxis, :]**pp[0][N.NewAxis, :, :], -1) * pp[1], 1) if m == n: Djnm = Djmn else: pp = self.preparePP(j, n, m) Djnm = N.add.reduce( N.multiply.reduce( quat2[:, N.NewAxis, :]**pp[0][N.NewAxis, :, :], -1) * pp[1], 1) Djmn = Djmn * c1 Djnm = Djnm * c1 return atomIndexes, (Djmn, Djnm)
def parsePDBReference(filename, pattern, verbose=None): """ for a given filename of a PDB file match atoms against objects in a list <pattern> """ pdb = PDBConfiguration(filename) if verbose: print 'A quick look into an MMTK pattern reveals ', print 'the presence of\n\t', len(pattern), print ' atom collections ready to be matched' tokens = getTokens(filename) if len(tokens) > 0 and verbose: print 'RE pattern defined in your PDB file: ' print tokens pdb_collection = {} for object in range(len(pattern)): natom = pattern[object].numberOfAtoms() pdb_natom = 0 for pdb_object in pdb.objects: if hasattr(pdb_object, 'atom_list'): gj = 0 for atom in pdb_object.atom_list: if atom.properties['element'] == '*': gj = gj + 1 if gj > 0: try: pdb_collection[object].append(pdb_object) except KeyError: pdb_collection[object] = [pdb_object] pdb_natom = pdb_natom + gj if hasattr(pdb_object, 'residues'): for residue in pdb_object.residues: gj = 0 for atom in residue.atom_list: if atom.properties['element'] == '*': gj = gj + 1 if gj > 0: try: pdb_collection[object].append(residue) except KeyError: pdb_collection[object] = [residue] pdb_natom = pdb_natom + gj if pdb_natom < natom: print 'Warning: fewer atoms in PDB for object:', print pattern[object] elif pdb_natom > natom: print 'ERROR: the number of atoms does not match' print object, len(pattern), len(pdb.objects) print pattern[object].atomList() print pdb_natom, pdb_collection[object] return None selection = [] for object in range(len(pattern)): coll = [] pdbmap = [] type_name = pattern[object].__class__.__name__ if verbose: print '\n\nPROCESSING ', pattern[object], print ' of type: ', type_name print '----------\n' if type_name == 'Protein': for chain in pattern[object].chains: for residue in chain[0]: pdbmap.append(residue) elif type_name == 'SubChain': for residue in pattern[object]: pdbmap.append(residue) elif type_name == 'Residue' or type_name == 'Molecule' or \ type_name == 'Collection': pdbmap.append(pattern[object]) if type_name == 'Protein' or type_name == 'SubChain' or\ type_name == 'Residue': for it in range(len(pdbmap)): pdb_item = pdb_collection[object][it] atom_list = pdbmap[it].atomList() res_list = [] for ia in pdbmap[it].pdbmap: res_list.append(ia[0]) res_list = map(upper, res_list) if res_list.count(upper(pdb_item.name)) == 0: print 'ERROR: problem with matching' print pdb_item.name, res_list return None for ia in pdb_item.atoms.keys(): atom = pdb_item.atoms[ia] if atom.properties['element'] == '*': anum = pdbmap[it].pdbmap[0][1][ia].number atra = atom_list[anum] oldpos = atra.position() atra.setPosition(atom.position / 10.) newpos = atra.position() coll.append(atra) if verbose: quickCheck(pdb_item, atom, atra, oldpos, newpos) selection.append(Collection(coll)) elif type_name == 'Molecule' or type_name == 'Collection': for it in range(len(pdb_collection[object])): pdb_item = pdb_collection[object][it] atom_list = pdbmap[0].atomList() res_list = [] gj = 0 for ia in pdbmap[0].pdbmap: if evalREPattern(pdb_item.name, upper(ia[0]), tokens): gj = 1 break if not gj: print 'ERROR: problem with matching' return None atname_list = pdb_item.atoms.keys() for ia in range(len(atname_list)): atom = pdb_item.atoms[atname_list[ia]] if atom.properties['element'] == '*' and \ evalREPattern(pdb_item.name, upper(pdbmap[0].pdbmap[it][0]),tokens): mmtk_map = pdbmap[0].pdbmap[it][1] for ib in mmtk_map.keys(): #if evalREPattern(atname_list[ia],ib,tokens): if atname_list[ia] == ib: aname = ib break anum = pdbmap[0].pdbmap[it][1][aname].number atra = atom_list[anum] oldpos = atra.position() atra.setPosition(atom.position / 10.) newpos = atra.position() coll.append(atra) if verbose: quickCheck(pdb_item, atom, atra, oldpos, newpos) selection.append(Collection(coll)) info = {'MMTK': pattern, 'PDB': selection} if verbose: print len(Collection(selection).atomList()), print 'MMTK atoms in ', len(pattern), 'objects', print 'were mapped successfully on PDB atoms in file ', filename return info
def finalize(self): """Finalizes the calculations (e.g. averaging the total term, output files creations ...). """ if self.architecture == 'monoprocessor': t = self.trajectory else: # Load the whole trajectory set. t = Trajectory(None, self.trajectoryFilename, 'r') orderedAtoms = sorted(t.universe.atomList(), key=operator.attrgetter('index')) groups = [ Collection([orderedAtoms[ind] for ind in g]) for g in self.group ] # 'freqencies' = 1D Numeric array. Frequencies at which the DOS was computed frequencies = N.arange(self.nFrames) / (2.0 * self.nFrames * self.dt) # The NetCDF output file is opened for writing. outputFile = NetCDFFile(self.output, 'w') outputFile.title = self.__class__.__name__ outputFile.jobinfo = self.information + '\nOutput file written on: %s\n\n' % asctime( ) # Dictionnary whose keys are of the form Gi where i is the group number # and the entries are the list of the index of the atoms building the group. comp = 1 for g in self.group: outputFile.jobinfo += 'Group %d: %s\n' % (comp, [index for index in g]) comp += 1 # Some dimensions are created. outputFile.createDimension('NFRAMES', self.nFrames) # Creation of the NetCDF output variables. # The time. TIMES = outputFile.createVariable('time', N.Float, ('NFRAMES', )) TIMES[:] = self.times[:] TIMES.units = 'ps' # The resolution function. RESOLUTIONFUNCTION = outputFile.createVariable('resolution_function', N.Float, ('NFRAMES', )) RESOLUTIONFUNCTION[:] = self.resolutionFunction[:] RESOLUTIONFUNCTION.units = 'unitless' # Creation of the NetCDF output variables. # The frequencies. FREQUENCIES = outputFile.createVariable('frequency', N.Float, ('NFRAMES', )) FREQUENCIES[:] = frequencies[:] FREQUENCIES.units = 'THz' OMEGAS = outputFile.createVariable('angular_frequency', N.Float, ('NFRAMES', )) OMEGAS[:] = 2.0 * N.pi * frequencies[:] OMEGAS.units = 'rad ps-1' avacfTotal = N.zeros((self.nFrames), typecode=N.Float) adosTotal = N.zeros((self.nFrames), typecode=N.Float) comp = 1 totalMass = 0.0 for g in groups: AVACF = outputFile.createVariable('avacf-group%s' % comp, N.Float, ('NFRAMES', )) AVACF[:] = self.AVACF[comp][:] AVACF.units = 'rad^2*ps^-2' N.add(avacfTotal, self.AVACF[comp], avacfTotal) ADOS = outputFile.createVariable('ados-group%s' % comp, N.Float, ('NFRAMES', )) ADOS[:] = self.ADOS[comp][:] ADOS.units = 'rad^2*ps^-1' N.add(adosTotal, g.mass() * self.ADOS[comp], adosTotal) comp += 1 totalMass += g.mass() adosTotal *= 0.5 * self.dt / (self.nGroups * totalMass) AVACF = outputFile.createVariable('avacf-total', N.Float, ('NFRAMES', )) AVACF[:] = avacfTotal AVACF.units = 'rad^2*ps^-2' ADOS = outputFile.createVariable('ados-total', N.Float, ('NFRAMES', )) ADOS[:] = adosTotal ADOS.units = 'rad^2*ps^-1' asciiVar = sorted(outputFile.variables.keys()) outputFile.close() self.toPlot = { 'netcdf': self.output, 'xVar': 'angular_frequency', 'yVar': 'ados-total' } # Create an ASCII version of the NetCDF output file. convertNetCDFToASCII(inputFile = self.output,\ outputFile = os.path.splitext(self.output)[0] + '.cdl',\ variables = asciiVar)
def inputFileRead(filename): """ read and process an input file """ keywords = [ 'trajectory', 'output_files', 'title', 'time_info', 'time_steps', 'frequency_points', 'q_vector_set', 'deuter', 'projection_vector', 'reference', 'rotation_coefficients', 'ft_window', 'groups', 'weights', 'atoms', 'units_length', 'units_frequency', 'log_file', 'groups_code', 'atoms_code', 'filter_window', 'results_file', 'atoms_pdb', 'differentiation', 'verbose', 'symbols', 'ar_order', 'ar_precision' ] newvars = {} file_text = Utility.readURL(filename) exec file_text in vars(sys.modules['__builtin__']), newvars input = Quidam() for key in keywords: if newvars.has_key(key): setattr(input, key, newvars[key]) else: setattr(input, key, None) import os print os.getcwd() print input.trajectory # # general settings # if input.trajectory: if len(input.trajectory) == 1: traj = Trajectory(None, input.trajectory[0], 'r') if traj.variables().count('quaternion') > 0: traj = qTrajectory(None, input.trajectory[0], 'r') elif len(input.trajectory) > 1: traj = TrajectorySet(None, input.trajectory) if not input.units_length: input.units_length = Units.nm if not input.units_frequency: input.units_frequency = Units.tera * Units.Hz types = getTypes(traj.universe) if input.q_vector_set is None: input.q_vector_set = (N.arange(0., 100., 2.), 1., 50) # default if input.time_info is None: input.time_info = (0, len(traj), 1) qVectors = qVectorGenerator(input.q_vector_set, traj) # # Substitute Hydrogen atoms with Deuter? # if input.deuter: collection = Collection() for i in input.deuter.keys(): for ia in input.deuter[i]: gj = getChemicalObjects({i: types[i]}, {i: ia}) collection.addObject(gj) h2d = collection.atomList() print 'number of Deuter atoms: ', len(h2d) # # Atom selection related keywords # atoms selected in a different way are stored together # and filtered at the end (if there're repetitions only # atoms which occur many times are stored and passed to # further calculations, else all atoms are passed) # if input.atoms: print 'processing atom selection:\n\t', input.atoms collection = [] for i in input.atoms.keys(): for ia in input.atoms[i]: typs = {} typs[i] = types[i] vlst = {} vlst[i] = ia gj = getChemicalObjects(typs, vlst) collection = collection + gj.atomList() input.atoms = collection print '\t...done\n\tstored ', len(input.atoms), ' atoms\n' if input.atoms_pdb: print 'processing atom selection from a PDB file\n\t(', print input.atoms_pdb, '):' atoms_add = parsePDBAtomSelection(input.atoms_pdb, traj) print '\t...done\n\tstored ', len(atoms_add.atomList()), ' atoms\n' if input.atoms: input.atoms = input.atoms + atoms_add.atomList() else: input.atoms = atoms_add.atomList() if input.atoms_code: print 'processing atom selection hardcoded in Python' # syntax: # def atoms_code(traj,nothing,dummy_a='gj') # # a python code here # return Collection(atom_list) # # atoms_code is a function object whose first argument is # a Trajectory object and which returns a Collection object. print '...done\n\tstored ', len(input.atoms_code(traj).atomList()), print ' atoms' if input.atoms: input.atoms = input.atoms + input.atoms_code(traj).atomList() else: input.atoms = input.atoms_code(traj).atomList() if not input.atoms: print ' No atom selection found, taking everything... just in case' input.atoms = traj.universe else: input.atoms = Collection(input.atoms) input.atoms = ghostBusters(input.atoms) print ' # atoms in selection: ', len(input.atoms.atomList()) # # Group selection # if input.groups: input.groups, input.reference = parseGroupSelection( types, input.groups, input.reference, verbose=input.verbose) if input.groups_code: # previous def (if any) overwritten # the result returned by groups_code should be consistent # with that one from misc.paresGroupSelection input.groups, input.reference = input.groups_code(traj) # # Another piece of general settings # if input.weights == 'mass': weightsList = MassList(traj.universe, input.atoms) elif input.weights == 'incoherent': if input.deuter: weightsList = BincohList(traj.universe, input.atoms, h2d) else: weightsList = BincohList(traj.universe, input.atoms) elif input.weights == 'coherent': if input.deuter: weightsList = BcohList(traj.universe, input.atoms, h2d) else: weightsList = BcohList(traj.universe, input.atoms) else: weightsList = None # input.trajectory = (traj, input.trajectory) input.trajectory = traj input.q_vector_set = qVectors input.weights = weightsList return input
def internalRun(self): """Runs the analysis.""" self.chrono = default_timer() orderedAtoms = sorted(self.universe.atomList(), key = operator.attrgetter('index')) selectedAtoms = Collection([orderedAtoms[ind] for ind in self.subset]) M1_2 = N.zeros((3*self.nSelectedAtoms,), N.Float) weightList = [N.sqrt(el[1]) for el in sorted([(at.index, at.mass()) for at in selectedAtoms])] for i in range(len(weightList)): M1_2[3*i:3*(i+1)] = weightList[i] invM1_2 = (1.0/M1_2)*N.identity(3*self.nSelectedAtoms, typecode = N.Float) # The initial structure configuration. initialStructure = self.trajectory.configuration[self.first] averageStructure = ParticleVector(self.universe) for conf in self.trajectory.configuration[self.first:self.last:self.skip]: averageStructure += self.universe.configurationDifference(initialStructure, conf) averageStructure = averageStructure/self.nFrames averageStructure = initialStructure + averageStructure mdr = N.zeros((self.nFrames, 3*self.nSelectedAtoms), N.Float) # Calculate the fluctuation matrix. sigmaPrim = N.zeros((3*self.nSelectedAtoms, 3*self.nSelectedAtoms), N.Float) comp = 0 for conf in self.trajectory.configuration[self.first:self.last:self.skip]: mdr[comp,:] = M1_2*N.ravel(N.compress(self.mask,(conf-averageStructure).array,0)) sigmaPrim += mdr[comp,:, N.NewAxis] * mdr[N.NewAxis, comp, :] comp += 1 sigmaPrim = sigmaPrim/float(self.nFrames) try: # Calculate the quasiharmonic modes omega, dx = Heigenvectors(sigmaPrim) except MemoryError: raise Error('Not enough memory to diagonalize the %sx%s fluctuation matrix.' % sigmaPrim.shape) # Due to numerical imprecisions, the result can have imaginary parts. # In that case, throw the imaginary parts away. # Conversion from uma*nm2 to kg*m2 (SI) omega = omega.real/(Units.kg*Units.m**2) omega = (Units.Hz/Units.invcm)*N.sqrt((Units.k_B*Units.K*self.temperature/Units.J)*(1.0/omega)) dx = dx.real dx = N.dot(invM1_2, dx) # Sort eigen vectors by decreasing fluctuation amplitude. indices = N.argsort(omega)[::-1] omega = N.take(omega, indices) dx = N.take(dx, indices) # Eq 66 of the reference paper. mdr = N.take(mdr, indices, axis = 1) at = N.dot(mdr,N.transpose(dx)) # The NetCDF output file is opened. outputFile = NetCDFFile(self.output, 'w') outputFile.title = self.__class__.__name__ outputFile.jobinfo = self.information + '\nOutput file written on: %s\n\n' % asctime() # The universe is emptied from its objects keeping just its topology. self.universe.removeObject(self.universe.objectList()[:]) # The atoms of the subset are copied atoms = copy.deepcopy(selectedAtoms.atomList()) # And their parent attribute removed to allow their transfer in the empty universe. for a in atoms: a.parent = None ac = AtomCluster(atoms,name='QHACluster') self.universe.addObject(ac) # Some dimensions are created. # NEIVALS = the number eigen values outputFile.createDimension('NEIGENVALS', len(omega)) # UDESCR = the universe description length outputFile.createDimension('UDESCR', len(self.universe.description())) # NATOMS = the number of atoms of the universe outputFile.createDimension('NATOMS', self.nSelectedAtoms) # NFRAMES = the number of frames. outputFile.createDimension('NFRAMES', self.nFrames) # NCOORDS = the number of coordinates (always = 3). outputFile.createDimension('NCOORDS', 3) # 3N. outputFile.createDimension('3N', 3*self.nSelectedAtoms) if self.universe.cellParameters() is not None: outputFile.createDimension('BOXDIM', len(self.universe.cellParameters())) # Creation of the NetCDF output variables. # EIVALS = the eigen values. OMEGA = outputFile.createVariable('omega', N.Float, ('NEIGENVALS',)) OMEGA[:] = omega # EIVECS = array of eigen vectors. DX = outputFile.createVariable('dx', N.Float, ('NEIGENVALS','NEIGENVALS')) DX[:,:] = dx # The time. TIMES = outputFile.createVariable('time', N.Float, ('NFRAMES',)) TIMES[:] = self.times[:] TIMES.units = 'ps' # MODE = the mode number. MODE = outputFile.createVariable('mode', N.Float, ('3N',)) MODE[:] = 1 + N.arange(3*self.nSelectedAtoms) # LCI = local character indicator. See eq 56. LCI = outputFile.createVariable('local_character_indicator', N.Float, ('3N',)) LCI[:] = (dx**4).sum(0) # GCI = global character indicator. See eq 57. GCI = outputFile.createVariable('global_character_indicator', N.Float, ('3N',)) GCI[:] = (N.sqrt(3.0*self.nSelectedAtoms)/(N.absolute(dx)).sum(0))**4 # Projection of MD traj onto normal modes. See eq 66.. AT = outputFile.createVariable('at', N.Float, ('NFRAMES','3N')) AT[:,:] = at[:,:] # DESCRIPTION = the universe description. DESCRIPTION = outputFile.createVariable('description', N.Character, ('UDESCR',)) DESCRIPTION[:] = self.universe.description() # AVGSTRUCT = the average structure. AVGSTRUCT = outputFile.createVariable('avgstruct', N.Float, ('NATOMS','NCOORDS')) AVGSTRUCT[:,:] = N.compress(self.mask,averageStructure.array,0) # If the universe is periodic, create an extra variable storing the box size. if self.universe.cellParameters() is not None: BOXSIZE = outputFile.createVariable('box_size', N.Float, ('BOXDIM',)) BOXSIZE[:] = self.universe.cellParameters() outputFile.close() self.toPlot = None self.chrono = default_timer() - self.chrono return None
from MMTK.ForceFields import Amber94ForceField import sys pdb = sys.argv[1] test = Protein(pdb) universe = InfiniteUniverse(Amber94ForceField()) universe.addObject(test) print universe.energy() print universe.charges() for i in universe.energyTerms(): print i, ":", print universe.energyTerms()[i] from MMTK.Collections import Collection c = Collection(test) print "Collection numberOfAtoms:", c.numberOfAtoms() from MMTK.Collections import GroupOfAtoms #g = GroupOfAtoms (test) #print "angular moment:", test.angularMomentum() print "charge :", universe.charge() print "degrees of freedom :", universe.degreesOfFreedom() print "dipole moment:", universe.dipole() #print "kinetic energy :", test.kineticEnergy() print "mas :", universe.mass() #print "momentum :", g.momentum() print " GroupOfAtoms numberOfAtoms:", universe.numberOfAtoms() #print " temperature:", universe.temperature ()