class SequenceShiftPredictPopup(BasePopup): """ **Predict Protein Shifts from Sequence** This popup window is designed to allow the prediction of chemical shifts for a protein chain from the sequence (so with no structural information), using the (external) program CamCoil. The Options to select are the Chain for which the prediction is made, and the prediction type and the pH used for the prediction, and also the Shift List, which is not used for the prediction but is used for the comparison with the prediction. CamCoil has two variations, one for the prediction of random coil chemical shifts and one for prediction of protein loops chemical shifts. The Chemical Shift Predictions table lists the atoms in the chain. For each atom the data listed is the residue number, residue type, atom name, first shift found for that atom in the chosen shiftList, chemical shift predicted by CamCoil, and the difference between the actual shift and the predicted shift (if both exist). To run the prediction click on the "Run CamCoil Prediction!" button. This does not store any predicted shifts in the project. **Caveats & Tips** **References** The CamCoil programme: http://www-vendruscolo.ch.cam.ac.uk/camcoil.php *A. De Simone, A. Cavalli, S-T. D. Hsu, W. Vranken and M. Vendruscolo Accurate random coil chemical shifts from an analysis of loop regions in native states of proteins. J. Am. Chem. Soc. 131(45):16332-3 """ def __init__(self, parent, *args, **kw): self.chain = None self.shiftList = None self.predictionDict = {} BasePopup.__init__( self, parent=parent, title='Data Analysis : Predict Shifts from Sequence') def body(self, guiFrame): self.geometry('700x500') guiFrame.expandGrid(1, 0) row = 0 # TOP LEFT FRAME frame = LabelFrame(guiFrame, text='Options') frame.grid(row=row, column=0, sticky='nsew') frame.columnconfigure(7, weight=1) label = Label(frame, text='Chain') label.grid(row=0, column=0, sticky='w') self.chainPulldown = PulldownList( frame, callback=self.changeChain, tipText='Choose the molecular system chain to make predictions for' ) self.chainPulldown.grid(row=0, column=1, sticky='w') label = Label(frame, text='Shift List') label.grid(row=0, column=2, sticky='w') self.shiftListPulldown = PulldownList( frame, callback=self.changeShiftList, tipText='Select the shift list to take input chemical shifts from') self.shiftListPulldown.grid(row=0, column=3, sticky='w') label = Label(frame, text='Type') label.grid(row=0, column=4, sticky='w') self.scriptPulldown = PulldownList( frame, texts=SCRIPT_TEXTS, callback=self.changeScript, tipText='Select the algorithm script for this chain') self.scriptPulldown.grid(row=0, column=5, sticky='w') self.pHLabel = Label(frame, text='pH') self.pHLabel.grid(row=0, column=6, sticky='w') self.pHPulldown = PulldownList( frame, texts=SCRIPT_PHS, tipText='Select the pH to make the prediction for') self.pHPulldown.grid(row=0, column=7, sticky='w') row += 1 # BOTTOM LEFT FRAME frame = LabelFrame(guiFrame, text='Chemical Shift Predictions') frame.grid(row=row, column=0, sticky='nsew') frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(0, weight=1) tipTexts = [ 'Residue number in chain', 'Residue type code', 'Atom name', 'Actual shift (first one it finds for atom in chosen shiftList)', 'CamCoil predicted shift', 'Predicted - Actual' ] headingList = [ 'Res\nNum', 'Res\nType', 'Atom\nName', 'Actual\nShift', 'Predicted\nShift', 'Difference' ] n = len(headingList) editWidgets = n * [None] editGetCallbacks = n * [None] editSetCallbacks = n * [None] self.predictionMatrix = ScrolledMatrix( frame, headingList=headingList, tipTexts=tipTexts, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks) self.predictionMatrix.grid(row=0, column=0, sticky='nsew') row += 1 tipTexts = [ 'Run the CamCoil method to predict chemical shifts from sequence' ] texts = ['Run CamCoil Prediction!'] commands = [self.runCamCoil] self.buttonList = createDismissHelpButtonList(guiFrame, texts=texts, commands=commands, help_url=self.help_url, expands=True, tipTexts=tipTexts) self.buttonList.grid(row=row, column=0) self.update() self.notify(self.registerNotify) def destroy(self): self.notify(self.unregisterNotify) BasePopup.destroy(self) def notify(self, notifyfunc): for func in ('__init__', 'delete'): notifyfunc(self.updateChainPulldown, 'ccp.molecule.MolSystem.Chain', func) for func in ('setValue', ): notifyfunc(self.updatePredictionMatrixAfter, 'ccp.nmr.Nmr.Shift', func) def update(self): self.updateShiftListPulldown() self.updateChainPulldown() self.updatePredictionMatrixAfter() def runCamCoil(self): chain = self.chain script = self.scriptPulldown.getText() if script == LFP_SCRIPT: pH = '' else: pH = self.pHPulldown.getText() if not chain: showError('Cannot Run CamCoil', 'Please specify a chain.', parent=self) return self.predictionDict[chain] = runCamCoil(chain, pH=pH, script=script) self.updatePredictionMatrix() def updatePredictionMatrixAfter(self, index=None, text=None): self.after_idle(self.updatePredictionMatrix) def updatePredictionMatrix(self): objectList = [] textMatrix = [] chain = self.chain shiftList = self.shiftList if chain: atomShiftDict = self.predictionDict.get(chain, {}) for residue in chain.sortedResidues(): for atom in residue.sortedAtoms(): currShift = shiftList and findFirstAtomShiftInShiftList( atom, shiftList) value = currShift and currShift.value predShift = atomShiftDict.get(atom) if currShift and predShift: delta = predShift - value else: delta = None data = [ residue.seqCode, residue.ccpCode, atom.name, value, predShift, delta ] textMatrix.append(data) objectList.append(atom) self.predictionMatrix.update(textMatrix=textMatrix, objectList=objectList) def changeChain(self, chain): if chain is not self.chain: self.chain = chain self.updatePredictionMatrixAfter() def changeShiftList(self, shiftList): if shiftList is not self.shiftList: self.shiftList = shiftList self.updatePredictionMatrixAfter() def changeScript(self, script): if script == LFP_SCRIPT: self.pHLabel.grid_forget() self.pHPulldown.grid_forget() else: self.pHLabel.grid(row=0, column=6, sticky='w') self.pHPulldown.grid(row=0, column=7, sticky='w') def updateChainPulldown(self, obj=None): index = 0 names = [] chains = [] chain = self.chain for molSystem in self.project.molSystems: msCode = molSystem.code for chainA in molSystem.chains: residues = chainA.residues if not residues: continue for residue in residues: # Must have at least one protein residue if residue.molType == 'protein': names.append('%s:%s' % (msCode, chainA.code)) chains.append(chainA) break if chains: if chain not in chains: chain = chains[0] index = chains.index(chain) else: chain = None if chain is not self.chain: self.chain = chain self.updatePredictionMatrixAfter() self.chainPulldown.setup(names, chains, index) def updateShiftListPulldown(self, obj=None): index = 0 names = [] shiftLists = getShiftLists(self.nmrProject) if shiftLists: if self.shiftList not in shiftLists: self.shiftList = shiftLists[0] index = shiftLists.index(self.shiftList) names = ['%s:%d' % (sl.name, sl.serial) for sl in shiftLists] else: self.shiftList = None self.shiftListPulldown.setup(names, shiftLists, index)