def redo(self): self.helix = Helix(self.currentChainModel, self.predHelix.serialNo, self.predHelix.label, self.startIndex, self.stopIndex) self.currentChainModel.addHelix(self.predHelix.serialNo, self.helix) self.helix.setAxisPoints(self.coord1, self.coord2) helixCoordList = helixEndpointsToCAlphaPositions( self.coord1, self.coord2) ''' #To see the ends of the helical axis as green and red atoms startAtom = PDBAtom('AAAA', 'A', 100000, 'CA') startAtom.setPosition(Vector3DFloat(*coord1)) startAtom.setColor(0, 1, 0, 1) startAtom = self.CAlphaViewer.renderer.addAtom(startAtom) stopAtom = startAtom = PDBAtom('AAAA', 'A', 100001, 'CA') stopAtom.setPosition(Vector3DFloat(*coord2)) stopAtom.setColor(1, 0, 0, 1) stopAtom = self.CAlphaViewer.renderer.addAtom(stopAtom) ''' for i in range( min(len(helixCoordList), self.stopIndex - self.startIndex + 1)): pos = helixCoordList[i] residue = self.currentChainModel[self.startIndex + i] rawAtom = residue.addAtom('CA', pos[0], pos[1], pos[2], 'C') atom = self.CAlphaViewer.renderer.addAtom(rawAtom) residue.addAtomObject(atom) atom.setSelected(True) try: prevAtom = self.currentChainModel[self.startIndex + i - 1].getAtom('CA') bond = PDBBond() bond.setAtom0Ix(prevAtom.getHashKey()) bond.setAtom1Ix(atom.getHashKey()) self.CAlphaViewer.renderer.addBond(bond) except (KeyError, IndexError, AttributeError): continue try: nextAtom = self.currentChainModel[self.startIndex + len(helixCoordList)] bond = PDBBond() bond.setAtom0Ix(atom.getHashKey()) bond.setAtom1Ix(nextAtom.getHashKey()) self.CAlphaViewer.renderer.addBond(bond) except (KeyError, IndexError, AttributeError): pass self.currentChainModel.setSelection( newSelection=range(self.startIndex, 1 + self.stopIndex)) if not self.CAlphaViewer.loaded: self.CAlphaViewer.loaded = True self.CAlphaViewer.emitModelLoaded() else: self.CAlphaViewer.emitModelChanged()
class CAlphaStructureEditorCommandPlaceHelix(QtGui.QUndoCommand): def __init__(self, currentChainModel, predHelix, startIndex, stopIndex, coord1, coord2, structureEditor, structurePrediction, description=None): super(CAlphaStructureEditorCommandPlaceHelix, self).__init__(description) self.currentChainModel = currentChainModel self.predHelix = predHelix self.startIndex = startIndex self.stopIndex = stopIndex self.coord1 = coord1 self.coord2 = coord2 self.structureEditor = structureEditor self.structurePrediction = structurePrediction self.CAlphaViewer = self.structureEditor.CAlphaViewer def redo(self): self.helix = Helix(self.currentChainModel, self.predHelix.serialNo, self.predHelix.label, self.startIndex, self.stopIndex) self.currentChainModel.addHelix(self.predHelix.serialNo, self.helix) self.helix.setAxisPoints(self.coord1, self.coord2) helixCoordList = helixEndpointsToCAlphaPositions(self.coord1, self.coord2) ''' #To see the ends of the helical axis as green and red atoms startAtom = PDBAtom('AAAA', 'A', 100000, 'CA') startAtom.setPosition(Vector3DFloat(*coord1)) startAtom.setColor(0, 1, 0, 1) startAtom = self.CAlphaViewer.renderer.addAtom(startAtom) stopAtom = startAtom = PDBAtom('AAAA', 'A', 100001, 'CA') stopAtom.setPosition(Vector3DFloat(*coord2)) stopAtom.setColor(1, 0, 0, 1) stopAtom = self.CAlphaViewer.renderer.addAtom(stopAtom) ''' for i in range(min(len(helixCoordList), self.stopIndex - self.startIndex + 1)): pos = helixCoordList[i] residue = self.currentChainModel[self.startIndex+i] rawAtom = residue.addAtom('CA', pos[0], pos[1], pos[2], 'C') atom = self.CAlphaViewer.renderer.addAtom(rawAtom) residue.addAtomObject(atom) atom.setSelected(True) try: prevAtom = self.currentChainModel[self.startIndex+i-1].getAtom('CA') bond = PDBBond() bond.setAtom0Ix(prevAtom.getHashKey()) bond.setAtom1Ix(atom.getHashKey()) self.CAlphaViewer.renderer.addBond(bond) except (KeyError, IndexError, AttributeError): continue try: nextAtom = self.currentChainModel[self.startIndex+len(helixCoordList)] bond = PDBBond() bond.setAtom0Ix(atom.getHashKey()) bond.setAtom1Ix(nextAtom.getHashKey()) self.CAlphaViewer.renderer.addBond(bond) except (KeyError, IndexError, AttributeError): pass self.currentChainModel.setSelection(newSelection = range(self.startIndex, 1+self.stopIndex)) if not self.CAlphaViewer.loaded: self.CAlphaViewer.loaded = True self.CAlphaViewer.emitModelLoaded() else: self.CAlphaViewer.emitModelChanged() def undo(self): for resNum in range(self.startIndex, 1+self.stopIndex): try: atom = self.currentChainModel[resNum].getAtom('CA') except (KeyError, IndexError, AttributeError): atom = None if atom: try: atomBefore = self.currentChainModel[resNum-1].getAtom('CA') except (KeyError, IndexError, AttributeError): atomBefore = None if atomBefore: bondBeforeIx = self.CAlphaViewer.renderer.getBondIndex(atomBefore.getHashKey(), atom.getHashKey()) if bondBeforeIx != -1: self.CAlphaViewer.renderer.deleteBond(bondBeforeIx) try: atomAfter = self.currentChainModel[resNum+1].getAtom('CA') except (KeyError, IndexError, AttributeError): atomAfter = None if atomAfter: bondAfterIx = self.CAlphaViewer.renderer.getBondIndex(atomAfter.getHashKey(), atom.getHashKey()) if bondAfterIx != -1: self.CAlphaViewer.renderer.deleteBond(bondAfterIx) for resNum in range(self.startIndex, 1+self.stopIndex): try: atom = self.currentChainModel[resNum].getAtom('CA') except (IndexError, AttributeError, KeyError): continue self.CAlphaViewer.renderer.deleteAtom(atom.getHashKey()) self.currentChainModel[resNum].clearAtom('CA') self.currentChainModel.removeSecel(self.helix) if not self.CAlphaViewer.loaded: self.CAlphaViewer.loaded = True self.CAlphaViewer.emitModelLoaded() else: self.CAlphaViewer.emitModelChanged()
def __loadFromPDB(cls, filename, qparent=None, whichChainID=None): ''' This loads the specified chain ID from a PDF file and returns a Chain object. If no chain ID is specified, it loads the first chain. ''' #print Chain.getChainKeys() if qparent and qtEnabled: result = Chain('', qparent=qparent) else: result = Chain('') header = open(filename, 'U') headerLine = header.read() if headerLine[:6] == 'HEADER': pdbID = headerLine[62:66] else: pdbID = cls.__createUniquePDBID() header.close() residue = None firstChain = None for line in open( filename, 'U' ): #calls the iterator for the file object each time the loop is run - don't have to load entire file into memory if line[0:4] == 'ATOM': chainID = line[21:22] if chainID == ' ': chainID = 'A' if whichChainID and chainID != whichChainID: #Search for the specified chainID (if one is specified), otherwise we find the first chain. continue if not firstChain: #Sets the value of the first and only chain we will store firstChain = chainID ####if the chain key already exists, point to that chain object ####perhaps this should be modified if not (pdbID, firstChain) in cls.getChainKeys(): result.setIDs(pdbID, firstChain) else: result = cls.getChain((pdbID, firstChain)) break if firstChain and chainID != firstChain: #If we've gone past the only chain we want to store, we will break out of the for loop break residueIndex = int(line[22:26]) if residueIndex not in result.residueRange(): residue = Residue(line[17:20].strip(), result) result[residueIndex] = residue else: residue = result[residueIndex] serialNo = int(line[6:11].strip()) atomName = line[12:16].strip() element = line[76:78].strip() try: tempFactor = float(line[60:66].strip()) except ValueError: tempFactor = None try: occupancy = float(line[54:60].strip()) except ValueError: occupancy = None try: x = float(line[30:38]) y = float(line[38:46]) z = float(line[46:54]) atom = residue.addAtom(atomName, x, y, z, element, serialNo, occupancy, tempFactor) #residue.atoms[atomName]=atom result.atoms[serialNo] = atom #Chain.chainsDict[result.key] = result except ValueError: print 'Chain.__loadFromPDB--no coordinates', elif line[0:6].strip() == 'HELIX': Helix.parsePDB(line, result, whichChainID) elif line[0:6].strip() == 'SHEET': Sheet.parsePDB(line, result, whichChainID) for sheetIndex, sheet in result.sheets.items(): validBonds = [] for bond in sheet.bonds: if bond[0] in result.residueRange( ) and bond[1] in result.residueRange(): validBonds.append(bond) sheet.bonds = validBonds #Setting up coils startList = [] endList = [] for secelIx, secel in result.secelList.items(): startList.append(secel.startIndex) endList.append(secel.stopIndex) startList.sort() endList.sort() if result.residueRange(): startPt = min(result.residueRange()) coilIx = 1 for i in range(len(startList)): if startPt < startList[i]: result.addCoil( coilIx, Coil(result, coilIx, 'L' + str(coilIx), startPt, startList[i] - 1)) coilIx = coilIx + 1 startPt = endList[i] + 1 if startPt < max(result.residueRange()): result.addCoil( coilIx, Coil(result, coilIx, 'L' + str(coilIx), startPt, max(result.residueRange()))) Chain.chainsDict[result.key] = result #Chain.setSelectedChainKey(result.getIDs()) return result
def __loadFromSeq(cls, filename, qparent=None): ''' Sequence files are a file type we defined. The first line gives the one-letter abbreviations for the sequence. The line below it shows the predicted secondary structure element for each residue as "H" for helix, "E" for strand, and "-" otherwise. Ex 1: GAPCSTLARFKEI HHHHHH--EEEE Ex 2: START 45 SAPQRVPELYC EEEHHHHHH- The first line may give a start residue (useful for post-translational modifications). That line will be interpreted and removed. Linebreaks are then removed. Finally, the first half of the remaining characters are interpreted as sequence, and the second half are treated as structure predictions. ''' F = open(filename) lines = [] for line in F: line = line.strip() lines.append(line) if lines[0][:5].upper() == 'START': firstLine = lines.pop(0) startIndex = int(firstLine.split()[-1]) print startIndex else: startIndex = 1 stopIndex = None lines = ''.join(lines) linesSize = len(lines) try: assert (linesSize % 2 == 0) except: "The file does not have an equal number of reisdues and secondary structure indicators." sequence = lines[:(linesSize // 2)] print sequence structure = lines[(linesSize // 2):] print structure if startIndex == 1: newChain = Chain(sequence, qparent) else: newChain = Chain('', qparent) n = 0 for char in sequence: newChain[startIndex + n] = Residue(char, newChain) n += 1 helix = 'H' strand = 'E' coil = '-' elementNum, helixSerialNum, strandSerialNum, coilSerialNum = 1, 1, 1, 1 currentElement = structure[0] assert currentElement in (helix, strand, coil) i = startIndex + 1 for character in structure[1:]: if character: assert character in (helix, strand, coil) if character == currentElement: i += 1 #continue #redundant right now else: stopIndex = i - 1 if currentElement == helix: newHelix = Helix(chain=newChain, serialNo=helixSerialNum, label='H' + str(elementNum), startIndex=startIndex, stopIndex=stopIndex) newChain.addHelix(serialNo=helixSerialNum, helix=newHelix) helixSerialNum += 1 elementNum += 1 elif currentElement == strand: newStrand = Strand(chain=newChain, strandNo=strandSerialNum, label='S' + str(elementNum), startIndex=startIndex, stopIndex=stopIndex) newChain.addStrand(strand=newStrand, strandNo=strandSerialNum) strandSerialNum += 1 elementNum += 1 elif currentElement == coil: newCoil = Coil(chain=newChain, serialNo=coilSerialNum, label='Coil', startIndex=startIndex, stopIndex=stopIndex) else: pass startIndex = i stopIndex = None currentElement = character i += 1 return newChain
def load(cls, filename, qparent=None, withStrands=0): ''' Sequence files are a file type we defined. The first line gives the one-letter abbreviations for the sequence. The line below it shows the predicted secondary structure element for each residue as "H" for helix, "E" for strand, and "-" otherwise. Ex 1: GAPCSTLARFKEI HHHHHH--EEEE Ex 2: START 45 SAPQRVPELYC EEEHHHHHH- The first line may give a start residue (useful for post-translational modifications). That line will be interpreted and removed. Linebreaks are then removed. Finally, the first half of the remaining characters are interpreted as sequence, and the second half are treated as structure predictions. The actual file reading and interpreting is handled in C++. ''' print "StructurePrediction.load called. cls = " + str(cls) + ", filename = " + str(filename) + "qparent = " + str(qparent) #secelIndex=0 secelDict={} secelType={} params=None comments=None if filename.split('.')[-1].lower() == 'seq': # data is a c++ SEQReader object data = SeqReader.loadFile(filename) startIndex = data.getStartResNo() sequence = data.getSequenceString() if startIndex == 1: chain = Chain(sequence, qparent) else: chain = Chain('', qparent) n = 0 for char in sequence: chain[startIndex+n] = Residue(char, chain) n += 1 numSSEs = data.getNumberOfStructures() for sseIx in range(numSSEs): # cppSse is a c++ SecondaryStructure object cppSse = data.getStructure(sseIx) if cppSse.isHelix(): # create python Helix object using info from c++ SecondaryStructure object pyHelix = Helix(chain, sseIx, str(cppSse.getSecondaryStructureID()), cppSse.getStartPosition(), cppSse.getEndPosition()) secelDict[sseIx] = pyHelix secelType[sseIx] = 'helix' elif cppSse.isSheet(): # create python strand object using info from c++ SecondaryStructure object pyStrand = Strand(chain, sseIx, str(cppSse.getSecondaryStructureID()), cppSse.getStartPosition(), cppSse.getEndPosition()) secelDict[sseIx] = pyStrand secelType[sseIx] = 'strand' pass # create new python StructurePrediction object and return it return StructurePrediction(secelDict, chain, params, comments, qparent, secelType) elif filename.split('.')[-1].lower() == 'pdb': # create python chain object using the python pdb file loader method chain = Chain.load(filename, qparent) i = 0 #for helixKey in chain.helices.keys(): # print "helixKey " + str(helixKey) # secelDict[i] = chain.helices[helixKey] # i += 1 #print "done adding helices. i=" + str(i) # #for sheetKey in chain.sheets.keys(): # print "sheetKey " + str(sheetKey) # for strandKey in chain.sheets[sheetKey].strandList.keys(): # print "strandKey " + str(strandKey) # secelDict[i] = chain.sheets[sheetKey].strandList[strandKey] # # self.sheets[sheetID].strandList[strandNo]=strand # #secelDict[i] = chain.sheets[sheetKey] # i += 1 #print "done adding sheets. i=" + str(i) # create secelDict from chain #for index in chain.residueRange()[::-1]: # if chain.residueList[index] is inputRes: # return index lastSecel = -1; #iterate over all secels. sort is needed because chain.secelList is a dict for index in sorted(chain.secelList): if chain.secelList[index] == lastSecel: pass #print "same as last secel at " + str(index) + " (" + str(chain.secelList[index]) + ")" else: #print "found new secel " + str(index) #+ " (" + str(chain.secelList[index]) + ")" if chain.secelList[index].type == 'helix': #print "helix at index " + str(index) secelDict[i] = chain.secelList[index] secelType[i] = 'helix' lastSecel = chain.secelList[index] i += 1 if chain.secelList[index].type == 'strand' and withStrands == 1: #print "strand at index " + str(index) secelDict[i] = chain.secelList[index] secelType[i] = 'strand' lastSecel = chain.secelList[index] i += 1 #chain.helices = {} #chain.sheets = {} #chain.secelList = {} #chain.orphanStrands = {} #chain.atoms = {} for resIndex in chain.residueRange(): chain[resIndex].clearAtoms() # create new python StructurePrediction object and return it return StructurePrediction(secelDict, chain, params, comments, qparent, secelType)