class WriteBmrbChemShiftDepPopup(BasePopup): help_url = joinPath(getHelpUrlDir(), 'WriteBmrbChemShiftDep.html') def __init__(self, parent, project): self.project = project self.guiParent = parent self.selectedFormats = [] self.defaultText = 'Select file' self.chainDict = {} self.chainList = [] self.shiftListDict = {} self.shiftLists = [] for shiftList in self.project.currentNmrProject.findAllMeasurementLists( className='ShiftList'): if shiftList.measurements != (): label = str(shiftList.serial) + ':' + str(shiftList.name) self.shiftListDict[label] = shiftList self.shiftLists.append(label) if not self.shiftLists: showError('Error', 'No shift lists available!') return BasePopup.__init__(self, parent=parent, title="Project '%s': " % project.name + 'Write BMRB chemical shift deposition file', modal=False, transient=True) def body(self, master): row = 0 label = Label(master, text="BMRB chemical shift deposition file writer.") label.grid(row=row, column=0, columnspan=2, sticky=Tkinter.W) row += 1 label = Label(master, text="Shift lists:") label.grid(row=row, column=0, sticky=Tkinter.W) self.shiftListSelect = PulldownMenu(master, entries=self.shiftLists, callback=self.setChainList, do_initial_callback=False) self.shiftListSelect.grid(row=row, column=1, sticky=Tkinter.EW) row += 1 label = Label(master, text="Chains (only one per file):") label.grid(row=row, column=0, sticky=Tkinter.W) self.chainListSelect = PulldownMenu(master, entries=self.chainList) self.chainListSelect.grid(row=row, column=1, sticky=Tkinter.EW) self.setChainList(0, self.shiftLists[0]) row += 1 label = Label(master, text="Chemical shift deposition file:") label.grid(row=row, column=0, sticky=Tkinter.W) self.fileButton = Tkinter.Button(master, text=self.defaultText, command=self.selectFile) self.fileButton.grid(row=row, column=1, sticky=Tkinter.W) row += 1 texts = ['Write file'] commands = [ self.ok ] # This calls 'ok' in BasePopup, this then calls 'apply' in here buttons = createDismissHelpButtonList(master, texts=texts, commands=commands, help_url=self.help_url) buttons.grid(row=row, columnspan=2, column=0) def setChainList(self, shiftListIndex, shiftListLabel): # # Has to be done... very slow this. # shiftList = self.shiftListDict[shiftListLabel] self.chainDict = {} self.chainList = [] for shift in shiftList.measurements: if shift.resonance: rs = shift.resonance.resonanceSet if rs: atom = rs.findFirstAtomSet().findFirstAtom() chain = atom.residue.chain if chain not in self.chainDict.values(): label = chain.molSystem.code + ":'" + chain.code + "'" self.chainDict[label] = chain self.chainList.append(label) self.chainListSelect.clearMenuItems() if self.chainList: self.chainListSelect.setup(self.chainList, 0) def selectFile(self): fileName = self.fileButton.__getitem__('text') if fileName == self.defaultText: fileName = 'bmrb.csdep' popup = FormatFilePopup(self, file=fileName, component='csdep', format='bmrb') if popup.fileSelected: self.fileButton.config(text=popup.file) popup.destroy() def apply(self): shiftListLabel = self.shiftListSelect.getSelected() shiftList = self.shiftListDict[shiftListLabel] try: chainLabel = self.chainListSelect.getSelected() chain = self.chainDict[chainLabel] except: showError( "No chains", "No chains were present or selected. Try running linkResonances first." ) return False fileName = self.fileButton.__getitem__('text') if fileName == self.defaultText: return False fileCreated = writeBmrbChemShiftDeposition(self.guiParent, chain, shiftList, fileName) if fileCreated: showInfo("Success", "Succesfully wrote chemical shift deposition file") else: showError("Not written", "Error writing file %s. File not written" % fileName) return False return True
class CloudHomologueAssignPopup(BasePopup): def __init__(self, parent, *args, **kw): self.guiParent = parent self.project = parent.getProject() self.molSystem = None self.chain = None self.assignment = None self.scores = [] BasePopup.__init__(self, parent, title="Cloud Threader", **kw) def body(self, guiFrame): guiFrame.grid_columnconfigure(3, weight=1) row = 0 label = Label(guiFrame, text='Molecular system: ') label.grid(row=row, column=0, sticky=Tkinter.NW) self.molSysPulldown = PulldownMenu(guiFrame, self.changeMolSystem, selected_index=-1, do_initial_callback=0) self.molSysPulldown.grid(row=row, column=1, sticky=Tkinter.NW) label = Label(guiFrame, text='Clouds files: ') label.grid(row=row, column=2, sticky=Tkinter.NW) self.filenameEntry = Entry(guiFrame,text='perfect00.pdb') self.filenameEntry.grid(row=row, column=3, sticky=Tkinter.NW) row += 1 label = Label(guiFrame, text='Chain: ') label.grid(row=row, column=0, sticky=Tkinter.NW) self.chainPulldown = PulldownMenu(guiFrame, self.changeChain, selected_index=-1, do_initial_callback=0) self.chainPulldown.grid(row=row, column=1, sticky=Tkinter.NW) label = Label(guiFrame, text='Thread steps: ') label.grid(row=row, column=2, sticky=Tkinter.NW) self.numStepsEntry = IntEntry(guiFrame,text=3000) self.numStepsEntry.grid(row=row, column=3, sticky=Tkinter.NW) row += 1 label = Label(guiFrame, text='Homologue PDB file: ') label.grid(row=row, column=0, sticky=Tkinter.NW) self.pdbEntry = Entry(guiFrame,text='') self.pdbEntry.grid(row=row, column=1, sticky=Tkinter.NW) label = Label(guiFrame, text='Dist. Threshold: ') label.grid(row=row, column=2, sticky=Tkinter.NW) self.distEntry = FloatEntry(guiFrame,text=3.0) self.distEntry.grid(row=row, column=3, sticky=Tkinter.NW) row += 1 label = Label(guiFrame, text='Global score: ') label.grid(row=row, column=0, sticky=Tkinter.NW) self.globalScoreLabel = Label(guiFrame, text='') self.globalScoreLabel.grid(row=row, column=1, sticky=Tkinter.NW) label = Label(guiFrame, text='Assignment Threshold: ') label.grid(row=row, column=2, sticky=Tkinter.NW) self.thresholdEntry = FloatEntry(guiFrame,text=-4.5) self.thresholdEntry.grid(row=row, column=3, sticky=Tkinter.NW) row += 1 guiFrame.grid_rowconfigure(row, weight=1) self.graph = ScrolledGraph(guiFrame, width=300, height=200) self.graph.grid(row=row, column=0, columnspan=4, sticky = Tkinter.NSEW) row += 1 texts = ['Run','Assign!'] commands = [self.run, self.assignSpinSystems] bottomButtons = createDismissHelpButtonList(guiFrame,texts=texts,commands=commands,expands=0,help_url=None) bottomButtons.grid(row=row, column=0, columnspan=4, sticky=Tkinter.EW) self.assignButton = bottomButtons.buttons[1] for func in ('__init__','delete'): Implementation.registerNotify(self.updateMolSystems, 'ccp.molecule.MolSystem.MolSystem', func) Implementation.registerNotify(self.updateChains, 'ccp.molecule.MolSystem.Chain', func) self.updateMolSystems() self.updateChains() def update(self): if self.assignment and self.scores: self.assignButton.enable() else: self.assignButton.disable() def run(self): if self.chain: pattern = self.filenameEntry.get() nSteps = self.numStepsEntry.get() or 4000 pdbFile = self.pdbEntry.get() dist = self.distEntry.get() or 3.0 pgb = ProgressBar(self, text='Searching', total=nSteps) files = getFileNamesFromPattern(pattern , '.') if not files: return clouds = getCloudsFromFile(files, self.chain.root) score, self.scores, self.assignment = cloudHomologueAssign(self.chain, clouds, pdbFile, dist, nSteps, self.graph, pgb) pgb.destroy() self.globalScoreLabel.set(str(score)) self.update() def assignSpinSystems(self): if self.assignment and self.scores: if showWarning('Query','Are you sure?'): threshold = self.thresholdEntry.get() or -4.0 i = 0 for residue in self.assignment.keys(): if self.scores[residue] > threshold: spinSystem = self.assignment[residue] assignSpinSystemResidue(spinSystem,residue=None) for residue in self.assignment.keys(): if self.scores[residue] > threshold: i += 1 spinSystem = self.assignment[residue] assignSpinSystemResidue(spinSystem,residue=residue) showWarning('Done','%d residues assigned' % i) def getMolSystems(self): names = [] for molSystem in self.project.molSystems: if molSystem.chains: names.append( '%s' % (molSystem.code) ) return names def changeMolSystem(self, i, name): self.molSystem = self.project.findFirstMolSystem(code=name) def updateMolSystems(self, *opt): names = self.getMolSystems() if names: if not self.molSystem: self.molSystem = self.project.findFirstMolSystem(code=names[0]) self.molSysPulldown.setup(names, names.index(self.molSystem.code)) def getChains(self): chains = [] if self.molSystem: for chain in self.molSystem.chains: chains.append( [chain.code, chain] ) return chains def changeChain(self, i, name=None): if not name: i = self.chainPulldown.selected_index chains = self.getChains() if chains: self.chain = chains[i][1] def updateChains(self, *chain): chains = self.getChains() if chains: names = [x[0] for x in chains] if (not self.chain) or (self.chain.code not in names): self.chain = chains[0][1] self.chainPulldown.setup(names, names.index(self.chain.code) ) self.update() def destroy(self): for func in ('__init__','delete'): Implementation.unregisterNotify(self.updateMolSystems, 'ccp.molecule.MolSystem.MolSystem', func) Implementation.unregisterNotify(self.updateChains, 'ccp.molecule.MolSystem.Chain', func) BasePopup.destroy(self)
class EditNoeClassesPopup(BasePopup): def __init__(self, parent, *args, **kw): self.guiParent = parent BasePopup.__init__(self, parent=parent, title='NOE Distance Classes', **kw) def body(self, guiFrame): self.noeClassChoice = None self.spectrum = None self.intensEntry = FloatEntry(self, returnCallback=self.setIntens, width=5) self.targetEntry = FloatEntry(self, returnCallback=self.setTarget, width=5) self.minEntry = FloatEntry(self, returnCallback=self.setMin, width=5) self.maxEntry = FloatEntry(self, returnCallback=self.setMax, width=5) row = 0 label = Label(guiFrame, text='Spectrum: ', grid=(row,0)) tipText = '' self.spectrumPulldown = PulldownMenu(guiFrame,self.changeSpectrum, grid=(row,1)) row +=1 guiFrame.expandGrid(row, 1) tipTexts = ['Lower bound of this intensity category. Values are relative to reference intensity.', 'Target restraint distance for this category', 'Lower bound distance for this category', 'Upper bound distance for this category'] headingList = ['Min. NOE\nIntensity','Target\nDist','Min\nDist','Max\nDist'] editWidgets = [self.intensEntry,self.targetEntry,self.minEntry,self.maxEntry] editGetCallbacks = [self.getIntens,self.getTarget,self.getMin,self.getMax] editSetCallbacks = [self.setIntens,self.setTarget,self.setMin,self.setMax] self.noeClassMatrix = ScrolledMatrix(guiFrame, headingList=headingList, callback=self.selectClass, tipTexts=tipTexts, editWidgets=editWidgets, editSetCallbacks=editSetCallbacks, editGetCallbacks=editGetCallbacks, deleteFunc=self.deleteClass, grid=(row,0), gridSpan=(1,2)) row +=1 tipTexts = ['Add a new distance restraint category', 'Deleted selected restraint categor'] texts = ['Add Class','Delete Class'] commands = [self.addClass,self.deleteClass] self.bottomButtons = UtilityButtonList(guiFrame, doClone=False, grid=(row,0), gridSpan=(1,2), tipTexts=tipTexts, commands=commands, texts=texts) for func in ('__init__','delete','setName'): self.registerNotify(self.updateSpectra, 'ccp.nmr.Nmr.Experiment', func) self.registerNotify(self.updateSpectra, 'ccp.nmr.Nmr.DataSource', func) self.updateSpectra() self.update() def open(self): self.updateSpectra() self.update() BasePopup.open(self) def updateSpectra(self, *opt): spectra = self.getSpectra() if not spectra: return names = [self.getSpectrumName(x) for x in spectra] if (not self.spectrum) or (self.spectrum not in spectra): self.spectrum = spectra[0] self.spectrumPulldown.setup(names, names.index(self.getSpectrumName(self.spectrum)) ) self.update() def changeSpectrum(self, i, name): self.spectrum = self.getSpectra()[i] self.update() def getSpectrumName(self,spectrum): name = '%s:%s' % (spectrum.experiment.name,spectrum.name) return name def getSpectra(self): spectra = set() peakLists = getThroughSpacePeakLists(self.nmrProject) for peakList in peakLists: spectra.add(peakList.dataSource) spectra = list(spectra) spectra.sort() return spectra def selectClass(self, noeClass, row, col): if noeClass: self.noeClassChoice = (row, noeClass) if len(self.noeClassMatrix.objectList) > 1: self.bottomButtons.buttons[1].enable() else: self.bottomButtons.buttons[1].disable() def addClass(self): if self.spectrum: noeClass = [0.0,6.0,0.0,6.0] noeClasses = getIntensityDistanceTable(self.spectrum) noeClasses.append(noeClass) setSpectrumNoeDistanceClasses(self.spectrum, noeClasses) self.update() def deleteClass(self, *event): if self.spectrum: noeClasses = getIntensityDistanceTable(self.spectrum) if self.noeClassChoice and (self.noeClassChoice[1] in noeClasses): if len(noeClasses) > 1: (i,noeClass) = self.noeClassChoice noeClasses.remove(noeClass) self.noeClassChoice = None setSpectrumNoeDistanceClasses(self.spectrum, noeClasses) self.update() def setIntens(self, event): if self.noeClassChoice: val = self.intensEntry.get() or 0.0 self.noeClassChoice[1][0] = val self.updateClass() def getIntens(self, row): if row: self.intensEntry.set(row[0]) def setTarget(self, event): if self.noeClassChoice: val = self.targetEntry.get() or 0.0 self.noeClassChoice[1][1] = val self.updateClass() def getTarget(self, row): if row: self.targetEntry.set(row[1]) def setMin(self, event): if self.noeClassChoice: val = self.minEntry.get() or 0.0 self.noeClassChoice[1][2] = val self.updateClass() def getMin(self, row): if row: self.minEntry.set(row[2]) def setMax(self, event): if self.noeClassChoice: val = self.maxEntry.get() or 0.0 self.noeClassChoice[1][3] = val self.updateClass() def getMax(self, row): if row: self.maxEntry.set(row[3]) def getClasses(self): noeClasses = [] if self.spectrum: noeClasses = getIntensityDistanceTable(self.spectrum) if noeClasses: for i in range(len(noeClasses)): (intens,target,minimum,maximum) = noeClasses[i] if minimum > maximum: (minimum,maximum) = (maximum,minimum) minimum = min(target, minimum) maximum = max(target, maximum) intens = max(intens, 0.0) noeClasses[i] = [intens,target,minimum,maximum] noeClasses.sort() noeClasses.reverse() else: noeClasses = [] if self.spectrum: # default noeClasses = getIntensityDistanceTable(self.spectrum) return noeClasses def updateClass(self): if self.spectrum and self.noeClassChoice: (i, noeClass) = self.noeClassChoice noeClasses = getIntensityDistanceTable(self.spectrum) noeClasses[i] = noeClass setSpectrumNoeDistanceClasses(self.spectrum, noeClasses) self.update() def update(self): textMatrix = [] objectList = self.getClasses() if self.spectrum: if self.noeClassChoice and (len(objectList) > 1): self.bottomButtons.buttons[1].enable() else: self.bottomButtons.buttons[1].disable() self.bottomButtons.buttons[0].enable() else: self.bottomButtons.buttons[0].disable() self.bottomButtons.buttons[1].disable() for (intens,target,minimum,maximum) in objectList: datum = [] datum.append(intens) datum.append(target) datum.append(minimum) datum.append(maximum) textMatrix.append(datum) self.noeClassMatrix.update(objectList=objectList,textMatrix=textMatrix) if self.spectrum: setSpectrumNoeDistanceClasses(self.spectrum,objectList) def destroy(self): for func in ('__init__','delete','setName'): self.unregisterNotify(self.updateSpectra, 'ccp.nmr.Nmr.Experiment', func) self.unregisterNotify(self.updateSpectra, 'ccp.nmr.Nmr.DataSource', func) BasePopup.destroy(self)
class ConfirmSeqSpinSystemsPopup(BasePopup): def __init__(self, parent, *args, **kw): self.guiParent = parent self.spinSystems = [] self.spectrum = None self.spectra = [] self.waiting = 0 self.shiftList = None self.spinSystem = None self.link = '-1' BasePopup.__init__(self, parent=parent, title="Confirm Sequential Spin System", **kw) def body(self, guiFrame): guiFrame.grid_columnconfigure(0, weight=1) row = 0 frame = Frame(guiFrame) frame.grid(row=row, column=0, sticky='nsew') frame.grid_columnconfigure(3, weight=1) label = Label(frame, text='Shift List:') label.grid(row=0, column=0, sticky='w') self.shiftListPulldown = PulldownMenu(frame, callback=self.setShiftList) self.shiftListPulldown.grid(row=0, column=1, sticky='w') label = Label(frame, text='Sequential Link Type:') label.grid(row=0, column=2, sticky='w') entries = ['-1', '-1,+1', '+1'] self.linkPulldown = PulldownMenu(frame, callback=self.setLink, entries=entries, do_initial_callback=False, selected_index=entries.index( self.link)) self.linkPulldown.grid(row=0, column=3, sticky='w') row += 1 frame = LabelFrame(guiFrame, text='Link Atoms:') frame.grid(row=row, column=0, sticky='nsew') frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(0, weight=1) labels = ['C', 'CA', 'CB', 'CG', 'CD', 'H', 'HA', 'HB', 'HG', 'HD'] selected = ['CA', 'CB'] self.atomSelector = PartitionedSelector(frame, objects=labels, labels=labels, selected=selected, toggledBg='#808080', callback=self.changeAtoms, maxRowObjects=10) self.atomSelector.grid(row=0, column=0, sticky='ew') row += 1 guiFrame.grid_rowconfigure(row, weight=1) frame = LabelFrame(guiFrame, text='Predicted Residue Assignments') frame.grid(row=row, column=0, sticky='nsew') frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(0, weight=1) headingList = [ '#', 'Predicted\nResidue', 'Prob.', 'Links', 'CA', 'CA -1', 'CB', 'CB -1' ] self.spinSystemMatrix = ScrolledMatrix(frame, headingList=headingList, callback=self.selectSpinSystem, multiSelect=1) self.spinSystemMatrix.grid(row=0, column=0, sticky='nsew') row += 1 texts = ['Link Selected', 'Link All', 'Commit Assignment'] commands = [ self.linkSelectedSpinSystems, self.linkAllSpinSystems, self.commitAssignments ] buttonList = UtilityButtonList(guiFrame, texts=texts, commands=commands, helpUrl=self.help_url) buttonList.grid(row=row, column=0, sticky='ew') self.buttons = buttonList.buttons for func in ('__init__', 'delete'): for clazz in ('ccp.nmr.Nmr.ShiftList', ): self.registerNotify(self.updateShiftLists, clazz, func) for func in ('__init__', 'delete', 'setNmrChains', 'setResidue', 'setResonances', 'addResonance', 'removeResonance'): self.registerNotify(self.updateSpinSystemsAfter, 'ccp.nmr.Nmr.ResonanceGroup', func) self.updateShiftLists() def setLink(self, index, name): self.link = name self.updateSpinSystemsAfter() def updateButtons(self): if len(self.spinSystemMatrix.currentObjects) > 1: self.buttons[0].enable() else: self.buttons[0].disable() if self.spinSystemMatrix.objectList: self.buttons[1].enable() else: self.buttons[1].disable() if self.spinSystem: self.buttons[2].enable() else: self.buttons[2].disable() def changeAtoms(self, *opt): self.updateSpinSystemsAfter() def getShiftListNames(self, shiftLists): shiftListNames = [] for shiftList in shiftLists: if not hasattr(shiftList, 'name'): shiftList.name = "ShiftList " + str(shiftList.serial) elif not shiftList.name: shiftList.name = "ShiftList " + str(shiftList.serial) shiftListNames.append(shiftList.name) return shiftListNames def updateShiftLists(self, *opt): shiftLists = list( self.nmrProject.findAllMeasurementLists(className='ShiftList')) shiftListNames = self.getShiftListNames(shiftLists) shiftList = None index = -1 if shiftListNames: if self.shiftList in shiftLists: shiftList = self.shiftList else: shiftList = shiftLists[0] index = shiftLists.index(shiftList) self.shiftList = shiftList self.shiftListPulldown.setup(shiftListNames, index) def setShiftList(self, index, name=None): shiftLists = list( self.nmrProject.findAllMeasurementLists(className='ShiftList')) if shiftLists: self.shiftList = shiftLists[index] else: self.shiftList = None self.updateSpinSystemsAfter() def linkSelectedSpinSystems(self): spinSystems = self.spinSystemMatrix.currentObjects self.linkSpinSystems(spinSystems) def linkAllSpinSystems(self): spinSystems = self.spinSystemMatrix.objectList self.linkSpinSystems(spinSystems) def linkSpinSystems(self, spinSystems): data = [] for spinSystem in spinSystems: residue, p = self.getProbableResidue(spinSystem) key = '%s%s%4.4d' % (residue.chain.molSystem.code, residue.chain.code, residue.seqCode) data.append([key, residue.seqCode, residue, spinSystem]) data.sort() seqCodes = [x[1] for x in data] residues = [x[2] for x in data] spinSystems = [x[3] for x in data] N = len(data) for i in range(N): if i > 0: delta = seqCodes[i] - seqCodes[i - 1] if delta == 1 and (residues[i].chain is residues[i - 1].chain): ss = findConnectedSpinSystem(spinSystems[i], delta=-1) if ss: mergeSpinSystems( ss, spinSystems[i - 1]) # copy resonances across & delete makeSeqSpinSystemLink(spinSystems[i - 1], spinSystems[i], delta=1) if i < N - 1: delta = seqCodes[i + 1] - seqCodes[i] if delta == 1 and (residues[i].chain is residues[i + 1].chain): ss = findConnectedSpinSystem(spinSystems[i], delta=1) if ss: mergeSpinSystems( ss, spinSystems[i + 1]) # copy resonances across & delete makeSeqSpinSystemLink(spinSystems[i], spinSystems[i + 1], delta=1) self.updateSpinSystemsAfter() def commitAssignments(self): merge = showYesNo('Query', 'Merge with any existing spin systems?', self) for spinSystem in self.spinSystemMatrix.currentObjects: if not spinSystem.residue: residue, p = self.getProbableResidue(spinSystem) assignSpinSystemResidue(spinSystem, residue, warnMerge=merge) def getProbableResidue(self, spinSystem): residue = None probability = 0.0 if spinSystem.residue: return spinSystem.residue, 1.0 data = [] for residueProb in spinSystem.residueProbs: data.append((residueProb.weight, residueProb.possibility)) data.sort() if data: residue, probability = data[-1] return residue, probability def getTentativeSpinSystems(self): spinSystemsList = [] if self.project: for spinSystem in self.nmrProject.sortedResonanceGroups(): if spinSystem.residueProbs and not spinSystem.residue: #if spinSystem.residue: residue, p = self.getProbableResidue(spinSystem) key = '%s%s%4.4d' % (residue.chain.molSystem.code, residue.chain.code, residue.seqCode) spinSystemsList.append((key, spinSystem)) spinSystemsList.sort() return [x[1] for x in spinSystemsList] def updateSpinSystemsAfter(self, spinSystem=None): if self.waiting: return else: if spinSystem: if not spinSystem.residueProbs: return if spinSystem.residue: return self.waiting = True self.after_idle(self.updateSpinSystems) def getHeadings(self): headingList = ['#', 'Predicted\nResidue', 'Prob.', 'Links'] atoms = self.atomSelector.getSelected() for atom in atoms: headingList.append(atom) if self.link == '-1': headingList.append('%s -1' % atom) headingList.append('D %s -1' % atom) elif self.link == '+1': headingList.append('%s +1' % atom) headingList.append('D %s +1' % atom) else: headingList.append('%s -1' % atom) headingList.append('D %s -1' % atom) headingList.append('%s +1' % atom) headingList.append('D %s +1' % atom) return headingList def addShiftData(self, spinSystem, datum): prevSS, nextSS = self.getConnectedSpinSystems(spinSystem) atoms = self.atomSelector.getSelected() dict = {} residue, p = self.getProbableResidue(spinSystem) prevRes = residue.chain.findFirstResidue(seqCode=residue.seqCode - 1) nextRes = residue.chain.findFirstResidue(seqCode=residue.seqCode + 1) prevSS0 = None nextSS0 = None for ss in self.getTentativeSpinSystems(): if self.getProbableResidue(ss)[0] is prevRes: prevSS0 = ss if self.getProbableResidue(ss)[0] is nextRes: nextSS0 = ss if nextSS0 and prevSS0: break for atom in atoms: resonances = [] resonancesPrev = [] resonancesNext = [] resonancesPrev0 = [] resonancesNext0 = [] for resonance0 in spinSystem.sortedResonances(): for name in resonance0.assignNames: if name[:2] == atom: resonances.append(resonance0) break text = '' if resonances: text = self.getResonanceText(resonances) datum.append(text) if prevSS and ('-1' in self.link): for resonance0 in prevSS.sortedResonances(): for name in resonance0.assignNames: if name[:2] == atom: resonancesPrev.append(resonance0) break deltasPrev = [] if prevSS0 and resonancesPrev: for resonance1 in prevSS0.sortedResonances(): for name1 in resonance1.assignNames: if name1[:2] == atom: shift1 = resonance1.findFirstShift( parentList=self.shiftList) deltas = [] for resonance2 in resonancesPrev: shift2 = resonance2.findFirstShift( parentList=self.shiftList) if shift1 and shift2: deltas.append( abs(shift1.value - shift2.value)) if deltas: deltas.sort() deltasPrev.append('%.2f' % deltas[0]) break if nextSS and ('+1' in self.link): for resonance0 in nextSS.sortedResonances(): for name in resonance0.assignNames: if name[:2] == atom: resonancesNext.append(resonance0) break deltasNext = [] if nextSS0 and resonancesNext: for resonance1 in nextSS0.sortedResonances(): for name1 in resonance1.assignNames: if name1[:2] == atom: shift1 = resonance1.findFirstShift( parentList=self.shiftList) deltas = [] for resonance2 in resonancesNext: shift2 = resonance2.findFirstShift( parentList=self.shiftList) if shift1 and shift2: deltas.append( abs(shift1.value - shift2.value)) if deltas: deltas.sort() deltasNext.append('%.2f' % deltas[0]) break if self.link == '-1': ppms = '' diff = '' if resonancesPrev: ppms = self.getResonanceText(resonancesPrev) diff = ','.join(deltasPrev) datum.append(ppms) datum.append(diff) elif self.link == '+1': ppms = '' diff = '' if resonancesNext: ppms = self.getResonanceText(resonancesNext) diff = ','.join(deltasNext) datum.append(ppms) datum.append(diff) else: ppms = '' diff = '' if resonancesPrev: ppms = self.getResonanceText(resonancesPrev) diff = ','.join(deltasPrev) datum.append(ppms) datum.append(diff) ppms = '' diff = '' if resonancesNext: ppms = self.getResonanceText(resonancesNext) diff = ','.join(deltasNext) datum.append(ppms) datum.append(diff) def updateSpinSystems(self): textMatrix = [] objectList = [] colorMatrix = [] headingList = self.getHeadings() for spinSystem in self.getTentativeSpinSystems(): residueText = None residue, probability = self.getProbableResidue(spinSystem) if residue: residueText = '%d%s' % (residue.seqCode, getResidueCode(residue)) links = [] color = '#D04040' if findConnectedSpinSystem(spinSystem, delta=-1): links.append('-1') if findConnectedSpinSystem(spinSystem, delta=1): links.append('+1') if len(links) == 2: color = '#40B040' elif len(links) == 1: color = '#B0B040' datum = [] datum.append(spinSystem.serial) datum.append(residueText) datum.append(probability) datum.append(' '.join(links)) self.addShiftData(spinSystem, datum) colors = [None] * len(headingList) colors[3] = color objectList.append(spinSystem) textMatrix.append(datum) colorMatrix.append(colors) if self.spinSystem not in objectList: self.spinSystem = None self.spinSystemMatrix.update(headingList=headingList, objectList=objectList, textMatrix=textMatrix, colorMatrix=colorMatrix) self.updateButtons() self.waiting = False def getResonanceText(self, resonances): shifts = [] for resonance in resonances: shift = resonance.findFirstShift(parentList=self.shiftList) if shift: shifts.append('%.2f' % shift.value) return ','.join(shifts) def getConnectedSpinSystems(self, spinSystem): if self.link == '-1': prevSS = findConnectedSpinSystem(spinSystem, delta=-1) nextSS = None elif self.link == '+1': prevSS = None nextSS = findConnectedSpinSystem(spinSystem, delta=1) else: prevSS = findConnectedSpinSystem(spinSystem, delta=-1) nextSS = findConnectedSpinSystem(spinSystem, delta=1) return prevSS, nextSS def selectSpinSystem(self, object, row, col): self.spinSystem = object self.updateButtons() def destroy(self): for func in ('__init__', 'delete'): for clazz in ('ccp.nmr.Nmr.ShiftList', ): self.unregisterNotify(self.updateShiftLists, clazz, func) for func in ('__init__', 'delete', 'setNmrChains', 'setResidue', 'setResonances', 'addResonance', 'removeResonance'): self.unregisterNotify(self.updateSpinSystemsAfter, 'ccp.nmr.Nmr.ResonanceGroup', func) BasePopup.destroy(self)
class EditSymmetryPopup(BasePopup): def __init__(self, parent, project): self.parent = parent self.ccpnProject = project self.hProject = project.currentHaddockProject self.molPartner = None self.molecules = [] self.symmetrySet = None self.symmetryOp = None self.symmetryCode = None self.waiting = False BasePopup.__init__(self, parent=parent, title='Symmetry Operations') self.font = 'Helvetica 12' self.setFont() def body(self, guiFrame): guiFrame.grid_columnconfigure(0, weight=1) guiFrame.grid_rowconfigure(1, weight=1) frame = LabelFrame(guiFrame, text='Options') frame.grid(row=0,column=0,sticky='ew') frame.grid_columnconfigure(5, weight=1) # Choose type of symmetry set to define or change (if allready present in the model) self.molLabel = Label(frame, text='Symmetry Operator:') self.molLabel.grid(row=0,column=2,sticky='w') self.symmCodePulldown = PulldownMenu(frame, callback=self.setSymmCode, entries=['NCS','C2','C3','C5'], do_initial_callback=False) self.symmCodePulldown.grid(row=0,column=3,sticky='w') frame = LabelFrame(guiFrame, text='Symmetry Operations') frame.grid(row=1,column=0,sticky='nsew') frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(0, weight=1) self.molSysPulldown = PulldownMenu(self, callback=self.setMolSystem, do_initial_callback=False) self.chainSelect = MultiWidget(self, CheckButton, callback=self.setChains, minRows=0, useImages=False) self.segStartEntry = IntEntry(self, returnCallback=self.setSegStart, width=6) self.segLengthEntry = IntEntry(self, returnCallback=self.setSegLength, width=6) headings = ['#','Symmetry\noperator','Mol System','Chains','Start\nresidue','Segment\nlength'] editWidgets = [None, None, self.molSysPulldown, self.chainSelect, self.segStartEntry, self.segLengthEntry] editGetCallbacks = [None, None, self.getMolSystem, self.getChains, self.getSegStart, self.getSegLength] editSetCallbacks = [None, self.setSymmCode, self.setMolSystem, self.setChains, self.setSegStart, self.setSegLength] self.symmetryMatrix = ScrolledMatrix(frame,headingList=headings, callback=self.selectSymmetry, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks) self.symmetryMatrix.grid(row=0,column=0,sticky='nsew') texts = ['Add Symmetry Set','Remove Symmetry Set'] commands = [self.addSymmetrySet,self.removeSymmetrySet] self.buttonList = createDismissHelpButtonList(guiFrame, texts=texts, commands=commands, expands=True) self.buttonList.grid(row=2,column=0,sticky='ew') self.updateMolPartners() self.notify(self.registerNotify) #Temporary report of parameters print self.molSystem print self.molecules print self.symmetrySet print self.symmetryOp print self.symmetryCode def getMolSystem(self, partner): """Select molecular system from list of molsystems stored in the project""" names = []; index = -1 molSystem = partner.molSystem molSystems = self.ccpnProject.sortedMolSystems() if molSystems: names = [ms.code for ms in molSystems] if molSystem not in molSystems: molSystem = molSystems[0] index = molSystems.index(molSystem) self.molSysPulldown.setup(names, index) def getChains(self, partner): names = [] values = [] molSystem = partner.molSystem if molSystem: for chain in molSystem.sortedChains(): names.append(chain.code) if not partner.chains: values.append(True) elif partner.findFirstChain(chain=chain): values.append(True) else: values.append(False) self.chainSelect.set(values=values,options=names) else: showWarning('Warning','Set Mol System or ensemble first',parent=self) self.symmetryMatrix.keyPressEscape() def getSegLength(self, symmetryOp): if symmetryOp and symmetryOp.segmentLength: self.segLengthEntry.set(symmetryOp.segmentLength) def getSegStart(self): pass def setMolSystem(self, partner, name=None): """Get all molsystems as stored in the project as list""" index = self.molSysPulldown.getSelectedIndex() molSystems = self.ccpnProject.sortedMolSystems() if molSystems: molSystem = molSystems[index] self.molPartner.molSystem = molSystem chains = molSystem.sortedChains() if (not self.molPartner.chains) and chains: setPartnerChains(self.molPartner,chains) self.updateAllAfter() def setChains(self, obj): """Get the list of chains for the selected molsystem""" if self.molPartner and self.molPartner.molSystem: if obj is not None: chains = self.molPartner.molSystem.sortedChains() values = self.chainSelect.get() chains = [chains[i] for i in range(len(values)) if values[i]] setPartnerChains(self.molPartner,chains) self.symmetryMatrix.keyPressEscape() self.updateAllAfter() def setSegLength(self, event): value = self.segLengthEntry.get() or 1 self.symmetryOp.segmentLength = value def setSegStart(self): pass def setSymmCode(self, index, name=None): self.symmetryCode = self.symmCodePulldown.getSelected() def selectSymmetry(self, obj, row, col): self.symmetryOp = obj self.updateMolSysPulldown() def notify(self, notifyFunc): for func in ('__init__', 'delete', 'setSymmetryCode','setSegmentLength'): notifyFunc(self.updateAllAfter, 'molsim.Symmetry.Symmetry', func) for func in ('__init__', 'delete','setfirstSeqId'): notifyFunc(self.updateAllAfter, 'molsim.Symmetry.Segment', func) def addSymmetrySet(self): if not self.ccpnProject.molSystems: showWarning('Warning','No molecular systems present in CCPN project',parent=self) return molSystem = self.ccpnProject.findFirstMolSystem() partner = self.hProject.newHaddockPartner(code=molSystem.code, molSystem=molSystem) setPartnerChains(partner, molSystem.chains) self.updateAllAfter() def removeSymmetrySet(self): pass def updateAllAfter(self, obj=None): if self.waiting: return else: self.waiting = True self.after_idle(self.updateSymmetries, self.updateMolPartners) def updateMolPartners(self): textMatrix = [] objectList = [] for partner in self.hProject.sortedHaddockPartners(): datum = [partner.code, self.symmetryCode, partner.molSystem.code, ','.join([c.chain.code for c in partner.chains]), partner.autoHistidinePstate and 'Yes' or 'No', partner.isDna and 'Yes' or 'No'] objectList.append(partner) textMatrix.append(datum) self.symmetryMatrix.update(objectList=objectList, textMatrix=textMatrix) self.updateMolSysPulldown() def updateMolSysPulldown(self): names = [] index = -1 partners = self.hProject.sortedHaddockPartners() if partners: if self.molPartner not in partners: self.molPartner = partners[0] names = ['Partner %s' % p.code for p in partners] index = partners.index(self.molPartner) else: self.molPartner = None self.molSysPulldown.setup(names, index) def updateSymmetries(self): textMatrix = []; objectList = [] if self.symmetrySet: for symmetryOp in self.symmetrySet.symmetries: chains = []; segments = [] length = symmetryOp.segmentLength for segment in symmetryOp.sortedSegments(): code = segment.chainCode chain = self.molSystem.findFirstChain(code=code) if chain: chains.append(code) seqId = segment.firstSeqId residue1 = chain.findFirstResidue(seqId=seqId) residue2 = chain.findFirstResidue(seqId=seqId+length-1) segments.append('%s:%d-%d' % (code,residue1.seqCode,residue2.seqCode)) datum = [symmetryOp.serial, symmetryOp.symmetryCode, length, '\n'.join(chains), '\n'.join(segments)] objectList.append(symmetryOp) textMatrix.append(datum) self.symmetryMatrix.update(objectList=objectList, textMatrix=textMatrix) self.waiting = False def destroy(self): self.notify(self.unregisterNotify) BasePopup.destroy(self)
class SetupStructureCalcFrame(Frame): def __init__(self, parent, application, *args, **kw): self.parent = parent self.molSystem = None self.constraintSet = None self.application = application self.project = application.project self.waiting = False self.tableObj = None Frame.__init__(self, parent=parent, **kw) self.grid_columnconfigure(3, weight=1) label = Label(self, text='Molecular system: ') label.grid(row=0, column=0, sticky='nw') self.molSysPulldown = PulldownMenu( self, self.changeMolSystem, tipText='Select which molecular system to use in the calculation') self.molSysPulldown.grid(row=0, column=1, sticky='nw') label = Label(self, text='Constraint Set: ') label.grid(row=0, column=2, sticky='nw') self.constraintSetPulldown = PulldownMenu( self, self.changeConstraintSet, tipText='Select which set of restraints to use in the calculation') self.constraintSetPulldown.grid(row=0, column=3, sticky='nw') self.shiftListPulldown = PulldownMenu( parent, callback=self.setShiftList, do_initial_callback=False, tipText='select the shift list to use in the calculation') tipTexts = [ 'The type of ccp object used in the calculation', 'The identifier for the input data', 'A toggle whether to use the data', 'Whether to filter violated restraints', 'Whether to keep CCPN assignments (otherwise new restraint assignments will be used)', 'Whether the restraints are overly anbiguous and need refining', 'The shift list to use for shift-peak matching' ] headingList = [ 'Input Class', 'Id', 'Use?', 'Filter\nViolated', 'Keep\nAssignments?', 'Ambiguous\nProtocol', 'Shift List' ] editWidgets = [ None, None, None, None, None, None, self.shiftListPulldown ] editGetCallbacks = [ None, None, self.toggleUse, self.toggleFilterViol, self.toggleKeepAssign, self.toggleAmbig, self.getShiftList ] editSetCallbacks = [ None, None, None, None, None, None, self.setShiftList ] self.grid_rowconfigure(1, weight=1) self.scrolledMatrix = ScrolledMatrix(self, headingList=headingList, editSetCallbacks=editSetCallbacks, editGetCallbacks=editGetCallbacks, editWidgets=editWidgets, multiSelect=True, tipTexts=tipTexts, callback=self.selectCell) self.scrolledMatrix.grid(row=1, column=0, columnspan=4, sticky='nsew') self.scrolledMatrix.doEditMarkExtraRules = self.doEditMarkExtraRules #texts = ['','',''] #commands = [None,None,None] #self.bottomButtons = ButtonList(self, texts=texts, expands=True, commands=commands) #self.bottomButtons.grid(row=2, column=0, columnspan=4, sticky='ew') self.updateMolSystems() self.updateConstraintSets() notify = self.application.registerNotify for func in ('__init__', 'delete'): notify(self.updateAfter, 'ccp.nmr.Nmr.PeakList', func) notify(self.updateConstraintSets, 'ccp.nmr.NmrConstraint.NmrConstraintStore', func) notify(self.updateMolSystems, 'ccp.molecule.MolSystem.MolSystem', func) notify(self.updateMolSystems, 'ccp.molecule.MolSystem.Chain', func) for func in ('__init__', 'delete', 'setName'): notify(self.updateAfter, 'ccp.nmr.Nmr.Experiment', func) notify(self.updateAfter, 'ccp.nmr.Nmr.DataSource', func) def doEditMarkExtraRules(self, obj, row, col): className = obj.className if className == 'PeakList': if col == 5: return False elif className == 'DistanceConstraintList': if col in (4, 6): return False else: if col in (4, 5, 6): return False return True def toggleUse(self, obj): bool = not obj.setupStructureCalcFrameDict['use'] obj.setupStructureCalcFrameDict['use'] = bool self.updateAfter() def toggleFilterViol(self, obj): bool = not obj.setupStructureCalcFrameDict['filter'] obj.setupStructureCalcFrameDict['filter'] = bool self.updateAfter() def toggleKeepAssign(self, obj): bool = not obj.setupStructureCalcFrameDict['preserve'] obj.setupStructureCalcFrameDict['preserve'] = bool self.updateAfter() def toggleAmbig(self, obj): bool = not obj.setupStructureCalcFrameDict['ambig'] obj.setupStructureCalcFrameDict['ambig'] = bool self.updateAfter() def selectCell(self, obj, row, col): self.tableObj = obj def getShiftList(self, peakList): names = [] index = -1 shiftLists = getShiftLists(self.project.currentNmrProject) if shiftLists: shiftList = peakList.dataSource.experiment.shiftList if shiftList not in shiftLists: shiftList = shiftLists[0] names = [sl.name or str(sl.serial) for sl in shiftLists] index = shiftLists.index(shiftList) print "getShiftList", names, index self.shiftListPulldown.setup(names, index) def setShiftList(self, index, name=None): print "setShiftList", index, name if not name: index = self.shiftListPulldown.getSelectedIndex() shiftList = getShiftLists(self.project.currentNmrProject)[index] self.tableObj.setupStructureCalcFrameDict['shiftList'] = shiftList self.updateAfter() def updateMolSystems(self, *opt): names = [] index = -1 molSystems = self.getMolSystems() if molSystems: names = [ms.code for ms in molSystems] if self.molSystem not in molSystems: self.molSystem = molSystems[0] index = molSystems.index(self.molSystem) self.molSysPulldown.setup(names, index) def getMolSystems(self): molSystems = [] if self.project: for molSystem in self.project.molSystems: if molSystem.chains: molSystems.append(molSystem) return molSystems def getTableObjects(self): objs = [] if self.project: objs = getThroughSpacePeakLists(self.project) if self.constraintSet: objs.extend(list(self.constraintSet.constraintLists)) return objs def updateConstraintSets(self, obj=None): names = [] index = -1 if self.project and self.project.currentNmrProject: constraintSets = self.project.currentNmrProject.sortedNmrConstraintStores( ) if constraintSets: if self.constraintSet not in constraintSets: self.constraintSet = constraintSets[0] names = [str(cs.serial) for cs in constraintSets] index = constraintSets.index(self.constraintSet) names.append('<None>') self.constraintSetPulldown.setup(names, index) def changeMolSystem(self, i, name): self.molSystem = self.project.findFirstMolSystem(code=name) self.updateAfter() def changeConstraintSet(self, i, name): if name == '<None>': self.constraintSet = None else: self.constraintSet = self.project.currentNmrProject.sortedNmrConstraintStores( )[i] self.updateAfter() def update(self): textMatrix = [] objectList = [] #headingList = ['Input Class','Use?','Filter\nViolated', # 'Keep\nAssignments?','Ambigous\nProtocol','Shift List'] for obj in self.getTableObjects(): if not hasattr(obj, 'setupStructureCalcFrameDict'): obj.setupStructureCalcFrameDict = dict = {} dict['use'] = True dict['filter'] = True dict['preserve'] = False dict['ambig'] = False dict['shiftList'] = None new = True else: dict = obj.setupStructureCalcFrameDict new = False className = obj.className if className == 'PeakList': spectrum = obj.dataSource experiment = spectrum.experiment shiftList = dict['shiftList'] or experiment.shiftList if shiftList: shiftListName = shiftList.name else: shiftListName = '<None>' if new and (self.molSystem not in experiment.molSystems): dict['use'] = False ident = '%s:%s:%d' % (experiment.name, spectrum.name, obj.serial) used = dict['use'] and 'Yes' or 'No' filtered = dict['filter'] and 'Yes' or 'No' preserved = dict['preserve'] and 'Yes' or 'No' ambig = None elif className == 'DistanceConstraintList': shiftListName = None if new: dict['filter'] = True dict['ambig'] = False ident = '%s:%d' % (obj.name or '', obj.serial) used = dict['use'] and 'Yes' or 'No' filtered = dict['filter'] and 'Yes' or 'No' preserved = None ambig = dict['ambig'] and 'Yes' or 'No' else: shiftListName = None if new: dict['filter'] = False dict['ambig'] = False ident = '%s:%d' % (obj.name or '', obj.serial) used = dict['use'] and 'Yes' or 'No' filtered = None preserved = None ambig = None datum = [ className, ident, used, filtered, preserved, ambig, shiftListName ] textMatrix.append(datum) objectList.append(obj) self.waiting = False self.scrolledMatrix.update(textMatrix=textMatrix, objectList=objectList) def getAriaData(self): if not self.project: showWarning('Failure', 'No active project', parent=self) return if not self.molSystem: showWarning('Failure', 'No molecular system selected', parent=self) return if len(self.molSystem.chains) > 1: code = self.molSystem.findFirstChain().code code = askString('Multiple chains', 'Enter chain code:', code, parent=self) chain = self.molSystem.findFirstChain(code=code) else: chain = self.molSystem.findFirstChain() peakData = [] dihedrals = [] ambigs = [] unambigs = [] jCouplings = [] for obj in self.scrolledMatrix.objectList: opts = obj.setupStructureCalcFrameDict if not opts['use']: continue className = obj.className key = getObjectKeyString(obj) if className == 'PeakList': shiftList = opts['shiftList'] if not shiftList: continue datum = { 'shifts': { KEY_ID: getObjectKeyString(shiftList) }, 'peaks': { KEY_ID: key }, 'use_assignments': opts['preserve'], 'trust_assigned_peaks': opts['filter'] } peakData.append(datum) elif className == 'DistanceConstraintList': if opts['ambig']: ambigs.append({ KEY_ID: key, 'filter_contributions': opts['filter'] }) else: unambigs.append({ KEY_ID: key, 'filter_contributions': opts['filter'] }) elif className == 'JCouplingConstraintList': jCouplings.append({KEY_ID: key}) elif className == 'DihedralConstraintList': dihedrals.append({KEY_ID: key}) projFileName = os.path.join(self.project.url.path, self.project.path) dict = { KEY_GENERAL: { 'project_name': self.project.name }, KEY_CCPN: { 'filename': projFileName }, KEY_MOLECULAR_SYSTEM: { KEY_ID: getObjectKeyString(chain) }, KEY_NOES: peakData, KEY_DIHEDRALS: dihedrals, KEY_DISTANCES_AMBIG: ambigs, KEY_DISTANCES_UNAMBIG: unambigs, KEY_JCOUPLINGS: jCouplings } return dict def updateAll(self): self.project = self.application.project self.updateMolSystems() self.updateConstraintSets() self.updateAfter() def updateAfter(self, obj=None): if self.waiting: return else: self.waiting = True self.after_idle(self.update) def destroy(self): notify = self.application.unregisterNotify for func in ('__init__', 'delete'): notify(self.updateAfter, 'ccp.nmr.Nmr.PeakList', func) notify(self.updateConstraintSets, 'ccp.nmr.NmrConstraint.NmrConstraintStore', func) notify(self.updateMolSystems, 'ccp.molecule.MolSystem.MolSystem', func) notify(self.updateMolSystems, 'ccp.molecule.MolSystem.Chain', func) for func in ('__init__', 'delete', 'setName'): notify(self.updateAfter, 'ccp.nmr.Nmr.Experiment', func) notify(self.updateAfter, 'ccp.nmr.Nmr.DataSource', func) Frame.destroy(self)
class EditSymmetryPopup(BasePopup): def __init__(self, parent, project): self.parent = parent self.project = project self.singleMolecule = True self.molSystem = None self.molecules = [] self.symmetrySet = None self.symmetryOp = None self.waiting = False BasePopup.__init__(self, parent=parent, title='Symmetry Operations') def body(self, guiFrame): guiFrame.grid_columnconfigure(0, weight=1) guiFrame.grid_rowconfigure(1, weight=1) frame = LabelFrame(guiFrame, text='Options') frame.grid(row=0, column=0, sticky='ew') frame.grid_columnconfigure(5, weight=1) label = Label(frame, text='MolSystem:') label.grid(row=0, column=0, sticky='w') self.molSystemPulldown = PulldownMenu(frame, callback=self.selectMolSystem) self.molSystemPulldown.grid(row=0, column=1, sticky='w') self.molLabel = Label(frame, text='Molecule:') self.molLabel.grid(row=0, column=2, sticky='w') self.moleculePulldown = PulldownMenu(frame, callback=self.selectMolecule) self.moleculePulldown.grid(row=0, column=3, sticky='w') label = Label(frame, text='Same Molecule Symmetry:') label.grid(row=0, column=4, sticky='w') self.molSelect = CheckButton(frame, callback=self.toggleSingleMolecule) self.molSelect.grid(row=0, column=5, sticky='w') self.molSelect.set(self.singleMolecule) frame = LabelFrame(guiFrame, text='Symmetry Operations') frame.grid(row=1, column=0, sticky='nsew') frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(0, weight=1) self.symmCodePulldown = PulldownMenu(self, callback=self.setSymmCode, do_initial_callback=False) self.segLengthEntry = IntEntry(self, returnCallback=self.setSegLength, width=6) self.setChainMulti = MultiWidget(self, CheckButton, callback=self.setChains, minRows=0, useImages=False) self.setSegmentMulti = MultiWidget(self, IntEntry, callback=self.setSegments, minRows=0, useImages=False) editWidgets = [ None, self.symmCodePulldown, self.segLengthEntry, self.setChainMulti, self.setSegmentMulti ] editGetCallbacks = [ None, self.getSymmCode, self.getSegLength, self.getChains, self.getSegments ] editSetCallbacks = [ None, self.setSymmCode, self.setSegLength, self.setChains, self.setSegments ] headings = [ '#', 'Symmetry\nType', 'Segment\nLength', 'Chains', 'Segment\nPositions' ] self.symmetryMatrix = ScrolledMatrix(frame, headingList=headings, callback=self.selectSymmetry, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks) self.symmetryMatrix.grid(row=0, column=0, sticky='nsew') texts = ['Add Symmetry Op', 'Remove Symmetrey Op'] commands = [self.addSymmOp, self.removeSymmOp] buttonList = createDismissHelpButtonList(guiFrame, texts=texts, commands=commands, expands=True) buttonList.grid(row=2, column=0, sticky='ew') self.updateMolSystems() self.updateMolecules() self.updateSymmetriesAfter() self.notify(self.registerNotify) def open(self): self.updateMolSystems() self.updateMolecules() self.updateSymmetriesAfter() BasePopup.open(self) def notify(self, notifyFunc): for func in ('__init__', 'delete', 'setSymmetryCode', 'setSegmentLength'): notifyFunc(self.updateSymmetriesAfter, 'molsim.Symmetry.Symmetry', func) for func in ('__init__', 'delete', 'setfirstSeqId'): notifyFunc(self.updateSymmetriesAfter, 'molsim.Symmetry.Segment', func) def getSymmCode(self, symmetryOp): """Get allowed symmetry operators from the model""" symmetryOpCodes = symmetryOp.parent.metaclass.container.getElement( 'SymmetryOpCode').enumeration index = 0 if symmetryOp.symmetryCode in symmetryOpCodes: index = symmetryOpCodes.index(symmetryOp.symmetryCode) self.symmCodePulldown.setup(symmetryOpCodes, index) def getSegLength(self, symmetryOp): if symmetryOp and symmetryOp.segmentLength: self.segLengthEntry.set(symmetryOp.segmentLength) def getChains(self, symmetryOp): chains = [] for chain in self.molSystem.chains: if chain.residues: if chain.molecule in self.molecules: chains.append(chain.code) chains.sort() values = [] for chain in chains: if symmetryOp.findFirstSegment(chainCode=chain): values.append(True) else: values.append(False) self.setChainMulti.set(values=values, options=chains) def getSegments(self, symmetryOp): values = [] names = [] if symmetryOp: for segment in symmetryOp.sortedSegments(): names.append(segment.chainCode) values.append(segment.firstSeqId) n = len(values) self.setSegmentMulti.maxRows = n self.setSegmentMulti.minRows = n self.setSegmentMulti.set(values=values, options=names) def setSymmCode(self, index, name=None): """Set the symmetry code as NCS,C2,C3,C4,C5,C6""" if self.symmetryOp: symmCode = self.symmCodePulldown.getSelected() self.symmetryOp.symmetryCode = symmCode def setSegLength(self, event): value = self.segLengthEntry.get() or 1 self.symmetryOp.segmentLength = value def setChains(self, obj): if self.symmetryOp and obj: codes = self.setChainMulti.options segment = self.symmetryOp.findFirstSegment() values = self.setChainMulti.get() if segment: seqId0 = segment.firstSeqId else: seqId0 = 1 for i in range(len(values)): segment = self.symmetryOp.findFirstSegment(chainCode=codes[i]) if segment and not values[i]: segment.delete() elif values[i] and not segment: chain = self.molSystem.findFirstChain(code=codes[i]) residue = chain.findFirstResidue(seqid=seqId0) if residue: seqId = seqId0 else: residue = chain.sortedResidues()[0] seqId = residue.seqId residue2 = chain.findFirstResidue( seqid=seqId + self.symmetryOp.segmentLength) if not residue2: residue2 = chain.sortedResidues()[-1] self.symmetryOp.segmentLength = (residue2.seqId - seqId) + 1 segment = self.symmetryOp.newSegment(chainCode=codes[i], firstSeqId=seqId) self.symmetryMatrix.keyPressEscape() def setSegments(self, obj): if self.symmetryOp and obj: segments = self.symmetryOp.sortedSegments() values = self.setSegmentMulti.get() for i in range(len(values)): seqCode = values[i] chain = self.molSystem.findFirstChain( code=segments[i].chainCode) residue = chain.findFirstResidue(seqCode=seqCode) if residue: seqId = residue.seqId if segments[i].firstSeqId != seqId: segments[i].delete() segments[i] = self.symmetryOp.newSegment( chainCode=chain.code, firstSeqId=seqId) self.symmetryMatrix.keyPressEscape() def selectSymmetry(self, obj, row, col): self.symmetryOp = obj def addSymmOp(self): if self.molSystem: if not self.symmetrySet: self.symmetrySet = self.molSystem.findFirstMolSystemSymmetrySet( ) if not self.symmetrySet: objGen = self.project.newMolSystemSymmetrySet self.symmetrySet = objGen(symmetrySetId=1, molSystem=self.molSystem) segLen = len(self.molSystem.findFirstChain().residues) symmetry = self.symmetrySet.newSymmetry(segmentLength=segLen) def removeSymmOp(self): if self.symmetryOp: self.symmetryOp.delete() def toggleSingleMolecule(self, boolean): self.singleMolecule = not boolean self.updateMolSystems() self.updateMolecules() def setMolecules(self, molecules): self.molecules = molecules if self.symmetrySet: for symmetryOp in self.symmetrySet.symmetries: for segment in symmetryOp.segments: chain = self.molSystem.findFirstChain( code=segment.chainCode) if chain and (chain.molecule not in molecules): segment.delete() def selectMolecule(self, index, name): self.setMolecules(self.getMolecules()[index]) self.updateSymmetries() def getMolecules(self): counts = {} moleculesList = [] for chain in self.molSystem.chains: molecule = chain.molecule counts[molecule] = counts.get(molecule, 0) + 1 molecules = counts.keys() if self.singleMolecule: for molecule in counts: if counts[molecule] > 1: moleculesList.append([ molecule, ]) elif molecules: molecules = counts.keys() n = len(molecules) moleculesList.append([ molecules[0], ]) if n > 1: moleculesList.append([ molecules[1], ]) moleculesList.append([molecules[0], molecules[1]]) if n > 2: moleculesList.append([ molecules[2], ]) moleculesList.append([molecules[1], molecules[2]]) moleculesList.append( [molecules[0], molecules[1], molecules[2]]) if n > 3: moleculesList.append([ molecules[3], ]) moleculesList.append([molecules[0], molecules[3]]) moleculesList.append([molecules[1], molecules[3]]) moleculesList.append([molecules[2], molecules[3]]) moleculesList.append( [molecules[0], molecules[1], molecules[3]]) moleculesList.append( [molecules[0], molecules[2], molecules[3]]) moleculesList.append( [molecules[1], molecules[2], molecules[3]]) moleculesList.append( [molecules[0], molecules[1], molecules[2], molecules[3]]) return moleculesList def updateMolecules(self): names = [] index = -1 moleculesList = self.getMolecules() if moleculesList: if self.molecules not in moleculesList: self.setMolecules(moleculesList[0]) self.symmetrySet = self.molSystem.findFirstMolSystemSymmetrySet( ) index = moleculesList.index(self.molecules) names = [] for molecules in moleculesList: names.append(','.join([mol.name for mol in molecules])) else: self.molecules = [] self.moleculePulldown.setup(names, index) def selectMolSystem(self, index, name): self.molSystem = self.getMolSystems()[index] self.symmetrySet = self.molSystem.findFirstMolSystemSymmetrySet() self.updateSymmetries() def getMolSystems(self): molSystems = [] for molSystem in self.project.sortedMolSystems(): n = len(molSystem.chains) if self.singleMolecule and (n > 1): molSystems.append(molSystem) elif n > 0: molSystems.append(molSystem) return molSystems def updateMolSystems(self): names = [] index = -1 molSystems = self.getMolSystems() if molSystems: if self.molSystem not in molSystems: self.molSystem = molSystems[0] index = molSystems.index(self.molSystem) names = [ms.code for ms in molSystems] else: self.molSystem = None self.molSystemPulldown.setup(names, index) def updateSymmetriesAfter(self, obj=None): if self.waiting: return else: self.waiting = True self.after_idle(self.updateSymmetries) def updateSymmetries(self): textMatrix = [] objectList = [] if self.symmetrySet: for symmetryOp in self.symmetrySet.symmetries: chains = [] segments = [] length = symmetryOp.segmentLength for segment in symmetryOp.sortedSegments(): code = segment.chainCode chain = self.molSystem.findFirstChain(code=code) if chain: chains.append(code) seqId = segment.firstSeqId residue1 = chain.findFirstResidue(seqId=seqId) residue2 = chain.findFirstResidue(seqId=seqId + length - 1) segments.append( '%s:%d-%d' % (code, residue1.seqCode, residue2.seqCode)) datum = [ symmetryOp.serial, symmetryOp.symmetryCode, length, '\n'.join(chains), '\n'.join(segments) ] objectList.append(symmetryOp) textMatrix.append(datum) self.symmetryMatrix.update(objectList=objectList, textMatrix=textMatrix) self.waiting = False def destroy(self): self.notify(self.unregisterNotify) BasePopup.destroy(self)
class ProchiralStatusPopup(TemporaryBasePopup): help_url = joinPath(getHelpUrlDir(), 'ProchiralStatus.html') def __init__(self, parent, chainList, chainAtomSetsDict): self.chainList = chainList self.chainAtomSetsDict = chainAtomSetsDict self.resParentDict = {} self.resParentList = [] self.resParentChainLabelDict = {} self.resParentChainLabelList = {} self.chainResonancesDict = {} for resParent in self.chainAtomSetsDict.keys(): if isinstance(resParent, NmrConstraint.NmrConstraintStore): strucGens = resParent.structureGenerations strucGenSerials = [str(sg.serial) for sg in strucGens] strucGenLabel = string.join(strucGenSerials, ',') resParentLabel = "Constraint set %d (strucGens %s)" % ( resParent.serial, strucGenSerials) else: resParentLabel = "Nmr project %s" % resParent.name self.resParentDict[resParentLabel] = resParent self.resParentList.append(resParentLabel) self.chainResonancesDict[resParent] = {} self.resParentChainLabelDict[resParent] = {} self.resParentChainLabelList[resParent] = [] for chain in self.chainList: self.project = chain.root if self.chainAtomSetsDict[resParent].has_key( chain) and self.chainAtomSetsDict[resParent][chain]: chainLabel = "Molecular system '%s':Chain '%s' (molecule '%s')" % ( chain.molSystem.code, chain.code, chain.molecule.name) self.resParentChainLabelList[resParent].append(chainLabel) self.resParentChainLabelDict[resParent][chainLabel] = chain self.chainResonancesDict[resParent][chain] = [] # modal = true means that it won't continue unless this one returns value TemporaryBasePopup.__init__( self, parent=parent, title="Project '%s': " % self.project.name + 'Set status prochiral atoms/resonances', modal=False, transient=True) def body(self, master): # # Setup header # row = 0 label = Label(master, text='Select the resonance list:') label.grid(row=row, column=0, sticky=Tkinter.EW) label = Label(master, text='Select the chain:') label.grid(row=row, column=1, sticky=Tkinter.EW) row += 1 self.resParentSelect = PulldownMenu(master, entries=self.resParentList, callback=self.setupResParentList, do_initial_callback=False) self.resParentSelect.grid(row=row, column=0, sticky=Tkinter.EW) self.chainSelect = PulldownMenu(master, entries=[], callback=self.setupProchiralList, do_initial_callback=False) self.chainSelect.grid(row=row, column=1, sticky=Tkinter.EW) row += 1 separator = Separator(master, height=3) separator.setColor('black', bgColor='black') separator.grid(row=row, columnspan=2, sticky=Tkinter.EW) row += 1 # THIS BIT TELLS MASTER TO CONFIGURE WINDOW ON INSIDE WIDGET!! master.grid_rowconfigure(row, weight=1) for i in range(2): master.grid_columnconfigure(i, weight=1) self.prochiralListFrame = ScrolledFrame(master, width=200, doExtraConfig=False) self.prochiralListFrame.grid(row=row, column=0, columnspan=2, sticky=Tkinter.NSEW) self.prochiralListFrameRow = row self.prochiralListFrameMaster = master row = row + 1 texts = ['Set all', 'Set chain'] commands = [ self.ok, self.setStereo ] # This calls 'ok' in BasePopup, this then calls 'apply' in here buttons = createDismissHelpButtonList(master, texts=texts, commands=commands, dismiss_text='Exit', help_url=self.help_url) buttons.grid(row=row, column=0, columnspan=2, sticky=Tkinter.EW) self.resParentSelect.callback(0, self.resParentList[0]) def setupResParentList(self, listIndex, resParentLabel): resParent = self.resParentDict[resParentLabel] self.resParent = resParent self.chainSelect.setup(self.resParentChainLabelList[self.resParent], 0) self.chainSelect.callback( 0, self.resParentChainLabelList[self.resParent][0]) def setupProchiralList(self, listIndex, chainLabel): chain = self.resParentChainLabelDict[self.resParent][chainLabel] self.chain = chain self.prochiralListFrame.destroy() self.prochiralListFrame = ScrolledFrame(self.prochiralListFrameMaster, width=200, doExtraConfig=False) self.prochiralListFrame.grid(row=self.prochiralListFrameRow, column=0, columnspan=2, sticky=Tkinter.NSEW) # # TODO: also handle case one resonance, two atomSets!?!? # frameRow = 0 x = y = 0 frame = self.prochiralListFrame.frame self.resonanceObjects = {} self.resonanceLabelDict = {} # # Reuse previous settings... # if len(self.chainResonancesDict[self.resParent][chain]) == len( self.chainAtomSetsDict[self.resParent][chain]): usePreviousSettings = True else: usePreviousSettings = False for i in range(0, len(self.chainAtomSetsDict[self.resParent][chain])): atomSetGroup = self.chainAtomSetsDict[self.resParent][chain][i] isStereo = False hasResonances = False isValidCase = False resonances = [] if usePreviousSettings and self.chainResonancesDict[ self.resParent][chain][i]: resonances = self.chainResonancesDict[ self.resParent][chain][i][3] isStereo = self.chainResonancesDict[ self.resParent][chain][i][0] hasResonances = True isValidCase = True else: for atomSet in atomSetGroup: resonanceSets = atomSet.sortedResonanceSets() if resonanceSets: hasResonances = True for resonanceSet in resonanceSets: for resonance in resonanceSet.sortedResonances(): if resonance not in resonances: resonances.append(resonance) if len(resonanceSets) == 1: isValidCase = True if len(resonanceSet.atomSets) == 1: isStereo = True else: # Case only one resonance but stereo assigned resonances.append(0) if len(resonances) == 1: # Case only one resonance, not stereo assigned resonances.append(None) # # Set up only for valid cases # if hasResonances and isValidCase: if not usePreviousSettings: self.chainResonancesDict[self.resParent][chain].append( [isStereo, False, False, resonances]) residue = atomSetGroup[0].findFirstAtom().residue ccpCode = residue.molResidue.ccpCode seqCode = residue.seqCode rowspan = 2 checkButton = CheckButton( frame, selected=isStereo, callback=lambda status=isStereo, fr=frameRow, item=i, setup =False: self.toggleResonances(status, fr, item, setup)) checkButton.grid(row=frameRow, rowspan=rowspan, column=0, sticky=Tkinter.EW) label = Label(frame, text=ccpCode, width=5) label.grid(row=frameRow, rowspan=rowspan, column=1, sticky=Tkinter.E) label = Label(frame, text=str(seqCode), width=5) label.grid(row=frameRow, rowspan=rowspan, column=2, sticky=Tkinter.W) # # Set up the atom names # for j in range(0, len(atomSetGroup)): atomSet = atomSetGroup[j] label = Label(frame, text=atomSet.name) label.grid(row=frameRow + j, column=3, sticky=Tkinter.E, ipadx=4) # # Set up the resonances # self.resonanceObjects[frameRow] = { True: [[], []], False: [[], []] } resonanceLabelList = [] for resonance in resonances: if not resonance: resonanceLabel = 'unknown' else: if hasattr(resonance, 'shifts') and resonance.shifts: shiftLabel = " (shifts: " for shift in resonance.sortedShifts(): shiftLabel += "%.2f, " % shift.value shiftLabel = shiftLabel[:-2] + ")" else: shiftLabel = "" resonanceLabel = "'%d.%s'%s" % ( seqCode, resonance.name, shiftLabel) self.resonanceLabelDict[resonanceLabel] = resonance resonanceLabelList.append(resonanceLabel) separator = Separator(frame, height=1, width=30) separator.setColor('black', bgColor='black') separator.grid(row=frameRow, column=4, sticky=Tkinter.EW) self.resonanceObjects[frameRow][True][0].append(separator) separator = CrossLine(frame, height=20, width=30, canvas_bg=frame['bg'], color='dimgray') self.resonanceObjects[frameRow][False][0].append(separator) resonanceList = PulldownMenu( frame, entries=resonanceLabelList, callback=lambda selInd=x, selItem=y, fr=frameRow, item=i: self.setProchiralLabels(selInd, selItem, fr, item), do_initial_callback=False, label_color='red') resonanceList.grid(row=frameRow, column=5, sticky=Tkinter.EW) self.resonanceObjects[frameRow][True][0].append(resonanceList) resonanceLabel = Label(frame, text="%s" % resonanceLabelList[0], fg='dimgray') self.resonanceObjects[frameRow][False][0].append( resonanceLabel) separator = Separator(frame, height=1, width=30) separator.setColor('black', bgColor='black') separator.grid(row=frameRow + 1, column=4) self.resonanceObjects[frameRow][True][1].append(separator) self.resonanceObjects[frameRow][False][1].append(None) resonanceLabel = Label(frame, text="%s" % resonanceLabelList[1], fg='red') resonanceLabel.grid(row=frameRow + 1, column=5, sticky=Tkinter.EW) self.resonanceObjects[frameRow][True][1].append(resonanceLabel) resonanceLabel = Label(frame, text="%s" % resonanceLabelList[1], fg='dimgray') self.resonanceObjects[frameRow][False][1].append( resonanceLabel) if not isStereo: checkButton.callback(isStereo, setup=True) separator = Separator(frame, height=1) separator.setColor('black', bgColor='black') separator.grid(row=frameRow + rowspan, columnspan=6, sticky=Tkinter.EW) frameRow += rowspan + 1 elif not usePreviousSettings: self.chainResonancesDict[self.resParent][chain].append(None) return True def setProchiralLabels(self, selInd, selItem, fr, item): resonanceLabel = self.resonanceObjects[fr][True][0][1].entries[selInd] self.resonanceObjects[fr][False][0][1].set(resonanceLabel) selInd = not selInd resonanceLabel = self.resonanceObjects[fr][True][0][1].entries[selInd] self.resonanceObjects[fr][True][1][1].set(resonanceLabel) self.resonanceObjects[fr][False][1][1].set(resonanceLabel) self.chainResonancesDict[self.resParent][ self.chain][item][2] = not self.chainResonancesDict[ self.resParent][self.chain][item][2] self.chainResonancesDict[self.resParent][self.chain][item][3].reverse() def toggleResonances(self, status, frameRow, item, setup): if not setup: self.chainResonancesDict[self.resParent][ self.chain][item][0] = status self.chainResonancesDict[self.resParent][ self.chain][item][1] = not self.chainResonancesDict[ self.resParent][self.chain][item][1] for i in range(0, len(self.resonanceObjects[frameRow])): # # Remove other widgets from grid # rpds = self.resonanceObjects[frameRow][not status][i] for rpd in rpds: if rpd: rpd.grid_forget() # # Set current widgets # rpds = self.resonanceObjects[frameRow][status][i] for j in range(0, len(rpds)): rpd = rpds[j] if rpd: keywds = {} if j == 1: keywds['sticky'] = Tkinter.W if j == 0: if not status: keywds['rowspan'] = 2 rpd.grid(row=frameRow + i, column=4 + j, **keywds) def setStereo(self, chain=None): if not chain: chain = self.chain if self.chainResonancesDict[self.resParent][chain]: for i in range( 0, len(self.chainResonancesDict[self.resParent][chain])): atomSetGroup = self.chainAtomSetsDict[self.resParent][chain][i] (stereoStatus, stereoStatusChanged, resChanged, resonances ) = self.chainResonancesDict[self.resParent][chain][i] if stereoStatusChanged or (stereoStatus and resChanged): residue = atomSetGroup[0].findFirstAtom().residue ccpCode = residue.molResidue.ccpCode seqCode = residue.seqCode atomText = "%s/%s" % (atomSetGroup[0].name, atomSetGroup[1].name) if stereoStatusChanged: if stereoStatus: stereoText = "non-stereospecific to stereospecific." else: stereoText = "stereospecific to non-stereospecific." print " Warning: Changed '%s.%d' prochiral resonances for atoms %s from %s" % ( ccpCode, seqCode, atomText, stereoText) self.chainResonancesDict[ self.resParent][chain][i][1] = False self.chainResonancesDict[ self.resParent][chain][i][2] = False if stereoStatus: resonanceSet = atomSetGroup[ 0].findFirstResonanceSet() if resonances[0]: resonanceSet.removeAtomSet(atomSetGroup[1]) if resonances[1]: if not resonances[0]: # Remove right atom set if only one resonance... resonanceSet.removeAtomSet(atomSetGroup[0]) else: # Only create a new resonance set if two resonances present! resonanceSet.removeResonance(resonances[1]) if isinstance( self.resParent, NmrConstraint.NmrConstraintStore): newResonanceSet = self.resParent.newFixedResonanceSet( resonances=[resonances[1]], atomSets=[atomSetGroup[1]]) else: newResonanceSet = self.resParent.newResonanceSet( resonances=[resonances[1]], atomSets=[atomSetGroup[1]]) else: if resonances[0]: resonanceSet = atomSetGroup[ 0].findFirstResonanceSet() if resonances[1]: atomSetGroup[1].findFirstResonanceSet( ).delete() resonanceSet.addResonance(resonances[1]) resonanceSet.addAtomSet(atomSetGroup[1]) elif resonances[1]: resonanceSet = atomSetGroup[1].resonanceSets[0] resonanceSet.addAtomSet(atomSetGroup[0]) elif stereoStatus and resChanged: print " Warning: Changed resonance assignment for '%s.%d' stereospecifically assigned atoms %s." % ( ccpCode, seqCode, atomText) self.chainResonancesDict[ self.resParent][chain][i][2] = False resonanceSets = [] for i in range(0, 2): if atomSetGroup[i].resonanceSets: resonanceSets.append( atomSetGroup[i].findFirstResonanceSet()) else: resonanceSets.append(None) for i in range(0, 2): resonanceSet = resonanceSets[i] if resonanceSet: resonanceSet.addAtomSet(atomSetGroup[not i]) resonanceSet.removeAtomSet(atomSetGroup[i]) def apply(self): for chain in self.chainList: self.setStereo(chain=chain) return True
class EditResStructuresPopup(BasePopup): def __init__(self, parent, *args, **kw): self.guiParent = parent self.structure = None self.constraintSet = None self.cloud = None self.cloudRmsdDict = {} self.strucRmsdDict = {} self.waiting = False BasePopup.__init__(self, parent=parent, title="Resonance Cloud Structures", **kw) def body(self, guiFrame): row = 0 guiFrame.grid_columnconfigure(1, weight=1) guiFrame.grid_rowconfigure(0, weight=0) guiFrame.grid_rowconfigure(1, weight=1) self.generationLabel = Label(guiFrame, text='Structure Generation:') constraintSets = [] constraintSetNames = [] index = -1 for constraintSet in self.project.nmrConstraintStores: index += 1 constraintSets.append(constraintSet) constraintSetNames.append(str(constraintSet.serial)) self.constraintSet = constraintSet self.constrSetPulldown = PulldownMenu(guiFrame, self.changeConstraintSet, constraintSetNames, selected_index=index, do_initial_callback=False) self.generationLabel.grid(row=row, column=0, columnspan=1, sticky='e') self.constrSetPulldown.grid(row=row, column=1, columnspan=1, sticky='w') strucLabel = Label(guiFrame, text='Comparison structure') strucLabel.grid(row=row, column=2, sticky='e') self.strucPulldown = PulldownMenu(guiFrame, entries=self.getStructures(), callback=self.setStructure, selected_index=0, do_initial_callback=False) self.strucPulldown.grid(row=row, column=3, sticky='w') sdTolLabel = Label(guiFrame, text='Tolerance (SDs):') sdTolLabel.grid(row=row, column=4, sticky='e') self.sdToleranceEntry = FloatEntry(guiFrame, text=2.0, width=6) self.sdToleranceEntry.grid(row=row, column=5, stick='w') row += 1 colHeadings = ['#', 'File name', 'RMSD to mean', 'RMSD to structure'] self.scrolledMatrix = ScrolledMatrix(guiFrame, initialRows=10, headingList=colHeadings, callback=self.selectCell, objectList=[], textMatrix=[ [], ]) self.scrolledMatrix.grid(row=row, column=0, columnspan=6, sticky='nsew') row += 1 texts = [ 'Calc\nRMSD', 'Make Cloud\nfrom structure', 'Delete', 'Delete\nbad' ] commands = [ self.calcRmsd, self.makeStrucCloud, self.deleteCloud, self.filterClouds ] self.bottomButtons = UtilityButtonList(guiFrame, texts=texts, expands=False, commands=commands, helpUrl=self.help_url) self.bottomButtons.grid(row=row, column=0, columnspan=6, sticky='nsew') self.update() for func in ('__init__', 'delete'): self.registerNotify(self.updateStructureGen, 'ccp.nmr.Nmr.StructureGeneration', func) def open(self): self.updateAfter() BasePopup.open(self) def getStructures(self): names = [ '<None>', ] for molSystem in self.project.sortedMolSystems(): for structure in molSystem.sortedStructureEnsembles(): names.append('%s:%d' % (molSystem.name, structure.ensembleId)) return names def setStructure(self, index, name=None): if index < 1: self.structure = None else: structures = [] for molSystem in self.project.sortedMolSystems(): for structure in molSystem.sortedStructureEnsembles(): structures.append(structure) self.structure = structures[index - 1] def filterClouds(self): if self.constraintSet: sdTolerance = self.sdToleranceEntry.get() or 2.0 keptClouds = [] clouds = self.guiParent.application.getValues( self.constraintSet, 'clouds') meanGroupRmsds = [] for cloud in clouds: rmsd = self.cloudRmsdDict.get(cloud) if rmsd is not None: meanGroupRmsds.append(rmsd) meanRmsd = 0.0 N = 0 for rmsd in meanGroupRmsds: meanRmsd += rmsd N += 1 if N > 0: meanRmsd /= float(N) sd = 0.0 for rmsd in meanGroupRmsds: sd += (rmsd - meanRmsd) * (rmsd - meanRmsd) if N > 0: sd /= float(N - 1) sd = sqrt(sd) print meanRmsd, '+/-', sd n = 0 for cloud in clouds: rmsd = self.cloudRmsdDict.get(cloud) if rmsd is None: keptClouds.append(cloud) elif abs(rmsd - meanRmsd) > (sdTolerance * sd): print 'Cloud %s is bad' % (cloud) else: keptClouds.append(cloud) self.guiParent.application.setValues(self.constraintSet, 'clouds', values=keptClouds) self.updateAfter() def makeStrucCloud(self): if self.structure: serials = self.guiParent.application.getValues( self.constraintSet, 'cloudsResonances') pdbFileName = 'CloudForStructure.pdb' #from ccpnmr.clouds.AtomCoordList import AtomCoordList from ccpnmr.c.AtomCoordList import AtomCoordList atomCoordList = AtomCoordList() resDict = {} hmass = 25 print "L1", len(serials) for resonance in self.nmrProject.resonances: resDict[resonance.serial] = resonance print "L2", len(resDict) resonances = [] for serial in serials: if resDict.get(serial) is not None: resonances.append(resDict[serial]) print "L3", len(resonances) C = 0 for resonance in resonances: resonanceSet = resonance.resonanceSet if resonanceSet: i = resonanceSet.sortedResonances().index(resonance) atomSet = resonance.resonanceSet.sortedAtomSets()[i] coords = getAtomSetCoords(atomSet, self.structure) coord = coords[0] atomCoordList.add(hmass, coord.x, coord.y, coord.z) C += 1 print "L4", len(atomCoordList) from ccpnmr.clouds.FilterClouds import writeTypedPdbCloud writeTypedPdbCloud(atomCoordList, pdbFileName, resonances) clouds = self.guiParent.application.getValues( self.constraintSet, 'clouds') clouds.append(pdbFileName) self.guiParent.application.setValues(self.constraintSet, 'clouds', values=clouds) self.updateAfter() def calcRmsd(self): if self.constraintSet: clouds = self.guiParent.application.getValues( self.constraintSet, 'clouds') from ccpnmr.clouds.FilterClouds import filterClouds rmsds = filterClouds(clouds) n = len(clouds) for i in range(n): cloud = clouds[i] rmsd = rmsds[i] self.cloudRmsdDict[cloud] = rmsd self.updateAfter() def changeConstraintSet(self, i, name): project = self.project if project.nmrConstraintStores: constraintSet = project.nmrConstraintStores[i] else: constraintSet = None if constraintSet is not self.constraintSet: self.constraintSet = constraintSet self.cloud = None self.updateAfter() def deleteCloud(self): if self.constraintSet and self.cloud and showOkCancel( 'Confirm', 'Really delete resonance cloud?', parent=self): clouds = self.guiParent.application.getValues( self.constraintSet, 'clouds') if clouds: clouds.remove(self.cloud) self.cloud = None self.guiParent.application.setValues(self.constraintSet, 'clouds', values=clouds) self.updateAfter() def selectCell(self, cloud, row, col): self.cloud = cloud self.bottomButtons.buttons[1].enable() def updateAfter(self, *opt): if self.waiting: return else: self.waiting = True self.after_idle(self.update) def getConstraintSetNames(self): names = [] constraintSets = self.project.nmrConstraintStores for set in constraintSets: names.append('%d' % set.serial) return names def updateStructureGen(self, *opt): project = self.project constraintSets = self.project.sortedNmrConstraintStores if constraintSets: constraintSetNames = self.getConstraintSetNames() # set defaults if self.constraintSet not in constraintSets: self.constraintSet = constraintSets[0] self.cloud = None i = constraintSets.index(self.constraintSet) self.constrSetPulldown.setup(constraintSetNames, i) else: self.constraintSet = None self.cloud = None self.constrSetPulldown.setup([], -1) def destroy(self): for func in ('__init__', 'delete'): self.unregisterNotify(self.updateStructureGen, 'ccp.nmr.Nmr.StructureGeneration', func) BasePopup.destroy(self) def update(self): objectList = [] textMatrix = [] if self.constraintSet: clouds = self.guiParent.application.getValues( self.constraintSet, 'clouds') if clouds: objectList = list(clouds) i = 0 for cloud in objectList: i += 1 datum = [] datum.append(i) datum.append(cloud) datum.append(self.cloudRmsdDict.get(cloud) or '-') datum.append(self.strucRmsdDict.get(cloud) or '-') textMatrix.append(datum) if not self.cloud: self.bottomButtons.buttons[1].disable() self.scrolledMatrix.update(objectList=objectList, textMatrix=textMatrix) self.waiting = False
class PredictKarplusPopup(BasePopup): def __init__(self, parent, *args, **kw): self.waiting = False self.molSystem = None self.residue = None self.jCouplings = [] self.atomNames = [] self.measureJCouplingList = None self.predictJCouplingList = None self.coeffAtomNames = [] self.coefficients = {} self.coefficient = None for i in range(3): self.coefficients[i] = {} BasePopup.__init__( self, parent=parent, title='Predict Karplus Coefficients from J Coupling', **kw) self.updateJCouplingLists() self.updateMolSystems() self.updateAfter() def body(self, guiFrame): guiFrame.grid_columnconfigure(0, weight=1, minsize=500) row = 0 frame = LabelFrame(guiFrame, text='General Options') frame.grid(row=row, column=0, sticky='nsew') frame.grid_columnconfigure(1, weight=1) label = Label(frame, text='Molecular System:') label.grid(row=0, column=0, sticky='w') self.molSystemPulldown = PulldownMenu(frame, self.changeMolSystem, do_initial_callback=False) self.molSystemPulldown.grid(row=0, column=1, sticky='w') label = Label(frame, text='Measured J coupling list:') label.grid(row=0, column=2, sticky='w') self.measureCouplingListPulldown = PulldownMenu( frame, self.changeMeasureCouplingList) self.measureCouplingListPulldown.grid(row=0, column=3, sticky='w') label = Label(frame, text='Predicted J coupling list:') label.grid(row=0, column=4, sticky='w') self.predictCouplingListPulldown = PulldownMenu( frame, self.changePredictCouplingList) self.predictCouplingListPulldown.grid(row=0, column=5, sticky='w') row += 1 guiFrame.grid_rowconfigure(row, weight=1) frame = LabelFrame(guiFrame, text='Angles & 3J Couplings') frame.grid(row=row, column=0, sticky='nsew') frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(0, weight=1) headingList = ['Residue', 'Phi', 'Chi^2'] editWidgets = [None, None, None] editGetCallbacks = [None, None, None] editSetCallbacks = [None, None, None] self.jCouplingEntry = FloatEntry( self, width=8, returnCallback=lambda event: self.setJCoupling()) i = 0 for names in couplingAtoms: headingList.extend( ['Pred\nJ(%s,%s)' % names, 'Expt\nJ(%s,%s)' % names]) editWidgets.extend([None, self.jCouplingEntry]) editGetCallbacks.extend( [None, lambda obj, i=i: self.getJCoupling(obj, i)]) editSetCallbacks.extend( [None, lambda event, i=i: self.setJCoupling(i)]) i += 1 self.couplingMatrix = ScrolledMatrix(frame, headingList=headingList, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, callback=self.selectJCoupling, multiSelect=False) self.couplingMatrix.grid(row=0, column=0, sticky='nsew') self.couplingMatrix.doEditMarkExtraRules = self.doEditMarkExtraRules row += 1 frame = LabelFrame(guiFrame, text='Karplus Coefficients') frame.grid(row=row, column=0, sticky='nsew') frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(0, weight=1) headingList = ['Phase'] editWidgets = [ None, ] editGetCallbacks = [ None, ] editSetCallbacks = [ None, ] self.coefficientEntry = FloatEntry( self, width=8, returnCallback=lambda event: self.setCoefficient()) for names in couplingAtoms: headingList.append('J(%s,%s)' % names) editWidgets.append(self.coefficientEntry) editGetCallbacks.append( lambda obj, n=names: self.getCoefficient(obj, n)) editSetCallbacks.append( lambda event, n=names: self.setCoefficient(n)) headingList = [ 'Phase', 'J(H,HA)', 'J(H,C)', 'J(H,CB)', 'J(C,HA)', 'J(C,C)', 'J(C,CB)' ] self.coefficientMatrix = ScrolledMatrix( frame, headingList=headingList, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, callback=self.selectCoefficient, maxRows=3, multiSelect=False) self.coefficientMatrix.grid(row=0, column=0, sticky='nsew') row += 1 texts = [] commands = [] self.bottomButtons = UtilityButtonList(guiFrame, commands=commands, texts=texts, helpUrl=self.help_url) self.bottomButtons.grid(row=row, column=0, sticky='ew') for func in ('__init__', 'delete', 'setValue', 'setError'): for clazz in ('ccp.nmr.Nmr.JCoupling', ): self.registerNotify(self.updateAfter, clazz, func) for func in ('__init__', 'delete'): for clazz in ('ccp.nmr.Nmr.JCouplingList', ): self.registerNotify(self.updateJCouplingLists, clazz, func) def getJCouplingLists(self, isSimulated=False): jCouplingLists = self.nmrProject.findAllMeasurementLists( className='JCouplingList', isSimulated=isSimulated) return jCouplingLists def updateJCouplingLists(self, *obj): jCouplingLists = self.getJCouplingLists(isSimulated=False) names = [ '%d:%s' % (jcl.serial, jcl.name or '') for jcl in jCouplingLists ] names.append('<New>') index = -1 if jCouplingLists: if self.measureJCouplingList in jCouplingLists: index = jCouplingLists.index(self.measureJCouplingList) else: self.measureJCouplingList = jCouplingLists[0] index = 0 else: self.measureJCouplingList = None self.measureCouplingListPulldown.setup(names, index) jCouplingLists = self.getJCouplingLists(isSimulated=True) names = ['%d:%s' % (jcl.serial, jcl.name) for jcl in jCouplingLists] names.append('<New>') index = -1 if jCouplingLists: if self.predictJCouplingList in jCouplingLists: index = jCouplingLists.index(self.predictJCouplingList) else: self.predictJCouplingList = jCouplingLists[0] index = 0 else: self.predictJCouplingList = None self.predictCouplingListPulldown.setup(names, index) def changeMeasureCouplingList(self, index, name): if name == '<New>': self.measureJCouplingList = None else: jCouplingLists = self.getJCouplingLists() jCouplingList = jCouplingLists[index] if jCouplingList is not self.measureJCouplingList: self.measureJCouplingList = jCouplingList if self.predictJCouplingList is self.measureJCouplingList: for jCouplingList2 in jCouplingLists: if self.measureJCouplingList is not jCouplingList2: self.predictJCouplingList = jCouplingList2 break else: self.predictJCouplingList = None self.updateAfter() def changePredictCouplingList(self, index, name): if name == '<New>': self.predictJCouplingList = None self.updateAfter() else: jCouplingLists = self.getJCouplingLists() jCouplingList = jCouplingLists[index] if jCouplingList is not self.predictJCouplingList: self.predictJCouplingList = jCouplingList if self.predictJCouplingList is self.measureJCouplingList: for jCouplingList2 in jCouplingLists: if self.predictJCouplingList is not jCouplingList2: self.measureJCouplingList = jCouplingList2 break else: self.measureJCouplingList = None self.updateAfter() def doEditMarkExtraRules(self, obj, row, col): i = (col - 3) / 2 if i > -1: atoms = couplingAtoms[i] residue = obj[0] for atomName in atoms: if not residue.findFirstAtom(name=atomName): return False return True def open(self): self.updateMolSystems() BasePopup.open(self) def selectJCoupling(self, object, row, col): self.residue = object[0] self.jCouplings = object[1:] def selectCoefficient(self, object, row, col): self.coefficient = object def getCoefficient(self, object, atomNames): self.coeffAtomNames = atomNames coefficient = self.coefficients[object].get(atomNames) self.coefficientEntry.set(coefficient) def setCoefficient(self, atomNames=None): if not atomNames: atomNames = self.coeffAtomNames value = self.coefficientEntry.get() if atomNames and (self.coefficient is not None): self.coefficients[self.coefficient][atomNames] = value #print self.coefficient, atomNames, value self.updateCoefficients() def getJCoupling(self, object, index): atomNames = couplingAtoms[index] self.atomNames = atomNames coupling = object[index + 1] if not coupling: residue = object[0] coupling = self.getResidueJCoupling(self.measureJCouplingList, residue, atomNames) if coupling: value = coupling.value else: value = None self.jCouplingEntry.set(value) def setJCoupling(self, index=None): if not index: atomNames = self.atomNames index = couplingAtoms.index(atomNames) else: atomNames = couplingAtoms[index] value = self.jCouplingEntry.get() if self.residue and atomNames: coupling = self.jCouplings[index] if value is None: if coupling: if showOkCancel('Confirm', 'Really remove J coupling?', parent=self): coupling.delete() else: if not coupling: self.setResidueJCoupling(self.measureJCouplingList, self.residue, atomNames, value, isSimulated=False) else: coupling.setValue(value) def getResidueJCoupling(self, jCouplingList, residue, atomNames): if jCouplingList: return getResidueJCoupling(jCouplingList, residue, atomNames) def setResidueJCoupling(self, jCouplingList, residue, atomNames, value, isSimulated=False): if jCouplingList is None: jCouplingList = self.nmrProject.newJCouplingList( isSimulated=isSimulated) if isSimulated: self.predictJCouplingList = jCouplingList else: self.measureJCouplingList = jCouplingList setResidueJCoupling(jCouplingList, self.residue, atomNames, value) def updateMolSystems(self, *obj): index = -1 names = [] molSystems = self.project.sortedMolSystems() if molSystems: if self.molSystem not in molSystems: self.molSystem = molSystems[0] names = [ms.code for ms in molSystems] index = molSystems.index(self.molSystem) self.molSystemPulldown.setup(names, index) def changeMolSystem(self, index, name): molSystems = self.project.sortedMolSystems() if molSystems: molSystem = molSystems[index] else: molSystem = None if molSystem is not self.molSystem: self.molSystem = molSystem self.updateAfter() def updateAfter(self, object=None): current = False if object and (object.className == 'JCoupling'): for resonance in object.resonances: resonanceSet = resonance.resonanceSet if resonanceSet: molSystem = resonanceSet.findFirstAtomSet().findFirstAtom( ).topObject if molSystem is self.molSystem: current = True break else: current = True if self.waiting or (not current): return else: self.waiting = True self.after_idle(self.update) def update(self): textMatrix = [] objectList = [] if self.molSystem: chains = self.molSystem.sortedChains() if len(chains) > 1: doChains = False else: doChains = True for chain in chains: if doChains: chainCode = chain.code else: chainCode = '' for residue in chain.sortedResidues(): name = '%s%d%s' % (chainCode, residue.seqCode, getResidueCode(residue)) phi = 0.0 chiSq = 0.0 datum = [name, phi, chiSq] object = [ residue, ] for atomNames in couplingAtoms: couplingM = self.getResidueJCoupling( self.measureJCouplingList, residue, atomNames) couplingP = self.getResidueJCoupling( self.predictJCouplingList, residue, atomNames) pred = None expt = None if couplingM: expt = couplingM.value if couplingP: pred = couplingP.value datum.append(pred) datum.append(expt) object.append(couplingM) objectList.append(object) textMatrix.append(datum) self.couplingMatrix.update(textMatrix=textMatrix, objectList=objectList) self.updateCoefficients() self.waiting = False def updateCoefficients(self): textMatrix = [] objectList = [] for i in range(3): name = 'C%d' % i datum = [ name, ] for atomNames in couplingAtoms: datum.append(self.coefficients[i].get(atomNames)) textMatrix.append(datum) objectList.append(i) self.coefficientMatrix.update(textMatrix=textMatrix, objectList=objectList) def destroy(self): for func in ('__init__', 'delete', 'setValue', 'setError'): for clazz in ('ccp.nmr.Nmr.JCoupling', ): self.unregisterNotify(self.updateAfter, clazz, func) for func in ('__init__', 'delete'): for clazz in ('ccp.nmr.Nmr.JCouplingList', ): self.unregisterNotify(self.updateJCouplingLists, clazz, func) BasePopup.destroy(self)
class BacusPopup(BasePopup): def __init__(self, parent, *args, **kw): self.project = parent.project self.hNoesy = None self.nNoesy = None self.cNoesy = None self.shiftList = None BasePopup.__init__(self, parent, title="BACUS control module", **kw) def body(self, guiParent): guiParent.grid_columnconfigure(0, weight=1) row = 0 guiParent.grid_rowconfigure(row, weight=1) inputFrame = LabelFrame(guiParent, text='Inputs:') inputFrame.grid(row=row, column=0, sticky=Tkinter.NSEW) label = Label(inputFrame, text='NOESY:') label.grid(row=0, column=0, sticky=Tkinter.NW) self.hNoesyPulldown = PulldownMenu(inputFrame,callback=self.setHNoesy) self.hNoesyPulldown.grid(row=0, column=1, sticky=Tkinter.NW) label = Label(inputFrame, text='15N NOESY:') label.grid(row=1, column=0, sticky=Tkinter.NW) self.nNoesyPulldown = PulldownMenu(inputFrame,callback=self.setNNoesy) self.nNoesyPulldown.grid(row=1, column=1, sticky=Tkinter.NW) label = Label(inputFrame, text='13C NOESY:') label.grid(row=2, column=0, sticky=Tkinter.NW) self.cNoesyPulldown = PulldownMenu(inputFrame,callback=self.setCNoesy) self.cNoesyPulldown.grid(row=2, column=1, sticky=Tkinter.NW) label = Label(inputFrame, text='Shift List:') label.grid(row=3, column=0, sticky=Tkinter.NW) self.shiftListPulldown = PulldownMenu(inputFrame,callback=self.setShiftList) self.shiftListPulldown.grid(row=3, column=1, sticky=Tkinter.NW) label = Label(inputFrame, text='2d BACUS executable:') label.grid(row=4, column=0, sticky=Tkinter.NW) self.executableEntry = Entry(inputFrame, text='/home/tjs23/clouds/justin/SpiBacusMidge/bacus/bacus_tjs.exe') self.executableEntry.grid(row=4, column=1, sticky=Tkinter.NW) self.executableButton = Button(inputFrame, text='Choose file', command=self.chooseExecutable) self.executableButton.grid(row=5, column=1, sticky=Tkinter.EW) row += 1 outputFrame = LabelFrame(guiParent, text='Output:') outputFrame.grid(row=row, column=0, sticky=Tkinter.NSEW) row += 1 texts = ['Run BACUS 2d','Run BACUS 3d'] commands = [self.runBacus,self.runBacus3d] self.bottomButtons = createDismissHelpButtonList(guiParent,texts=texts,commands=commands,expands=0,help_url=None) self.bottomButtons.grid(row=row, column=0, sticky=Tkinter.EW) self.update() def chooseExecutable(self): fileTypes = [FileType('Table', ['*.exe']), FileType('All', ['*'])] fileSelectPopup = FileSelectPopup(self, file_types = fileTypes, title = 'Choose 2d BACUS executable', dismiss_text = 'Cancel', selected_file_must_exist = False) fileName = fileSelectPopup.getFile() if fileName: self.executableEntry.set(fileName) def update(self): # set defaults via pulldown callbacks names = [self.getPeakListlabel(x) for x in self.gethNoesys()] if names: self.hNoesyPulldown.setup(names,0) else: self.hNoesyPulldown.setup([],-1) names = [self.getPeakListlabel(x) for x in self.getNNoesys()] if names: self.nNoesyPulldown.setup(names,0) else: self.nNoesyPulldown.setup([],-1) names = [self.getPeakListlabel(x) for x in self.getCNoesys()] if names: self.cNoesyPulldown.setup(names,0) else: self.cNoesyPulldown.setup([],-1) names = ['Shift List %d' % x.serial for x in self.getShiftLists()] if names: self.shiftListPulldown.setup(names,0) else: self.shiftListPulldown.setup([],-1) self.updateButtons() def updateButtons(self): if ( self.cNoesy or self.nNoesy ) and self.shiftList: self.bottomButtons.buttons[1].enable() else: self.bottomButtons.buttons[1].disable() if self.hNoesy and self.executableEntry.get() and self.shiftList: self.bottomButtons.buttons[0].enable() else: self.bottomButtons.buttons[0].disable() def runBacus3d(self, fileRoot='CCPN1'): if ( self.cNoesy or self.nNoesy ) and self.shiftList: run3dBacus(fileRoot,self.shiftList,self.cNoesy,self.nNoesy) def runBacus(self, fileRoot='CCPN1'): executable = self.executableEntry.get() if self.hNoesy and self.shiftList and executable: run2dBacus(fileRoot, executable, self.hNoesy, self.shiftList) def getPeakListlabel(self, peakList): return '%s:%s:%d' % (peakList.dataSource.experiment.name, peakList.dataSource.name, peakList.serial) def getShiftLists(self): shiftLists = [] if self.project: nmrProject = self.project.currentNmrProject shiftLists = nmrProject.findAllMeasurementLists(className='ShiftList') return list(shiftLists) def setShiftList(self, index, name=None): shiftLists = self.getShiftLists() if shiftLists: self.shiftList = shiftLists[index] else: self.shiftList = None def gethNoesys(self): peakLists = [] if self.project: for experiment in self.project.currentNmrProject.experiments: for spectrum in experiment.dataSources: isotopes = getSpectrumIsotopes(spectrum) if isotopes == ['1H', '1H']: for peakList in spectrum.peakLists: #if 'NOE' in experiment.name.upper(): # peakLists.insert(0, peakList) #else: peakLists.append(peakList) return peakLists def getNNoesys(self): peakLists = [] if self.project: for experiment in self.project.currentNmrProject.experiments: for spectrum in experiment.dataSources: isotopes = getSpectrumIsotopes(spectrum) isotopes.sort() if isotopes == ['15N', '1H', '1H']: for peakList in spectrum.peakLists: #if 'NOE' in experiment.name.upper(): # peakLists.insert(0, peakList) #else: peakLists.append(peakList) return peakLists def getCNoesys(self): peakLists = [] if self.project: for experiment in self.project.currentNmrProject.experiments: for spectrum in experiment.dataSources: isotopes = getSpectrumIsotopes(spectrum) isotopes.sort() if isotopes == ['13C', '1H', '1H']: for peakList in spectrum.peakLists: if 'NOE' in experiment.name.upper(): peakLists.insert(0, peakList) else: peakLists.append(peakList) return peakLists def setHNoesy(self, index, name=None): peakLists = self.gethNoesys() if peakLists: self.hNoesy = peakLists[index] else: self.hNoesy = None def setNNoesy(self, index, name=None): peakLists = self.getNNoesys() if peakLists: self.nNoesy = peakLists[index] else: self.nNoesy = None def setCNoesy(self, index, name=None): peakLists = self.getCNoesys() if peakLists: self.cNoesy = peakLists[index] else: self.cNoesy = None def destroy(self): BasePopup.destroy(self)
class HcloudsMdPopup(BasePopup): def __init__(self, parent, *args, **kw): self.guiParent = parent self.project = parent.getProject() self.waiting = 0 self.constraintSet = None self.constrLists = [None] * 4 self.numClouds = 100 self.filePrefix = 't_intra_' self.cloudsFiles = [] self.adcAtomTypes = 'HN' # step num, initial temp, final temp, cooling steps, MD steps, MD tau, rep scale self.coolingScheme = [] self.coolingScheme.append([1, 1, 1, 3, 500, 0.001, 0]) self.coolingScheme.append([2, 80000, 4000, 19, 1000, 0.001, 0]) self.coolingScheme.append([3, 4000, 1, 5, 500, 0.001, 0]) self.coolingScheme.append([4, 15000, 1, 3, 1000, 0.001, 0]) self.coolingScheme.append([5, 1, 1, 5, 500, 0.001, 0]) self.coolingScheme.append([6, 8000, 1, 3, 1000, 0.001, 0]) self.coolingScheme.append([7, 1, 1, 5, 500, 0.001, 0]) self.coolingScheme.append([8, 3000, 25, 60, 2500, 0.001, 1]) self.coolingScheme.append([9, 25, 25, 1, 7500, 0.001, 1]) self.coolingScheme.append([10, 10, 10, 1, 7500, 0.001, 1]) self.coolingScheme.append([11, 0.01, 0.01, 1, 7500, 0.0005, 1]) self.coolingStep = None BasePopup.__init__(self, parent, title="Hydrogen Cloud Molecular Dynamics", **kw) def body(self, guiFrame): self.mdInitTempEntry = FloatEntry(self, text='', returnCallback=self.setMdInitTemp) self.mdFinTempEntry = FloatEntry(self, text='', returnCallback=self.setMdFinTemp) self.mdCoolStepsEntry = IntEntry(self, text='', returnCallback=self.setMdCoolSteps) self.mdSimStepsEntry = IntEntry(self, text='', returnCallback=self.setMdSimSteps) self.mdTauEntry = FloatEntry(self, text='', returnCallback=self.setMdTau) self.mdRepScaleEntry = FloatEntry(self, text='', returnCallback=self.setMdRepScale) guiFrame.grid_columnconfigure(0, weight=1) row = 0 guiFrame.grid_rowconfigure(row, weight=1) frame = LabelFrame(guiFrame, text='Input constraints') frame.grid(row=row, column=0, sticky=Tkinter.NSEW) frame.grid_columnconfigure(2, weight=1) srow = 0 label = Label(frame, text='Constraint set:') label.grid(row=srow, column=0, sticky=Tkinter.W) self.constraintSetPulldown = PulldownMenu( frame, callback=self.changeConstraintSet, selected_index=0, do_initial_callback=0) self.constraintSetPulldown.grid(row=srow, column=1, sticky=Tkinter.W) srow += 1 label = Label(frame, text='Dist constraint list 1:') label.grid(row=srow, column=0, sticky=Tkinter.W) self.distance1Pulldown = PulldownMenu( frame, callback=self.changeDistance1ConstraintList, selected_index=0, do_initial_callback=0) self.distance1Pulldown.grid(row=srow, column=1, sticky=Tkinter.W) self.numConstr1Label = Label(frame, text='Constraints: 0') self.numConstr1Label.grid(row=srow, column=2, sticky=Tkinter.W) srow += 1 label = Label(frame, text='Dist constraint list 2:') label.grid(row=srow, column=0, sticky=Tkinter.W) self.distance2Pulldown = PulldownMenu( frame, callback=self.changeDistance2ConstraintList, selected_index=0, do_initial_callback=0) self.distance2Pulldown.grid(row=srow, column=1, sticky=Tkinter.W) self.numConstr2Label = Label(frame, text='Constraints: 0') self.numConstr2Label.grid(row=srow, column=2, sticky=Tkinter.W) srow += 1 label = Label(frame, text='Dist constraint list 3:') label.grid(row=srow, column=0, sticky=Tkinter.W) self.distance3Pulldown = PulldownMenu( frame, callback=self.changeDistance3ConstraintList, selected_index=0, do_initial_callback=0) self.distance3Pulldown.grid(row=srow, column=1, sticky=Tkinter.W) self.numConstr3Label = Label(frame, text='Constraints: 0') self.numConstr3Label.grid(row=srow, column=2, sticky=Tkinter.W) srow += 1 label = Label(frame, text='Dist constraint list 4:') label.grid(row=srow, column=0, sticky=Tkinter.W) self.distance4Pulldown = PulldownMenu( frame, callback=self.changeDistance4ConstraintList, selected_index=0, do_initial_callback=0) self.distance4Pulldown.grid(row=srow, column=1, sticky=Tkinter.W) self.numConstr4Label = Label(frame, text='Constraints: 0') self.numConstr4Label.grid(row=srow, column=2, sticky=Tkinter.W) row += 1 frame0 = LabelFrame(guiFrame, text='Cooling scheme') frame0.grid(row=row, column=0, sticky=Tkinter.NSEW) frame0.grid_columnconfigure(1, weight=1) f0row = 0 frame0.grid_rowconfigure(f0row, weight=1) colHeadings = [ 'Step', 'Initial\nTemp.', 'Final\nTemp.', 'Cooling\nSteps', 'MD Steps', 'MD Tau', 'Rep.\nScale' ] editWidgets = [ None, self.mdInitTempEntry, self.mdFinTempEntry, self.mdCoolStepsEntry, self.mdSimStepsEntry, self.mdTauEntry, self.mdRepScaleEntry ] editGetCallbacks = [ None, self.getMdInitTemp, self.getMdFinTemp, self.getMdCoolSteps, self.getMdSimSteps, self.getMdTau, self.getMdRepScale ] editSetCallbacks = [ None, self.setMdInitTemp, self.setMdFinTemp, self.setMdCoolSteps, self.setMdSimSteps, self.setMdTau, self.setMdRepScale ] self.coolingSchemeMatrix = ScrolledMatrix( frame0, editSetCallbacks=editSetCallbacks, editGetCallbacks=editGetCallbacks, editWidgets=editWidgets, maxRows=9, initialRows=12, headingList=colHeadings, callback=self.selectCoolingStep, objectList=self.coolingScheme, textMatrix=self.coolingScheme) self.coolingSchemeMatrix.grid(row=f0row, column=0, columnspan=4, sticky=Tkinter.NSEW) f0row += 1 texts = ['Move earlier', 'Move later', 'Add step', 'Remove step'] commands = [ self.moveStepEarlier, self.moveStepLater, self.addCoolingStep, self.removeCoolingStep ] self.coolingSchemeButtons = ButtonList(frame0, expands=1, commands=commands, texts=texts) self.coolingSchemeButtons.grid(row=f0row, column=0, columnspan=4, sticky=Tkinter.EW) row += 1 guiFrame.grid_rowconfigure(row, weight=1) frame1 = LabelFrame(guiFrame, text='Dynamics control') frame1.grid(row=row, column=0, sticky=Tkinter.NSEW) frame1.grid_columnconfigure(1, weight=1) f1row = 0 label20 = Label(frame1, text='Number of clouds:') label20.grid(row=f1row, column=0, sticky=Tkinter.NW) self.numCloudsEntry = IntEntry(frame1, text=1, returnCallback=self.setNumClouds, width=10) self.numCloudsEntry.grid(row=f1row, column=1, sticky=Tkinter.NW) label21 = Label(frame1, text='Cloud file prefix:') label21.grid(row=f1row, column=2, sticky=Tkinter.NW) self.filePrefixEntry = Entry(frame1, text='t_intra_', returnCallback=self.setFilePrefix, width=10) self.filePrefixEntry.grid(row=f1row, column=3, sticky=Tkinter.NW) f1row += 1 texts = ['Start molecular dynamics', 'Show dynamics progress'] commands = [self.startMd, self.showMdProgress] self.mdButtons = ButtonList(frame1, expands=1, commands=commands, texts=texts) self.mdButtons.grid(row=f1row, column=0, columnspan=4, sticky=Tkinter.NSEW) row += 1 self.bottomButtons = createDismissHelpButtonList(guiFrame, expands=0, help_url=None) self.bottomButtons.grid(row=row, column=0, sticky=Tkinter.EW) self.update() for func in ('__init__', 'delete', 'setName'): for clazz in ('ccp.nmr.NmrConstraint.DistanceConstraintList', ): Implementation.registerNotify(self.updateConstraintLists, clazz, func) for func in ('__init__', 'delete'): Implementation.registerNotify( self.updateConstraintSets, 'ccp.nmr.NmrConstraint.NmrConstraintStore', func) def getContraintSetNames(self): names = [] constraintSets = self.project.currentNmrProject.nmrConstraintStores for set in constraintSets: names.append('%d' % set.serial) return names def changeConstraintSet(self, i, name): project = self.project if project.currentNmrProject.nmrConstraintStores: constraintSet = project.currentNmrProject.sortedNmrConstraintStores( )[i] else: constraintSet = None if constraintSet is not self.constraintSet: self.constraintSet = constraintSet self.updateConstraintLists() self.update() def updateConstraintLists(self, *opt): constrListData = self.getConstraintLists() constrListNames = [x[0] for x in constrListData] constraintLists = [x[1] for x in constrListData] # copes with self.constraintSet being None if constrListNames: i = 0 for constraintList in self.constrLists: if constraintList not in constraintLists: if i == 0: self.constrLists[i] = constraintLists[0] else: self.constrLists[i] = None i += 1 constraintLists.append(None) constrListNames.append('<None>') self.distance1Pulldown.setup( constrListNames, constraintLists.index(self.constrLists[0])) self.distance2Pulldown.setup( constrListNames, constraintLists.index(self.constrLists[1])) self.distance3Pulldown.setup( constrListNames, constraintLists.index(self.constrLists[2])) self.distance4Pulldown.setup( constrListNames, constraintLists.index(self.constrLists[3])) else: self.constrLists = [None] * 4 self.distance1Pulldown.setup([], -1) self.distance2Pulldown.setup([], -1) self.distance3Pulldown.setup([], -1) self.distance4Pulldown.setup([], -1) def updateConstraintSets(self, *opt): project = self.project constraintSets = list(project.currentNmrProject.nmrConstraintStores) if constraintSets: constraintSetNames = self.getContraintSetNames() # set defaults if self.constraintSet not in constraintSets: self.constraintSet = constraintSets[0] if self.constraintSet: j = 0 for constraintList in self.constrLists: if constraintList and (constraintList.nmrConstraintStore is not self.constraintSet): if self.constraintSet.constraintLists and j == 0: self.constrLists[ j] = self.constraintSet.constraintLists[0] else: self.constrLists[j] = None j += 1 else: self.constrLists = [None] * 4 i = constraintSets.index(self.constraintSet) self.constraintSetPulldown.setup(constraintSetNames, i) else: self.constraintSet = None self.constrLists = [None] * 4 self.constraintSetPulldown.setup([], -1) def getConstraintListName(self, constraintList): if constraintList.name: listName = ':%s' % (constraintList.name) else: listName = '' name = '%d:%d:%s%s' % (constraintList.nmrConstraintStore.serial, constraintList.serial, constraintList.className[:-14], listName) return name def getConstraintLists(self): constraintLists = [] if self.constraintSet: for constraintList in self.constraintSet.constraintLists: if constraintList.className == 'DistanceConstraintList': name = self.getConstraintListName(constraintList) constraintLists.append([name, constraintList]) return constraintLists def changeDistance1ConstraintList(self, i, name): self.changeDistanceConstraintList(i, name, 0) def changeDistance2ConstraintList(self, i, name): self.changeDistanceConstraintList(i, name, 1) def changeDistance3ConstraintList(self, i, name): self.changeDistanceConstraintList(i, name, 2) def changeDistance4ConstraintList(self, i, name): self.changeDistanceConstraintList(i, name, 3) def changeDistanceConstraintList(self, i, name, listNum): project = self.project constraintLists = self.getConstraintLists() if constraintLists and (i < 4): self.constrLists[listNum] = constraintLists[i][1] else: self.constrLists[listNum] = None self.update() def startMd(self): self.setNumClouds() self.setFilePrefix() if ((self.constrLists != [None] * 4) and (self.numClouds > 0) and self.filePrefix): resDict = {} for resonance in self.guiParent.project.currentNmrProject.resonances: resDict[resonance.serial] = resonance constraints = [] constraintStore = None for dcl in self.constrLists: if dcl: constraintStore = dcl.nmrConstraintStore constraints.extend(list(dcl.constraints)) resonances = [] for constraint in constraints: for item in constraint.items: for fixedResonance in item.resonances: if fixedResonance.resonanceSerial is None: resonance = newResonance( self.guiParent.project, isotopeCode=fixedResonance.isotopeCode) resonance.setName(fixedResonance.name) fixedResonance.setResonanceSerial(resonance.serial) resDict[resonance.serial] = resonance if fixedResonance.resonanceSet: atomSets = list( fixedResonance.resonanceSet.atomSets) assignAtomsToRes(atomSets, resonance) if resDict.get( fixedResonance.resonanceSerial) is not None: resonances.append( resDict[fixedResonance.resonanceSerial]) resDict[fixedResonance.resonanceSerial] = None resonances, intraConstraintList = self.makeIntraConstraints( resonances, constraintStore) constraints.extend(list(intraConstraintList.constraints)) resonances, interConstraintList = self.makeInterConstraints( resonances, constraintStore) constraints.extend(list(interConstraintList.constraints)) startMdProcess(self.numClouds, constraints, resonances, self.coolingScheme, self.filePrefix) #structGen = self.distanceConstraintList.structureGeneration serials = [] for resonance in resonances: serials.append(resonance.serial) clouds = [] for i in range(self.numClouds): clouds.append('%s%3.3d.pdb' % (self.filePrefix, i)) self.guiParent.application.setValues(constraintStore, 'clouds', values=clouds) self.guiParent.application.setValues(constraintStore, 'cloudsResonances', values=serials) # do better than this check for creation def makeInterConstraints(self, resonances, constraintSet): from ccpnmr.analysis.core.ConstraintBasic import getFixedResonance from ccpnmr.analysis.core.AssignmentBasic import findConnectedSpinSystem project = constraintSet.root constraintList = constraintSet.newDistanceConstraintList() constraintList.name = 'Seq connections' resDict = {} spinSystemDict = {} for resonance in resonances: resDict[resonance] = True spinSystem = resonance.resonanceGroup if spinSystem: spinSystemDict[spinSystem] = None spinSystems = spinSystemDict.keys() for spinSystem in spinSystems: nextSpinSystem = findConnectedSpinSystem(spinSystem, delta=1) if nextSpinSystem: ca = spinSystem.newAtoms.get('CA') c = spinSystem.newAtoms.get('C') n = nextSpinSystem.newAtoms.get('N') if ca and c and n: if resDict.get(ca) is None: resonances.append(ca) if resDict.get(c) is None: resonances.append(c) if resDict.get(n) is None: resonances.append(n) c_n = constraintList.newDistanceConstraint( weight=1.0, origData=1.0, targetValue=1.32, upperLimit=1.35, lowerLimit=1.29, error=0.06) # below based on angle constraints ca_n = constraintList.newDistanceConstraint( weight=1.0, origData=1.0, targetValue=2.415, upperLimit=2.513, lowerLimit=2.316, error=0.197) frCa = getFixedResonance(constraintSet, ca) frC = getFixedResonance(constraintSet, c) frN = getFixedResonance(constraintSet, n) item = ca_n.newDistanceConstraintItem( resonances=[frCa, frN]) item = c_n.newDistanceConstraintItem(resonances=[frC, frN]) return resonances, constraintList def makeIntraConstraints(self, resonances, constraintSet): from ccpnmr.analysis.core.ConstraintBasic import getFixedResonance project = constraintSet.root constraintList = constraintSet.newDistanceConstraintList() constraintList.name = 'Backbone intra' dict = {} for resonance in resonances: if resonance.resonanceGroup and resonance.assignNames: dict[resonance] = 1 resonance.resonanceGroup.newAtoms = {} for resonance in dict.keys(): ss = resonance.resonanceGroup if resonance.assignNames[0] == 'H': for resonance2 in ss.resonances: if dict.get(resonance2 ) and resonance2.assignNames[0][:2] == 'HA': ca = ss.newAtoms.get('CA') if ca is None: ca = project.newResonance(isotopeCode='13C', assignNames=[ 'CA', ]) resonances.append(ca) c = ss.newAtoms.get('C') if c is None: c = project.newResonance(isotopeCode='13C', assignNames=[ 'C', ]) resonances.append(c) n = ss.newAtoms.get('N') if n is None: n = project.newResonance(isotopeCode='15N', assignNames=[ 'N', ]) resonances.append(n) ss.newAtoms['C'] = c ss.newAtoms['CA'] = ca ss.newAtoms['N'] = n frCa = getFixedResonance(constraintSet, ca) frC = getFixedResonance(constraintSet, c) frN = getFixedResonance(constraintSet, n) frH = getFixedResonance(constraintSet, resonance) frha = getFixedResonance(constraintSet, resonance2) h_n = constraintList.newDistanceConstraint( weight=1.0, origData=1.0, targetValue=1.01, upperLimit=1.1, lowerLimit=0.9, error=0.2) n_ca = constraintList.newDistanceConstraint( weight=1.0, origData=1.0, targetValue=1.465, upperLimit=1.50, lowerLimit=1.43, error=0.07) ca_c = constraintList.newDistanceConstraint( weight=1.0, origData=1.0, targetValue=1.525, upperLimit=1.55, lowerLimit=1.50, error=0.05) # below based on angle constraints n_c = constraintList.newDistanceConstraint( weight=1.0, origData=1.0, targetValue=2.464, upperLimit=2.572, lowerLimit=2.356, error=0.216) item = h_n.newDistanceConstraintItem( resonances=[frH, frN]) item = n_ca.newDistanceConstraintItem( resonances=[frN, frCa]) item = ca_c.newDistanceConstraintItem( resonances=[frCa, frC]) item = n_c.newDistanceConstraintItem( resonances=[frN, frC]) if ss.newAtoms.get('CAHA') is None: ca_ha = constraintList.newDistanceConstraint( weight=1.0, origData=1.0, targetValue=1.09, upperLimit=1.19, lowerLimit=0.99, error=0.2) item = ca_ha.newDistanceConstraintItem( resonances=[frC, frha]) ss.newAtoms['CAHA'] = 1 if resonance.assignNames[0][:2] == 'HA': for resonance2 in ss.resonances: if dict.get(resonance2 ) and resonance2.assignNames[0][:2] == 'HB': ca = ss.newAtoms.get('CA') if ca is None: ca = project.newResonance(isotopeCode='13C', assignNames=[ 'CA', ]) resonances.append(ca) cb = ss.newAtoms.get('CB') if cb is None: cb = project.newResonance(isotopeCode='13C', assignNames=[ 'CB', ]) resonances.append(cb) ss.newAtoms['CA'] = cb ss.newAtoms['CB'] = ca ss.newAtoms['CAHA'] = 1 frCA = getFixedResonance(constraintSet, ca) frCB = getFixedResonance(constraintSet, cb) frHA = getFixedResonance(constraintSet, resonance) frHB = getFixedResonance(constraintSet, resonance2) c_b = constraintList.newDistanceConstraint( weight=1.0, origData=1.0, targetValue=1.09, upperLimit=1.19, lowerLimit=0.99, error=0.2) c_c = constraintList.newDistanceConstraint( weight=1.0, origData=1.0, targetValue=1.53, upperLimit=1.56, lowerLimit=1.51, error=0.05) item = c_b.newDistanceConstraintItem( resonances=[frCB, frHB]) item = c_c.newDistanceConstraintItem( resonances=[frCA, frCB]) if ss.newAtoms.get('CAHA') is None: c_a = constraintList.newDistanceConstraint( weight=1.0, origData=1.0, targetValue=1.09, upperLimit=1.19, lowerLimit=0.99, error=0.2) item = c_a.newDistanceConstraintItem( resonances=[frCA, frHA]) ss.newAtoms['CAHA'] = 1 return resonances, constraintList def showMdProgress(self): n = 0 m = self.numClouds for i in range(m): pdbFileName = '%s%3.3d.pdb' % (self.filePrefix, i) if os.path.exists(pdbFileName): n += 1 p = n * 100 / float(m) text = 'Done %d of %d clouds (%1.2f)%%' % (n, m, p) showInfo('MD Progress', text) def setFilePrefix(self, text=None): if not text: text = self.filePrefixEntry.get() if text: self.filePrefix = text def setNumClouds(self, n=None, *event): if not n: n = self.numCloudsEntry.get() if n: self.numClouds = int(n) def update(self): self.updateConstraintSets() self.updateConstraintLists() if (self.constrLists != [None] * 4) and self.coolingScheme: self.mdButtons.buttons[0].enable() self.mdButtons.buttons[1].enable() else: self.mdButtons.buttons[0].disable() self.mdButtons.buttons[1].disable() if self.constrLists[0]: self.numConstr1Label.set('Constraints: ' + str(len(self.constrLists[0].constraints))) else: self.numConstr1Label.set('Constraints: 0') if self.constrLists[1]: self.numConstr2Label.set('Constraints: ' + str(len(self.constrLists[1].constraints))) else: self.numConstr2Label.set('Constraints: 0') if self.constrLists[2]: self.numConstr3Label.set('Constraints: ' + str(len(self.constrLists[2].constraints))) else: self.numConstr3Label.set('Constraints: 0') if self.constrLists[3]: self.numConstr4Label.set('Constraints: ' + str(len(self.constrLists[3].constraints))) else: self.numConstr4Label.set('Constraints: 0') def getMdInitTemp(self, coolingStep): self.mdInitTempEntry.set(coolingStep[1]) def getMdFinTemp(self, coolingStep): self.mdFinTempEntry.set(coolingStep[2]) def getMdCoolSteps(self, coolingStep): self.mdCoolStepsEntry.set(coolingStep[3]) def getMdSimSteps(self, coolingStep): self.mdSimStepsEntry.set(coolingStep[4]) def getMdTau(self, coolingStep): self.mdTauEntry.set(coolingStep[5]) def getMdRepScale(self, coolingStep): self.mdRepScaleEntry.set(coolingStep[6]) def setMdInitTemp(self, event): value = self.mdInitTempEntry.get() if value is not None: self.coolingStep[1] = value self.updateCoolingScheme() def setMdFinTemp(self, event): value = self.mdFinTempEntry.get() if value is not None: self.coolingStep[2] = value self.updateCoolingScheme() def setMdCoolSteps(self, event): value = self.mdCoolStepsEntry.get() if value is not None: self.coolingStep[3] = value self.updateCoolingScheme() def setMdSimSteps(self, event): value = self.mdSimStepsEntry.get() if value is not None: self.coolingStep[4] = value self.updateCoolingScheme() def setMdTau(self, event): value = self.mdTauEntry.get() if value is not None: self.coolingStep[5] = value self.updateCoolingScheme() def setMdRepScale(self, event): value = self.mdRepScaleEntry.get() if value is not None: self.coolingStep[6] = value self.updateCoolingScheme() def selectCoolingStep(self, object, row, col): self.coolingStep = object def moveStepEarlier(self): if self.coolingStep: i = self.coolingStep[0] - 1 if i > 0: coolingStep = self.coolingScheme[i - 1] coolingStep[0] = i + 1 self.coolingStep[0] = i self.coolingScheme[i - 1] = self.coolingStep self.coolingScheme[i] = coolingStep self.updateCoolingScheme() self.coolingSchemeMatrix.hilightObject(self.coolingStep) def moveStepLater(self): if self.coolingStep: i = self.coolingStep[0] - 1 if i < len(self.coolingScheme) - 1: coolingStep = self.coolingScheme[i + 1] coolingStep[0] = i + 1 self.coolingStep[0] = i + 2 self.coolingScheme[i + 1] = self.coolingStep self.coolingScheme[i] = coolingStep self.updateCoolingScheme() self.coolingSchemeMatrix.hilightObject(self.coolingStep) def addCoolingStep(self): i = len(self.coolingScheme) + 1 datum = [i, 3000, 100, 10, 2500, 0.001, 1] self.coolingScheme.append(datum) self.updateCoolingScheme() def removeCoolingStep(self): if self.coolingStep: coolingScheme = [] i = 0 for coolingStep in self.coolingScheme: if coolingStep is not self.coolingStep: i += 1 coolingStep[0] = i coolingScheme.append(coolingStep) self.coolingScheme = coolingScheme self.updateCoolingScheme() def updateCoolingScheme(self): objectList = self.coolingScheme textMatrix = self.coolingScheme self.coolingSchemeMatrix.update(objectList=objectList, textMatrix=textMatrix) def updateMidgeParams(self): data = [ self.specFreq, self.maxIter, self.mixTime, self.corrTime, self.leakRate, self.maxIntens ] self.midgeParamsMatrix.update(textMatrix=[ data, ]) def destroy(self): for func in ('__init__', 'delete', 'setName'): for clazz in ('ccp.nmr.NmrConstraint.DistanceConstraintList', ): Implementation.unregisterNotify(self.updateConstraintLists, clazz, func) for func in ('__init__', 'delete'): Implementation.unregisterNotify( self.updateConstraintSets, 'ccp.nmr.NmrConstraint.NmrConstraintStore', func) BasePopup.destroy(self)