def __init__(self, parent, guiParent, *args, **kw): Frame.__init__(self, parent, *args, **kw) self.guiParent = guiParent self.aliasing = 0 self.peakDim = None self.contrib = None self.component = None self.structure = None self.resonances = [] self.jCouplings = [] headingList = ['#', 'Name', 'Delta', 'Shift', 'SD', 'Dist'] self.scrolledMatrix = ScrolledMatrix(self, initialRows=5, headingList=headingList, tipTexts=TIP_TEXTS, callback=self.setCurrentResonance, highlightType=None) row = 0 self.scrolledMatrix.grid(row=row, column=0, columnspan=2, sticky='nsew', padx=1) self.grid_rowconfigure(row, weight=1) self.grid_columnconfigure(0, weight=1) self.grid_columnconfigure(1, weight=1) self.update(None, None)
def body(self, guiFrame): self.geometry('500x500') guiFrame.grid_columnconfigure(0, weight=1) guiFrame.grid_rowconfigure(1, weight=1) frame = LabelFrame(guiFrame, text='RDC protocol settings') frame.grid(row=1, column=0, sticky='nsew') frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(0, weight=1) self.floatEntry = FloatEntry(self, returnCallback=self.setValue) headingList = ['Parameter', 'Value', 'Description'] justifyList = ['center', 'center', 'left'] editWidgets = [None, self.floatEntry, None] editGetCallbacks = [None, self.getValue, None] editSetCallbacks = [None, self.setValue, None] self.rdcMatrix = ScrolledMatrix(frame, headingList=headingList, justifyList=justifyList, editSetCallbacks=editSetCallbacks, editGetCallbacks=editGetCallbacks, editWidgets=editWidgets, multiSelect=False, initialRows=10, passSelfToCallback=True, callback=self.selectRdc) self.rdcMatrix.grid(row=0, column=0, sticky='nsew') self.rdcMatrix.refreshFunc = self.updateRdcSet self.updateRdcSet()
def body(self, guiParent): self.geometry('600x300') guiParent.grid_columnconfigure(1, weight=1) url = '' if self.server: url = self.server.url label = Label(guiParent, text='Server location: %s' % url) label.grid(row=0, column=0, sticky='w', columnspan=2) label = Label(guiParent, text='Installation root: %s%s' % (self.installRoot, os.sep)) label.grid(row=1, column=0, sticky='w', columnspan=2) editWidgets = [None] * 5 editGetCallbacks = [None, self.toggleSelected, None, None, None] editSetCallbacks = [None] * 5 guiParent.grid_rowconfigure(2, weight=1) headingList = [ 'File', 'Install?', 'Date', 'Relative Path', 'Priority', 'Comments' ] self.scrolledMatrix = ScrolledMatrix(guiParent, headingList=headingList, highlightType=0, editWidgets=editWidgets, callback=self.selectCell, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks) self.scrolledMatrix.grid(row=2, column=0, columnspan=2, sticky='nsew') if self.exitOnClose: txt = 'Quit' cmd = sys.exit else: txt = 'Close' cmd = self.close texts = ['Refresh List', 'Select All', 'Install Selected', txt] commands = [self.updateFiles, self.selectAll, self.install, cmd] self.buttonList = ButtonList(guiParent, texts=texts, commands=commands, expands=True) self.buttonList.grid(row=3, column=0, columnspan=2, sticky='ew') if self.server: for fileUpdate in self.server.fileUpdates: fileUpdate.isSelected = False #self.update() # need self.updateFiles, not just self.update # because otherwise the 2.0.5 to 2.0.6 upgrades do not work # (self.server not set on first pass so need call to updateFiles here) self.updateFiles()
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 body(self, guiFrame): '''Describes where all the GUI element are.''' self.geometry('400x500') guiFrame.expandGrid(0, 0) tableFrame = Frame(guiFrame) tableFrame.grid( row=0, column=0, sticky='nsew', ) tableFrame.expandGrid(0, 0) buttonFrame = Frame(guiFrame) buttonFrame.grid( row=1, column=0, sticky='nsew', ) headingList = ['Spinsystem Number', 'Assignment', 'Residue Type Probs'] self.table = ScrolledMatrix(tableFrame, headingList=headingList, callback=self.updateSpinSystemSelection, multiSelect=True) self.table.grid(row=0, column=0, sticky='nsew') texts = ['Add Prob'] commands = [self.addProb] self.AddProbButton = ButtonList(buttonFrame, commands=commands, texts=texts) self.AddProbButton.grid(row=0, column=0, sticky='nsew') texts = ['Remove Prob'] commands = [self.removeProb] self.AddProbButton = ButtonList(buttonFrame, commands=commands, texts=texts) self.AddProbButton.grid(row=0, column=2, sticky='nsew') selectCcpCodes = sorted(self.chemCompDict.keys()) tipText = 'select ccpCode' self.selectCcpCodePulldown = PulldownList(buttonFrame, texts=selectCcpCodes, grid=(0, 1), tipText=tipText) selectCcpCodes = ['All Residue Types'] tipText = 'select ccpCode' self.selectCcpCodeRemovePulldown = PulldownList(buttonFrame, texts=selectCcpCodes, index=0, grid=(0, 3), tipText=tipText) self.updateTable()
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 body(self, guiParent): guiParent.grid_columnconfigure(1,weight=1) row = 0 file_types = [ FileType('Python', ['*.py']), FileType('All', ['*']) ] self.file_select = FileSelect(guiParent, file_types=file_types, single_callback=self.chooseFile, double_callback=self.chooseFile) self.file_select.grid(row=row, column=0, columnspan=2, sticky='nsew') row = row + 1 headingList=('Function',) self.scrolledMatrix = ScrolledMatrix(guiParent, initialRows=4, headingList=headingList, callback=self.selectFunction) self.scrolledMatrix.grid(row=row, column=0, columnspan=2, sticky='nsew') guiParent.grid_rowconfigure(row,weight=1) row = row + 1 self.moduleLabel1 = Label(guiParent, text='Module: ') self.moduleLabel1.grid(row=row, column=0, sticky='nw') self.moduleLabel2 = Label(guiParent, text=' ') self.moduleLabel2.grid(row=row, column=1, sticky='nw') row = row + 1 self.functionLabel1 = Label(guiParent, text='Function: ') self.functionLabel1.grid(row=row, column=0, sticky='nw') self.functionLabel2 = Label(guiParent, text=' ') self.functionLabel2.grid(row=row, column=1, sticky='nw') row = row + 1 self.nameLabel = Label(guiParent, text='Name: ') self.nameLabel.grid(row=row, column=0, sticky='nw') self.nameEntry = Entry(guiParent, text=' ', width=40) self.nameEntry.grid(row=row, column=1, sticky='nw') row = row + 1 texts = [ 'Load Macro' ] commands = [ self.loadMacro ] buttons = UtilityButtonList(guiParent, texts=texts, commands=commands, helpUrl=self.help_url) buttons.grid(row=row, column=0, columnspan=2, sticky='ew') self.loadButton = buttons.buttons[0] self.loadButton.disable() self.path = None self.module = None self.function = None
def body(self, master): textMatrix = self.getTextMatrix(self.objects) self.label = Label(self,text='Select %s ' % self.objectName) self.label.grid(row=0,column=0,sticky='nw') self.scrolledMatrix = ScrolledMatrix(self, initialRows=10, headingList=self.headingList, callback=self.selectCell, objectList=self.objects, textMatrix=textMatrix) self.scrolledMatrix.grid(row=1,column=0,sticky='nsew') self.grid_rowconfigure (0, weight=0) self.grid_rowconfigure (1, weight=1) self.grid_columnconfigure(0, weight=1) self.protocol('WM_DELETE_WINDOW', self.close)
def body(self): '''Sets up the body of this view.''' frame = self.frame frame.grid_rowconfigure(2, weight=1) frame.grid_columnconfigure(0, weight=1) headingList = [ '#', 'Spectrum', 'Peak List', 'use?', 'labelling scheme' ] tipTexts = [ 'Row number', 'spectrum name', 'which peak list to use', 'use this spectrum?', 'Which labelling scheme belongs to this spectrum?' ] self.autoLabellingPulldown = PulldownList(self.guiParent, self.setAutoLabellingScheme) self.autoPeakListPulldown = PulldownList(self.guiParent, self.setAutoPeakList) editWidgets = [ None, None, self.autoPeakListPulldown, None, self.autoLabellingPulldown ] editGetCallbacks = [ None, None, self.getAutoPeakLists, self.changeUse, self.getAutoLabellingSchemes ] editSetCallbacks = [None, None, None, None, None] self.displayTable = ScrolledMatrix(frame, headingList=headingList, callback=self.selectAutoSpec, editWidgets=editWidgets, multiSelect=False, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, tipTexts=tipTexts) self.displayTable.grid(row=2, column=0, sticky='nsew')
def body(self, guiFrame): guiFrame.grid_rowconfigure(0, weight=1) guiFrame.grid_columnconfigure(0, weight=1) row = 0 frame = LabelFrame(guiFrame, text='Matched Peak Groups') frame.grid_rowconfigure(0, weight=1) frame.grid_columnconfigure(0, weight=1) frame.grid(row=row, sticky='nsew') headingList, tipTexts = self.getHeadingList() self.scrolledMatrix = ScrolledMatrix(frame, initialRows=15, multiSelect=True, headingList=headingList, tipTexts=tipTexts, grid=(0,0), gridSpan=(1,3)) tipTexts = ['Remove the selected peak groups from the table', 'Show 1D positional ruler lines for the selected groups', 'Remove any ruler lines previously added for peak group', 'Display selected peak groups within strips of selected window'] texts = ['Remove\nGroups','Show\nRulers', 'Delete\nRulers','Display Groups\nIn Strips'] commands = [self.removeGroups,self.addRulers, self.removeRulers,self.stripGroups] self.buttons = ButtonList(frame, texts=texts, commands=commands, tipTexts=tipTexts) self.buttons.grid(row=1, column=0, sticky='ew') tipText = 'Selects the spectrum window in which to display strips & ruler lines' label = Label(frame, text='Target window:', grid=(1,1)) self.windowPulldown = PulldownList(frame, callback=None, grid=(1,2), tipText=tipText) row+= 1 bottomButtons = UtilityButtonList(guiFrame, helpUrl=self.help_url, expands=True, doClone=False) bottomButtons.grid(row = row, sticky = 'ew') self.update() for func in ('__init__', 'delete', 'setName'): self.registerNotify(self.updateWindowsAfter, 'ccpnmr.Analysis.SpectrumWindow', func)
def body(self, guiFrame): x = self.parent.winfo_rootx() + 50 y = self.parent.winfo_rooty() + 50 location = '500x400+%d+%d' % (x, y) self.geometry(location) guiFrame.expandGrid(1,0) textMatrix = self.getTextMatrix(self.objects) self.label = Label(guiFrame, text='Select a %s ' % self.objectName, grid=(0,0)) self.scrolledMatrix = ScrolledMatrix(guiFrame, initialRows=10, headingList=self.headingList, callback=self.selectCell, objectList=self.objects, textMatrix=textMatrix, grid=(1,0)) self.protocol('WM_DELETE_WINDOW', self.close)
def __init__(self, parent, metaclass, objects=None, includeNumber=True, *args, **kw): self.metaclass = metaclass self.includeNumber = includeNumber headings = [] if (includeNumber): headings.append('Number') self.keyList = keyList = getKeyList(metaclass) for key in keyList: attr = key[-1] s = attr.name if (len(key) > 1): if (type(key[-2]) == type(0)): role = key[-3] n = key[-2] t = '%s[%d]' % (role.otherClass.name, n) else: role = key[-2] t = role.otherClass.name else: t = metaclass.name headings.append('%s\n%s' % (t, s)) ScrolledMatrix.__init__(self, parent, headingList=headings, *args, **kw) self.setObjects(objects)
def __init__(self, guiParent, dataText, dataObjects, dataValues, **kw): dataValueDict = {} for n, dataObject in enumerate(dataObjects): dataValueDict[dataObject] = dataValues[n] self.dataValueDict = dataValueDict self.isUsedSet = set() # default is that none selected editWidgets = 2 * [None] editSetCallbacks = 2 * [None] editGetCallbacks = [None, self.toggleIsUsed] headings = [dataText, 'Is Used?'] ScrolledMatrix.__init__(self, guiParent, headingList=headings, objectList=dataObjects, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, **kw) self.doUpdate()
def body(self, guiFrame): '''Describes where all the GUI element are.''' self.geometry('400x500') guiFrame.expandGrid(0, 0) tableFrame = Frame(guiFrame) tableFrame.grid(row=0, column=0, sticky='nsew', ) tableFrame.expandGrid(0, 0) buttonFrame = Frame(guiFrame) buttonFrame.grid(row=1, column=0, sticky='nsew', ) headingList = ['Spinsystem Number', 'Assignment', 'Residue Type Probs'] self.table = ScrolledMatrix(tableFrame, headingList=headingList, callback=self.updateSpinSystemSelection, multiSelect=True) self.table.grid(row=0, column=0, sticky='nsew') texts = ['Add Prob'] commands = [self.addProb] self.AddProbButton = ButtonList(buttonFrame, commands=commands, texts=texts) self.AddProbButton.grid(row=0, column=0, sticky='nsew') texts = ['Remove Prob'] commands = [self.removeProb] self.AddProbButton = ButtonList(buttonFrame, commands=commands, texts=texts) self.AddProbButton.grid(row=0, column=2, sticky='nsew') selectCcpCodes = sorted(self.chemCompDict.keys()) tipText = 'select ccpCode' self.selectCcpCodePulldown = PulldownList(buttonFrame, texts=selectCcpCodes, grid=(0, 1), tipText=tipText) selectCcpCodes = ['All Residue Types'] tipText = 'select ccpCode' self.selectCcpCodeRemovePulldown = PulldownList(buttonFrame, texts=selectCcpCodes, index=0, grid=(0, 3), tipText=tipText) self.updateTable()
def body(self): '''Sets up the body of this view.''' frame = self.frame frame.grid_rowconfigure(2, weight=1) frame.grid_columnconfigure(0, weight=1) headingList = [ '#', 'Spectrum', 'Peak List', 'use?', 'labelling scheme'] tipTexts = ['Row number', 'spectrum name', 'which peak list to use', 'use this spectrum?', 'Which labelling scheme belongs to this spectrum?'] self.autoLabellingPulldown = PulldownList( self.guiParent, self.setAutoLabellingScheme) self.autoPeakListPulldown = PulldownList( self.guiParent, self.setAutoPeakList) editWidgets = [None, None, self.autoPeakListPulldown, None, self.autoLabellingPulldown] editGetCallbacks = [None, None, self.getAutoPeakLists, self.changeUse, self.getAutoLabellingSchemes] editSetCallbacks = [None, None, None, None, None] self.displayTable = ScrolledMatrix(frame, headingList=headingList, callback=self.selectAutoSpec, editWidgets=editWidgets, multiSelect=False, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, tipTexts=tipTexts) self.displayTable.grid(row=2, column=0, sticky='nsew')
class editResidueTypePopup(BasePopup): ''' The main popup that is shown when the macro is loaded. ''' def __init__(self, parent, *args, **kw): self.font = 'Helvetica 10' self.sFont = 'Helvetica %d' self.project = parent.project self.guiParent = parent self.chemCompDict = {} self.createChemCompDict() self.waiting = False BasePopup.__init__(self, parent, title="Residue Type Probabilities", **kw) def open(self): self.updateAfter() BasePopup.open(self) def body(self, guiFrame): '''Describes where all the GUI element are.''' self.geometry('400x500') guiFrame.expandGrid(0, 0) tableFrame = Frame(guiFrame) tableFrame.grid(row=0, column=0, sticky='nsew', ) tableFrame.expandGrid(0, 0) buttonFrame = Frame(guiFrame) buttonFrame.grid(row=1, column=0, sticky='nsew', ) headingList = ['Spinsystem Number', 'Assignment', 'Residue Type Probs'] self.table = ScrolledMatrix(tableFrame, headingList=headingList, callback=self.updateSpinSystemSelection, multiSelect=True) self.table.grid(row=0, column=0, sticky='nsew') texts = ['Add Prob'] commands = [self.addProb] self.AddProbButton = ButtonList(buttonFrame, commands=commands, texts=texts) self.AddProbButton.grid(row=0, column=0, sticky='nsew') texts = ['Remove Prob'] commands = [self.removeProb] self.AddProbButton = ButtonList(buttonFrame, commands=commands, texts=texts) self.AddProbButton.grid(row=0, column=2, sticky='nsew') selectCcpCodes = sorted(self.chemCompDict.keys()) tipText = 'select ccpCode' self.selectCcpCodePulldown = PulldownList(buttonFrame, texts=selectCcpCodes, grid=(0, 1), tipText=tipText) selectCcpCodes = ['All Residue Types'] tipText = 'select ccpCode' self.selectCcpCodeRemovePulldown = PulldownList(buttonFrame, texts=selectCcpCodes, index=0, grid=(0, 3), tipText=tipText) self.updateTable() def updateSpinSystemSelection(self, obj, row, col): '''Called after selectin a row in the table.''' self.updateRemoveCcpCodePullDown() def updateRemoveCcpCodePullDown(self): '''Updates the pulldown showing all current residueTypeProbs for a resonanceGroup that can be removed. ''' removeCcpCodes = [] for spinSystem in self.table.currentObjects: removeCcpCodes.extend([typeProp.possibility.ccpCode for typeProp in spinSystem.getResidueTypeProbs()]) removeCcpCodes = ['All Residue Types'] + list(set(removeCcpCodes)) self.selectCcpCodeRemovePulldown.setup(texts=removeCcpCodes, objects=removeCcpCodes, index=0) def getSpinSystems(self): '''Get resonanceGroups (spin systems) in the project.''' return self.nmrProject.resonanceGroups def addProb(self): '''Add the residue type selected in the selectCcpCodePulldown as an residueTypeProb. ''' ccpCode = self.selectCcpCodePulldown.object for spinSystem in self.table.currentObjects: if ccpCode not in [typeProp.possibility.ccpCode for typeProp in spinSystem.getResidueTypeProbs()]: chemComp = self.chemCompDict.get(ccpCode) spinSystem.newResidueTypeProb(possibility=chemComp) self.updateTable() self.updateRemoveCcpCodePullDown() def removeProb(self): '''Removes the residueTypeProb selected in the selectCcpCodeRemovePulldown from the selected resonanceGroup. ''' ccpCode = self.selectCcpCodeRemovePulldown.object for spinSystem in self.table.currentObjects: residueTypeProbs = spinSystem.getResidueTypeProbs() for typeProb in residueTypeProbs: if ccpCode == 'All Residue Types' or ccpCode == typeProb.possibility.ccpCode: typeProb.delete() self.updateTable() self.updateRemoveCcpCodePullDown() def createChemCompDict(self): '''Make a list of all amino acid types present in any of the molecular chains present in the project. ''' chains = self.getChains() for chain in chains: for residue in chain.sortedResidues(): if residue.ccpCode not in self.chemCompDict: self.chemCompDict[residue.ccpCode] = residue.chemCompVar.chemComp def getChains(self): '''Get all molecular chains stored in the project.''' chains = [] if self.project: for molSystem in self.project.sortedMolSystems(): for chain in molSystem.sortedChains(): if chain.residues: chains.append(chain) return chains def updateTable(self): '''Update the whole table.''' objectList = [] data = [] for spinSystem in self.getSpinSystems(): objectList.append(spinSystem) residueTypeProbs = spinSystem.getResidueTypeProbs() spinSystemInfo = self.getStringDescriptionOfSpinSystem(spinSystem) probString = '' for typeProp in residueTypeProbs: probString += typeProp.possibility.ccpCode + ' ' data.append([spinSystem.serial, spinSystemInfo, probString]) self.table.update(objectList=objectList, textMatrix=data) def getStringDescriptionOfSpinSystem(self, spinsys): '''Get a simple identifier for the assignment status of a resonanceGroup. ''' spinSystemInfo = '' if spinsys.residue: spinSystemInfo += str(spinsys.residue.seqCode) + ' ' + spinsys.residue.ccpCode elif spinsys.residueProbs: for residueProb in spinsys.residueProbs: res = residueProb.possibility spinSystemInfo += '{} {}? /'.format(res.seqCode, res.ccpCode) spinSystemInfo = spinSystemInfo[:-1] elif spinsys.ccpCode: spinSystemInfo += spinsys.ccpCode return spinSystemInfo
class UpdatePopup(BasePopup, UpdateAgent): def __init__(self, parent, serverLocation=UPDATE_SERVER_LOCATION, serverDirectory=UPDATE_DIRECTORY, dataFile=UPDATE_DATABASE_FILE, exitOnClose=False): self.exitOnClose = exitOnClose UpdateAgent.__init__(self, serverLocation, serverDirectory, dataFile, isStandAlone=exitOnClose) self.fileUpdate = None if exitOnClose: quitFunc = sys.exit else: quitFunc = None BasePopup.__init__(self, parent=parent, title='CcpNmr Software Updates', quitFunc=quitFunc) def body(self, guiParent): self.geometry('600x300') guiParent.grid_columnconfigure(1, weight=1) url = '' if self.server: url = self.server.url label = Label(guiParent, text='Server location: %s' % url) label.grid(row=0, column=0, sticky='w', columnspan=2) label = Label(guiParent, text='Installation root: %s%s' % (self.installRoot, os.sep)) label.grid(row=1, column=0, sticky='w', columnspan=2) editWidgets = [None] * 5 editGetCallbacks = [None, self.toggleSelected, None, None, None] editSetCallbacks = [None] * 5 guiParent.grid_rowconfigure(2, weight=1) headingList = [ 'File', 'Install?', 'Date', 'Relative Path', 'Priority', 'Comments' ] self.scrolledMatrix = ScrolledMatrix(guiParent, headingList=headingList, highlightType=0, editWidgets=editWidgets, callback=self.selectCell, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks) self.scrolledMatrix.grid(row=2, column=0, columnspan=2, sticky='nsew') if self.exitOnClose: txt = 'Quit' cmd = sys.exit else: txt = 'Close' cmd = self.close texts = ['Refresh List', 'Select All', 'Install Selected', txt] commands = [self.updateFiles, self.selectAll, self.install, cmd] self.buttonList = ButtonList(guiParent, texts=texts, commands=commands, expands=True) self.buttonList.grid(row=3, column=0, columnspan=2, sticky='ew') if self.server: for fileUpdate in self.server.fileUpdates: fileUpdate.isSelected = False #self.update() # need self.updateFiles, not just self.update # because otherwise the 2.0.5 to 2.0.6 upgrades do not work # (self.server not set on first pass so need call to updateFiles here) self.updateFiles() def toggleSelected(self, fileUpdate): boolean = fileUpdate.isSelected fileUpdate.isSelected = not boolean self.update() def install(self): if self.server: self.installUpdates() self.updateFiles() def selectAll(self): if self.server: for fileUpdate in self.scrolledMatrix.objectList: fileUpdate.isSelected = True self.update() def selectCell(self, object, row, col): self.fileUpdate = object def updateButtons(self): buttons = self.buttonList.buttons if self.server: selected = False if self.server and self.server.fileUpdates: for fileUpdate in self.scrolledMatrix.objectList: if fileUpdate.isSelected: selected = True break buttons[1].enable() else: buttons[1].disable() if selected: buttons[2].enable() buttons[2].config(bg='#A0FFA0') else: buttons[2].disable() buttons[2].config(bg=buttons[1].cget('bg')) else: for button in buttons[:-1]: button.disable() def updateFiles(self): if self.server: if not self.server.fileUpdates: self.server.getFileUpdates() for fileUpdate in self.server.fileUpdates: fileUpdate.isSelected = False self.update() def update(self): self.updateButtons() self.fileUpdate = None textMatrix = [] objectList = [] colorMatrix = [] if self.server: for fileUpdate in self.server.fileUpdates: if fileUpdate.getIsUpToDate(): continue color = [None, '#A04040', None, None, None] yesNo = 'No' if fileUpdate.isSelected: color = [None, '#A0FFA0', None, None, None] yesNo = 'Yes' datum = [] datum.append(fileUpdate.fileName) datum.append(yesNo) datum.append(fileUpdate.date) datum.append(fileUpdate.filePath + os.sep) datum.append(fileUpdate.priority) datum.append(fileUpdate.details) colorMatrix.append(color) textMatrix.append(datum) objectList.append(fileUpdate) self.scrolledMatrix.update(textMatrix=textMatrix, objectList=objectList, colorMatrix=colorMatrix)
class NewWindowPopup(BasePopup): """ **Create New Windows to Display Spectra** This tool is used to make new windows for the graphical display of spectra, which will usually be as contours. It is notable that some spectrum windows will be made automatically when spectra are loaded if there is no existing appropriate window to display a spectrum. However, making new spectrum windows allows the user to specialise different windows for different tasks and gives complete freedom as to which types of axis go in which direction. For example the user may wish to make a new window so that a spectrum can be viewed from an orthogonal, rotated aspect. A new spectrum window is made by first considering whether it is similar to any existing windows. If so, then the user selects the appropriate template window to base the new one upon. The user then chooses a name for the window via the "New window name" field, although the name may be changed after the window is created. Usually the user does not need to consider the "Strips" section, but if required the new window can be created with starting strips and orthogonal sub-divisions (although these are not permanent). After setting the required axes and spectrum visibility, as described below, the user clicks on [Create Window!] to actually make the new spectrum display window. **Axes** The number and type of axes for the new window are chosen using the pulldown menus in the "Axes" section. The idea is that the user chooses which NMR isotopes should appear on the X, Y, & Z axes. Naturally, X and Y axes must always be set to something, to represent the plane of the screen, but the Z axes are optional. If not required, a Z axis may be set to "None" to indicate that it will not be used. Up to four Z axes may be specified, labelled as "z1", "z2" etc., and these represent extra dimensions orthogonal to the plane of the screen, which are often conceptualised as depth axes. It should be noted that the Y axis type may be set to "value", which refers to a spectrum intensity axis, rather than an NMR isotope axis. Setting the Y axis to "value" and only having the X axis set to an isotope is used to create windows that can show 1D spectra. Such value axes can also be used for 2D and higher dimensionality spectra, to show the data as an intensity graph (a "slice") rather than as contours. **Spectra** The lower "Viewed Spectra" section lists all of the spectra within the project that may be shown by a window with the selected axes. All spectra with isotopes in their data dimensions that match the isotope types of the window axes can potentially be displayed. This system also allows for displayed spectra to have fewer dimensions than the axes has windows, as long as at least the X and Y axes are present. For example a 2D H-N spectrum can be shown in a 3D H-N-H window, but not a 3D H-H-N. For spectra that have more than one data dimension of the same isotope, then which data dimension goes with which window axis is not always known to Analysis. Where there is ambiguity, this system will simply map the spectrum data dimensions in order to the next matching window axis. If this mapping turns out to be wrong, then it may be changed at any time via the main _Windows settings; toggling the "Dim. Mapping" of the "Spectrum & Peak List Mappings" tab. For the spectra listed in the lower table, which may be placed in the new window, the user has control over whether the spectra actually will appear. Firstly the user can change the "Visible?" column, either via a double-click or by using the appropriate lower buttons. By default spectra are set as not being visible in new windows, and the user toggles the ones that should be seen to "Yes". This basic spectrum visibility can readily be changed by the toggle buttons that appear in the "toolbar" at the top of the spectrum display, so the "Visible?" setting here is only about what initially appears. The "In Toolbar?" setting of a spectrum is a way of allowing the user to state that a spectrum should never appear in the window, and not even allow it to be toggled on later via the toolbar at the top of the windows. This is a way of reducing clutter, and allows certain windows to be used for particular subsets of spectra. For example the user may wish to put the spectra for a temperature series in one window, but not in other windows used for resonance assignment where they would get in the way. The "In Toolbar" setting can be changed after a window has been made, but only via the main Windows_ settings popup. .. _Windows: EditWindowPopup.html """ def __init__(self, parent, *args, **kw): self.visibleSpectra = parent.visibleSpectra self.toolbarSpectra = parent.toolbarSpectra self.waiting = False self.window = None BasePopup.__init__(self, parent=parent, title='Window : New Window', **kw) def body(self, guiFrame): guiFrame.grid_columnconfigure(2, weight=1) row = 0 label = Label(guiFrame, text='Template window: ', grid=(row, 0)) tipText = 'Selects which window to use as the basis for making a new spectrum window; sets the axis types accordingly' self.window_list = PulldownList(guiFrame, grid=(row, 1), callback=self.setAxisTypes, tipText=tipText) frame = LabelFrame(guiFrame, text='Strips', grid=(row, 2), gridSpan=(2, 1)) buttons = UtilityButtonList(guiFrame, doClone=False, helpUrl=self.help_url, grid=(row, 3)) row += 1 label = Label(guiFrame, text='New window name: ', grid=(row, 0)) tipText = 'A short name to identify the spectrum window, which will appear in the graphical interface' self.nameEntry = Entry(guiFrame, width=16, grid=(row, 1), tipText=tipText) row += 1 label = Label(frame, text='Columns: ', grid=(0, 0)) tipText = 'The number of vertical strips/dividers to initially make in the spectrum window' self.cols_menu = PulldownList(frame, objects=STRIP_NUMS, grid=(0, 1), texts=[str(x) for x in STRIP_NUMS], tipText=tipText) label = Label(frame, text='Rows: ', grid=(0, 2)) tipText = 'The number of horizontal strips/dividers to initially make in the spectrum window' self.rows_menu = PulldownList(frame, objects=STRIP_NUMS, grid=(0, 3), texts=[str(x) for x in STRIP_NUMS], tipText=tipText) row += 1 div = LabelDivider(guiFrame, text='Axes', grid=(row, 0), gridSpan=(1, 4)) row += 1 self.axis_lists = {} frame = Frame(guiFrame, grid=(row, 0), gridSpan=(1, 4)) col = 0 self.axisTypes = {} self.axisTypesIncludeNone = {} for label in AXIS_LABELS: self.axisTypes[label] = None w = Label(frame, text=' ' + label) w.grid(row=0, column=col, sticky='w') col += 1 if label in ('x', 'y'): includeNone = False tipText = 'Sets the kind of measurement (typically ppm for a given isotope) that will be used along the window %s axis' % label else: includeNone = True tipText = 'Where required, sets the kind of measurement (typically ppm for a given isotope) that will be used along the window %s axis' % label self.axisTypesIncludeNone[label] = includeNone getAxisTypes = lambda label=label: self.getAxisTypes(label) callback = lambda axisType, label=label: self.changedAxisType( label, axisType) self.axis_lists[label] = PulldownList(frame, callback=callback, tipText=tipText) self.axis_lists[label].grid(row=0, column=col, sticky='w') col += 1 frame.grid_columnconfigure(col, weight=1) row += 1 div = LabelDivider(guiFrame, text='Viewed Spectra', grid=(row, 0), gridSpan=(1, 4)) row += 1 guiFrame.grid_rowconfigure(row, weight=1) editWidgets = [None, None, None, None] editGetCallbacks = [None, self.toggleVisible, self.toggleToolbar, None] editSetCallbacks = [None, None, None, None] tipTexts = [ 'The "experiment:spectrum" name for the spectrum that may be viewed in the new window, given the axis selections', 'Sets whether the spectrum contours will be visible in the new window', 'Sets whether the spectrum appears at all in the window; if not in the toolbar it cannot be displayed', 'The number of peak lists the spectrum contains' ] headingList = ['Spectrum', 'Visible?', 'In Toolbar?', 'Peak Lists'] self.scrolledMatrix = ScrolledMatrix(guiFrame, headingList=headingList, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, multiSelect=True, grid=(row, 0), gridSpan=(1, 4), tipTexts=tipTexts) row += 1 tipTexts = [ 'Creates a new spectrum window with the specified parameters', 'Sets the contours of the selected spectra to be visible when the new window is made', 'Sets the contours of the selected spectra to not be displayed when the new window is made', 'Sets the selected spectra as absent from the window toolbar, and thus not displayable at all' ] texts = [ 'Create Window!', 'Selected\nVisible', 'Selected\nNot Visible', 'Selected\nNot In Toolbar' ] commands = [ self.ok, self.setSelectedDisplay, self.setSelectedHide, self.setSelectedAbsent ] buttonList = ButtonList(guiFrame, texts=texts, grid=(row, 0), commands=commands, gridSpan=(1, 4), tipTexts=tipTexts) buttonList.buttons[0].config(bg='#B0FFB0') self.updateAxisTypes() self.updateWindow() self.updateWindowName() self.administerNotifiers(self.registerNotify) self.updateAfter() def administerNotifiers(self, notifyFunc): self.registerNotify(self.updateWindowName, 'ccpnmr.Analysis.SpectrumWindow', '__init__') for clazz in ('ccp.nmr.Nmr.Experiment', 'ccp.nmr.Nmr.DataSource'): for func in ('__init__', 'delete', 'setName'): notifyFunc(self.updateAfter, clazz, func) for func in ('__init__', 'delete'): notifyFunc(self.updateAfter, 'ccp.nmr.Nmr.PeakList', func) for func in ('__init__', 'delete', 'setName', 'addSpectrumWindowGroup', 'removeSpectrumWindowGroup', 'setSpectrumWindowGroups'): notifyFunc(self.updateWindow, 'ccpnmr.Analysis.SpectrumWindow', func) for func in ('addSpectrumWindow', 'removeSpectrumWindow', 'setSpectrumWindows'): notifyFunc(self.updateWindow, 'ccpnmr.Analysis.SpectrumWindowGroup', func) for func in ('__init__', 'delete', 'setName'): notifyFunc(self.updateAxisTypes, 'ccpnmr.Analysis.AxisType', func) # Set visible contours, on commit, according to selection # Get hold of spectrumWindowView ASAP def destroy(self): self.administerNotifiers(self.unregisterNotify) BasePopup.destroy(self) def getSpectra(self): spectrumIsotopes = {} spectra = [] for experiment in self.nmrProject.sortedExperiments(): name = experiment.name for spectrum in experiment.sortedDataSources(): spectrumIsotopes[spectrum] = [] spectra.append(['%s:%s' % (name, spectrum.name), spectrum]) for dataDim in spectrum.dataDims: dimTypes = [] if dataDim.className != 'SampledDataDim': for dataDimRef in dataDim.dataDimRefs: expDimRef = dataDimRef.expDimRef isotopes = set() for isotopeCode in expDimRef.isotopeCodes: isotopes.add(isotopeCode) dimTypes.append( (expDimRef.measurementType.lower(), isotopes)) else: dimTypes.append('sampled') spectrumIsotopes[spectrum].append(dimTypes) axisIsotopes = {} for label in AXIS_LABELS: if label not in ('x', 'y'): if self.axis_lists[label].getSelectedIndex() == 0: continue axisType = self.axis_lists[label].getObject() axisIsotopes[label] = (axisType.measurementType.lower(), set(axisType.isotopeCodes)) spectraSel = [] axes = axisIsotopes.keys() axes.sort() for name, spectrum in spectra: dimIsotopes = spectrumIsotopes[spectrum] for label in axes: mType, selected = axisIsotopes[label] if label == 'y' and mType == 'none': continue # value axis for i, dimTypes in enumerate(dimIsotopes): for dimType in dimTypes: if dimType == 'sampled': if label != 'z1': continue axisType = self.axis_lists[label].getObject() if axisType.name != 'sampled': continue dimIsotopes.pop(i) break else: measurementType, isotopes = dimType if (mType == measurementType) and (selected <= isotopes): dimIsotopes.pop(i) break else: continue break else: if label in ('x', 'y'): break else: if not dimIsotopes: spectraSel.append([name, spectrum]) return spectraSel def setSelectedAbsent(self): for spectrum in self.scrolledMatrix.currentObjects: self.visibleSpectra[spectrum] = False self.toolbarSpectra[spectrum] = False self.updateAfter() def setSelectedDisplay(self): for spectrum in self.scrolledMatrix.currentObjects: self.visibleSpectra[spectrum] = True self.toolbarSpectra[spectrum] = True self.updateAfter() def setSelectedHide(self): for spectrum in self.scrolledMatrix.currentObjects: self.visibleSpectra[spectrum] = False self.toolbarSpectra[spectrum] = True self.updateAfter() def toggleToolbar(self, spectrum): boolean = not self.toolbarSpectra.get(spectrum, True) self.toolbarSpectra[spectrum] = boolean if boolean is False: self.visibleSpectra[spectrum] = False self.updateAfter() def toggleVisible(self, spectrum): boolean = not self.visibleSpectra.get(spectrum, False) self.visibleSpectra[spectrum] = boolean if boolean: if not self.toolbarSpectra.get(spectrum, True): self.toolbarSpectra[spectrum] = True self.updateAfter() def updateAfter(self, object=None): if self.waiting: return else: self.waiting = True self.after_idle(self.update) def update(self): for spectrum in self.visibleSpectra.keys(): if spectrum.isDeleted: del self.visibleSpectra[spectrum] textMatrix = [] objectList = [] colorMatrix = [] for name, spectrum in self.getSpectra(): colours = [None, None, None, None] if self.visibleSpectra.get(spectrum): colours[0] = '#60F060' isVisible = 'Yes' self.visibleSpectra[ spectrum] = True # do not need this but play safe in case above if changed else: isVisible = 'No' self.visibleSpectra[spectrum] = False if self.toolbarSpectra.get(spectrum, True): inToolbar = 'Yes' self.toolbarSpectra[spectrum] = True else: colours[0] = '#600000' inToolbar = 'No' self.toolbarSpectra[spectrum] = False datum = [ name, isVisible, inToolbar, ','.join(['%d' % pl.serial for pl in spectrum.peakLists]) ] textMatrix.append(datum) objectList.append(spectrum) colorMatrix.append(colours) self.scrolledMatrix.update(objectList=objectList, textMatrix=textMatrix, colorMatrix=colorMatrix) self.waiting = False def updateAxisTypes(self, *extra): for label in AXIS_LABELS: names = [] objects = [] includeNone = self.axisTypesIncludeNone[label] if includeNone: names.append('None') objects.append(None) axisType = self.axisTypes[label] axisTypes = self.getAxisTypes(label) objects.extend(axisTypes) if axisTypes: if axisType not in objects: axisType = objects[0] index = objects.index(axisType) names.extend([x.name for x in axisTypes]) else: index = 0 self.axis_lists[label].setup(names, objects, index) self.changedAxisType(label, axisType) def changedAxisType(self, label, axisType): if axisType is not self.axisTypes[label]: self.axisTypes[label] = axisType self.updateAfter() def updateWindow(self, *extra): window = self.window windows = self.parent.getWindows() if windows: if window not in windows: window = windows[0] index = windows.index(window) names = [x.name for x in windows] else: index = 0 names = [] self.window_list.setup(names, windows, index) self.setAxisTypes(window) def updateWindowName(self, *extra): self.nameEntry.set(WindowBasic.defaultWindowName(self.project)) def getAxisTypes(self, label): axisTypes = self.parent.getAxisTypes() if label == 'z1': axisTypes = [ axisType for axisType in axisTypes if axisType.name == 'sampled' or not axisType.isSampled ] else: axisTypes = [ axisType for axisType in axisTypes if not axisType.isSampled ] if label != 'y': axisTypes = [ at for at in axisTypes if at.name != WindowBasic.VALUE_AXIS_NAME ] return axisTypes def setAxisTypes(self, window): project = self.project if not project: return if window is self.window: return self.window = window if window: windowPanes = window.sortedSpectrumWindowPanes() if windowPanes: # might be empty because notifier called before windowPanes set up windowPane = windowPanes[0] for label in AXIS_LABELS: axisPanel = windowPane.findFirstAxisPanel(label=label) if axisPanel and axisPanel.panelType \ and axisPanel.panelType.axisType: self.axis_lists[label].setSelected( axisPanel.panelType.axisType) elif label not in ('x', 'y'): self.axis_lists[label].setIndex(0) self.updateAfter() def apply(self): project = self.project if not project: return False name = self.nameEntry.get().strip() if not name: showError('No name', 'Need to enter name', parent=self) return False names = [ window.name for window in self.analysisProject.spectrumWindows ] if (name in names): showError('Repeated name', 'Name already used', parent=self) return False axisTypes = [] for label in AXIS_LABELS: if label not in ('x', 'y'): if self.axis_lists[label].getSelectedIndex() == 0: continue axisType = self.axis_lists[label].getObject() axisTypes.append(axisType) ncols = self.cols_menu.getObject() nrows = self.rows_menu.getObject() window = WindowBasic.createSpectrumWindow(project, name, [ axisTypes, ], ncols=ncols, nrows=nrows) return True
class CingFrame(NmrSimRunFrame): def __init__(self, parent, application, *args, **kw): project = application.project simStore = project.findFirstNmrSimStore(application=APP_NAME) or \ project.newNmrSimStore(application=APP_NAME, name=APP_NAME) self.application = application self.residue = None self.structure = None self.serverCredentials = None self.iCingBaseUrl = DEFAULT_URL self.resultsUrl = None self.chain = None self.nmrProject = application.nmrProject self.serverDone = False NmrSimRunFrame.__init__(self, parent, project, simStore, *args, **kw) # # # # # # New Structure Frame # # # # # self.structureFrame.grid_forget() tab = self.tabbedFrame.frames[0] frame = Frame(tab, grid=(1,0)) frame.expandGrid(2,1) div = LabelDivider(frame, text='Structures', grid=(0,0), gridSpan=(1,2)) label = Label(frame, text='Ensemble: ', grid=(1,0)) self.structurePulldown = PulldownList(frame, callback=self.changeStructure, grid=(1,1)) headingList = ['Model','Use'] editWidgets = [None,None] editGetCallbacks = [None,self.toggleModel] editSetCallbacks = [None,None,] self.modelTable = ScrolledMatrix(frame, grid=(2,0), gridSpan=(1,2), callback=self.selectStructModel, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, headingList=headingList) texts = ['Activate Selected','Inactivate Selected'] commands = [self.activateModels, self.disableModels] buttons = ButtonList(frame, texts=texts, commands=commands, grid=(3,0), gridSpan=(1,2)) # # # # # # Submission frame # # # # # # tab = self.tabbedFrame.frames[1] tab.expandGrid(1,0) frame = LabelFrame(tab, text='Server Job Submission', grid=(0,0)) frame.expandGrid(None,2) srow = 0 label = Label(frame, text='iCing URL:', grid=(srow, 0)) urls = [DEFAULT_URL,] self.iCingBaseUrlPulldown = PulldownList(frame, texts=urls, objects=urls, index=0, grid=(srow,1)) srow +=1 label = Label(frame, text='Results File:', grid=(srow, 0)) self.resultFileEntry = Entry(frame, bd=1, text='', grid=(srow,1), width=50) self.setZipFileName() button = Button(frame, text='Choose File', bd=1, sticky='ew', command=self.chooseZipFile, grid=(srow, 2)) srow +=1 label = Label(frame, text='Results URL:', grid=(srow, 0)) self.resultUrlEntry = Entry(frame, bd=1, text='', grid=(srow,1), width=50) button = Button(frame, text='View Results HTML', bd=1, sticky='ew', command=self.viewHtmlResults, grid=(srow, 2)) srow +=1 texts = ['Submit Project!', 'Check Run Status', 'Purge Server Result', 'Download Results'] commands = [self.runCingServer, self.checkStatus, self.purgeCingServer, self.downloadResults] self.buttonBar = ButtonList(frame, texts=texts, commands=commands, grid=(srow, 0), gridSpan=(1,3)) for button in self.buttonBar.buttons[:1]: button.config(bg=CING_BLUE) # # # # # # Residue frame # # # # # # frame = LabelFrame(tab, text='Residue Options', grid=(1,0)) frame.expandGrid(1,1) label = Label(frame, text='Chain: ') label.grid(row=0,column=0,sticky='w') self.chainPulldown = PulldownList(frame, callback=self.changeChain) self.chainPulldown.grid(row=0,column=1,sticky='w') headingList = ['#','Residue','Linking','Decriptor','Use?'] editWidgets = [None,None,None,None,None] editGetCallbacks = [None,None,None,None,self.toggleResidue] editSetCallbacks = [None,None,None,None,None,] self.residueMatrix = ScrolledMatrix(frame, headingList=headingList, multiSelect=True, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, callback=self.selectResidue) self.residueMatrix.grid(row=1, column=0, columnspan=2, sticky = 'nsew') texts = ['Activate Selected','Inactivate Selected'] commands = [self.activateResidues, self.deactivateResidues] self.resButtons = ButtonList(frame, texts=texts, commands=commands,) self.resButtons.grid(row=2, column=0, columnspan=2, sticky='ew') """ # # # # # # Validate frame # # # # # # frame = LabelFrame(tab, text='Validation Options', grid=(2,0)) frame.expandGrid(None,2) srow = 0 self.selectCheckAssign = CheckButton(frame) self.selectCheckAssign.grid(row=srow, column=0,sticky='nw' ) self.selectCheckAssign.set(True) label = Label(frame, text='Assignments and shifts') label.grid(row=srow,column=1,sticky='nw') srow += 1 self.selectCheckResraint = CheckButton(frame) self.selectCheckResraint.grid(row=srow, column=0,sticky='nw' ) self.selectCheckResraint.set(True) label = Label(frame, text='Restraints') label.grid(row=srow,column=1,sticky='nw') srow += 1 self.selectCheckQueen = CheckButton(frame) self.selectCheckQueen.grid(row=srow, column=0,sticky='nw' ) self.selectCheckQueen.set(False) label = Label(frame, text='QUEEN') label.grid(row=srow,column=1,sticky='nw') srow += 1 self.selectCheckScript = CheckButton(frame) self.selectCheckScript.grid(row=srow, column=0,sticky='nw' ) self.selectCheckScript.set(False) label = Label(frame, text='User Python script\n(overriding option)') label.grid(row=srow,column=1,sticky='nw') self.validScriptEntry = Entry(frame, bd=1, text='') self.validScriptEntry.grid(row=srow,column=2,sticky='ew') scriptButton = Button(frame, bd=1, command=self.chooseValidScript, text='Browse') scriptButton.grid(row=srow,column=3,sticky='ew') """ # # # # # # # # # # self.update(simStore) self.administerNotifiers(application.registerNotify) def downloadResults(self): if not self.run: msg = 'No current iCing run' showWarning('Failure', msg, parent=self) return credentials = self.serverCredentials if not credentials: msg = 'No current iCing server job' showWarning('Failure', msg, parent=self) return fileName = self.resultFileEntry.get() if not fileName: msg = 'No save file specified' showWarning('Failure', msg, parent=self) return if os.path.exists(fileName): msg = 'File %s already exists. Overwite?' % fileName if not showOkCancel('Query', msg, parent=self): return url = self.iCingBaseUrl iCingUrl = self.getServerUrl(url) logText = iCingRobot.iCingFetch(credentials, url, iCingUrl, fileName) print logText msg = 'Results saved to file %s\n' % fileName msg += 'Purge results from iCing server?' if showYesNo('Query',msg, parent=self): self.purgeCingServer() def getServerUrl(self, baseUrl): iCingUrl = os.path.join(baseUrl, 'icing/serv/iCingServlet') return iCingUrl def viewHtmlResults(self): resultsUrl = self.resultsUrl if not resultsUrl: msg = 'No current iCing results URL' showWarning('Failure', msg, parent=self) return webBrowser = WebBrowser(self.application, popup=self.application) webBrowser.open(self.resultsUrl) def runCingServer(self): if not self.project: return run = self.run if not run: msg = 'No CING run setup' showWarning('Failure', msg, parent=self) return structure = self.structure if not structure: msg = 'No structure ensemble selected' showWarning('Failure', msg, parent=self) return ensembleText = getModelsString(run) if not ensembleText: msg = 'No structural models selected from ensemble' showWarning('Failure', msg, parent=self) return residueText = getResiduesString(structure) if not residueText: msg = 'No active residues selected in structure' showWarning('Failure', msg, parent=self) return url = self.iCingBaseUrlPulldown.getObject() url.strip() if not url: msg = 'No iCing server URL specified' showWarning('Failure', msg, parent=self) self.iCingBaseUrl = None return msg = 'Submit job now? You will be informed when the job is done.' if not showOkCancel('Confirm', msg, parent=self): return self.iCingBaseUrl = url iCingUrl = self.getServerUrl(url) self.serverCredentials, results, tarFileName = iCingRobot.iCingSetup(self.project, userId='ccpnAp', url=iCingUrl) if not results: # Message already issued on failure self.serverCredentials = None self.resultsUrl = None self.update() return else: credentials = self.serverCredentials os.unlink(tarFileName) entryId = iCingRobot.iCingProjectName(credentials, iCingUrl).get(iCingRobot.RESPONSE_RESULT) baseUrl, htmlUrl, logUrl, zipUrl = iCingRobot.getResultUrls(credentials, entryId, url) self.resultsUrl = htmlUrl # Save server data in this run for persistence setRunParameter(run, iCingRobot.FORM_USER_ID, self.serverCredentials[0][1]) setRunParameter(run, iCingRobot.FORM_ACCESS_KEY, self.serverCredentials[1][1]) setRunParameter(run, ICING_BASE_URL, url) setRunParameter(run, HTML_RESULTS_URL, htmlUrl) self.update() run.inputStructures = structure.sortedModels() # select residues from the structure's chain #iCingRobot.iCingResidueSelection(credentials, iCingUrl, residueText) # Select models from ensemble #iCingRobot.iCingEnsembleSelection(credentials, iCingUrl, ensembleText) # Start the actual run self.serverDone = False iCingRobot.iCingRun(credentials, iCingUrl) # Fetch server progress occasionally, report when done # this function will call itself again and again self.after(CHECK_INTERVAL, self.timedCheckStatus) self.update() def timedCheckStatus(self): if not self.serverCredentials: return if self.serverDone: return status = iCingRobot.iCingStatus(self.serverCredentials, self.getServerUrl(self.iCingBaseUrl)) if not status: #something broke, already warned return result = status.get(iCingRobot.RESPONSE_RESULT) if result == iCingRobot.RESPONSE_DONE: self.serverDone = True msg = 'CING run is complete!' showInfo('Completion', msg, parent=self) return self.after(CHECK_INTERVAL, self.timedCheckStatus) def checkStatus(self): if not self.serverCredentials: return status = iCingRobot.iCingStatus(self.serverCredentials, self.getServerUrl(self.iCingBaseUrl)) if not status: #something broke, already warned return result = status.get(iCingRobot.RESPONSE_RESULT) if result == iCingRobot.RESPONSE_DONE: msg = 'CING run is complete!' showInfo('Completion', msg, parent=self) self.serverDone = True return else: msg = 'CING job is not done.' showInfo('Processing', msg, parent=self) self.serverDone = False return def purgeCingServer(self): if not self.project: return if not self.run: msg = 'No CING run setup' showWarning('Failure', msg, parent=self) return if not self.serverCredentials: msg = 'No current iCing server job' showWarning('Failure', msg, parent=self) return url = self.iCingBaseUrl results = iCingRobot.iCingPurge(self.serverCredentials, self.getServerUrl(url)) if results: showInfo('Info','iCing server results cleared') self.serverCredentials = None self.iCingBaseUrl = None self.serverDone = False deleteRunParameter(self.run, iCingRobot.FORM_USER_ID) deleteRunParameter(self.run, iCingRobot.FORM_ACCESS_KEY) deleteRunParameter(self.run, HTML_RESULTS_URL) else: showInfo('Info','Purge failed') self.update() def chooseZipFile(self): fileTypes = [ FileType('Zip', ['*.zip']), ] popup = FileSelectPopup(self, file_types=fileTypes, file=self.resultFileEntry.get(), title='Results zip file location', dismiss_text='Cancel', selected_file_must_exist=False) fileName = popup.getFile() if fileName: self.resultFileEntry.set(fileName) popup.destroy() def setZipFileName(self): zipFile = '%s_CING_report.zip' % self.project.name self.resultFileEntry.set(zipFile) def selectStructModel(self, model, row, col): self.model = model def selectResidue(self, residue, row, col): self.residue = residue def deactivateResidues(self): for residue in self.residueMatrix.currentObjects: residue.useInCing = False self.updateResidues() def activateResidues(self): for residue in self.residueMatrix.currentObjects: residue.useInCing = True self.updateResidues() def activateModels(self): if self.run: for model in self.modelTable.currentObjects: if model not in self.run.inputStructures: self.run.addInputStructure(model) self.updateModels() def disableModels(self): if self.run: for model in self.modelTable.currentObjects: if model in self.run.inputStructures: self.run.removeInputStructure(model) self.updateModels() def toggleModel(self, *opt): if self.model and self.run: if self.model in self.run.inputStructures: self.run.removeInputStructure(self.model) else: self.run.addInputStructure(self.model) self.updateModels() def toggleResidue(self, *opt): if self.residue: self.residue.useInCing = not self.residue.useInCing self.updateResidues() def updateResidues(self): if self.residue and (self.residue.topObject is not self.structure): self.residue = None textMatrix = [] objectList = [] colorMatrix = [] if self.chain: chainCode = self.chain.code for residue in self.chain.sortedResidues(): msResidue = residue.residue if not hasattr(residue, 'useInCing'): residue.useInCing = True if residue.useInCing: colors = [None, None, None, None, CING_BLUE] use = 'Yes' else: colors = [None, None, None, None, None] use = 'No' datum = [residue.seqCode, msResidue.ccpCode, msResidue.linking, msResidue.descriptor, use,] textMatrix.append(datum) objectList.append(residue) colorMatrix.append(colors) self.residueMatrix.update(objectList=objectList, textMatrix=textMatrix, colorMatrix=colorMatrix) def updateChains(self): index = 0 names = [] chains = [] chain = self.chain if self.structure: chains = self.structure.sortedCoordChains() names = [chain.code for chain in chains] if chains: if chain not in chains: chain = chains[0] index = chains.index(chain) self.changeChain(chain) self.chainPulldown.setup(names, chains, index) def updateStructures(self): index = 0 names = [] structures = [] structure = self.structure if self.run: model = self.run.findFirstInputStructure() if model: structure = model.structureEnsemble structures0 = [(s.ensembleId, s) for s in self.project.structureEnsembles] structures0.sort() for eId, structure in structures0: name = '%s:%s' % (structure.molSystem.code, eId) structures.append(structure) names.append(name) if structures: if structure not in structures: structure = structures[-1] index = structures.index(structure) self.changeStructure(structure) self.structurePulldown.setup(names, structures, index) def updateModels(self): textMatrix = [] objectList = [] colorMatrix = [] if self.structure and self.run: used = self.run.inputStructures for model in self.structure.sortedModels(): if model in used: colors = [None, CING_BLUE] use = 'Yes' else: colors = [None, None] use = 'No' datum = [model.serial,use] textMatrix.append(datum) objectList.append(model) colorMatrix.append(colors) self.modelTable.update(objectList=objectList, textMatrix=textMatrix, colorMatrix=colorMatrix) def changeStructure(self, structure): if self.project and (self.structure is not structure): self.project.currentEstructureEnsemble = structure self.structure = structure if self.run: self.run.inputStructures = structure.sortedModels() self.updateModels() self.updateChains() def changeChain(self, chain): if self.project and (self.chain is not chain): self.chain = chain self.updateResidues() def chooseValidScript(self): # Prepend default Cyana file extension below fileTypes = [ FileType('Python', ['*.py']), ] popup = FileSelectPopup(self, file_types = fileTypes, title='Python file', dismiss_text='Cancel', selected_file_must_exist = True) fileName = popup.getFile() self.validScriptEntry.set(fileName) popup.destroy() def updateAll(self, project=None): if project: self.project = project self.nmrProject = project.currentNmrProject simStore = project.findFirstNmrSimStore(application='CING') or \ project.newNmrSimStore(application='CING', name='CING') else: simStore = None if not self.project: return self.setZipFileName() if not self.project.currentNmrProject: name = self.project.name self.nmrProject = self.project.newNmrProject(name=name) else: self.nmrProject = self.project.currentNmrProject self.update(simStore) def update(self, simStore=None): NmrSimRunFrame.update(self, simStore) run = self.run urls = [DEFAULT_URL,] index = 0 if run: userId = getRunParameter(run, iCingRobot.FORM_USER_ID) accessKey = getRunParameter(run, iCingRobot.FORM_ACCESS_KEY) if userId and accessKey: self.serverCredentials = [(iCingRobot.FORM_USER_ID, userId), (iCingRobot.FORM_ACCESS_KEY, accessKey)] url = getRunParameter(run, ICING_BASE_URL) if url: htmlUrl = getRunParameter(run, HTML_RESULTS_URL) self.iCingBaseUrl = url self.resultsUrl = htmlUrl # May be None self.resultUrlEntry.set(self.resultsUrl) if self.iCingBaseUrl and self.iCingBaseUrl not in urls: index = len(urls) urls.append(self.iCingBaseUrl) self.iCingBaseUrlPulldown.setup(urls, urls, index) self.updateButtons() self.updateStructures() self.updateModels() self.updateChains() def updateButtons(self, event=None): buttons = self.buttonBar.buttons if self.project and self.run: buttons[0].enable() if self.resultsUrl and self.serverCredentials: buttons[1].enable() buttons[2].enable() buttons[3].enable() else: buttons[1].disable() buttons[2].disable() buttons[3].disable() else: buttons[0].disable() buttons[1].disable() buttons[2].disable() buttons[3].disable()
def body(self, guiFrame): self.geometry("500x500") self.nameEntry = Entry(self, text='', returnCallback=self.setName, width=12) self.detailsEntry = Entry(self, text='', returnCallback=self.setDetails, width=16) self.valueEntry = FloatEntry(self, text='', returnCallback=self.setValue, width=10) self.errorEntry = FloatEntry(self, text='', returnCallback=self.setError, width=8) self.conditionNamesPulldown = PulldownList(self, callback=self.setConditionName, texts=self.getConditionNames()) self.unitPulldown = PulldownList(self, callback=self.setUnit, texts=self.getUnits()) self.experimentPulldown = PulldownList(self, callback=self.setExperiment) guiFrame.grid_columnconfigure(0, weight=1) row = 0 frame = Frame(guiFrame, grid=(row, 0)) frame.expandGrid(None,0) div = LabelDivider(frame, text='Current Series', grid=(0, 0)) utilButtons = UtilityButtonList(frame, helpUrl=self.help_url, grid=(0,1)) row += 1 frame0 = Frame(guiFrame, grid=(row, 0)) frame0.expandGrid(0,0) tipTexts = ['The serial number of the experiment series, but left blank if the series as actually a pseudo-nD experiment (with a sampled non-frequency axis)', 'The name of the experiment series, which may be a single pseudo-nD experiment', 'The number of separate experiments (and hence spectra) present in the series', 'The kind of quantity that varies for different experiments/planes within the NMR series, e.g. delay time, temperature, ligand concentration etc.', 'The number of separate points, each with a separate experiment/plane and parameter value, in the series'] headingList = ['#','Name','Experiments','Parameter\nVaried','Num\nPoints'] editWidgets = [None, self.nameEntry, None, self.conditionNamesPulldown, None] editGetCallbacks = [None, self.getName, None, self.getConditionName, None] editSetCallbacks = [None, self.setName, None, self.setConditionName, None] self.seriesMatrix = ScrolledMatrix(frame0, tipTexts=tipTexts, editSetCallbacks=editSetCallbacks, editGetCallbacks=editGetCallbacks, editWidgets=editWidgets, headingList=headingList, callback=self.selectExpSeries, deleteFunc=self.deleteExpSeries, grid=(0,0), gridSpan=(None, 3)) tipTexts = ['Make a new, blank NMR series specification in the CCPN project', 'Delete the selected NMR series from the project, although any component experiments remain. Note you cannot delete pseudo-nD series; delete the actual experiment instead', 'Colour the spectrum contours for each experiment in the selected series (not pseudo-nD) using a specified scheme'] texts = ['Add Series','Delete Series', 'Auto Colour Spectra'] commands = [self.addExpSeries,self.deleteExpSeries, self.autoColorSpectra] self.seriesButtons = ButtonList(frame0, texts=texts, commands=commands, grid=(1,0), tipTexts=tipTexts) label = Label(frame0, text='Scheme:', grid=(1,1)) tipText = 'Selects which colour scheme to apply to the contours of (separate) experiments within an NMR series' self.colorSchemePulldown = PulldownList(frame0, grid=(1,2), tipText=tipText) row += 1 div = LabelDivider(guiFrame, text='Experimental Parameters & Conditions', grid=(row, 0)) row += 1 guiFrame.grid_rowconfigure(row, weight=1) frame1 = Frame(guiFrame, grid=(row, 0)) frame1.expandGrid(0,0) tipTexts = ['The kind of experimental parameter that is being used to define the NMR series', 'The experiment that corresponds to the specified parameter value; can be edited from an arbitrary initial experiment', 'The numeric value of the parameter (condition) that relates to the experiment or point in the NMR series', 'The estimated error in value of the condition', 'The measurement unit in which the value of the condition is represented'] headingList = ['Parameter','Experiment','Value','Error','Unit'] editWidgets = [None,self.experimentPulldown,self.valueEntry,self.errorEntry, self.unitPulldown] editGetCallbacks = [None,self.getExperiment, self.getValue, self.getError, self.getUnit] editSetCallbacks = [None,self.setExperiment, self.setValue, self.setError, self.setUnit] self.conditionPointsMatrix = ScrolledMatrix(frame1, grid=(0,0), tipTexts=tipTexts, editSetCallbacks=editSetCallbacks, editGetCallbacks=editGetCallbacks, editWidgets=editWidgets, headingList=headingList, callback=self.selectConditionPoint, deleteFunc=self.deleteConditionPoint) self.conditionPointsMatrix.doEditMarkExtraRules = self.conditionTableShow tipTexts = ['Add a new point to the NMR series with an associated parameter value and experiment', 'Remove the selected point from the series, including any associated parameter value', 'For appropriate kinds of NMR series, set or unset a point as representing the plane to use as a reference'] texts = ['Add Series Point','Delete Series Point','Set/Unset Ref Plane'] commands = [self.addConditionPoint,self.deleteConditionPoint,self.setSampledReferencePlane] self.conditionPointsButtons = ButtonList(frame1, texts=texts, commands=commands, tipTexts=tipTexts, grid=(1,0)) self.updateAfter() self.updateColorSchemes() self.administerNotifiers(self.registerNotify)
def body(self, guiFrame): guiFrame.grid_columnconfigure(0, weight=1) row = 0 self.scrolledGraph = ScrolledGraph(guiFrame, width=400, height=300, symbolSize=5, symbols=['square', 'circle'], dataColors=['#000080', '#800000'], lineWidths=[0, 1], grid=(row, 0)) #self.scrolledGraph.setZoom(0.7) row += 1 frame = Frame(guiFrame, grid=(row, 0), sticky='ew') label = Label(frame, text='Fitting Function:', grid=(0, 0)) tipText = 'Selects which form of function to fit to the experimental data' self.methodPulldown = PulldownList(frame, self.changeMethod, grid=(0, 1), tipText=tipText) row += 1 frame = Frame(guiFrame, grid=(row, 0), sticky='ew') tipText = 'The effective equation of the final fitted graph, incorporating all parameters' self.equationLabel = Label(frame, text='Equation:', grid=(0, 0), tipText=tipText) tipText = 'The error in the fit of the selected parameterised function to the experimental data' self.errorLabel = Label(frame, text='Fit Error:', grid=(0, 1), tipText=tipText) row += 1 frame = Frame(guiFrame, grid=(row, 0), sticky='ew') label = Label(frame, text='Include x origin?:', grid=(0, 0)) tipText = 'Whether to include the x=0 point in the drawing' self.xOriginSelect = CheckButton(frame, callback=self.draw, grid=(0, 1), selected=False, tipText=tipText) label = Label(frame, text='Include y origin?:', grid=(0, 2)) tipText = 'Whether to include the y=0 point in the drawing' self.yOriginSelect = CheckButton(frame, callback=self.draw, grid=(0, 3), selected=False, tipText=tipText) label = Label(frame, text='Include y error?:', grid=(0, 4)) tipText = 'Whether to include the y error bars in the drawing (if these exist)' self.yErrorSelect = CheckButton(frame, callback=self.draw, grid=(0, 5), selected=False, tipText=tipText) row += 1 frame = Frame(guiFrame, grid=(row, 0), sticky='ew') label = Label(frame, text='Navigation Window:', grid=(0, 0)) tipText = 'Selects which spectrum window will be used for navigating to peak positions' self.windowPanePulldown = PulldownList(frame, self.changeWindow, grid=(0, 1), tipText=tipText) label = Label(frame, text='Follow in window?:', grid=(0, 2)) tipText = 'Whether to navigate to the position of the reference peak (for the group), in the selected window' self.followSelect = CheckButton(frame, callback=self.windowPaneNavigate, grid=(0, 3), selected=False, tipText=tipText) label = Label(frame, text='Mark Ref Peak?:', grid=(0, 4)) tipText = 'Whether to put a multi-dimensional cross-mark through the reference peak position, so it can be identified in spectra' self.markSelect = CheckButton(frame, callback=None, tipText=tipText, grid=(0, 5), selected=False) row += 1 guiFrame.grid_rowconfigure(row, weight=1) tipTexts = [ 'The number of the data point, in order of increasing X-axis value', 'For each point, the value of the parameter which is varied in the NMR series, e.g. T1, temperature, concentration etc.', 'For each point, the experimental value being fitted, e.g. peak intensity of chemical shift distance', 'The value of the best-fit function at the X-axis location', 'The difference between the experimental (Y-axis) value and the fitted value', 'The error in the experimental (Y-axis) value' ] headingList = ['Point', 'x', 'y', 'Fitted y', u'\u0394', 'y error'] self.scrolledMatrix = ScrolledMatrix(guiFrame, headingList=headingList, callback=self.selectObject, tipTexts=tipTexts, grid=(row, 0)) row += 1 tipTexts = [ 'Remove the selected data point, optionally removing the underlying peak', 'Show a table of spectrum peaks that correspond to the selected data point' ] texts = ['Remove Point', 'Show Peak'] commands = [self.removePoint, self.showObject] if self.prevSetFunction: texts.append('Previous Set') tipTexts.append( 'Move to the previous set of fitted values; the next group of peaks, often corresponding to a different residue or resonance' ) commands.append(self.prevSet) if self.nextSetFunction: tipTexts.append( 'Move to the next set of fitted values; the next group of peaks, often corresponding to a different residue or resonance' ) texts.append('Next Set') commands.append(self.nextSet) bottomButtons = UtilityButtonList(guiFrame, texts=texts, commands=commands, helpUrl=self.help_url, tipTexts=tipTexts, grid=(row, 0), doClone=False) self.removeButton = bottomButtons.buttons[0] for func in ('__init__', 'delete', 'setName'): self.registerNotify(self.updateWindows, 'ccpnmr.Analysis.SpectrumWindow', func) self.update()
def body(self, guiFrame): self.geometry('700x700') guiFrame.expandGrid(0,0) options = ['Peak Lists & Settings','Peak Intensity Comparison'] tabbedFrame = TabbedFrame(guiFrame, options=options, callback=self.changeTab) tabbedFrame.grid(row=0, column=0, sticky='nsew') self.tabbedFrame = tabbedFrame frameA, frameB = tabbedFrame.frames row = 0 frameA.grid_columnconfigure(1, weight=1) frameA.grid_columnconfigure(3, weight=1) frameA.grid_columnconfigure(5, weight=1) frameA.grid_rowconfigure(5, weight=1) tipText = 'Number of reference peaks (no saturation)' self.peaksALabel = Label(frameA, text='Number of Ref Peaks: ', tipText=tipText) self.peaksALabel.grid(row=1,column=0,columnspan=2,sticky='w') tipText = 'Number of NOE saturation peaks' self.peaksBLabel = Label(frameA, text='Number of Sat Peaks: ', tipText=tipText) self.peaksBLabel.grid(row=1,column=2,columnspan=2,sticky='w') tipText = 'Number of peaks in assigned list' self.peaksCLabel = Label(frameA, text='Number of Assign Peaks: ', tipText=tipText) self.peaksCLabel.grid(row=1,column=4,columnspan=2,sticky='w') tipText = 'Selects which peak list is considered the NOE intensity reference (no saturation)' specALabel = Label(frameA, text='Ref Peak List: ') specALabel.grid(row=0,column=0,sticky='w') self.specAPulldown = PulldownList(frameA, callback=self.setRefPeakList, tipText=tipText) self.specAPulldown.grid(row=0,column=1,sticky='w') tipText = 'Selects which peak list is considered as NOE saturated.' specBLabel = Label(frameA, text='Sat Peak List: ') specBLabel.grid(row=0,column=2,sticky='w') self.specBPulldown = PulldownList(frameA, callback=self.setSatPeakList, tipText=tipText) self.specBPulldown.grid(row=0,column=3,sticky='w') tipText = 'Selects a peak list with assignments to use as a positional reference' specCLabel = Label(frameA, text='Assignment Peak List: ') specCLabel.grid(row=0,column=4,sticky='w') self.specCPulldown = PulldownList(frameA, callback=self.setAssignPeakList, tipText=tipText) self.specCPulldown.grid(row=0,column=5,sticky='w') frame0a = Frame(frameA) frame0a.grid(row=2,column=0,columnspan=6,sticky='nsew') frame0a.grid_columnconfigure(9, weight=1) tipText = '1H ppm tolerance for matching assigned peaks to reference & NOE saturation peaks' tolHLabel = Label(frame0a, text='Tolerances: 1H') tolHLabel.grid(row=0,column=0,sticky='w') self.tolHEntry = FloatEntry(frame0a,text='0.02', width=6, tipText=tipText) self.tolHEntry .grid(row=0,column=1,sticky='w') tipText = '15N ppm tolerance for matching assigned peaks to reference & NOE saturation peaks' tolNLabel = Label(frame0a, text=' 15N') tolNLabel .grid(row=0,column=2,sticky='w') self.tolNEntry = FloatEntry(frame0a,text='0.1', width=6, tipText=tipText) self.tolNEntry .grid(row=0,column=3,sticky='w') tipText = 'Whether to peak new peaks in reference & NOE saturated lists (at assignment locations)' label = Label(frame0a, text=' Pick new peaks?', grid=(0,4)) self.pickPeaksSelect = CheckButton(frame0a, tipText=tipText, grid=(0,5), selected=True) tipText = 'Whether to assign peaks in the peaks in the reference & NOE saturation lists, if not already assigned' label = Label(frame0a, text=' Assign peaks?') label.grid(row=0,column=6,sticky='w') self.assignSelect = CheckButton(frame0a, tipText=tipText) self.assignSelect.set(1) self.assignSelect.grid(row=0,column=7,sticky='w') tipText = 'Whether to consider peak height or volume in the heteronuclear NOE calculation' intensLabel = Label(frame0a, text=' Intensity Type:') intensLabel .grid(row=0,column=8,sticky='w') self.intensPulldown = PulldownList(frame0a, texts=['height','volume'], callback=self.setIntensityType, tipText=tipText) self.intensPulldown.grid(row=0,column=9,sticky='w') divider = LabelDivider(frameA, text='Peaks', grid=(3,0), gridSpan=(1,6)) tipTexts = ['Show the selected intensity reference peaks in the below table', 'Show the selected NOE saturation peaks in the below table', 'Show the selected assigned peak list in the below table', 'Show the displayed peaks in a separate peak table, where assignments etc. may be adjusted'] texts = ['Show Ref Peaks','Show Sat Peaks', 'Show Assign Peaks', 'Separate Peak Table'] commands = [self.viewRefPeakList, self.viewSatPeakList, self.viewAssignPeakList, self.viewSeparatePeakTable] self.viewPeaksButtons = ButtonList(frameA, expands=True, tipTexts=tipTexts, texts=texts, commands=commands) self.viewPeaksButtons.grid(row=4,column=0,columnspan=6,sticky='nsew') self.peakTable = PeakTableFrame(frameA, self.guiParent, grid=(5,0), gridSpan=(1,6)) self.peakTable.bottomButtons1.grid_forget() self.peakTable.bottomButtons2.grid_forget() #self.peakTable.topFrame.grid_forget() self.peakTable.topFrame.grid(row=2, column=0, sticky='ew') # Next tab frameB.expandGrid(0,0) tipTexts = ['Row number', 'Assignment annotation for NOE saturation peak', 'Assignment annotation for reference peak (no saturation)', '1H chemical shift of NOE saturation peak', '1H chemical shift of reference peak', '15N chemical shift of NOE saturation peak', '15N chemical shift of reference peak', 'The separation between compared peaks: square root of the sum of ppm differences squared', 'The intensity if the NOE saturation peak', 'The intensity of the reference peak (no saturation)', 'Ratio of peak intensities: saturated over reference', 'Residue(s) for reference peak'] colHeadings = ['#','Sat Peak','Ref Peak','1H shift A', '1H shift B','15N shift A','15N shift B', 'Closeness\nScore','Intensity A','Intensity B', 'Intensity\nRatio','Residue'] self.scrolledMatrix = ScrolledMatrix(frameB, multiSelect=True, headingList=colHeadings, callback=self.selectCell, tipTexts=tipTexts, grid=(0,0), deleteFunc=self.removePair) tipTexts = ['Force a manual update of the table; pair-up NOE saturation and reference peaks according to assigned peak positions', 'Remove the selected rows of peak pairs', 'Show peaks corresponding to the selected row in a table', 'Save the Heteronuclear NOE values in the CCPN project as a data list'] texts = ['Refresh Table','Remove Pairs', 'Show Peak Pair','Create Hetero NOE List'] commands = [self.matchPeaks,self.removePair, self.showPeakPair,self.makeNoeList] self.pairButtons = ButtonList(frameB, tipTexts=tipTexts, grid=(1,0), texts=texts, commands=commands) bottomButtons = UtilityButtonList(tabbedFrame.sideFrame, helpUrl=self.help_url) bottomButtons.grid(row=0, column=0, sticky='e') self.updatePulldowns() self.updateAfter() self.administerNotifiers(self.registerNotify)
def body(self, mainFrame): mainFrame.grid_columnconfigure(1, weight=1, minsize=100) mainFrame.config(borderwidth=5, relief='solid') row = 0 label = Label(mainFrame, text="Frame (with sub-widgets):") label.grid(row=row, column=0, sticky=Tkinter.E) frame = Frame(mainFrame, relief='raised', border=2, background='#8080D0') # Frame expands East-West frame.grid(row=row, column=1, sticky=Tkinter.EW) # Last column expands => Widgets pusted to the West frame.grid_columnconfigure(3, weight=1) # Label is within the sub frame label = Label(frame, text='label ') label.grid(row=0, column=0, sticky=Tkinter.W) entry = Entry(frame, text='Entry', returnCallback=self.showWarning) entry.grid(row=0, column=1, sticky=Tkinter.W) self.check = CheckButton(frame, text='Checkbutton', selected=True, callback=self.updateObjects) self.check.grid(row=0, column=2, sticky=Tkinter.W) # stick a button to the East wall button = Button(frame, text='Button', command=self.pressButton) button.grid(row=0, column=3, sticky=Tkinter.E) row += 1 label = Label(mainFrame, text="Text:") label.grid(row=row, column=0, sticky=Tkinter.E) self.textWindow = Text(mainFrame, text='Initial Text\n', width=60, height=5) self.textWindow.grid(row=row, column=1, sticky=Tkinter.NSEW) row += 1 label = Label(mainFrame, text="CheckButtons:") label.grid(row=row, column=0, sticky=Tkinter.E) entries = ['Alpha','Beta','Gamma','Delta'] selected = entries[2:] self.checkButtons = CheckButtons(mainFrame, entries, selected=selected,select_callback=self.changedCheckButtons) self.checkButtons.grid(row=row, column=1, sticky=Tkinter.W) row += 1 label = Label(mainFrame, text="PartitionedSelector:") label.grid(row=row, column=0, sticky=Tkinter.E) labels = ['Bool','Int','Float','String'] objects = [type(0),type(1),type(1.0),type('a')] selected = [type('a')] self.partitionedSelector= PartitionedSelector(mainFrame, labels=labels, objects=objects, colors = ['red','yellow','green','#000080'], callback=self.toggleSelector,selected=selected) self.partitionedSelector.grid(row=row, column=1, sticky=Tkinter.EW) row += 1 label = Label(mainFrame, text="PulldownMenu") label.grid(row=row, column=0, sticky=Tkinter.E) entries = ['Frodo','Pipin','Merry','Sam','Bill','Gandalf','Strider','Gimli','Legolas'] self.pulldownMenu = PulldownMenu(mainFrame, callback=self.selectPulldown, entries=entries, selected_index=2, do_initial_callback=False) self.pulldownMenu.grid(row=row, column=1, sticky=Tkinter.W) row += 1 label = Label(mainFrame, text="RadioButtons in a\nScrolledFrame.frame:") label.grid(row=row, column=0, sticky=Tkinter.EW) frame = ScrolledFrame(mainFrame, yscroll = False, doExtraConfig = True, width=100) frame.grid(row=row, column=1, sticky=Tkinter.EW) frame.grid_columnconfigure(0, weight=1) self.radioButtons = RadioButtons(frame.frame, entries=entries, select_callback=self.checkRadioButtons, selected_index=1, relief='groove') self.radioButtons.grid(row=0, column=0, sticky=Tkinter.W) row += 1 label = Label(mainFrame, text="LabelFrame with\nToggleLabels inside:") label.grid(row=row, column=0, sticky=Tkinter.E) labelFrame = LabelFrame(mainFrame, text='Frame Title') labelFrame.grid(row=row, column=1, sticky=Tkinter.NSEW) labelFrame.grid_rowconfigure(0, weight=1) labelFrame.grid_columnconfigure(3, weight=1) self.toggleLabel1 = ToggleLabel(labelFrame, text='ScrolledMatrix', callback=self.toggleFrame1) self.toggleLabel1.grid(row=0, column=0, sticky=Tkinter.W) self.toggleLabel1.arrowOn() self.toggleLabel2 = ToggleLabel(labelFrame, text='ScrolledGraph', callback=self.toggleFrame2) self.toggleLabel2.grid(row=0, column=1, sticky=Tkinter.W) self.toggleLabel3 = ToggleLabel(labelFrame, text='ScrolledCanvas', callback=self.toggleFrame3) self.toggleLabel3.grid(row=0, column=2, sticky=Tkinter.W) row += 1 mainFrame.grid_rowconfigure(row, weight=1) label = Label(mainFrame, text="changing/shrinking frames:") label.grid(row=row, column=0, sticky=Tkinter.E) self.toggleRow = row self.toggleFrame = Frame(mainFrame) self.toggleFrame.grid(row=row, column=1, sticky=Tkinter.NSEW) self.toggleFrame.grid_rowconfigure(0, weight=1) self.toggleFrame.grid_columnconfigure(0, weight=1) # option 1 self.intEntry = IntEntry(self, returnCallback = self.setNumber, width=8) self.multiWidget = MultiWidget(self, Entry, options=None, values=None, callback=self.setKeywords, minRows=3, maxRows=5) editWidgets = [None, None, self.intEntry, self.multiWidget] editGetCallbacks = [None, None, self.getNumber, self.getKeywords] editSetCallbacks = [None, None, self.setNumber, self.setKeywords] headingList = ['Name','Color','Number','Keywords'] self.scrolledMatrix = ScrolledMatrix(self.toggleFrame, headingList=headingList, editSetCallbacks=editSetCallbacks, editGetCallbacks=editGetCallbacks, editWidgets=editWidgets, callback=self.selectObject, multiSelect=False) self.scrolledMatrix.grid(row=0, column=0, sticky=Tkinter.NSEW) # option 2 self.scrolledGraph = ScrolledGraph(self.toggleFrame, width=400, height=300, symbolSize=5, symbols=['square','circle'], dataColors=['#000080','#800000'], lineWidths=[0,1] ) self.scrolledGraph.setZoom(1.3) dataSet1 = [[0,0],[1,1],[2,4],[3,9],[4,16],[5,25]] dataSet2 = [[0,0],[1,3],[2,6],[3,9],[4,12],[5,15]] self.scrolledGraph.update(dataSets=[dataSet1,dataSet2], xLabel = 'X axis label', yLabel = 'Y axis label', title = 'Main Title') self.scrolledGraph.draw() # option 3 self.scrolledCanvas = ScrolledCanvas(self.toggleFrame,relief = 'groove', borderwidth = 2, resizeCallback=None) canvas = self.scrolledCanvas.canvas font = 'Helvetica 10' box = canvas.create_rectangle(10,10,150,200, outline='grey', fill='grey90') line = canvas.create_line(0,0,200,200,fill='#800000', width=2) text = canvas.create_text(120,50, text='Text', font=font, fill='black') circle = canvas.create_oval(30,30,50,50,outline='#008000',fill='#404040',width=3) row += 1 label = Label(mainFrame, text="FloatEntry:") label.grid(row=row, column=0, sticky=Tkinter.E) self.floatEntry = FloatEntry(mainFrame, text=3.14159265, returnCallback=self.floatEntryReturn) self.floatEntry.grid(row=row, column=1, sticky=Tkinter.W) row += 1 label = Label(mainFrame, text="Scale:") label.grid(row=row, column=0, sticky=Tkinter.E) self.scale = Scale(mainFrame, from_=10, to=90, value=50, orient=Tkinter.HORIZONTAL) self.scale.grid(row=row, column=1, sticky=Tkinter.W) row += 1 label = Label(mainFrame, text="Value Ramp:") label.grid(row=row, column=0, sticky=Tkinter.E) self.valueRamp = ValueRamp(mainFrame, self.valueRampCallback, speed = 1.5, delay = 50) self.valueRamp.grid(row=row, column=1, sticky=Tkinter.W) row += 1 label = Label(mainFrame, text="ButtonList:") label.grid(row=row, column=0, sticky=Tkinter.E) texts = ['Select File','Close','Quit'] commands = [self.selectFile, self.close, self.quit] bottomButtons = ButtonList(mainFrame, texts=texts, commands=commands, expands=True) bottomButtons.grid(row=row, column=1, sticky=Tkinter.EW) self.protocol('WM_DELETE_WINDOW', self.quit)
def body(self, guiFrame): self.geometry('700x500') guiFrame.expandGrid(1, 0) row = 0 # TOP LEFT FRAME frame = LabelFrame(guiFrame, text='Options') frame.grid(row=row, column=0, sticky='nsew') frame.columnconfigure(5, weight=1) label = Label(frame, text='Chain') label.grid(row=0, column=0, sticky='w') self.chainPulldown = PulldownList( frame, callback=self.changeChain, tipText='Choose the molecular system chain to make predictions for' ) self.chainPulldown.grid(row=0, column=1, sticky='w') label = Label(frame, text='Shift List') label.grid(row=0, column=2, sticky='w') self.shiftListPulldown = PulldownList( frame, callback=self.changeShiftList, tipText='Select the shift list to take input chemical shifts from') self.shiftListPulldown.grid(row=0, column=3, sticky='w') row += 1 # BOTTOM LEFT FRAME frame = LabelFrame(guiFrame, text='Secondary Structure Predictions') frame.grid(row=row, column=0, sticky='nsew') frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(0, weight=1) tipTexts = ('Residue number in chain', 'Residue type code', 'Current stored secondary structure code', 'Predicted secondary structure code') + SEC_STRUC_TIPS headingList = ('Res\nNum', 'Res\nType', 'Current\nSS', 'Predicted\nSS') + SEC_STRUC_KEYS n = len(headingList) editWidgets = n * [None] editGetCallbacks = n * [None] editSetCallbacks = n * [None] self.predictionMatrix = ScrolledMatrix( frame, headingList=headingList, tipTexts=tipTexts, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks) self.predictionMatrix.grid(row=0, column=0, sticky='nsew') row += 1 tipTexts = [ 'Run the D2D method to predict secondary structure', 'Store the secondary structure predictions in the CCPN project' ] texts = [ 'Run D2D Prediction!', 'Commit Predicted\nSecondary Structure' ] commands = [self.runD2D, self.storeSecondaryStructure] self.buttonList = createDismissHelpButtonList(guiFrame, texts=texts, commands=commands, help_url=self.help_url, expands=True, tipTexts=tipTexts) self.buttonList.grid(row=row, column=0, columnspan=2, sticky='ew') self.update() self.notify(self.registerNotify)
class SpectrumSelectionTab(object): '''Class describing the tab containing a big table with all the spectra. The user can select which spectra from the project to use with the assignment algorithm. For each spectrum a peak list and a labelling scheme can be selected. ''' def __init__(self, parent, frame): '''Init. args: parent: the guiElement that this tab is part of. frame: the frame this part of the GUI lives in. ''' self.guiParent = parent self.frame = frame self.project = parent.project self.nmrProject = parent.nmrProject self.specConfigList = [] self.displayTable = None self.selectedAutoSpec = None self.autoLabellingPulldown = None self.autoPeakListPulldown = None self.body() self.updateSpecSelection() # self.setupSpectrumSettings() self.updateAutoMatrix() def body(self): '''Sets up the body of this view.''' frame = self.frame frame.grid_rowconfigure(2, weight=1) frame.grid_columnconfigure(0, weight=1) headingList = [ '#', 'Spectrum', 'Peak List', 'use?', 'labelling scheme'] tipTexts = ['Row number', 'spectrum name', 'which peak list to use', 'use this spectrum?', 'Which labelling scheme belongs to this spectrum?'] self.autoLabellingPulldown = PulldownList( self.guiParent, self.setAutoLabellingScheme) self.autoPeakListPulldown = PulldownList( self.guiParent, self.setAutoPeakList) editWidgets = [None, None, self.autoPeakListPulldown, None, self.autoLabellingPulldown] editGetCallbacks = [None, None, self.getAutoPeakLists, self.changeUse, self.getAutoLabellingSchemes] editSetCallbacks = [None, None, None, None, None] self.displayTable = ScrolledMatrix(frame, headingList=headingList, callback=self.selectAutoSpec, editWidgets=editWidgets, multiSelect=False, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, tipTexts=tipTexts) self.displayTable.grid(row=2, column=0, sticky='nsew') def updateSpecSelection(self): '''Update the list with spectrum settings. This function can be called to initialize this list or to update it when some spectra are added in the project. ''' # TODO: also implement what has to happen # when spectra get deleted from the project. presentSpectrumSettings = set([specSetting.ccpnSpectrum for specSetting in self.specConfigList]) for expt in self.nmrProject.sortedExperiments(): for spec in expt.sortedDataSources(): if spec.dataType == 'processed' and spec not in presentSpectrumSettings: newSpectrumSetting = SpectrumSettings() newSpectrumSetting.ccpnSpectrum = spec newSpectrumSetting.peakList = spec.getActivePeakList() self.specConfigList.append(newSpectrumSetting) def getLabellingSchemes(self): '''Returns all labellinSchemes in the project''' return [True, None, ] + self.project.sortedLabelingSchemes() def setAutoLabellingScheme(self, scheme): '''Select a labelling scheme for the selected spectrum. ''' self.selectedAutoSpec.setupLabellingScheme(scheme) self.updateAutoMatrix() def getAutoLabellingSchemes(self, notifyScheme=None): '''Sets up the the pulldown lists with labelling schemes used for the pulldown lists. ''' #names = [] #index = 0 # #scheme = self.selectedAutoSpec.labellingScheme #schemes = self.getLabellingSchemes() # # # if schemes: # names = ['Automatic from sample','<None>'] + [sc.name for sc in schemes[2:]] # # index = schemes.index(scheme) names = ['Automatic from sample'] schemes = [True] index = 0 self.autoLabellingPulldown.setup(names, schemes, index) def setAutoPeakList(self, peakList): '''Select a peakList for the selected spectrum.''' self.selectedAutoSpec.setupPeakList(peakList) self.updateAutoMatrix() def selectAutoSpec(self, obj, *args, **kwargs): '''Set the selection of a spectrum in the table. args: obj: (SpectrumSettings) the spectrum that should be selected. ''' self.selectedAutoSpec = obj def getAutoPeakLists(self, *args, **kwargs): '''Set up the the autoPeakListPulldown for the selected spectrum. ''' names = [] index = 0 peakList = self.selectedAutoSpec.peakList peakLists = self.selectedAutoSpec.ccpnSpectrum.sortedPeakLists() if peakLists: names = [str(pl.serial) for pl in peakLists] index = peakLists.index(peakList) self.autoPeakListPulldown.setup(names, peakLists, index) def changeUse(self, *args): '''Toggle whether a spectrum is used in the procedure or not. ''' if self.selectedAutoSpec.used is False: self.selectedAutoSpec.changeSpectrumUse(True) elif self.selectedAutoSpec.used is True: self.selectedAutoSpec.changeSpectrumUse(False) self.updateAutoMatrix() def updateAutoMatrix(self): '''Update the whole table.''' textMatrix = [] colorMatrix = [] spectra = self.specConfigList for i, spectrum in enumerate(spectra): dataSource = spectrum.ccpnSpectrum expt = dataSource.experiment name = '%s:%s' % (expt.name, dataSource.name) peakListName = str(spectrum.peakList.serial) if spectrum.labellingScheme is None: schemeName = 'None' elif spectrum.labellingScheme is True: schemeName = 'Automatic from sample' else: schemeName = spectrum.labellingScheme.name datum = [i + 1, name, peakListName, spectrum.used and 'Yes' or 'No', schemeName] textMatrix.append(datum) hexColors = dataSource.analysisSpectrum.posColors hexColor = hexColors[int(0.7 * len(hexColors))] if spectrum.used: colorMatrix.append([hexColor, hexColor, hexColor, hexColor, hexColor]) else: colorMatrix.append([hexColor, None, None, None, None]) self.displayTable.update(textMatrix=textMatrix, objectList=spectra, colorMatrix=colorMatrix) def update(self, *args): '''update the view''' self.updateSpecSelection() self.updateAutoMatrix()
def __init__(self, parent, application, *args, **kw): project = application.project simStore = project.findFirstNmrSimStore(application=APP_NAME) or \ project.newNmrSimStore(application=APP_NAME, name=APP_NAME) self.application = application self.residue = None self.structure = None self.serverCredentials = None self.iCingBaseUrl = DEFAULT_URL self.resultsUrl = None self.chain = None self.nmrProject = application.nmrProject self.serverDone = False NmrSimRunFrame.__init__(self, parent, project, simStore, *args, **kw) # # # # # # New Structure Frame # # # # # self.structureFrame.grid_forget() tab = self.tabbedFrame.frames[0] frame = Frame(tab, grid=(1,0)) frame.expandGrid(2,1) div = LabelDivider(frame, text='Structures', grid=(0,0), gridSpan=(1,2)) label = Label(frame, text='Ensemble: ', grid=(1,0)) self.structurePulldown = PulldownList(frame, callback=self.changeStructure, grid=(1,1)) headingList = ['Model','Use'] editWidgets = [None,None] editGetCallbacks = [None,self.toggleModel] editSetCallbacks = [None,None,] self.modelTable = ScrolledMatrix(frame, grid=(2,0), gridSpan=(1,2), callback=self.selectStructModel, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, headingList=headingList) texts = ['Activate Selected','Inactivate Selected'] commands = [self.activateModels, self.disableModels] buttons = ButtonList(frame, texts=texts, commands=commands, grid=(3,0), gridSpan=(1,2)) # # # # # # Submission frame # # # # # # tab = self.tabbedFrame.frames[1] tab.expandGrid(1,0) frame = LabelFrame(tab, text='Server Job Submission', grid=(0,0)) frame.expandGrid(None,2) srow = 0 label = Label(frame, text='iCing URL:', grid=(srow, 0)) urls = [DEFAULT_URL,] self.iCingBaseUrlPulldown = PulldownList(frame, texts=urls, objects=urls, index=0, grid=(srow,1)) srow +=1 label = Label(frame, text='Results File:', grid=(srow, 0)) self.resultFileEntry = Entry(frame, bd=1, text='', grid=(srow,1), width=50) self.setZipFileName() button = Button(frame, text='Choose File', bd=1, sticky='ew', command=self.chooseZipFile, grid=(srow, 2)) srow +=1 label = Label(frame, text='Results URL:', grid=(srow, 0)) self.resultUrlEntry = Entry(frame, bd=1, text='', grid=(srow,1), width=50) button = Button(frame, text='View Results HTML', bd=1, sticky='ew', command=self.viewHtmlResults, grid=(srow, 2)) srow +=1 texts = ['Submit Project!', 'Check Run Status', 'Purge Server Result', 'Download Results'] commands = [self.runCingServer, self.checkStatus, self.purgeCingServer, self.downloadResults] self.buttonBar = ButtonList(frame, texts=texts, commands=commands, grid=(srow, 0), gridSpan=(1,3)) for button in self.buttonBar.buttons[:1]: button.config(bg=CING_BLUE) # # # # # # Residue frame # # # # # # frame = LabelFrame(tab, text='Residue Options', grid=(1,0)) frame.expandGrid(1,1) label = Label(frame, text='Chain: ') label.grid(row=0,column=0,sticky='w') self.chainPulldown = PulldownList(frame, callback=self.changeChain) self.chainPulldown.grid(row=0,column=1,sticky='w') headingList = ['#','Residue','Linking','Decriptor','Use?'] editWidgets = [None,None,None,None,None] editGetCallbacks = [None,None,None,None,self.toggleResidue] editSetCallbacks = [None,None,None,None,None,] self.residueMatrix = ScrolledMatrix(frame, headingList=headingList, multiSelect=True, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, callback=self.selectResidue) self.residueMatrix.grid(row=1, column=0, columnspan=2, sticky = 'nsew') texts = ['Activate Selected','Inactivate Selected'] commands = [self.activateResidues, self.deactivateResidues] self.resButtons = ButtonList(frame, texts=texts, commands=commands,) self.resButtons.grid(row=2, column=0, columnspan=2, sticky='ew') """ # # # # # # Validate frame # # # # # # frame = LabelFrame(tab, text='Validation Options', grid=(2,0)) frame.expandGrid(None,2) srow = 0 self.selectCheckAssign = CheckButton(frame) self.selectCheckAssign.grid(row=srow, column=0,sticky='nw' ) self.selectCheckAssign.set(True) label = Label(frame, text='Assignments and shifts') label.grid(row=srow,column=1,sticky='nw') srow += 1 self.selectCheckResraint = CheckButton(frame) self.selectCheckResraint.grid(row=srow, column=0,sticky='nw' ) self.selectCheckResraint.set(True) label = Label(frame, text='Restraints') label.grid(row=srow,column=1,sticky='nw') srow += 1 self.selectCheckQueen = CheckButton(frame) self.selectCheckQueen.grid(row=srow, column=0,sticky='nw' ) self.selectCheckQueen.set(False) label = Label(frame, text='QUEEN') label.grid(row=srow,column=1,sticky='nw') srow += 1 self.selectCheckScript = CheckButton(frame) self.selectCheckScript.grid(row=srow, column=0,sticky='nw' ) self.selectCheckScript.set(False) label = Label(frame, text='User Python script\n(overriding option)') label.grid(row=srow,column=1,sticky='nw') self.validScriptEntry = Entry(frame, bd=1, text='') self.validScriptEntry.grid(row=srow,column=2,sticky='ew') scriptButton = Button(frame, bd=1, command=self.chooseValidScript, text='Browse') scriptButton.grid(row=srow,column=3,sticky='ew') """ # # # # # # # # # # self.update(simStore) self.administerNotifiers(application.registerNotify)
class FileSelect(Frame): def __init__(self, parent, file_types=None, directory=None, single_callback=None, double_callback=None, select_dir_callback=None, change_dir_callback=None, should_change_dir_callback=None, prompt=None, show_file=True, file='', multiSelect=False, default_dir=None, getRowColor=None, getExtraCell=None, extraHeadings=None, extraJustifies=None, displayExtra=True, manualFileFilter=False, extraTipTexts=None, *args, **kw): if file_types is None: file_types = [FileType("All", ["*"])] if manualFileFilter: self.manualFilter = FileType("Manual") file_types.append(self.manualFilter) else: self.manualFilter = None if directory is None: directory = normalisePath(os.getcwd()) if extraHeadings is None: extraHeadings = () else: extraHeadings = tuple(extraHeadings) if extraJustifies is None: extraJustifies = () else: extraJustifies = tuple(extraJustifies) if extraHeadings or extraJustifies: assert len(extraHeadings) == len(extraJustifies) assert getExtraCell self.extraHeadings = extraHeadings self.extraJustifies = extraJustifies self.extraTipTexts = extraTipTexts or [] self.displayExtra = displayExtra Frame.__init__(self, parent, *args, **kw) self.file_types = file_types self.fileType = file_types[0] self.single_callback = single_callback self.double_callback = double_callback self.select_dir_callback = select_dir_callback self.change_dir_callback = change_dir_callback self.should_change_dir_callback = should_change_dir_callback self.show_file = show_file self.directory = None self.historyBack = [] self.historyFwd = [] self.determineDir(directory) self.default_dir = default_dir self.getRowColor = getRowColor self.getExtraCell = getExtraCell self.grid_columnconfigure(0, weight=1) row = 0 if prompt: label = Label(self, text=prompt, grid=(row, 0)) row += 1 self.grid_rowconfigure(row, weight=1) if show_file: headings = ('Name', 'Size', 'Date') justifies = ('left', 'right', 'right') tipTexts = [ 'Name of file, directory or link', 'Size of file in bytes', 'Date of last modification' ] else: headings = ('Directory', ) justifies = ('left', ) tipTexts = ['Name of directory'] self.normalHeadings = headings self.normalJustifies = justifies self.normalTipTexts = tipTexts headings = headings + extraHeadings justifies = justifies + extraJustifies tipTexts += [None] * len(extraHeadings) self.fileList = ScrolledMatrix(self, headingList=headings, justifyList=justifies, initialRows=10, callback=self.singleCallback, doubleCallback=self.doubleCallback, tipTexts=tipTexts, multiSelect=multiSelect, grid=(row, 0)) row += 1 tipTexts = [ 'Go to previous location in history', 'Go forward in location history', 'Go up one directory level', 'Go to root directory', 'Go to home directory', 'Make a new directory', 'Refresh directory listing' ] texts = ['Back', 'Forward', 'Up', 'Top', 'Home', 'New', 'Refresh'] commands = [ self.backDir, self.fwdDir, self.upDir, self.topDir, self.homeDir, self.createDir, self.updateFileList ] if self.default_dir: texts.append('Default') commands.append(self.setDefaultDir) tipTexts.append('Set the current directory as the default') self.icons = [] for name in ICON_NAMES: icon = Tkinter.PhotoImage( file=os.path.join(GFX_DIR, name + '.gif')) self.icons.append(icon) self.buttons = ButtonList(self, texts=texts, commands=commands, images=self.icons, grid=(row, 0), tipTexts=tipTexts) if show_file: row += 1 self.file_entry = LabeledEntry(self, label='File name', label_width=10, entry_width=40, returnCallback=self.setSelectedFile) self.file_entry.grid(row=row, column=0, sticky=Tkinter.EW) else: self.file_entry = None row += 1 self.directory_entry = LabeledEntry(self, label='Directory', entry=directory, label_width=10, entry_width=40, returnCallback=self.entryDir) self.directory_entry.grid(row=row, column=0, sticky=Tkinter.EW) row += 1 subFrame = Frame(self, grid=(row, 0)) subFrame.expandGrid(None, 6) if show_file: label = Label(subFrame, text='File type:', grid=(0, 0)) type_labels = self.determineTypeLabels() self.fileType_menu = PulldownList( subFrame, callback=self.typeCallback, texts=type_labels, objects=self.file_types, grid=(0, 1), tipText='Restrict listed files to selected suffix') label = Label(subFrame, text=' Show hidden:', grid=(0, 2)) self.hidden_checkbutton = CheckButton( subFrame, text='', selected=False, callback=self.updateFileList, grid=(0, 3), tipText='Show hidden files beginning with "." etc.') label = Label(subFrame, text='Dir path:', grid=(0, 4)) self.pathMenu = PulldownList( subFrame, callback=self.dirCallback, objects=range(len(self.dirs)), texts=self.dirs, index=len(self.dirs) - 1, indent=' ', prefix=dirsep, grid=(0, 5), tipText='Directory navigation to current location') if show_file and self.manualFilter is not None: row += 1 self.manual_filter_entry = LabeledEntry( self, label='Manual Select', entry=defaultFilter, label_width=13, entry_width=40, returnCallback=self.entryFilter, tipText= 'Path specification with wildcards to select multiple files') self.manual_filter_entry.grid(row=row, column=0, sticky=Tkinter.EW) self.updateFileList() self.updateButtons() if file: self.setFile(file) def updateDisplayExtra(self, displayExtra): self.displayExtra = displayExtra self.updateFileList() def isRootDirectory(self, directory=''): if not directory: directory = self.directory if directory: return os.path.dirname(directory) == directory return True # arbitrary def updateButtons(self): buttons = self.buttons.buttons isRoot = self.isRootDirectory if self.historyBack: buttons[0].enable() else: buttons[0].disable() if self.historyFwd: buttons[1].enable() else: buttons[1].disable() if self.directory and not isRoot(self.directory): buttons[2].enable() buttons[3].enable() else: buttons[2].disable() buttons[3].disable() homeDir = self.getHomeDir() if homeDir and os.path.isdir(homeDir): buttons[4].enable() else: buttons[4].disable() def backDir(self): if self.historyBack: self.historyFwd.insert(0, self.directory) dirName = self.historyBack.pop() self.changeDir(dirName, addHistory=False) def fwdDir(self): if self.historyFwd: self.historyBack.append(self.directory) dirName = self.historyFwd.pop(0) self.changeDir(dirName, addHistory=False) def topDir(self): if self.directory: isRoot = self.isRootDirectory dirName = self.directory while not isRoot(dirName): dirName = joinPath(dirName, os.pardir) self.changeDir(dirName) def homeDir(self): homeDir = self.getHomeDir() if homeDir: self.changeDir(homeDir) def getHomeDir(self): return os.environ.get('HOME') or os.environ.get('HOMEPATH') def upDir(self): self.changeDir(joinPath(self.directory, os.pardir)) def setDefaultDir(self): self.changeDir(self.default_dir) def createDir(self): from memops.gui.DataEntry import askString msg = 'Enter new sub-directory name' dirName = askString('New directory', msg, parent=self) if dirName: dirName = joinPath(self.directory, dirName) if os.path.exists(dirName): msg = 'Directory "%s" already exists' % dirName showError('Directory exists', msg, parent=self) else: os.mkdir(dirName) self.updateFileList() def determineTypeLabels(self): type_labels = [] for t in self.file_types: s = t.message + ' (' + ', '.join(t.filters) + ')' type_labels.append(s) return type_labels def setFileTypes(self, file_types): self.file_types = file_types if self.fileType not in file_types: self.fileType = file_types[0] if self.show_file: ind = self.file_types.index(self.fileType) type_labels = self.determineTypeLabels() self.fileType_menu.setup(type_labels, self.file_types, ind) self.updateFileList() def determineDir(self, directory): directory = normalisePath(directory) assert os.path.isdir(directory), '"%s" is not a directory' % directory self.prev_directory = self.directory if not os.path.isabs(directory): if self.directory is None: # first time around directory = joinPath(normalisePath(os.getcwd()), directory) else: directory = joinPath(self.directory, directory) self.directory = directory self.dirs = self.directory.split(dirsep) def setSelectedFile(self, *event): file = self.file_entry.getEntry() try: self.fileList.selectObject(file) except: showError('Some err', 'some err') def entryDir(self, *event): dirName = self.directory_entry.getEntry() try: self.changeDir(dirName) except: showError('Not a directory', '"' + dirName + '" is not a directory.') def entryFilter(self, *event): filterString = self.manual_filter_entry.getEntry() filters = [str.strip(x) for x in filterString.split(',')] self.manualFilter.filters = filters self.fileType = self.manualFilter self.setFileTypes( self.file_types) # to trigger update after filter change self.updateFileList() self.manual_filter_entry.setEntry(filterString) def changeDir(self, dirName, addHistory=True): if not os.path.isdir(dirName): return if self.should_change_dir_callback: if not self.should_change_dir_callback(dirName): return oldDir = self.directory self.determineDir(dirName) self.updateFileList() self.directory_entry.setEntry(self.directory) if self.change_dir_callback: self.change_dir_callback(self.directory) nDirs = len(self.dirs) self.pathMenu.setup(self.dirs, range(nDirs), index=nDirs - 1) if addHistory: if oldDir and (self.directory != oldDir): self.historyBack.append(oldDir) self.historyFwd = [] self.updateButtons() def getEntryInfo(self, entry): file = joinPath(self.directory, entry) if os.path.islink(file): # plain arrow: u' \u2192 ' entry = entry + u' \u21D2 ' + unicode(os.readlink(file), 'utf-8') size = None color = '#E0D0C0' elif os.path.isdir(file): if not self.isRootDirectory(entry): entry = entry + dirsep size = None color = '#C0D0C0' else: color = '#C0C0D0' if self.show_file: try: size = str(os.path.getsize(file)) except: size = None else: size = None try: fileTime = self.fileTime(file) except: fileTime = '' return (entry, size, fileTime, color) def getDrives(self): if isWindowsOS(): #import win32api #drives = win32api.GetLogicalDriveStrings() #drives = drives.split('\x00') #drives = [normalisePath(drive) for drive in drives if drive] #drives.sort() # 19 Mar 2012: do not use win32api because not standard from ctypes import windll import string drives = [] bitmask = windll.kernel32.GetLogicalDrives() for letter in string.ascii_uppercase: if bitmask & 1: drives.append(letter) bitmask >>= 1 drives = [drive + ':\\' for drive in drives] drives = [normalisePath(drive) for drive in drives] else: drives = [] return drives def updateFileList(self, *extra): try: if self.directory: directory = self.directory else: directory = dirsep entries = self.getFilterFiles(directory) except OSError, e: showError('OS Error', str(e)) if self.prev_directory: self.directory = None self.changeDir(self.prev_directory) return if self.directory: if self.isRootDirectory(): entries[:0] = [ drive for drive in self.getDrives() if drive not in self.directory ] else: entries[:0] = [os.pardir ] # add parent directory at front of list # DJOD: Not elegant, but robust !?! showHidden = self.hidden_checkbutton.getSelected() show_ent = [] for entry in entries: if not showHidden: if not entry.startswith('.'): show_ent.append(entry) else: show_ent.append(entry) # if not show_ent.__contains__('.'): # show_ent.append('.') if not show_ent.__contains__('..'): show_ent.insert(0, '..') entries = show_ent textMatrix = [] colorMatrix = [] for entryActual in entries: (entry, size, fileTime, color) = self.getEntryInfo(entryActual) fullEntry = joinPath(directory, entryActual) if self.getRowColor: color = self.getRowColor(fullEntry) if self.displayExtra and self.getExtraCell: data = self.getExtraCell(fullEntry) headingList = self.normalHeadings + self.extraHeadings justifyList = self.normalJustifies + self.extraJustifies tipTexts = self.normalTipTexts + self.extraTipTexts else: data = () headingList = self.normalHeadings justifyList = self.normalJustifies tipTexts = self.normalTipTexts # in case we had sorted on a now removed line : self.fileList.lastSortLine = None if self.show_file: text = [entry, size, fileTime] else: text = [ entry, ] text = text + list(data) textMatrix.append(text) numCols = len(headingList) colorMatrix.append(numCols * [color]) self.fileList.update(objectList=entries, textMatrix=textMatrix, colorMatrix=colorMatrix, headingList=headingList, justifyList=justifyList, tipTexts=tipTexts)
class PopupTemplate(BasePopup): def __init__(self, parent, project=None, *args, **kw): self.project = project self.parent = parent self.objects = self.getObjects() self.object = None BasePopup.__init__(self, parent=parent, title='Popup Template', **kw) self.updateObjects() def body(self, mainFrame): mainFrame.grid_columnconfigure(1, weight=1, minsize=100) mainFrame.config(borderwidth=5, relief='solid') row = 0 label = Label(mainFrame, text="Frame (with sub-widgets):") label.grid(row=row, column=0, sticky=Tkinter.E) frame = Frame(mainFrame, relief='raised', border=2, background='#8080D0') # Frame expands East-West frame.grid(row=row, column=1, sticky=Tkinter.EW) # Last column expands => Widgets pusted to the West frame.grid_columnconfigure(3, weight=1) # Label is within the sub frame label = Label(frame, text='label ') label.grid(row=0, column=0, sticky=Tkinter.W) entry = Entry(frame, text='Entry', returnCallback=self.showWarning) entry.grid(row=0, column=1, sticky=Tkinter.W) self.check = CheckButton(frame, text='Checkbutton', selected=True, callback=self.updateObjects) self.check.grid(row=0, column=2, sticky=Tkinter.W) # stick a button to the East wall button = Button(frame, text='Button', command=self.pressButton) button.grid(row=0, column=3, sticky=Tkinter.E) row += 1 label = Label(mainFrame, text="Text:") label.grid(row=row, column=0, sticky=Tkinter.E) self.textWindow = Text(mainFrame, text='Initial Text\n', width=60, height=5) self.textWindow.grid(row=row, column=1, sticky=Tkinter.NSEW) row += 1 label = Label(mainFrame, text="CheckButtons:") label.grid(row=row, column=0, sticky=Tkinter.E) entries = ['Alpha','Beta','Gamma','Delta'] selected = entries[2:] self.checkButtons = CheckButtons(mainFrame, entries, selected=selected,select_callback=self.changedCheckButtons) self.checkButtons.grid(row=row, column=1, sticky=Tkinter.W) row += 1 label = Label(mainFrame, text="PartitionedSelector:") label.grid(row=row, column=0, sticky=Tkinter.E) labels = ['Bool','Int','Float','String'] objects = [type(0),type(1),type(1.0),type('a')] selected = [type('a')] self.partitionedSelector= PartitionedSelector(mainFrame, labels=labels, objects=objects, colors = ['red','yellow','green','#000080'], callback=self.toggleSelector,selected=selected) self.partitionedSelector.grid(row=row, column=1, sticky=Tkinter.EW) row += 1 label = Label(mainFrame, text="PulldownMenu") label.grid(row=row, column=0, sticky=Tkinter.E) entries = ['Frodo','Pipin','Merry','Sam','Bill','Gandalf','Strider','Gimli','Legolas'] self.pulldownMenu = PulldownMenu(mainFrame, callback=self.selectPulldown, entries=entries, selected_index=2, do_initial_callback=False) self.pulldownMenu.grid(row=row, column=1, sticky=Tkinter.W) row += 1 label = Label(mainFrame, text="RadioButtons in a\nScrolledFrame.frame:") label.grid(row=row, column=0, sticky=Tkinter.EW) frame = ScrolledFrame(mainFrame, yscroll = False, doExtraConfig = True, width=100) frame.grid(row=row, column=1, sticky=Tkinter.EW) frame.grid_columnconfigure(0, weight=1) self.radioButtons = RadioButtons(frame.frame, entries=entries, select_callback=self.checkRadioButtons, selected_index=1, relief='groove') self.radioButtons.grid(row=0, column=0, sticky=Tkinter.W) row += 1 label = Label(mainFrame, text="LabelFrame with\nToggleLabels inside:") label.grid(row=row, column=0, sticky=Tkinter.E) labelFrame = LabelFrame(mainFrame, text='Frame Title') labelFrame.grid(row=row, column=1, sticky=Tkinter.NSEW) labelFrame.grid_rowconfigure(0, weight=1) labelFrame.grid_columnconfigure(3, weight=1) self.toggleLabel1 = ToggleLabel(labelFrame, text='ScrolledMatrix', callback=self.toggleFrame1) self.toggleLabel1.grid(row=0, column=0, sticky=Tkinter.W) self.toggleLabel1.arrowOn() self.toggleLabel2 = ToggleLabel(labelFrame, text='ScrolledGraph', callback=self.toggleFrame2) self.toggleLabel2.grid(row=0, column=1, sticky=Tkinter.W) self.toggleLabel3 = ToggleLabel(labelFrame, text='ScrolledCanvas', callback=self.toggleFrame3) self.toggleLabel3.grid(row=0, column=2, sticky=Tkinter.W) row += 1 mainFrame.grid_rowconfigure(row, weight=1) label = Label(mainFrame, text="changing/shrinking frames:") label.grid(row=row, column=0, sticky=Tkinter.E) self.toggleRow = row self.toggleFrame = Frame(mainFrame) self.toggleFrame.grid(row=row, column=1, sticky=Tkinter.NSEW) self.toggleFrame.grid_rowconfigure(0, weight=1) self.toggleFrame.grid_columnconfigure(0, weight=1) # option 1 self.intEntry = IntEntry(self, returnCallback = self.setNumber, width=8) self.multiWidget = MultiWidget(self, Entry, options=None, values=None, callback=self.setKeywords, minRows=3, maxRows=5) editWidgets = [None, None, self.intEntry, self.multiWidget] editGetCallbacks = [None, None, self.getNumber, self.getKeywords] editSetCallbacks = [None, None, self.setNumber, self.setKeywords] headingList = ['Name','Color','Number','Keywords'] self.scrolledMatrix = ScrolledMatrix(self.toggleFrame, headingList=headingList, editSetCallbacks=editSetCallbacks, editGetCallbacks=editGetCallbacks, editWidgets=editWidgets, callback=self.selectObject, multiSelect=False) self.scrolledMatrix.grid(row=0, column=0, sticky=Tkinter.NSEW) # option 2 self.scrolledGraph = ScrolledGraph(self.toggleFrame, width=400, height=300, symbolSize=5, symbols=['square','circle'], dataColors=['#000080','#800000'], lineWidths=[0,1] ) self.scrolledGraph.setZoom(1.3) dataSet1 = [[0,0],[1,1],[2,4],[3,9],[4,16],[5,25]] dataSet2 = [[0,0],[1,3],[2,6],[3,9],[4,12],[5,15]] self.scrolledGraph.update(dataSets=[dataSet1,dataSet2], xLabel = 'X axis label', yLabel = 'Y axis label', title = 'Main Title') self.scrolledGraph.draw() # option 3 self.scrolledCanvas = ScrolledCanvas(self.toggleFrame,relief = 'groove', borderwidth = 2, resizeCallback=None) canvas = self.scrolledCanvas.canvas font = 'Helvetica 10' box = canvas.create_rectangle(10,10,150,200, outline='grey', fill='grey90') line = canvas.create_line(0,0,200,200,fill='#800000', width=2) text = canvas.create_text(120,50, text='Text', font=font, fill='black') circle = canvas.create_oval(30,30,50,50,outline='#008000',fill='#404040',width=3) row += 1 label = Label(mainFrame, text="FloatEntry:") label.grid(row=row, column=0, sticky=Tkinter.E) self.floatEntry = FloatEntry(mainFrame, text=3.14159265, returnCallback=self.floatEntryReturn) self.floatEntry.grid(row=row, column=1, sticky=Tkinter.W) row += 1 label = Label(mainFrame, text="Scale:") label.grid(row=row, column=0, sticky=Tkinter.E) self.scale = Scale(mainFrame, from_=10, to=90, value=50, orient=Tkinter.HORIZONTAL) self.scale.grid(row=row, column=1, sticky=Tkinter.W) row += 1 label = Label(mainFrame, text="Value Ramp:") label.grid(row=row, column=0, sticky=Tkinter.E) self.valueRamp = ValueRamp(mainFrame, self.valueRampCallback, speed = 1.5, delay = 50) self.valueRamp.grid(row=row, column=1, sticky=Tkinter.W) row += 1 label = Label(mainFrame, text="ButtonList:") label.grid(row=row, column=0, sticky=Tkinter.E) texts = ['Select File','Close','Quit'] commands = [self.selectFile, self.close, self.quit] bottomButtons = ButtonList(mainFrame, texts=texts, commands=commands, expands=True) bottomButtons.grid(row=row, column=1, sticky=Tkinter.EW) self.protocol('WM_DELETE_WINDOW', self.quit) def floatEntryReturn(self, event): value = self.floatEntry.get() self.textWindow.setText('%s\n' % value) def selectObject(self, object, row, col): self.object = object def getKeywords(self, object): if object : values = object.keywords self.multiWidget.set(values) def setKeywords(self, event): values = self.multiWidget.get() self.object.keywords = values self.updateObjects() def getNumber(self, object): if object : self.intEntry.set(object.quantity) def setNumber(self, event): value = self.intEntry.get() self.object.quantity = value self.updateObjects() def toggleFrame1(self, isHidden): if isHidden: self.scrolledMatrix.grid_forget() self.toggleFrame.grid_forget() else: self.scrolledGraph.grid_forget() self.scrolledCanvas.grid_forget() self.scrolledMatrix.grid(row=0, column=0, sticky=Tkinter.NSEW) self.toggleFrame.grid(row=self.toggleRow, column=1,sticky=Tkinter.NSEW) self.toggleLabel2.arrowOff() self.toggleLabel3.arrowOff() def toggleFrame2(self, isHidden): if isHidden: self.scrolledGraph.grid_forget() self.toggleFrame.grid_forget() else: self.scrolledMatrix.grid_forget() self.scrolledCanvas.grid_forget() self.scrolledGraph.grid(row=0, column=0, sticky=Tkinter.NSEW) self.toggleFrame.grid(row=self.toggleRow, column=1,sticky=Tkinter.NSEW) self.toggleLabel1.arrowOff() self.toggleLabel3.arrowOff() def toggleFrame3(self, isHidden): if isHidden: self.scrolledCanvas.grid_forget() self.toggleFrame.grid_forget() else: self.scrolledMatrix.grid_forget() self.scrolledGraph.grid_forget() self.scrolledCanvas.grid(row=0, column=0, sticky=Tkinter.NSEW) self.toggleFrame.grid(row=self.toggleRow, column=1,sticky=Tkinter.NSEW) self.toggleLabel1.arrowOff() self.toggleLabel2.arrowOff() def valueRampCallback(self, value): self.textWindow.setText('%s\n' % value) def checkRadioButtons(self, value): self.textWindow.setText('%s\n' % value) def selectPulldown(self, index, name): self.textWindow.setText('%d, %s\n' % (index, name)) def toggleSelector(self, value): self.textWindow.setText('%s\n' % value) def changedCheckButtons(self, values): self.textWindow.setText(','.join(values) + '\n') def getObjects(self): objects = [] objects.append( Fruit('Lemon', '#FFFF00',1,keywords=['Bitter','Tangy'] ) ) objects.append( Fruit('Orange', '#FF8000',4 ) ) objects.append( Fruit('Banana', '#FFF000',5 ) ) objects.append( Fruit('Pinapple','#FFD000',9 ) ) objects.append( Fruit('Kiwi', '#008000',12) ) objects.append( Fruit('Lime', '#00FF00',2 ) ) objects.append( Fruit('Apple', '#800000',5,keywords=['Crunchy'] ) ) objects.append( Fruit('Pear', '#408000',6 ) ) objects.append( Fruit('Peach', '#FFE0C0',2,keywords=['Sweet','Furry'] ) ) objects.append( Fruit('Plumb', '#800080',7 ) ) return objects def updateObjects(self, event=None): textMatrix = [] objectList = [] colorMatrix = [] for object in self.objects: datum = [] datum.append( object.name ) datum.append( None ) datum.append( object.quantity ) datum.append( ','.join(object.keywords) ) colors = [None, object.color, None, None] textMatrix.append(datum) objectList.append(object) colorMatrix.append(colors) if self.check.get(): self.scrolledMatrix.update(textMatrix=textMatrix, objectList=objectList) else: self.scrolledMatrix.update(textMatrix=textMatrix, objectList=objectList, colorMatrix=colorMatrix) def selectFile(self): fileSelectPopup = FileSelectPopup(self, title = 'Choose file', dismiss_text = 'Cancel', selected_file_must_exist = True) fileName = fileSelectPopup.getFile() self.textWindow.setText('File Selected: %s\n' % fileName) def showWarning(self, eventObject): self.textWindow.setText('Text Entry Return Pressed\n') showWarning('Warning Title','Warning Message') return def pressButton(self): self.textWindow.setText('Button Pressed\n') if showYesNo('Title','Prompt: Clear text window?'): self.textWindow.clear() return def quit(self): BasePopup.destroy(self)
def __init__(self, parent, file_types=None, directory=None, single_callback=None, double_callback=None, select_dir_callback=None, change_dir_callback=None, should_change_dir_callback=None, prompt=None, show_file=True, file='', multiSelect=False, default_dir=None, getRowColor=None, getExtraCell=None, extraHeadings=None, extraJustifies=None, displayExtra=True, manualFileFilter=False, extraTipTexts=None, *args, **kw): if file_types is None: file_types = [FileType("All", ["*"])] if manualFileFilter: self.manualFilter = FileType("Manual") file_types.append(self.manualFilter) else: self.manualFilter = None if directory is None: directory = normalisePath(os.getcwd()) if extraHeadings is None: extraHeadings = () else: extraHeadings = tuple(extraHeadings) if extraJustifies is None: extraJustifies = () else: extraJustifies = tuple(extraJustifies) if extraHeadings or extraJustifies: assert len(extraHeadings) == len(extraJustifies) assert getExtraCell self.extraHeadings = extraHeadings self.extraJustifies = extraJustifies self.extraTipTexts = extraTipTexts or [] self.displayExtra = displayExtra Frame.__init__(self, parent, *args, **kw) self.file_types = file_types self.fileType = file_types[0] self.single_callback = single_callback self.double_callback = double_callback self.select_dir_callback = select_dir_callback self.change_dir_callback = change_dir_callback self.should_change_dir_callback = should_change_dir_callback self.show_file = show_file self.directory = None self.historyBack = [] self.historyFwd = [] self.determineDir(directory) self.default_dir = default_dir self.getRowColor = getRowColor self.getExtraCell = getExtraCell self.grid_columnconfigure(0, weight=1) row = 0 if prompt: label = Label(self, text=prompt, grid=(row, 0)) row += 1 self.grid_rowconfigure(row, weight=1) if show_file: headings = ('Name', 'Size', 'Date') justifies = ('left', 'right', 'right') tipTexts = [ 'Name of file, directory or link', 'Size of file in bytes', 'Date of last modification' ] else: headings = ('Directory', ) justifies = ('left', ) tipTexts = ['Name of directory'] self.normalHeadings = headings self.normalJustifies = justifies self.normalTipTexts = tipTexts headings = headings + extraHeadings justifies = justifies + extraJustifies tipTexts += [None] * len(extraHeadings) self.fileList = ScrolledMatrix(self, headingList=headings, justifyList=justifies, initialRows=10, callback=self.singleCallback, doubleCallback=self.doubleCallback, tipTexts=tipTexts, multiSelect=multiSelect, grid=(row, 0)) row += 1 tipTexts = [ 'Go to previous location in history', 'Go forward in location history', 'Go up one directory level', 'Go to root directory', 'Go to home directory', 'Make a new directory', 'Refresh directory listing' ] texts = ['Back', 'Forward', 'Up', 'Top', 'Home', 'New', 'Refresh'] commands = [ self.backDir, self.fwdDir, self.upDir, self.topDir, self.homeDir, self.createDir, self.updateFileList ] if self.default_dir: texts.append('Default') commands.append(self.setDefaultDir) tipTexts.append('Set the current directory as the default') self.icons = [] for name in ICON_NAMES: icon = Tkinter.PhotoImage( file=os.path.join(GFX_DIR, name + '.gif')) self.icons.append(icon) self.buttons = ButtonList(self, texts=texts, commands=commands, images=self.icons, grid=(row, 0), tipTexts=tipTexts) if show_file: row += 1 self.file_entry = LabeledEntry(self, label='File name', label_width=10, entry_width=40, returnCallback=self.setSelectedFile) self.file_entry.grid(row=row, column=0, sticky=Tkinter.EW) else: self.file_entry = None row += 1 self.directory_entry = LabeledEntry(self, label='Directory', entry=directory, label_width=10, entry_width=40, returnCallback=self.entryDir) self.directory_entry.grid(row=row, column=0, sticky=Tkinter.EW) row += 1 subFrame = Frame(self, grid=(row, 0)) subFrame.expandGrid(None, 6) if show_file: label = Label(subFrame, text='File type:', grid=(0, 0)) type_labels = self.determineTypeLabels() self.fileType_menu = PulldownList( subFrame, callback=self.typeCallback, texts=type_labels, objects=self.file_types, grid=(0, 1), tipText='Restrict listed files to selected suffix') label = Label(subFrame, text=' Show hidden:', grid=(0, 2)) self.hidden_checkbutton = CheckButton( subFrame, text='', selected=False, callback=self.updateFileList, grid=(0, 3), tipText='Show hidden files beginning with "." etc.') label = Label(subFrame, text='Dir path:', grid=(0, 4)) self.pathMenu = PulldownList( subFrame, callback=self.dirCallback, objects=range(len(self.dirs)), texts=self.dirs, index=len(self.dirs) - 1, indent=' ', prefix=dirsep, grid=(0, 5), tipText='Directory navigation to current location') if show_file and self.manualFilter is not None: row += 1 self.manual_filter_entry = LabeledEntry( self, label='Manual Select', entry=defaultFilter, label_width=13, entry_width=40, returnCallback=self.entryFilter, tipText= 'Path specification with wildcards to select multiple files') self.manual_filter_entry.grid(row=row, column=0, sticky=Tkinter.EW) self.updateFileList() self.updateButtons() if file: self.setFile(file)
class SpinSystemComparePopup(BasePopup): '''The popop for comparing spin systems to one another.''' def __init__(self, parent, *args, **kw): '''Init. Args: parent: guiParent. ''' self.guiParent = parent self.spinSystem1 = None self.spinSystem2 = None self.correction = True self.protonatedShiftList = None self.deuteratedShiftList = None BasePopup.__init__(self, parent, title="Compare Spin Systems", **kw) self.waiting = False def open(self): self.updateAfter() BasePopup.open(self) def body(self, guiFrame): '''This method describes the outline of the body of the application. args: guiFrame: frame the body should live in. ''' self.geometry('800x530') guiFrame.grid_columnconfigure(0, weight=1) guiFrame.grid_rowconfigure(0, weight=0) guiFrame.grid_rowconfigure(1, weight=2) guiFrame.grid_rowconfigure(2, weight=1) isotopeFrame = LabelFrame(guiFrame, text='Isotope Shift Correction CA and CB') isotopeFrame.grid(row=0, column=0, sticky='nsew') frameA = LabelFrame(guiFrame, text='Spin Systems') frameA.grid(row=1, column=0, sticky='nsew') frameA.grid_rowconfigure(0, weight=1) frameA.grid_columnconfigure(0, weight=1) frameA.grid_columnconfigure(1, weight=1) frameA1 = LabelFrame(frameA, text='Spin System 1') frameA1.grid(row=0, column=0, sticky='nsew') frameA1.grid_columnconfigure(0, weight=1) frameA1.grid_rowconfigure(0, weight=1) frameA2 = LabelFrame(frameA, text='Spin System 2') frameA2.grid(row=0, column=1, sticky='nsew') frameA2.grid_columnconfigure(0, weight=1) frameA2.grid_rowconfigure(0, weight=1) frameB = LabelFrame(guiFrame, text='Comparison') frameB.grid(row=2, column=0, sticky='nsew') frameB.grid_rowconfigure(0, weight=1) frameB.grid_columnconfigure(0, weight=1) frameB.grid_columnconfigure(1, weight=2) frameB.grid_columnconfigure(2, weight=1) frameB1 = LabelFrame(frameB, text='Unique to Spin System 1') frameB1.grid(row=0, column=0, sticky='nsew') frameB1.expandGrid(0, 0) frameB2 = LabelFrame(frameB, text='Intersection') frameB2.grid(row=0, column=1, sticky='nsew') frameB2.expandGrid(0, 0) frameB3 = LabelFrame(frameB, text='Unique to Spin System 2') frameB3.grid(row=0, column=2, sticky='nsew') frameB3.expandGrid(0, 0) # Settings for isotope shift correction shiftLists = getShiftLists(self.nmrProject) self.protonatedShiftList = shiftLists[0] self.deuteratedShiftList = shiftLists[1] shiftListNames = ['{}: {}'.format(shiftList.serial, shiftList.name) for shiftList in shiftLists] Label(isotopeFrame, text='Correct for isotope shift:', grid=(0, 0)) self.correctCheck = CheckButton(isotopeFrame, selected=True, callback=self.setCorrection, grid=(0, 1)) Label(isotopeFrame, text='Protonated shift list:', grid=(1, 0)) self.protonatedPulldown = PulldownList(isotopeFrame, callback=self.setProtonatedShiftList, texts=shiftListNames, objects=shiftLists, grid=(1, 1), index=0) Label(isotopeFrame, text='Deuterated shift list:', grid=(2, 0)) self.deuteratedPulldown = PulldownList(isotopeFrame, callback=self.setDeuteratedShiftList, texts=shiftListNames, objects=shiftLists, grid=(2, 1), index=1) # Table A1 headingList = ['#', 'shift lists', 'Assignment'] tipTexts = ['Spin System Serial', 'shift lists', 'The residue (tentatively) assigned to this spin system', 'The amount of spin systems that overlap with this spin system and have no violations'] editGetCallbacks = [self.setSpinSystem1]*3 editSetCallbacks = [None]*3 self.tableA1 = ScrolledMatrix(frameA1, headingList=headingList, multiSelect=False, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, tipTexts=tipTexts) self.tableA1.grid(row=0, column=0, sticky='nsew') # Table A2 headingList = ['#', 'shift lists', 'Assignment', 'offset'] tipTexts = ['Spin System Serial', 'The residue (tentatively) assigned to this spin system', 'Root mean squared deviation of this spin system to the spin system selected in the table on the left.'] editGetCallbacks = [self.setSpinSystem2]*4 editSetCallbacks = [None]*4 self.tableA2 = ScrolledMatrix(frameA2, headingList=headingList, #editWidgets=editWidgets, multiSelect=False, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, tipTexts=tipTexts) self.tableA2.grid(row=0, column=0, sticky='nsew') # Table B1 headingList = ['atom', 'c.s.'] tipTexts = ['atom', 'chemical shift'] self.tableB1 = ScrolledMatrix(frameB1, headingList=headingList, multiSelect=False, tipTexts=tipTexts) self.tableB1.grid(row=0, column=0, sticky='nsew') # Table B 2 headingList = ['atom', 'c.s. 1', 'c.s. 2', 'delta c.s.'] tipTexts = ['name of the atom', 'chemical shift of atom with this name in spin system 1', 'chemical shift of atom with this name in spin system 2', 'difference between the chemical shift of spin systems 1 and 2'] self.tableB2 = ScrolledMatrix(frameB2, headingList=headingList, tipTexts=tipTexts) self.tableB2.grid(row=0, column=0, sticky='nsew') # Table B 3 headingList = ['atom', 'c.s.'] tipTexts = ['atom', 'chemical shift.'] self.tableB3 = ScrolledMatrix(frameB3, headingList=headingList, multiSelect=False, tipTexts=tipTexts) self.tableB3.grid(row=0, column=0, sticky='nsew') self.matchMatrix = {} self.amountOfMatchesPerSpinSystem = {} self.updateTableA1() def update(self): '''Updates all tables except for tableA1. ''' self.updateTableA2() self.updateCompareTables() def setCorrection(self, selected): '''Toggles on/off whether the isotope correction should be applied or not. args: selected: Boolean, is True if isotope correction is to be applied. ''' if self.correction is not selected: self.correction = selected self.update() def setProtonatedShiftList(self, shiftList): '''Set the shift list where protonated values of the chemical shifts should be fetched. args: shiftList: shift list with protonated shifts. ''' if not self.protonatedShiftList is shiftList: self.protonatedShiftList = shiftList self.update() def setDeuteratedShiftList(self, shiftList): '''Set the shift list where deuterated values of the chemical shifts should be fetched. args: shiftList: shift list with deuterated shifts. ''' if not self.deuteratedShiftList is shiftList: self.deuteratedShiftList = shiftList self.update() def setSpinSystem1(self, spinSystem): '''Set the first of two spin systems that should be compared. args: spinSystem: first of two spin systems ''' if spinSystem is not self.spinSystem1: self.spinSystem1 = spinSystem self.updateTableA2() def setSpinSystem2(self, spinSystem): '''Set the second of two spin systems that should be compared. args: spinSystem: second of two spin systems ''' if spinSystem is not self.spinSystem2: self.spinSystem2 = spinSystem self.updateCompareTables() def updateTableA1(self): '''Update tableA1 where the first spin systems is picked from. ''' data = [] objectList = [] spinSystems = self.nmrProject.resonanceGroups for spinSystem in spinSystems: objectList.append(spinSystem) shiftLists_string = make_shiftLists_string(find_all_shiftLists_for_resonanceGroup(spinSystem)) data.append([spinSystem.serial, shiftLists_string, make_resonanceGroup_string(spinSystem)]) self.tableA1.update(objectList=objectList, textMatrix=data) self.tableA1.sortLine(2) def updateTableA2(self): '''Update tableA2 where the second spin systems is picked from. ''' if not self.spinSystem1: return comparisons = self.compareToSpinSystem(self.spinSystem1) data = [] objectList = [] colorMatrix = [] for comp in comparisons: resonanceGroup = comp.spinSystem2 objectList.append(resonanceGroup) oneRow = [] oneRow.append(resonanceGroup.serial) shiftLists_string = make_shiftLists_string(find_all_shiftLists_for_resonanceGroup(resonanceGroup)) oneRow.append(shiftLists_string) oneRow.append(make_resonanceGroup_string(resonanceGroup)) if comp.deviation is None: oneRow.append('-') else: oneRow.append(comp.deviation) if comp.match: colorMatrix.append(['#298A08']*4) else: colorMatrix.append([None]*4) data.append(oneRow) data, objectList, colorMatrix = zip(*sorted(zip(data, objectList, colorMatrix), key=lambda x: x[0][3])) self.tableA2.update(objectList=objectList, textMatrix=data, colorMatrix=colorMatrix) def updateCompareTables(self): '''Update all tables that compare 2 spin systems. These are the diff tables that show resonances unique to either one of the spin systems and the union table, where resonance types that are present in both spin systems are compared by chemical shift. ''' if not self.spinSystem1 or not self.spinSystem2: return spinSystemComp = self.compare2spinSystems(self.spinSystem1, self.spinSystem2) self.updateUnionTable(spinSystemComp) self.updateDiffTables(spinSystemComp) def updateDiffTables(self, spinSystemComp): '''Update the two tables that show the resonance types that are unique to respectively either the first or the second spin system. args: spinSystemComp: SpinSystemComparison comparing the two selected spin systems. ''' for shiftedShifts, table in [(spinSystemComp.unique_to_1, self.tableB1), (spinSystemComp.unique_to_2, self.tableB3)]: data = [] for shiftedShift in shiftedShifts: data.append([shiftedShift.create_name(), shiftedShift.create_shift_description()]) table.update(objectList=data, textMatrix=data) def updateUnionTable(self, spinSystemComp): '''Update the table that shows the resonance types that are present in both spin systems. args: spinSystemComp: SpinSystemComparison comparing the two selected spin systems. ''' intersectData = [] colorMatrix = [] for resComp in spinSystemComp.intersection: oneRow = [resComp.resonance_name] oneRow.extend(resComp.shifts_description) oneRow.append(resComp.delta) intersectData.append(oneRow) if resComp.match: colorMatrix.append(['#298A08']*4) else: colorMatrix.append([None]*4) self.tableB2.update(objectList=intersectData, textMatrix=intersectData, colorMatrix=colorMatrix) def compareToSpinSystem(self, spinSystem): '''Compare one spin system to all others. args: spinSystem: spin system returns: list of SpinSystemComparison objects. ''' spinSystems = self.nmrProject.resonanceGroups comparisons = [] for spinSystem2 in spinSystems: comparisons.append(self.compare2spinSystems(spinSystem, spinSystem2)) return comparisons def compare2spinSystems(self, spinSystem1, spinSystem2): '''Compare two spin systems to each other. args: spinSystem1: the first spin system spinSystem2: the second spin system returns: SpinSystemComparison object ''' comp = SpinSystemComparison(spinSystem1=spinSystem1, spinSystem2=spinSystem2, isotope_correction=self.correction, protonatedShiftList=self.protonatedShiftList, deuteratedShiftList=self.deuteratedShiftList) return comp
class CalcHeteroNoePopup(BasePopup): """ **Calculate Heteronuclear NOE Values From Peak Intensities** The purpose of this popup window is to calculate the heteronuclear NOE for amide resonances based upon a comparison of the peak intensities in spectra that derive from an NOE saturated experiment and an unsaturated (reference) experiment. The basic idea of this tool is that three peak lists are chosen, two of which are for heteronuclear NOE experiments (H,N axes); unsaturated reference and saturated, and one which is the source of assignments and peak locations. This last "Assignment" peak list may be the same as one of the NOE peak lists, but may also be entirely separate. The "Assignment" peak list is used to specify which peak assignments and locations should be used for the calculation of the heteronuclear NOE values, and thus can be used to specify only a subset of the resonances for measurement. For example, it is common to copy an HQSC peak list for use as the "Assignment" peak list but remove overlapped and NH2 peaks so that the NOE values are only calculated for separated backbone amides. The calculation process involves taking each of these assigned peaks and finding peaks with the same assignment in the NOE peak lists, or if that fails finding peaks with a similar position (within the stated tolerances); new peaks may be picked if the "Pick new peaks?" option is set. The first "Peak Lists & Settings" tab allows the user to choose the peak lists and various options that will be used in the peak-finding and NOE calculation. The "Peaks" table allows the peaks from each of the three peak list selections to be displayed when one of the "Show" buttons is clicked. The [Separate Peak Table] function allows these peaks to be displayed in the main, separate `Peak Lists`_ table, which has many more peak manipulation options. The options below the table may be used to locate selected peaks within the spectrum window displays. The second "Peak Intensity Comparison" tab is where the heteronuclear NOE values are actually calculated. Assuming that two NOE experiment peak lists have been chosen and that some of their peaks match the assigned peak positions then the peak intensities are extracted and NOE values automatically calculated when the tab is opened. Although, a refresh of the table can be forced with [Find Matching Peaks] at the bottom If pairs of NOE saturated and reference peaks are found then the actual heteronuclear NOE value is displayed as the "Intensity Ratio" in the last, rightmost, column of the table. To store these values as a NOE measurement list; so that the data can be saved in the CCPN project without need for recalculation, the [Create Hetero NOE List] function can be used. The results are then available to view at any time via the `Measurement Lists`_ table. **Caveats & Tips** Erroneous peak intensity comparisons may be removed with the [Remove Pairs] function, but its is common to curate the "Assign" peak list first and avoid tidying afterwards. The "Closeness score" can be used to find peak positions where the compared NOE peaks are unexpectedly far from one another. .. _`Peak Lists`: EditPeakListsPopup.html .. _`Measurement Lists`: EditMeasurementListsPopup.html """ def __init__(self, parent, *args, **kw): self.guiParent = parent self.peakPairs = [] self.intensityType = 'height' self.selectedPair = None self.assignPeakList = None self.refPeakList = None self.satPeakList = None self.displayPeakList = None self.waiting = 0 BasePopup.__init__(self, parent, title="Data Analysis : Heteronuclear NOE", **kw) def body(self, guiFrame): self.geometry('700x700') guiFrame.expandGrid(0,0) options = ['Peak Lists & Settings','Peak Intensity Comparison'] tabbedFrame = TabbedFrame(guiFrame, options=options, callback=self.changeTab) tabbedFrame.grid(row=0, column=0, sticky='nsew') self.tabbedFrame = tabbedFrame frameA, frameB = tabbedFrame.frames row = 0 frameA.grid_columnconfigure(1, weight=1) frameA.grid_columnconfigure(3, weight=1) frameA.grid_columnconfigure(5, weight=1) frameA.grid_rowconfigure(5, weight=1) tipText = 'Number of reference peaks (no saturation)' self.peaksALabel = Label(frameA, text='Number of Ref Peaks: ', tipText=tipText) self.peaksALabel.grid(row=1,column=0,columnspan=2,sticky='w') tipText = 'Number of NOE saturation peaks' self.peaksBLabel = Label(frameA, text='Number of Sat Peaks: ', tipText=tipText) self.peaksBLabel.grid(row=1,column=2,columnspan=2,sticky='w') tipText = 'Number of peaks in assigned list' self.peaksCLabel = Label(frameA, text='Number of Assign Peaks: ', tipText=tipText) self.peaksCLabel.grid(row=1,column=4,columnspan=2,sticky='w') tipText = 'Selects which peak list is considered the NOE intensity reference (no saturation)' specALabel = Label(frameA, text='Ref Peak List: ') specALabel.grid(row=0,column=0,sticky='w') self.specAPulldown = PulldownList(frameA, callback=self.setRefPeakList, tipText=tipText) self.specAPulldown.grid(row=0,column=1,sticky='w') tipText = 'Selects which peak list is considered as NOE saturated.' specBLabel = Label(frameA, text='Sat Peak List: ') specBLabel.grid(row=0,column=2,sticky='w') self.specBPulldown = PulldownList(frameA, callback=self.setSatPeakList, tipText=tipText) self.specBPulldown.grid(row=0,column=3,sticky='w') tipText = 'Selects a peak list with assignments to use as a positional reference' specCLabel = Label(frameA, text='Assignment Peak List: ') specCLabel.grid(row=0,column=4,sticky='w') self.specCPulldown = PulldownList(frameA, callback=self.setAssignPeakList, tipText=tipText) self.specCPulldown.grid(row=0,column=5,sticky='w') frame0a = Frame(frameA) frame0a.grid(row=2,column=0,columnspan=6,sticky='nsew') frame0a.grid_columnconfigure(9, weight=1) tipText = '1H ppm tolerance for matching assigned peaks to reference & NOE saturation peaks' tolHLabel = Label(frame0a, text='Tolerances: 1H') tolHLabel.grid(row=0,column=0,sticky='w') self.tolHEntry = FloatEntry(frame0a,text='0.02', width=6, tipText=tipText) self.tolHEntry .grid(row=0,column=1,sticky='w') tipText = '15N ppm tolerance for matching assigned peaks to reference & NOE saturation peaks' tolNLabel = Label(frame0a, text=' 15N') tolNLabel .grid(row=0,column=2,sticky='w') self.tolNEntry = FloatEntry(frame0a,text='0.1', width=6, tipText=tipText) self.tolNEntry .grid(row=0,column=3,sticky='w') tipText = 'Whether to peak new peaks in reference & NOE saturated lists (at assignment locations)' label = Label(frame0a, text=' Pick new peaks?', grid=(0,4)) self.pickPeaksSelect = CheckButton(frame0a, tipText=tipText, grid=(0,5), selected=True) tipText = 'Whether to assign peaks in the peaks in the reference & NOE saturation lists, if not already assigned' label = Label(frame0a, text=' Assign peaks?') label.grid(row=0,column=6,sticky='w') self.assignSelect = CheckButton(frame0a, tipText=tipText) self.assignSelect.set(1) self.assignSelect.grid(row=0,column=7,sticky='w') tipText = 'Whether to consider peak height or volume in the heteronuclear NOE calculation' intensLabel = Label(frame0a, text=' Intensity Type:') intensLabel .grid(row=0,column=8,sticky='w') self.intensPulldown = PulldownList(frame0a, texts=['height','volume'], callback=self.setIntensityType, tipText=tipText) self.intensPulldown.grid(row=0,column=9,sticky='w') divider = LabelDivider(frameA, text='Peaks', grid=(3,0), gridSpan=(1,6)) tipTexts = ['Show the selected intensity reference peaks in the below table', 'Show the selected NOE saturation peaks in the below table', 'Show the selected assigned peak list in the below table', 'Show the displayed peaks in a separate peak table, where assignments etc. may be adjusted'] texts = ['Show Ref Peaks','Show Sat Peaks', 'Show Assign Peaks', 'Separate Peak Table'] commands = [self.viewRefPeakList, self.viewSatPeakList, self.viewAssignPeakList, self.viewSeparatePeakTable] self.viewPeaksButtons = ButtonList(frameA, expands=True, tipTexts=tipTexts, texts=texts, commands=commands) self.viewPeaksButtons.grid(row=4,column=0,columnspan=6,sticky='nsew') self.peakTable = PeakTableFrame(frameA, self.guiParent, grid=(5,0), gridSpan=(1,6)) self.peakTable.bottomButtons1.grid_forget() self.peakTable.bottomButtons2.grid_forget() #self.peakTable.topFrame.grid_forget() self.peakTable.topFrame.grid(row=2, column=0, sticky='ew') # Next tab frameB.expandGrid(0,0) tipTexts = ['Row number', 'Assignment annotation for NOE saturation peak', 'Assignment annotation for reference peak (no saturation)', '1H chemical shift of NOE saturation peak', '1H chemical shift of reference peak', '15N chemical shift of NOE saturation peak', '15N chemical shift of reference peak', 'The separation between compared peaks: square root of the sum of ppm differences squared', 'The intensity if the NOE saturation peak', 'The intensity of the reference peak (no saturation)', 'Ratio of peak intensities: saturated over reference', 'Residue(s) for reference peak'] colHeadings = ['#','Sat Peak','Ref Peak','1H shift A', '1H shift B','15N shift A','15N shift B', 'Closeness\nScore','Intensity A','Intensity B', 'Intensity\nRatio','Residue'] self.scrolledMatrix = ScrolledMatrix(frameB, multiSelect=True, headingList=colHeadings, callback=self.selectCell, tipTexts=tipTexts, grid=(0,0), deleteFunc=self.removePair) tipTexts = ['Force a manual update of the table; pair-up NOE saturation and reference peaks according to assigned peak positions', 'Remove the selected rows of peak pairs', 'Show peaks corresponding to the selected row in a table', 'Save the Heteronuclear NOE values in the CCPN project as a data list'] texts = ['Refresh Table','Remove Pairs', 'Show Peak Pair','Create Hetero NOE List'] commands = [self.matchPeaks,self.removePair, self.showPeakPair,self.makeNoeList] self.pairButtons = ButtonList(frameB, tipTexts=tipTexts, grid=(1,0), texts=texts, commands=commands) bottomButtons = UtilityButtonList(tabbedFrame.sideFrame, helpUrl=self.help_url) bottomButtons.grid(row=0, column=0, sticky='e') self.updatePulldowns() self.updateAfter() self.administerNotifiers(self.registerNotify) def administerNotifiers(self, notifyFunc): for func in ('__init__', 'delete','setName'): for clazz in ('ccp.nmr.Nmr.DataSource', 'ccp.nmr.Nmr.Experiment',): notifyFunc(self.updatePulldowns, clazz, func) for func in ('__init__', 'delete'): notifyFunc(self.updatePulldowns,'ccp.nmr.Nmr.PeakList', func) for func in ('__init__', 'delete','setAnnotation','setFigOfMerit'): notifyFunc(self.updatePeaks, 'ccp.nmr.Nmr.Peak', func) for func in ('setAnnotation','setPosition','setNumAliasing'): notifyFunc(self.updatePeakChild, 'ccp.nmr.Nmr.PeakDim', func) for func in ('__init__', 'delete', 'setValue'): notifyFunc(self.updatePeakChild, 'ccp.nmr.Nmr.PeakIntensity', func) def changeTab(self, index): if index == 1: self.matchPeaks() def open(self): self.updatePulldowns() self.updateAfter() BasePopup.open(self) def destroy(self): self.administerNotifiers(self.unregisterNotify) BasePopup.destroy(self) def updatePulldowns(self, *obj): index0 = 0 index1 = 0 index2 = 0 names, peakLists = self.getPeakLists() if names: if self.refPeakList not in peakLists: self.refPeakList = peakLists[0] if self.satPeakList not in peakLists: self.satPeakList = peakLists[0] if self.assignPeakList not in peakLists: self.assignPeakList = peakLists[0] index0 = peakLists.index(self.refPeakList) index1 = peakLists.index(self.satPeakList) index2 = peakLists.index(self.assignPeakList) self.specAPulldown.setup(names, peakLists, index0) self.specBPulldown.setup(names, peakLists, index1) self.specCPulldown.setup(names, peakLists, index2) def updatePeakChild(self,peakChild): if self.waiting: return self.updatePeaks(peakChild.peak) def updatePeaks(self, peak): if self.waiting: return if peak.peakList in (self.refPeakList,self.satPeakList,self.assignPeakList): if peak.isDeleted and (peak.peakList in (self.refPeakList,self.satPeakList) ): for peaks in self.peakPairs: if peak in peaks: self.peakPairs.remove(peaks) if self.selectedPair is peaks: self.selectedPair = None self.updateAfter() return self.updateAfter() def setIntensityType(self, intensityType): self.intensityType = intensityType self.updateAfter() def viewRefPeakList(self): if self.refPeakList: self.updatePeakTable(self.refPeakList) def viewSatPeakList(self): if self.satPeakList: self.updatePeakTable(self.satPeakList) def viewAssignPeakList(self): if self.assignPeakList: self.updatePeakTable(self.assignPeakList) def viewSeparatePeakTable(self): if self.displayPeakList: self.guiParent.editPeakList(peakList=self.displayPeakList) def setRefPeakList(self, refPeakList): if self.displayPeakList is self.refPeakList: self.updatePeakTable(refPeakList) self.refPeakList = refPeakList self.updateViewButtons() self.updateAfter() def setSatPeakList(self, satPeakList): if self.displayPeakList is self.satPeakList: self.updatePeakTable(satPeakList) self.satPeakList = satPeakList self.updateViewButtons() self.updateAfter() def setAssignPeakList(self, assignPeakList): if self.displayPeakList is self.assignPeakList: self.updatePeakTable(assignPeakList) self.assignPeakList = assignPeakList self.updateViewButtons() self.updateAfter() def getPeakListName(self, peakList): if peakList: spectrum = peakList.dataSource experiment = spectrum.experiment name = '%s:%s:%d' % (experiment.name, spectrum.name, peakList.serial) else: name = '<None>' return name def getPeakLists(self): names = [] peakLists = [] for experiment in self.nmrProject.sortedExperiments(): for dataSource in experiment.sortedDataSources(): if dataSource.numDim == 2: dimsN = findSpectrumDimsByIsotope(dataSource,'15N') dimsH = findSpectrumDimsByIsotope(dataSource,'1H') if len(dimsN) == 1 and len(dimsH) == 1: for peakList in dataSource.sortedPeakLists(): name = self.getPeakListName(peakList) names.append( name ) peakLists.append(peakList) return names, peakLists def showPeakPair(self): if self.selectedPair: self.guiParent.viewPeaks(self.selectedPair) def selectCell(self, object, row, col): self.selectedPair = object if self.selectedPair: self.pairButtons.buttons[1].enable() self.pairButtons.buttons[2].enable() else: self.pairButtons.buttons[1].disable() self.pairButtons.buttons[2].disable() def removePair(self, *event): pairs = self.scrolledMatrix.currentObjects if pairs: for pair in pairs: self.peakPairs.remove(pair) self.selectedPair = None self.updateAfter() def matchPeaks(self): # assign relative to reference if self.assignPeakList and self.assignPeakList.peaks and self.refPeakList and self.satPeakList: tolH = float( self.tolHEntry.get() ) tolN = float( self.tolNEntry.get() ) pickNewPeaks = self.pickPeaksSelect.get() doAssign = self.assignSelect.get() dimH = findSpectrumDimsByIsotope(self.assignPeakList.dataSource,'1H' )[0] dimHA = findSpectrumDimsByIsotope(self.refPeakList.dataSource,'1H' )[0] dimHB = findSpectrumDimsByIsotope(self.satPeakList.dataSource,'1H' )[0] dimN = 1-dimH dimNA = 1-dimHA dimNB = 1-dimHB tolerancesA = [0,0] tolerancesA[dimHA] = tolH tolerancesA[dimNA] = tolN tolerancesB = [0,0] tolerancesB[dimHB] = tolH tolerancesB[dimNB] = tolN self.peakPairs = matchHnoePeaks(self.assignPeakList,self.refPeakList, self.satPeakList,tolerancesA,tolerancesB, pickNewPeaks,doAssign) self.updateAfter() def makeNoeList(self): if self.refPeakList is self.satPeakList: showWarning('Same Peak List', 'Ref Peak List and Sat Peak List cannot be the same', parent=self) return if self.peakPairs: s1 = self.refPeakList.dataSource s2 = self.satPeakList.dataSource noiseRef = getSpectrumNoise(s1) noiseSat = getSpectrumNoise(s2) es = '%s-%s' % (s1.experiment.name,s2.experiment.name) if len(es) > 50: es = 'Expt(%d)-Expt(%d)' % (s1.experiment.serial,s2.experiment.serial) noeList = self.nmrProject.newNoeList(unit='None',name='Hetero NOE list for %s' % es) noeList.setExperiments([s1.experiment,]) if s1.experiment is not s2.experiment: noeList.addExperiment( s2.experiment ) # TBD: sf, noeValueType, refValue, refDescription resonancePairsSeen = set() for (peakA,peakB) in self.peakPairs: # peakA is sat intensA = getPeakIntensity(peakA,self.intensityType) intensB = getPeakIntensity(peakB,self.intensityType) value = float(intensA)/intensB error = abs(value) * sqrt((noiseSat/intensA)**2 + (noiseRef/intensB)**2) resonances = tuple(self.getPeakResonances(peakA)) frozenResonances = frozenset(resonances) if len(resonances) < 2: pl = peakA.peakList sp = pl.dataSource msg = 'Skipping %s:%s:%d peak %d it has too few resonances assigned' data = (sp.experiment.name, sp.name, pl.serial, peakA.serial) showWarning('Warning',msg % data, parent=self) elif len(resonances) > 2: pl = peakA.peakList sp = pl.dataSource resonanceText = ' '.join([makeResonanceGuiName(r) for r in resonances]) msg = 'Skipping %s:%s:%d peak %d it has too many resonances assigned (%s)' data = (sp.experiment.name, sp.name, pl.serial, peakA.serial, resonanceText) showWarning('Warning', msg % data, parent=self) elif frozenResonances not in resonancePairsSeen: resonancePairsSeen.add(frozenResonances) noeList.newNoe(value=value,resonances=resonances,peaks=[peakA,peakB],error=error) else: resonanceText = ' '.join([makeResonanceGuiName(r) for r in resonances]) msg = 'Skipping duplicate entry for resonances %s' % resonanceText showWarning('Warning', msg, parent=self) self.parent.editMeasurements(measurementList=noeList) def getPeakResonances(self,peak): resonances = [] for peakDim in peak.sortedPeakDims(): for contrib in peakDim.sortedPeakDimContribs(): resonances.append(contrib.resonance) return resonances def updateAfter(self, *opt): if self.waiting: return else: self.waiting = True self.after_idle(self.update) def updateViewButtons(self): if self.refPeakList: self.viewPeaksButtons.buttons[0].enable() else: self.viewPeaksButtons.buttons[0].disable() if self.satPeakList: self.viewPeaksButtons.buttons[1].enable() else: self.viewPeaksButtons.buttons[1].disable() if self.assignPeakList: self.viewPeaksButtons.buttons[2].enable() else: self.viewPeaksButtons.buttons[2].disable() def updatePeakTable(self, peakList): if peakList is not self.displayPeakList: self.displayPeakList = peakList self.peakTable.update(peaks=peakList.sortedPeaks()) def update(self): if self.refPeakList: self.peaksALabel.set( 'Number of Ref Peaks: %d' % len(self.refPeakList.peaks) ) else: self.peaksALabel.set( 'Number of Ref Peaks: %d' % 0 ) if self.satPeakList: self.peaksBLabel.set( 'Number of Sat Peaks: %d' % len(self.satPeakList.peaks) ) else: self.peaksBLabel.set( 'Number of Sat Peaks: %d' % 0 ) if self.assignPeakList: self.peaksCLabel.set( 'Number of Assign Peaks: %d' % len(self.assignPeakList.peaks) ) else: self.peaksCLabel.set( 'Number of Assign Peaks: %d' % 0 ) if self.refPeakList and self.satPeakList and self.assignPeakList: if self.refPeakList is self.satPeakList: self.pairButtons.buttons[0].disable() else: self.pairButtons.buttons[0].enable() else: self.pairButtons.buttons[0].disable() if self.selectedPair: self.pairButtons.buttons[1].enable() self.pairButtons.buttons[2].enable() else: self.pairButtons.buttons[1].disable() self.pairButtons.buttons[2].disable() if self.peakPairs: self.pairButtons.buttons[3].enable() dsA = self.peakPairs[0][0].peakList.dataSource dsB = self.peakPairs[0][1].peakList.dataSource dimHA = findSpectrumDimsByIsotope(dsA,'1H')[0] dimHB = findSpectrumDimsByIsotope(dsB,'1H')[0] dimNA = findSpectrumDimsByIsotope(dsA,'15N')[0] dimNB = findSpectrumDimsByIsotope(dsB,'15N')[0] else: self.pairButtons.buttons[3].disable() objectList = [] textMatrix = [] i = 0 for (peakA,peakB) in self.peakPairs: i += 1 peakDimsA = peakA.sortedPeakDims() peakDimsB = peakB.sortedPeakDims() ppm0 = peakDimsA[dimHA].value ppm1 = peakDimsB[dimHB].value ppm2 = peakDimsA[dimNA].value ppm3 = peakDimsB[dimNB].value d0 = abs(ppm0-ppm1) d1 = abs(ppm2-ppm3) intensA = getPeakIntensity(peakA,self.intensityType) intensB = getPeakIntensity(peakB,self.intensityType) datum = [] datum.append( i ) datum.append( getPeakAnnotation(peakA, doPeakDims=False) ) datum.append( getPeakAnnotation(peakB, doPeakDims=False) ) datum.append( ppm0 ) datum.append( ppm1 ) datum.append( ppm2 ) datum.append( ppm3 ) datum.append( sqrt((d0*d0)+(d1*d1)) ) datum.append( intensA ) datum.append( intensB ) if intensB: datum.append( float(intensA)/intensB ) else: datum.append( None ) seqCodes = ','.join(['%s' % seqCode for seqCode in getPeakSeqCodes(peakB)]) datum.append(seqCodes) objectList.append( (peakA,peakB) ) textMatrix.append( datum ) if not objectList: textMatrix.append([]) self.scrolledMatrix.update(objectList=objectList, textMatrix=textMatrix) self.waiting = False
def body(self, guiFrame): self.geometry('600x350') project = self.project analysisProject = self.analysisProject guiFrame.grid_columnconfigure(1, weight=1) row = 0 frame = Frame(guiFrame, grid=(0,0)) label = Label(frame, text=' Window:', grid=(0,0)) self.windowPulldown = PulldownList(frame, grid=(0,1), tipText='The window that will be printed out', callback=self.selectWindow) tipTexts = ['For the window pulldown, show all of the spectrum windows in the current project, irrespective of the active group', 'For the window pulldown, show only spectrum windows that are in the currently active window group'] self.whichWindows = RadioButtons(frame, grid=(0,2), entries=ACTIVE_OPTIONS, tipTexts=tipTexts, select_callback=self.updateWindows) texts = [ 'Save Print File' ] tipTexts = [ 'Save the printout to the specified file' ] commands = [ self.saveFile ] buttons = UtilityButtonList(guiFrame, helpUrl=self.help_url, grid=(row,2), commands=commands, texts=texts, tipTexts=tipTexts) self.buttons = buttons buttons.buttons[0].config(bg='#B0FFB0') row += 1 guiFrame.grid_rowconfigure(row, weight=1) options = ['Options', 'Spectra', 'Peak Lists', 'Region'] tipTexts = ['Optional settings for spectra', 'Optional settings for peak lists', 'Optional settings for the region'] tabbedFrame = TabbedFrame(guiFrame, options=options, tipTexts=tipTexts) tabbedFrame.grid(row=row, column=0, columnspan=3, sticky='nsew') self.tabbedFrame = tabbedFrame optionFrame, spectrumFrame, peakListFrame, regionFrame = tabbedFrame.frames optionFrame.expandGrid(0, 0) getOption = lambda key, defaultValue: PrintBasic.getPrintOption(analysisProject, key, defaultValue) setOption = lambda key, value: PrintBasic.setPrintOption(analysisProject, key, value) self.printFrame = PrintFrame(optionFrame, getOption=getOption, grid=(0,0), gridSpan=(1,1), setOption=setOption, haveTicks=True, doOutlineBox=False) spectrumFrame.expandGrid(0, 0) frame = Frame(spectrumFrame, grid=(0,0), gridSpan=(1,1)) frame.expandGrid(1,0) self.overrideSpectrum = CheckButton(frame, text='Use below settings when printing', tipText='Use below settings when printing instead of the window values', grid=(0,0), sticky='w') tipText = 'Change the settings of the selected spectra back to their window values' button = Button(frame, text='Reset Selected', tipText=tipText, command=self.resetSelected, grid=(0,1), sticky='e') self.posColorPulldown = PulldownList(self, callback=self.setPosColor) self.negColorPulldown = PulldownList(self, callback=self.setNegColor) headings = ['Spectrum', 'Pos. Contours\nDrawn', 'Neg. Contours\nDrawn', 'Positive\nColours', 'Negative\nColours'] tipTexts = ['Spectrum in window', 'Whether the positive contours should be drawn', 'Whether the negative contours should be drawn', 'Colour scheme for positive contours (can be a single colour)', 'Colour scheme for negative contours (can be a single colour)'] editWidgets = [ None, None, None, self.posColorPulldown, self.negColorPulldown] editGetCallbacks = [ None, self.togglePos, self.toggleNeg, self.getPosColor, self.getNegColor] editSetCallbacks = [ None, None, None, self.setPosColor, self.setNegColor] self.spectrumTable = ScrolledMatrix(frame, headingList=headings, tipTexts=tipTexts, multiSelect=True, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, grid=(1,0), gridSpan=(1,2)) peakListFrame.expandGrid(0, 0) frame = Frame(peakListFrame, grid=(0,0), gridSpan=(1,3)) frame.expandGrid(1,0) self.overridePeakList = CheckButton(frame, text='Use below settings when printing', tipText='Use below settings when printing instead of the window values', grid=(0,0)) tipText = 'Change the settings of the selected peak lists back to their window values' button = Button(frame, text='Reset Selected', tipText=tipText, command=self.resetSelected, grid=(0,1), sticky='e') colors = Color.standardColors self.peakColorPulldown = PulldownList(self, callback=self.setPeakColor, texts=[c.name for c in colors], objects=[c.hex for c in colors], colors=[c.hex for c in colors]) headings = [ 'Peak List', 'Symbols Drawn', 'Peak Font', 'Peak Colour'] self.fontMenu = FontList(self, mode='Print', extraTexts=[no_peak_text]) editWidgets = [ None, None, self.fontMenu, self.peakColorPulldown] editGetCallbacks = [ None, self.togglePeaks, self.getPeakFont, self.getPeakColor ] editSetCallbacks = [ None, None, self.setPeakFont, self.setPeakColor ] self.peakListTable = ScrolledMatrix(frame, headingList=headings, multiSelect=True, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, grid=(1,0), gridSpan=(1,2)) regionFrame.expandGrid(0, 0) frame = Frame(regionFrame, grid=(0,0), gridSpan=(1,3)) frame.expandGrid(3,0) tipText = 'Use the specified override region when printing rather than the window values' self.overrideButton = CheckButton(frame, text='Use override region when printing', tipText=tipText, callback=self.toggledOverride, grid=(0,0)) tipTexts = ('Use min and max to specify override region', 'Use center and width to specify override region') self.use_entry = USE_ENTRIES[0] self.useButtons = RadioButtons(frame, entries=USE_ENTRIES, tipTexts=tipTexts, select_callback=self.changedUseEntry, grid=(1,0)) texts = ('Set Region from Window', 'Set Center from Window', 'Set Width from Window') tipTexts = ('Set the override region to be the current window region', 'Set the center of the override region to be the center of the current window region', 'Set the width of the override region to be the width of the current window region') commands = (self.setRegionFromWindow, self.setCenterFromWindow, self.setWidthFromWindow) self.setRegionButton = ButtonList(frame, texts=texts, tipTexts=tipTexts, commands=commands, grid=(2,0)) self.minRegionWidget = FloatEntry(self, returnCallback=self.setMinRegion, width=10) self.maxRegionWidget = FloatEntry(self, returnCallback=self.setMaxRegion, width=10) headings = MIN_MAX_HEADINGS editWidgets = [ None, None, self.minRegionWidget, self.maxRegionWidget ] editGetCallbacks = [ None, None, self.getMinRegion, self.getMaxRegion ] editSetCallbacks = [ None, None, self.setMinRegion, self.setMaxRegion ] self.regionTable = RegionScrolledMatrix(frame, headingList=headings, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, grid=(3,0)) self.updateWindows() self.updateAfter() self.administerNotifiers(self.registerNotify)
class EditFitGraphPopup(BasePopup): """ **Analyse Function Curve Fitting to Peak Series Data** This popup is used to display the fit of a curve, of the displayed equation type, to data that has been extracted for a group of spectrum peaks from an NMR series. Precisely which kind of data is being fitted depends on the parent tool that this popup window was launched from. For example, for the `Follow Intensity Changes`_ tool the displayed graph is of a time or frequency value on the "X" axis (e.g. T1) verses peak intensity. For the `Follow Shift Changes`_ system the plot is for the parameters of the experiment titration on the "X" axis (e.g concentration) verses chemical shift distance. The upper graph shows the peak data that was used; the blue points, and the points of the fitted theoretical curve; red points. The lower table lists the data points for all of the peaks in the group, to which the data relates. There will be one peak for each row of the table, and hence point on the "X" axis. For each data point in the table the corresponding peak from which the data was extracted may be located with the "Follow in window" option, using the stated spectrum window and making marker lines as desired. Alternatively, the peak may be viewed in a table with [Show Peak] In general operation this system is used to check how well the selected function curve fits the peak data. The data that is displayed comes from the analysis tool that launched this popup. Any outliers may be removed using [Remove Point] (only with good reason) or the peaks themselves may be corrected if something has gone awry. Given that the display is launched from the selection of a specific group of peaks from a popup like `Follow Shift Changes`_ or `Follow Intensity Changes`_ and there are usually several peak groups that need to be analysed, the [Previous Set] and [Next Set] buttons can be used to quickly jump to the next peak group and see the next curve in the analysis results. .. _`Follow Intensity Changes`: CalcRatesPopup.html .. _`Follow Shift Changes`: FollowShiftChangesPopup.html """ def __init__(self, parent, dataFitting, getXYfunction, updateFunction, xLabel, yLabel, showObjectFunction=None, nextSetFunction=None, prevSetFunction=None, graphTitle='', **kw): self.guiParent = parent self.getXYfunction = getXYfunction self.updateFunction = updateFunction self.nextSetFunction = nextSetFunction self.prevSetFunction = prevSetFunction self.dataFitting = dataFitting self.object = None self.xLabel = xLabel self.yLabel = yLabel self.x = [] self.y = [] self.yFit = [] self.params = () self.chiSq = 0 self.method = dataFitting.fitFunction self.waiting = False self.noiseLevel = dataFitting.noiseLevel self.graphTitle = graphTitle self.windowPane = None self.mark = None BasePopup.__init__(self, parent=parent, title='Fit Graph', **kw) parent.protocol("WM_DELETE_WINDOW", self.close) def body(self, guiFrame): guiFrame.grid_columnconfigure(0, weight=1) row = 0 self.scrolledGraph = ScrolledGraph(guiFrame, width=400, height=300, symbolSize=5, symbols=['square', 'circle'], dataColors=['#000080', '#800000'], lineWidths=[0, 1], grid=(row, 0)) #self.scrolledGraph.setZoom(0.7) row += 1 frame = Frame(guiFrame, grid=(row, 0), sticky='ew') label = Label(frame, text='Fitting Function:', grid=(0, 0)) tipText = 'Selects which form of function to fit to the experimental data' self.methodPulldown = PulldownList(frame, self.changeMethod, grid=(0, 1), tipText=tipText) row += 1 frame = Frame(guiFrame, grid=(row, 0), sticky='ew') tipText = 'The effective equation of the final fitted graph, incorporating all parameters' self.equationLabel = Label(frame, text='Equation:', grid=(0, 0), tipText=tipText) tipText = 'The error in the fit of the selected parameterised function to the experimental data' self.errorLabel = Label(frame, text='Fit Error:', grid=(0, 1), tipText=tipText) row += 1 frame = Frame(guiFrame, grid=(row, 0), sticky='ew') label = Label(frame, text='Include x origin?:', grid=(0, 0)) tipText = 'Whether to include the x=0 point in the drawing' self.xOriginSelect = CheckButton(frame, callback=self.draw, grid=(0, 1), selected=False, tipText=tipText) label = Label(frame, text='Include y origin?:', grid=(0, 2)) tipText = 'Whether to include the y=0 point in the drawing' self.yOriginSelect = CheckButton(frame, callback=self.draw, grid=(0, 3), selected=False, tipText=tipText) label = Label(frame, text='Include y error?:', grid=(0, 4)) tipText = 'Whether to include the y error bars in the drawing (if these exist)' self.yErrorSelect = CheckButton(frame, callback=self.draw, grid=(0, 5), selected=False, tipText=tipText) row += 1 frame = Frame(guiFrame, grid=(row, 0), sticky='ew') label = Label(frame, text='Navigation Window:', grid=(0, 0)) tipText = 'Selects which spectrum window will be used for navigating to peak positions' self.windowPanePulldown = PulldownList(frame, self.changeWindow, grid=(0, 1), tipText=tipText) label = Label(frame, text='Follow in window?:', grid=(0, 2)) tipText = 'Whether to navigate to the position of the reference peak (for the group), in the selected window' self.followSelect = CheckButton(frame, callback=self.windowPaneNavigate, grid=(0, 3), selected=False, tipText=tipText) label = Label(frame, text='Mark Ref Peak?:', grid=(0, 4)) tipText = 'Whether to put a multi-dimensional cross-mark through the reference peak position, so it can be identified in spectra' self.markSelect = CheckButton(frame, callback=None, tipText=tipText, grid=(0, 5), selected=False) row += 1 guiFrame.grid_rowconfigure(row, weight=1) tipTexts = [ 'The number of the data point, in order of increasing X-axis value', 'For each point, the value of the parameter which is varied in the NMR series, e.g. T1, temperature, concentration etc.', 'For each point, the experimental value being fitted, e.g. peak intensity of chemical shift distance', 'The value of the best-fit function at the X-axis location', 'The difference between the experimental (Y-axis) value and the fitted value', 'The error in the experimental (Y-axis) value' ] headingList = ['Point', 'x', 'y', 'Fitted y', u'\u0394', 'y error'] self.scrolledMatrix = ScrolledMatrix(guiFrame, headingList=headingList, callback=self.selectObject, tipTexts=tipTexts, grid=(row, 0)) row += 1 tipTexts = [ 'Remove the selected data point, optionally removing the underlying peak', 'Show a table of spectrum peaks that correspond to the selected data point' ] texts = ['Remove Point', 'Show Peak'] commands = [self.removePoint, self.showObject] if self.prevSetFunction: texts.append('Previous Set') tipTexts.append( 'Move to the previous set of fitted values; the next group of peaks, often corresponding to a different residue or resonance' ) commands.append(self.prevSet) if self.nextSetFunction: tipTexts.append( 'Move to the next set of fitted values; the next group of peaks, often corresponding to a different residue or resonance' ) texts.append('Next Set') commands.append(self.nextSet) bottomButtons = UtilityButtonList(guiFrame, texts=texts, commands=commands, helpUrl=self.help_url, tipTexts=tipTexts, grid=(row, 0), doClone=False) self.removeButton = bottomButtons.buttons[0] for func in ('__init__', 'delete', 'setName'): self.registerNotify(self.updateWindows, 'ccpnmr.Analysis.SpectrumWindow', func) self.update() def destroy(self): for func in ('__init__', 'delete', 'setName'): self.unregisterNotify(self.updateWindows, 'ccpnmr.Analysis.SpectrumWindow', func) BasePopup.destroy(self) def nextSet(self): if self.nextSetFunction: self.nextSetFunction() self.windowPaneNavigate() def prevSet(self): if self.prevSetFunction: self.prevSetFunction() self.windowPaneNavigate() def windowPaneNavigate(self, event=None): if self.followSelect.get() and self.dataFitting: peaks = self.dataFitting.objects if self.windowPane and peaks: peak = peaks[int(len(peaks) / 2)] windowFrame = self.windowPane.getWindowFrame() windowFrame.gotoPeak(peak) if self.markSelect.get(): if self.mark and not self.mark.isDeleted: self.mark.delete() self.mark = createPeakMark(self.dataFitting.refObject) def getWindows(self): peaks = self.scrolledMatrix.objectList windowPanes = [] if peaks: peak = peaks[0] project = peak.root spectrum = peak.peakList.dataSource tryWindows = getActiveWindows(project) for window in tryWindows: for windowPane in window.sortedSpectrumWindowPanes(): if isSpectrumInWindowPane(windowPane, spectrum): windowPanes.append(windowPane) return windowPanes def changeWindow(self, windowPane): if windowPane is not self.windowPane: self.windowPane = windowPane self.windowPaneNavigate() def updateWindows(self, window=None): windowPanes = self.getWindows() index = -1 names = [getWindowPaneName(wp) for wp in windowPanes] windowPane = self.windowPane if windowPanes: if windowPane not in windowPanes: windowPane = windowPanes[0] index = windowPanes.index(windowPane) if windowPane is not self.windowPane: self.windowPane = windowPane self.windowPaneNavigate() self.windowPanePulldown.setup(names, windowPanes, index) def showObject(self): if self.object and (self.object.className == 'Peak'): peaks = [self.object] self.guiParent.guiParent.viewPeaks(peaks) def close(self): BasePopup.close(self) def changeMethod(self, index): if self.dataFitting: self.method = index self.dataFitting.fitFunction = self.method self.updateAfter() def updateMethods(self, *opt): n = len(METHOD_NAMES) if self.method >= n: self.method = 1 self.methodPulldown.setup(METHOD_NAMES, range(n), self.method) def selectObject(self, object, row, col): if object: self.object = object self.updateButtons() def removePoint(self): if self.object and (len(self.dataFitting.objects) > 2): self.dataFitting.objects.remove(self.object) if showYesNo('Query', 'Delete the corresponding %s?' % (self.object.className), parent=self): self.object.delete() self.updateAfter() def draw(self, *junk): title = '%s Function fit %s' % (self.graphTitle, METHOD_NAMES[self.method]) dataSet1 = [] dataSet2 = [] useErr = self.yErrorSelect.isSelected() if not useErr: useErr = None for i in range(len(self.scrolledMatrix.textMatrix)): row = self.scrolledMatrix.textMatrix[i] x = row[1] y = row[2] y2 = row[3] err = useErr and row[5] dataSet1.append([x, y, err]) dataSet2.append([x, y2]) dataSet1.sort() dataSet2.sort() if dataSet1 and dataSet2: drawOriginX = self.xOriginSelect.isSelected() drawOriginY = self.yOriginSelect.isSelected() self.scrolledGraph.update(dataSets=[dataSet1, dataSet2], xLabel=self.xLabel, yLabel=self.yLabel, title=title, drawOriginX=drawOriginX, drawOriginY=drawOriginY) self.scrolledGraph.draw() def updateAfter(self, *object): if self.waiting: return else: self.waiting = True self.after_idle(self.update) def update(self, dataFitting=None, xLabel=None, yLabel=None, graphTitle=None, force=False): if (not force) and dataFitting and (self.dataFitting is dataFitting): if (self.method, self.xLabel, self.yLabel, self.noiseLevel) == \ (self.dataFitting.fitFunction, xLabel, yLabel, self.dataFitting.noiseLevel): self.waiting = False return if dataFitting: self.dataFitting = dataFitting self.xLabel = xLabel or self.xLabel self.yLabel = yLabel or self.yLabel self.graphTitle = graphTitle or self.graphTitle if not self.dataFitting: self.waiting = False return else: dataFitting = self.dataFitting dataFitting = self.getXYfunction(dataFitting) if dataFitting.fitFunction is not None: self.method = dataFitting.fitFunction self.noiseLevel = dataFitting.noiseLevel or self.noiseLevel self.updateMethods() isFitted = dataFitting.fit() textMatrix = [] objectList = [] if isFitted and self.method: methodInfo = getFitMethodInfo()[self.method - 1] textFormat, indices = methodInfo[2] textParams = [dataFitting.parameters[i] or 0 for i in indices] equationText = textFormat % tuple(textParams) errorText = '%4f' % dataFitting.fitError x = dataFitting.dataX y = dataFitting.dataY yFit = dataFitting.fittedY N = len(x) err = hasattr(dataFitting, 'dataErr') and dataFitting.dataErr if not err: err = None # wb104: 10 Mar 2014: not sure why the below was here, it isn't needed #if self.method == 10: # x = [sqrt(v) for v in x] data = [(x[i], y[i], yFit[i], y[i] - yFit[i], dataFitting.objects[i], err and err[i]) for i in range(N)] data.sort() for i in range(N): xi, yi, yFiti, deltai, object, erri = data[i] textMatrix.append([i + 1, xi, yi, yFiti, deltai, erri]) objectList.append(object) else: equationText = 'Equation: <No Fit>' errorText = '<None>' x = dataFitting.dataX y = dataFitting.dataY for i, x in enumerate(x): textMatrix.append([i + 1, x, y[i], None, None, None]) objectList.append(dataFitting.objects[i]) self.equationLabel.set('Equation: %s' % equationText) self.errorLabel.set('Fit Error: %s' % errorText) self.scrolledMatrix.update(textMatrix=textMatrix, objectList=objectList) self.updateWindows() self.updateButtons() self.draw() if self.updateFunction: self.updateFunction(dataFitting) self.waiting = False def updateButtons(self): if self.object: self.removeButton.enable() else: self.removeButton.disable()
def body(self, guiFrame): guiFrame.grid_columnconfigure(2, weight=1) row = 0 label = Label(guiFrame, text='Template window: ', grid=(row, 0)) tipText = 'Selects which window to use as the basis for making a new spectrum window; sets the axis types accordingly' self.window_list = PulldownList(guiFrame, grid=(row, 1), callback=self.setAxisTypes, tipText=tipText) frame = LabelFrame(guiFrame, text='Strips', grid=(row, 2), gridSpan=(2, 1)) buttons = UtilityButtonList(guiFrame, doClone=False, helpUrl=self.help_url, grid=(row, 3)) row += 1 label = Label(guiFrame, text='New window name: ', grid=(row, 0)) tipText = 'A short name to identify the spectrum window, which will appear in the graphical interface' self.nameEntry = Entry(guiFrame, width=16, grid=(row, 1), tipText=tipText) row += 1 label = Label(frame, text='Columns: ', grid=(0, 0)) tipText = 'The number of vertical strips/dividers to initially make in the spectrum window' self.cols_menu = PulldownList(frame, objects=STRIP_NUMS, grid=(0, 1), texts=[str(x) for x in STRIP_NUMS], tipText=tipText) label = Label(frame, text='Rows: ', grid=(0, 2)) tipText = 'The number of horizontal strips/dividers to initially make in the spectrum window' self.rows_menu = PulldownList(frame, objects=STRIP_NUMS, grid=(0, 3), texts=[str(x) for x in STRIP_NUMS], tipText=tipText) row += 1 div = LabelDivider(guiFrame, text='Axes', grid=(row, 0), gridSpan=(1, 4)) row += 1 self.axis_lists = {} frame = Frame(guiFrame, grid=(row, 0), gridSpan=(1, 4)) col = 0 self.axisTypes = {} self.axisTypesIncludeNone = {} for label in AXIS_LABELS: self.axisTypes[label] = None w = Label(frame, text=' ' + label) w.grid(row=0, column=col, sticky='w') col += 1 if label in ('x', 'y'): includeNone = False tipText = 'Sets the kind of measurement (typically ppm for a given isotope) that will be used along the window %s axis' % label else: includeNone = True tipText = 'Where required, sets the kind of measurement (typically ppm for a given isotope) that will be used along the window %s axis' % label self.axisTypesIncludeNone[label] = includeNone getAxisTypes = lambda label=label: self.getAxisTypes(label) callback = lambda axisType, label=label: self.changedAxisType( label, axisType) self.axis_lists[label] = PulldownList(frame, callback=callback, tipText=tipText) self.axis_lists[label].grid(row=0, column=col, sticky='w') col += 1 frame.grid_columnconfigure(col, weight=1) row += 1 div = LabelDivider(guiFrame, text='Viewed Spectra', grid=(row, 0), gridSpan=(1, 4)) row += 1 guiFrame.grid_rowconfigure(row, weight=1) editWidgets = [None, None, None, None] editGetCallbacks = [None, self.toggleVisible, self.toggleToolbar, None] editSetCallbacks = [None, None, None, None] tipTexts = [ 'The "experiment:spectrum" name for the spectrum that may be viewed in the new window, given the axis selections', 'Sets whether the spectrum contours will be visible in the new window', 'Sets whether the spectrum appears at all in the window; if not in the toolbar it cannot be displayed', 'The number of peak lists the spectrum contains' ] headingList = ['Spectrum', 'Visible?', 'In Toolbar?', 'Peak Lists'] self.scrolledMatrix = ScrolledMatrix(guiFrame, headingList=headingList, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, multiSelect=True, grid=(row, 0), gridSpan=(1, 4), tipTexts=tipTexts) row += 1 tipTexts = [ 'Creates a new spectrum window with the specified parameters', 'Sets the contours of the selected spectra to be visible when the new window is made', 'Sets the contours of the selected spectra to not be displayed when the new window is made', 'Sets the selected spectra as absent from the window toolbar, and thus not displayable at all' ] texts = [ 'Create Window!', 'Selected\nVisible', 'Selected\nNot Visible', 'Selected\nNot In Toolbar' ] commands = [ self.ok, self.setSelectedDisplay, self.setSelectedHide, self.setSelectedAbsent ] buttonList = ButtonList(guiFrame, texts=texts, grid=(row, 0), commands=commands, gridSpan=(1, 4), tipTexts=tipTexts) buttonList.buttons[0].config(bg='#B0FFB0') self.updateAxisTypes() self.updateWindow() self.updateWindowName() self.administerNotifiers(self.registerNotify) self.updateAfter()
class EditExperimentSeriesPopup(BasePopup): """ **Setup Experiment Series for Chemical Shift and Intensity Changes** The purpose of this popup is to setup ordered groups of experiments that are related by the variation in some condition or parameter, but otherwise the kind of experiment being run is the same. For example the user could setup experiments for a temperature series, ligand binding titration or relaxation rate measurement. The layout is divided into two tables. The upper table shows all of the series that are known to the current project and the lower table shows all of the experiments or planes that comprise the selected series. These series relate to both groups of separate experiments (and hence spectra) and also single experiment where one dimension is not for NMR frequency but rather a "sampled" dimension and thus effectively combines many experiments (e.g. for different T1 values) as different planes. A stack of effectively 2D experiments combined in this manner is typically referred to as pseudo-3D. - The experiment is 3D but there are only two NMR dimensions. Series which are stacks of planes in a single experiment entity are automatically detected and entered into the table once they are loaded. Series that are constructed from multiple, separate experiments however must be setup by the user. To setup a new series of this kind [Add Series] makes a new, empty NMR series. Next the user should change the "Parameter varied" column to specify what type of thing is varied between the different experiments. The user then adds experiments into this series with the [Add Series Point] function at the bottom. Once the points have been added to the series the name of the experiment for each point may be changed. Initially, arbitrary experiments appear for the series points, so these almost always have to be adjusted. Once a stacked-plane experiment or series of experiments is setup, the user next sets (or checks) the value of the parameter associated with each point in the lower table. When loading stacked-plane experiments these values may come though automatically, if they are present in the spectrum header or parameter file. Given a completed NMR series specification the user may then extract the relevant data from the series using one of the analysis tools like `Follow Intensity Changes`_ or `Follow Shift Changes`_. **Caveats & Tips** Make sure the "Parameter Varied" for a given NMR series is appropriate to the type of analysis being performed. Many tools that extract T1 or Kd measurements for example look for specific types of series. The "Set/Unset Ref Plane" function is only used in certain kinds of series such as those that use trains of CPMG pulses. .. _`Follow Intensity Changes`: CalcRatesPopup.html .. _`Follow Shift Changes`: FollowShiftChangesPopup.html """ def __init__(self, parent, *args, **kw): self.guiParent = parent self.expSeries = None self.conditionPoint = None self.waiting = 0 BasePopup.__init__(self, parent, title="Experiment : NMR Series", **kw) def body(self, guiFrame): self.geometry("500x500") self.nameEntry = Entry(self, text='', returnCallback=self.setName, width=12) self.detailsEntry = Entry(self, text='', returnCallback=self.setDetails, width=16) self.valueEntry = FloatEntry(self, text='', returnCallback=self.setValue, width=10) self.errorEntry = FloatEntry(self, text='', returnCallback=self.setError, width=8) self.conditionNamesPulldown = PulldownList(self, callback=self.setConditionName, texts=self.getConditionNames()) self.unitPulldown = PulldownList(self, callback=self.setUnit, texts=self.getUnits()) self.experimentPulldown = PulldownList(self, callback=self.setExperiment) guiFrame.grid_columnconfigure(0, weight=1) row = 0 frame = Frame(guiFrame, grid=(row, 0)) frame.expandGrid(None,0) div = LabelDivider(frame, text='Current Series', grid=(0, 0)) utilButtons = UtilityButtonList(frame, helpUrl=self.help_url, grid=(0,1)) row += 1 frame0 = Frame(guiFrame, grid=(row, 0)) frame0.expandGrid(0,0) tipTexts = ['The serial number of the experiment series, but left blank if the series as actually a pseudo-nD experiment (with a sampled non-frequency axis)', 'The name of the experiment series, which may be a single pseudo-nD experiment', 'The number of separate experiments (and hence spectra) present in the series', 'The kind of quantity that varies for different experiments/planes within the NMR series, e.g. delay time, temperature, ligand concentration etc.', 'The number of separate points, each with a separate experiment/plane and parameter value, in the series'] headingList = ['#','Name','Experiments','Parameter\nVaried','Num\nPoints'] editWidgets = [None, self.nameEntry, None, self.conditionNamesPulldown, None] editGetCallbacks = [None, self.getName, None, self.getConditionName, None] editSetCallbacks = [None, self.setName, None, self.setConditionName, None] self.seriesMatrix = ScrolledMatrix(frame0, tipTexts=tipTexts, editSetCallbacks=editSetCallbacks, editGetCallbacks=editGetCallbacks, editWidgets=editWidgets, headingList=headingList, callback=self.selectExpSeries, deleteFunc=self.deleteExpSeries, grid=(0,0), gridSpan=(None, 3)) tipTexts = ['Make a new, blank NMR series specification in the CCPN project', 'Delete the selected NMR series from the project, although any component experiments remain. Note you cannot delete pseudo-nD series; delete the actual experiment instead', 'Colour the spectrum contours for each experiment in the selected series (not pseudo-nD) using a specified scheme'] texts = ['Add Series','Delete Series', 'Auto Colour Spectra'] commands = [self.addExpSeries,self.deleteExpSeries, self.autoColorSpectra] self.seriesButtons = ButtonList(frame0, texts=texts, commands=commands, grid=(1,0), tipTexts=tipTexts) label = Label(frame0, text='Scheme:', grid=(1,1)) tipText = 'Selects which colour scheme to apply to the contours of (separate) experiments within an NMR series' self.colorSchemePulldown = PulldownList(frame0, grid=(1,2), tipText=tipText) row += 1 div = LabelDivider(guiFrame, text='Experimental Parameters & Conditions', grid=(row, 0)) row += 1 guiFrame.grid_rowconfigure(row, weight=1) frame1 = Frame(guiFrame, grid=(row, 0)) frame1.expandGrid(0,0) tipTexts = ['The kind of experimental parameter that is being used to define the NMR series', 'The experiment that corresponds to the specified parameter value; can be edited from an arbitrary initial experiment', 'The numeric value of the parameter (condition) that relates to the experiment or point in the NMR series', 'The estimated error in value of the condition', 'The measurement unit in which the value of the condition is represented'] headingList = ['Parameter','Experiment','Value','Error','Unit'] editWidgets = [None,self.experimentPulldown,self.valueEntry,self.errorEntry, self.unitPulldown] editGetCallbacks = [None,self.getExperiment, self.getValue, self.getError, self.getUnit] editSetCallbacks = [None,self.setExperiment, self.setValue, self.setError, self.setUnit] self.conditionPointsMatrix = ScrolledMatrix(frame1, grid=(0,0), tipTexts=tipTexts, editSetCallbacks=editSetCallbacks, editGetCallbacks=editGetCallbacks, editWidgets=editWidgets, headingList=headingList, callback=self.selectConditionPoint, deleteFunc=self.deleteConditionPoint) self.conditionPointsMatrix.doEditMarkExtraRules = self.conditionTableShow tipTexts = ['Add a new point to the NMR series with an associated parameter value and experiment', 'Remove the selected point from the series, including any associated parameter value', 'For appropriate kinds of NMR series, set or unset a point as representing the plane to use as a reference'] texts = ['Add Series Point','Delete Series Point','Set/Unset Ref Plane'] commands = [self.addConditionPoint,self.deleteConditionPoint,self.setSampledReferencePlane] self.conditionPointsButtons = ButtonList(frame1, texts=texts, commands=commands, tipTexts=tipTexts, grid=(1,0)) self.updateAfter() self.updateColorSchemes() self.administerNotifiers(self.registerNotify) def administerNotifiers(self, notifyFunc): #for func in ('__init__', 'delete','setName'): for func in ('__init__', 'delete','setName','setConditionNames', 'addConditionName','removeConditionName'): notifyFunc(self.updateAfter,'ccp.nmr.Nmr.NmrExpSeries', func) for func in ('__init__', 'delete','setName'): notifyFunc(self.updateExperiments,'ccp.nmr.Nmr.Experiment', func) for func in ('__init__', 'delete'): notifyFunc(self.updateDataDim,'ccp.nmr.Nmr.SampledDataDim', func) for func in ('__init__', 'delete','setCondition','setUnit','setValue','setError'): notifyFunc(self.updateConditionsAfter,'ccp.nmr.Nmr.SampleCondition', func) for func in ('__init__', 'delete','setCondition'): notifyFunc(self.updateAfter,'ccp.nmr.Nmr.SampleCondition', func) for func in ('setConditionVaried', 'setPointErrors', 'addPointError', 'removePointError', 'setPointValues','addPointValue', 'removePointValue','setUnit'): notifyFunc(self.updateAfter,'ccp.nmr.Nmr.SampledDataDim', func) for func in ('__init__', 'delete'): notifyFunc(self.updateColorSchemes,'ccpnmr.AnalysisProfile.ColorScheme', func) def open(self): self.updateAfter() BasePopup.open(self) def updateColorSchemes(self, scheme=None): index = 0 prevScheme = self.colorSchemePulldown.getObject() schemes = getHueSortedColorSchemes(self.analysisProfile) schemes = [s for s in schemes if len(s.colors) > 1] colors = [list(s.colors) for s in schemes] if schemes: names = [s.name for s in schemes] if prevScheme in schemes: index = schemes.index(prevScheme) else: names = [] self.colorSchemePulldown.setup(names, schemes, index, colors) def autoColorSpectra(self): if self.expSeries and (self.expSeries.className != 'Experiment'): scheme = self.colorSchemePulldown.getObject() if scheme: colors = scheme.colors else: colors = ['#FF0000','#00FF00','#0000FF'] cdict = getNmrExpSeriesSampleConditions(self.expSeries) conditionName = list(self.expSeries.conditionNames)[0] expList = [] for sampleCondition in cdict.get(conditionName, []): expList.append( (sampleCondition.value, sampleCondition.parent.experiments) ) expList.sort() m = len(expList)-1.0 c = len(colors)-1 for i, (value, experiments) in enumerate(expList): p = c*i/m j = int(p) r1, g1, b1 = Color.hexToRgb(colors[j]) r2, g2, b2 = Color.hexToRgb(colors[min(c,j+1)]) f2 = p-j f1 = 1.0-f2 r = (r1*f1)+(r2*f2) g = (g1*f1)+(g2*f2) b = (b1*f1)+(b2*f2) hexColor = Color.hexRepr(r,g,b) for experiment in experiments: for spectrum in experiment.dataSources: if spectrum.dataType == 'processed': analysisSpec = getAnalysisSpectrum(spectrum) if analysisSpec.posColors: analysisSpec.posColors = [hexColor,] elif analysisSpec.negColors: analysisSpec.negColors = [hexColor,] def getUnusedExperiments(self): sampleExperiments = getSampledDimExperiments(self.nmrProject) experiments = [] for experiment in self.nmrProject.sortedExperiments(): if experiment in sampleExperiments: continue if self.expSeries and (self.expSeries.className != 'Experiment'): if experiment in self.expSeries.experiments: continue experiments.append(experiment) return experiments def conditionTableShow(self, object, row, col): if type(object) is type(()): dataDim, index = object refPlane = dataDim.analysisDataDim.refSamplePlane if refPlane == index: return False if col == 1: return False return True def setSampledReferencePlane(self): if self.expSeries and (self.expSeries.className == 'Experiment'): if self.conditionPoint: dataDim, point = self.conditionPoint analysisDataDim = dataDim.analysisDataDim refPoint = analysisDataDim.refSamplePlane if refPoint == point: analysisDataDim.refSamplePlane = None else: analysisDataDim.refSamplePlane = point self.updateAfter() def checkAddSampleCondition(self, experiment): conditionSet = getExperimentConditionSet(experiment) conditionName = self.expSeries.conditionNames[0] condDict = getNmrExpSeriesSampleConditions(self.expSeries) sampleConditions = condDict.get(conditionName, []) units = [sc.unit for sc in sampleConditions if sc.unit] if units: sortList = list(set(units)) sortList.sort(key = lambda u:units.count(u)) unit = sortList[-1] else: unit = CONDITION_UNITS_DICT[conditionName][0] condition = conditionSet.findFirstSampleCondition(condition=conditionName) if not condition: condition = conditionSet.newSampleCondition(condition=conditionName, unit=unit, value=0.0, error=0.0) def addConditionPoint(self): if self.expSeries and (self.expSeries.className != 'Experiment'): experiments = self.getUnusedExperiments() if not experiments: showWarning('Warning','No experiments available', parent=self) return experiment = experiments[0] if experiment not in self.expSeries.experiments: self.expSeries.addExperiment(experiment) self.checkAddSampleCondition(experiment) self.updateAfter() def deleteConditionPoint(self, *event): if self.conditionPoint and (self.expSeries.className != 'Experiment'): if showOkCancel('Confirm','Really delete series point?', parent=self): conditionSet = self.conditionPoint.sampleConditionSet experiments = [e for e in conditionSet.experiments if e in self.expSeries.experiments] for experiment in experiments: self.expSeries.removeExperiment(experiment) for experiment in experiments: for expSeries in experiment.nmrExpSeries: if self.conditionPoint.condition in self.expSeries.conditionNames: break else: continue break else: self.conditionPoint.delete() self.conditionPoint = None def selectConditionPoint(self, object, row, col): if object: self.conditionPoint = object self.updateButtons() def selectExpSeries(self, object, row, col): if object: self.expSeries = object self.checkExperimentConditionsConsistent() self.updateConditions() def checkExperimentConditionsConsistent(self): if self.expSeries.className != 'Experiment': for experiment in self.expSeries.experiments: self.checkAddSampleCondition(experiment) def getUnits(self): units = [] if self.expSeries: if self.expSeries.className == 'Experiment': conditionName = getExperimentSampledDim(self.expSeries).conditionVaried else: conditionName = self.expSeries.conditionNames[0] units = CONDITION_UNITS_DICT.get(conditionName) if not units: units = ['?',] return units def getUnit(self, sampleCondition): index = -1 units = self.getUnits() if units: if sampleCondition: if type(sampleCondition) is type(()): dataDim, index = sampleCondition unit = dataDim.unit else: unit = sampleCondition.unit if unit not in units: unit = units[0] index = units.index(unit) self.unitPulldown.setup(units,units,index) def setUnit(self, obj): name = self.unitPulldown.getObject() if self.conditionPoint: if type(self.conditionPoint) is type(()): dataDim, index = self.conditionPoint dataDim.setUnit(name) else: self.conditionPoint.setUnit(name) def getConditionNames(self): if self.expSeries and (self.expSeries.className == 'Experiment'): names = ['delay time','mixing time','num delays','pulsing frequency','gradient strength'] else: names = CONDITION_UNITS_DICT.keys() names.sort() return names def setConditionName(self, obj): name = self.conditionNamesPulldown.getObject() if self.expSeries: if self.expSeries.className == 'Experiment': dataDim = getExperimentSampledDim(self.expSeries) dataDim.conditionVaried = name else: self.expSeries.setConditionNames([name,]) def getConditionName(self, expSeries): index = 0 names = self.getConditionNames() if names: if expSeries: if expSeries.className == 'Experiment': name = getExperimentSampledDim(expSeries).conditionVaried else: name = expSeries.conditionNames[0] if name: index = names.index(name) else: index = 0 self.conditionNamesPulldown.setup(names,names,index) def getName(self, expSeries): if expSeries : self.nameEntry.set(expSeries.name) def setName(self, event): text = self.nameEntry.get() if text and text != ' ': self.expSeries.setName( text ) def getValue(self, conditionPoint): if conditionPoint: if type(self.conditionPoint) is type(()): dataDim, index = conditionPoint value = dataDim.pointValues[index] else: value = conditionPoint.value self.valueEntry.set(value) def setValue(self, event): value = self.valueEntry.get() if value is not None: if type(self.conditionPoint) is type(()): dataDim, index = self.conditionPoint values = list(dataDim.pointValues) values[index] = value dataDim.setPointValues(values) else: self.conditionPoint.setValue( value ) def getError(self, conditionPoint): if conditionPoint: if type(self.conditionPoint) is type(()): dataDim, index = conditionPoint if index < len(dataDim.pointErrors): error = dataDim.pointValues[index] else: error = 0.0 else: error = conditionPoint.error self.errorEntry.set(error) def setError(self, event): value = self.errorEntry.get() if value is not None: if type(self.conditionPoint) is type(()): dataDim, index = self.conditionPoint pointErrors = dataDim.pointErrors if pointErrors: values = list(pointErrors) else: values = [0.0] * dataDim.numPoints values[index] = value dataDim.setPointErrors(values) else: self.conditionPoint.setError( value ) def getDetails(self, expSeries): if expSeries : self.detailsEntry.set(expSeries.details) def setDetails(self, event): text = self.detailsEntry.get() if text and text != ' ': self.expSeries.setDetails( text ) def addExpSeries(self): expSeries = self.nmrProject.newNmrExpSeries(conditionNames=['delay time',]) def deleteExpSeries(self, *event): if self.expSeries and (self.expSeries.className != 'Experiment'): if showOkCancel('Confirm','Really delete series?', parent=self): self.expSeries.delete() self.expSeries = None self.conditionPoint = None def getExperiments(self): if self.expSeries and (self.expSeries.className == 'Experiment'): return [self.expSeries,] else: return self.nmrProject.sortedExperiments() def getExperiment(self, sampleCondition): index = 0 names = [] if self.conditionPoint and (type(self.conditionPoint) != type(())): index = 0 experiment = self.conditionPoint.parent.findFirstExperiment() experiments = self.getUnusedExperiments() name = experiment.name names = [name] + [e.name for e in experiments] experiments = [experiment,] + experiments self.experimentPulldown.setup(names,experiments,index) def setExperiment(self, obj): experiment = self.experimentPulldown.getObject() if self.conditionPoint and (type(self.conditionPoint) != type(())): conditionSet = getExperimentConditionSet(experiment) if conditionSet is not self.conditionPoint.parent: if experiment not in self.expSeries.experiments: self.expSeries.addExperiment(experiment) unit = self.conditionPoint.unit if not unit: unit = CONDITION_UNITS_DICT[self.expSeries.conditionNames[0]] condition = self.conditionPoint.condition experiments = set(self.expSeries.experiments) for experiment0 in self.conditionPoint.parent.experiments: if experiment0 in experiments: experiments.remove(experiment0) self.expSeries.experiments = experiments value = self.conditionPoint.value error = self.conditionPoint.error self.conditionPoint.delete() self.conditionPoint = conditionSet.findFirstSampleCondition(condition=condition) if self.conditionPoint: self.conditionPoint.unit = unit self.updateAfter() else: self.conditionPoint = conditionSet.newSampleCondition(condition=condition,unit=unit, value=value,error=error) def updateDataDim(self, sampledDataDim): experiment = sampledDataDim.dataSource.experiment self.updateExperiments(experiment) def updateExperiments(self, experiment): experiments = self.getExperiments() names = [e.name for e in experiments] self.experimentPulldown.setup(names, experiments,0) if getExperimentSampledDim(experiment): self.updateAfter() elif self.expSeries: if self.expSeries.className == 'Experiment': if experiment is self.expSeries: self.updateConditionsAfter() elif experiment in self.expSeries.experiments: self.updateConditionsAfter() def updateConditionsAfter(self, sampleCondition=None): if self.waitingConditions: return if sampleCondition: experiments = sampleCondition.sampleConditionSet.experiments for experiment in experiments: if self.expSeries.className == 'Experiment': if experiment is self.expSeries: self.waitingConditions = True self.after_idle(self.updateConditions) break elif experiment in self.expSeries.experiments: self.waitingConditions = True self.after_idle(self.updateConditions) break else: self.waitingConditions = True self.after_idle(self.updateConditions) def updateConditions(self): self.updateButtons() objectList = [] textMatrix = [] colorMatrix = [] nCols = len(self.conditionPointsMatrix.headingList) defaultColors = [None] * nCols if self.expSeries: if self.expSeries.className == 'Experiment': dataDim = getExperimentSampledDim(self.expSeries) analysisDataDim = getAnalysisDataDim(dataDim) conditionVaried = dataDim.conditionVaried expName = self.expSeries.name unit = dataDim.unit pointValues = dataDim.pointValues pointErrors = dataDim.pointErrors refPlane = analysisDataDim.refSamplePlane for i in range(dataDim.numPoints): if i < len(pointErrors): error = pointErrors[i] else: error = None pointText = ':%3d' % (i+1) if i == refPlane: datum = ['* Ref Plane *', expName+pointText, None, None, None] colorMatrix.append(['#f08080'] * nCols) else: datum = [conditionVaried , expName+pointText, pointValues[i], error, unit] colorMatrix.append(defaultColors) textMatrix.append(datum) objectList.append((dataDim, i)) else: condDict = getNmrExpSeriesSampleConditions(self.expSeries) conditionNames = self.expSeries.conditionNames for conditionName in conditionNames: for sampleCondition in condDict.get(conditionName, []): datum = [sampleCondition.condition, ' '.join([e.name for e in sampleCondition.parent.experiments]), sampleCondition.value, sampleCondition.error, sampleCondition.unit] textMatrix.append(datum) objectList.append(sampleCondition) colorMatrix.append(defaultColors) self.conditionPointsMatrix.update(objectList=objectList, colorMatrix=colorMatrix, textMatrix=textMatrix) self.waitingConditions = 0 def updateAfter(self, object=None): if self.waiting: return else: self.waiting = True self.after_idle(self.update) def updateButtons(self): if self.expSeries is None: self.seriesButtons.buttons[1].disable() self.seriesButtons.buttons[2].disable() self.conditionPointsButtons.buttons[0].disable() self.conditionPointsButtons.buttons[1].disable() self.conditionPointsButtons.buttons[2].disable() elif self.expSeries.className == 'Experiment': self.seriesButtons.buttons[1].disable() self.seriesButtons.buttons[2].disable() self.conditionPointsButtons.buttons[0].disable() self.conditionPointsButtons.buttons[1].disable() self.conditionPointsButtons.buttons[2].enable() else: self.seriesButtons.buttons[1].enable() self.seriesButtons.buttons[2].enable() self.conditionPointsButtons.buttons[0].enable() self.conditionPointsButtons.buttons[2].disable() if self.conditionPoint is None: self.conditionPointsButtons.buttons[1].disable() else: self.conditionPointsButtons.buttons[1].enable() def update(self): self.updateButtons() objectList = [] textMatrix = [] for experiment in getSampledDimExperiments(self.nmrProject): getExperimentConditionSet(experiment) sampledDim = getExperimentSampledDim(experiment) datum = [None, experiment.name, 1, sampledDim.conditionVaried, sampledDim.numPoints] textMatrix.append(datum) objectList.append(experiment) for expSeries in self.nmrProject.sortedNmrExpSeries(): experiments = expSeries.experiments conditionSets = len([e.sampleConditionSet for e in experiments if e.sampleConditionSet]) datum = [expSeries.serial, expSeries.name or ' ', len(experiments), ','.join(expSeries.conditionNames), conditionSets] textMatrix.append(datum) objectList.append(expSeries) self.seriesMatrix.update(objectList=objectList, textMatrix=textMatrix) self.updateConditions() self.waiting = False def destroy(self): self.administerNotifiers(self.unregisterNotify) BasePopup.destroy(self)
def body(self, guiFrame): '''This method describes the outline of the body of the application. args: guiFrame: frame the body should live in. ''' self.geometry('800x530') guiFrame.grid_columnconfigure(0, weight=1) guiFrame.grid_rowconfigure(0, weight=0) guiFrame.grid_rowconfigure(1, weight=2) guiFrame.grid_rowconfigure(2, weight=1) isotopeFrame = LabelFrame(guiFrame, text='Isotope Shift Correction CA and CB') isotopeFrame.grid(row=0, column=0, sticky='nsew') frameA = LabelFrame(guiFrame, text='Spin Systems') frameA.grid(row=1, column=0, sticky='nsew') frameA.grid_rowconfigure(0, weight=1) frameA.grid_columnconfigure(0, weight=1) frameA.grid_columnconfigure(1, weight=1) frameA1 = LabelFrame(frameA, text='Spin System 1') frameA1.grid(row=0, column=0, sticky='nsew') frameA1.grid_columnconfigure(0, weight=1) frameA1.grid_rowconfigure(0, weight=1) frameA2 = LabelFrame(frameA, text='Spin System 2') frameA2.grid(row=0, column=1, sticky='nsew') frameA2.grid_columnconfigure(0, weight=1) frameA2.grid_rowconfigure(0, weight=1) frameB = LabelFrame(guiFrame, text='Comparison') frameB.grid(row=2, column=0, sticky='nsew') frameB.grid_rowconfigure(0, weight=1) frameB.grid_columnconfigure(0, weight=1) frameB.grid_columnconfigure(1, weight=2) frameB.grid_columnconfigure(2, weight=1) frameB1 = LabelFrame(frameB, text='Unique to Spin System 1') frameB1.grid(row=0, column=0, sticky='nsew') frameB1.expandGrid(0, 0) frameB2 = LabelFrame(frameB, text='Intersection') frameB2.grid(row=0, column=1, sticky='nsew') frameB2.expandGrid(0, 0) frameB3 = LabelFrame(frameB, text='Unique to Spin System 2') frameB3.grid(row=0, column=2, sticky='nsew') frameB3.expandGrid(0, 0) # Settings for isotope shift correction shiftLists = getShiftLists(self.nmrProject) self.protonatedShiftList = shiftLists[0] self.deuteratedShiftList = shiftLists[1] shiftListNames = ['{}: {}'.format(shiftList.serial, shiftList.name) for shiftList in shiftLists] Label(isotopeFrame, text='Correct for isotope shift:', grid=(0, 0)) self.correctCheck = CheckButton(isotopeFrame, selected=True, callback=self.setCorrection, grid=(0, 1)) Label(isotopeFrame, text='Protonated shift list:', grid=(1, 0)) self.protonatedPulldown = PulldownList(isotopeFrame, callback=self.setProtonatedShiftList, texts=shiftListNames, objects=shiftLists, grid=(1, 1), index=0) Label(isotopeFrame, text='Deuterated shift list:', grid=(2, 0)) self.deuteratedPulldown = PulldownList(isotopeFrame, callback=self.setDeuteratedShiftList, texts=shiftListNames, objects=shiftLists, grid=(2, 1), index=1) # Table A1 headingList = ['#', 'shift lists', 'Assignment'] tipTexts = ['Spin System Serial', 'shift lists', 'The residue (tentatively) assigned to this spin system', 'The amount of spin systems that overlap with this spin system and have no violations'] editGetCallbacks = [self.setSpinSystem1]*3 editSetCallbacks = [None]*3 self.tableA1 = ScrolledMatrix(frameA1, headingList=headingList, multiSelect=False, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, tipTexts=tipTexts) self.tableA1.grid(row=0, column=0, sticky='nsew') # Table A2 headingList = ['#', 'shift lists', 'Assignment', 'offset'] tipTexts = ['Spin System Serial', 'The residue (tentatively) assigned to this spin system', 'Root mean squared deviation of this spin system to the spin system selected in the table on the left.'] editGetCallbacks = [self.setSpinSystem2]*4 editSetCallbacks = [None]*4 self.tableA2 = ScrolledMatrix(frameA2, headingList=headingList, #editWidgets=editWidgets, multiSelect=False, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks, tipTexts=tipTexts) self.tableA2.grid(row=0, column=0, sticky='nsew') # Table B1 headingList = ['atom', 'c.s.'] tipTexts = ['atom', 'chemical shift'] self.tableB1 = ScrolledMatrix(frameB1, headingList=headingList, multiSelect=False, tipTexts=tipTexts) self.tableB1.grid(row=0, column=0, sticky='nsew') # Table B 2 headingList = ['atom', 'c.s. 1', 'c.s. 2', 'delta c.s.'] tipTexts = ['name of the atom', 'chemical shift of atom with this name in spin system 1', 'chemical shift of atom with this name in spin system 2', 'difference between the chemical shift of spin systems 1 and 2'] self.tableB2 = ScrolledMatrix(frameB2, headingList=headingList, tipTexts=tipTexts) self.tableB2.grid(row=0, column=0, sticky='nsew') # Table B 3 headingList = ['atom', 'c.s.'] tipTexts = ['atom', 'chemical shift.'] self.tableB3 = ScrolledMatrix(frameB3, headingList=headingList, multiSelect=False, tipTexts=tipTexts) self.tableB3.grid(row=0, column=0, sticky='nsew') self.matchMatrix = {} self.amountOfMatchesPerSpinSystem = {} self.updateTableA1()
class SecStructurePredictPopup(BasePopup): """ **Predict Protein Secondary Structure** This popup window is designed to allow the prediction of secondary structure for a protein chain given chemical shifts, using the (external) program D2D. The Options to select are the Chain and the Shift List, for which the prediction is then made. The Secondary Structure Predictions table lists the residues in the chain. For each residue the residue number, residue type and current secondary structure set for that residue is given. The remaining columns are for the predictions made by D2D, and of course are only filled in once D2D is run. The predicted secondary structure is listed first, followed by the probability of that residue being Helix, Beta, Coil or PPII (the predicted secondary structure will be specified by the maximum of these). To run the prediction click on the "Run D2D Prediction!" button. This does not store this information in the project. To do that you have to click on the "Commit Predicted Secondary Structure" button. **Caveats & Tips** The predicted secondary structure cell is coloured red if the prediction is unreliable. Unreliable predictions are not stored with the "Commit" button but all reliable ones are. If you need to edit the secondary structure for a residue then use the Secondary Structure Chart: .. _Secondary Structure Chart: SecStructureGraphPopup.html **References** The D2D programme: http://www-vendruscolo.ch.cam.ac.uk/d2D/index.php *C. Camilloni, A. De Simone, W. Vranken and M. Vendruscolo. Determination of Secondary Structure Populations in Disordered States of Proteins using NMR Chemical Shifts. Biochemistry 2012, 51: 2224-2231 """ def __init__(self, parent, *args, **kw): self.chain = None self.shiftList = None self.predictionDict = {} BasePopup.__init__(self, parent=parent, title='Structure : Predict Secondary Structure') def body(self, guiFrame): self.geometry('700x500') guiFrame.expandGrid(1, 0) row = 0 # TOP LEFT FRAME frame = LabelFrame(guiFrame, text='Options') frame.grid(row=row, column=0, sticky='nsew') frame.columnconfigure(5, weight=1) label = Label(frame, text='Chain') label.grid(row=0, column=0, sticky='w') self.chainPulldown = PulldownList( frame, callback=self.changeChain, tipText='Choose the molecular system chain to make predictions for' ) self.chainPulldown.grid(row=0, column=1, sticky='w') label = Label(frame, text='Shift List') label.grid(row=0, column=2, sticky='w') self.shiftListPulldown = PulldownList( frame, callback=self.changeShiftList, tipText='Select the shift list to take input chemical shifts from') self.shiftListPulldown.grid(row=0, column=3, sticky='w') row += 1 # BOTTOM LEFT FRAME frame = LabelFrame(guiFrame, text='Secondary Structure Predictions') frame.grid(row=row, column=0, sticky='nsew') frame.grid_columnconfigure(0, weight=1) frame.grid_rowconfigure(0, weight=1) tipTexts = ('Residue number in chain', 'Residue type code', 'Current stored secondary structure code', 'Predicted secondary structure code') + SEC_STRUC_TIPS headingList = ('Res\nNum', 'Res\nType', 'Current\nSS', 'Predicted\nSS') + SEC_STRUC_KEYS n = len(headingList) editWidgets = n * [None] editGetCallbacks = n * [None] editSetCallbacks = n * [None] self.predictionMatrix = ScrolledMatrix( frame, headingList=headingList, tipTexts=tipTexts, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks) self.predictionMatrix.grid(row=0, column=0, sticky='nsew') row += 1 tipTexts = [ 'Run the D2D method to predict secondary structure', 'Store the secondary structure predictions in the CCPN project' ] texts = [ 'Run D2D Prediction!', 'Commit Predicted\nSecondary Structure' ] commands = [self.runD2D, self.storeSecondaryStructure] self.buttonList = createDismissHelpButtonList(guiFrame, texts=texts, commands=commands, help_url=self.help_url, expands=True, tipTexts=tipTexts) self.buttonList.grid(row=row, column=0, columnspan=2, sticky='ew') self.update() self.notify(self.registerNotify) def destroy(self): self.notify(self.unregisterNotify) BasePopup.destroy(self) def notify(self, notifyfunc): for func in ('__init__', 'delete'): notifyfunc(self.updateChainPulldown, 'ccp.molecule.MolSystem.Chain', func) for func in ('__init__', 'delete', 'setName'): notifyfunc(self.updateShiftListPulldown, 'ccp.nmr.Nmr.ShiftList', func) for func in ('setSecStrucCode', ): notifyfunc(self.updatePredictionMatrixAfter, 'ccp.nmr.Nmr.ResonanceGroup', func) def update(self): self.updateShiftListPulldown() self.updateChainPulldown() self.updatePredictionMatrixAfter() def runD2D(self): chain = self.chain shiftList = self.shiftList if (not chain) or (not shiftList): showError('Cannot Run D2D', 'Please specify a chain and a shift list.', parent=self) return self.predictionDict[chain] = runD2D(chain, shiftList) self.updatePredictionMatrix() def storeSecondaryStructure(self): if not self.chain: return getSpinSystem = self.nmrProject.findFirstResonanceGroup newSpinSystem = self.nmrProject.newResonanceGroup predDict = self.predictionDict.get(self.chain, {}) n = 0 for residue in predDict: (ssCode, isReliable, probabilityDict) = predDict[residue] if isReliable: spinSystem = getSpinSystem(residue=residue) if not spinSystem: spinSystem = newSpinSystem(residue=residue, ccpCode=residue.ccpCode) spinSystem.secStrucCode = ssCode n += 1 showInfo('Info', 'Stored secondary structure types for %d residues.' % n, parent=self) def updatePredictionMatrixAfter(self, index=None, text=None): self.after_idle(self.updatePredictionMatrix) def updatePredictionMatrix(self): objectList = [] textMatrix = [] colorMatrix = [] n = len(SEC_STRUC_KEYS) chain = self.chain if chain: predDict = self.predictionDict.get(chain, {}) getSpinSystem = self.nmrProject.findFirstResonanceGroup for residue in chain.sortedResidues(): spinSystem = getSpinSystem(residue=residue) currentSsCode = spinSystem and spinSystem.secStrucCode data = [residue.seqCode, residue.ccpCode, currentSsCode] colors = 3 * [None] if residue in predDict: (ssCode, isReliable, probabilityDict) = predDict[residue] data.append(ssCode) if isReliable: colors.append(None) else: colors.append('#FF3333') for key in SEC_STRUC_KEYS: data.append(probabilityDict[key]) colors.extend(n * [None]) else: data.extend((n + 1) * [None]) colors.extend((n + 1) * [None]) textMatrix.append(data) objectList.append(residue) colorMatrix.append(colors) self.predictionMatrix.update(textMatrix=textMatrix, objectList=objectList, colorMatrix=colorMatrix) def changeChain(self, chain): if chain is not self.chain: self.chain = chain self.updatePredictionMatrixAfter() def changeShiftList(self, shiftList): if shiftList is not self.shiftList: self.shiftList = shiftList self.updatePredictionMatrixAfter() def updateChainPulldown(self, obj=None): index = 0 names = [] chains = [] chain = self.chain for molSystem in self.project.molSystems: msCode = molSystem.code for chainA in molSystem.chains: residues = chainA.residues if not residues: continue for residue in residues: # Must have at least one protein residue if residue.molType == 'protein': names.append('%s:%s' % (msCode, chainA.code)) chains.append(chainA) break if chains: if chain not in chains: chain = chains[0] index = chains.index(chain) else: chain = None if chain is not self.chain: self.chain = chain self.updatePredictionMatrixAfter() self.chainPulldown.setup(names, chains, index) def updateShiftListPulldown(self, obj=None): index = 0 names = [] shiftLists = getShiftLists(self.nmrProject) if shiftLists: if self.shiftList not in shiftLists: self.shiftList = shiftLists[0] index = shiftLists.index(self.shiftList) names = ['%s:%d' % (sl.name, sl.serial) for sl in shiftLists] else: self.shiftList = None self.shiftListPulldown.setup(names, shiftLists, index)
def __init__(self, parent, project, path = None, molTypeEntries = None, chemCompEntries = None, selectedChemComps = None, selectLinking = None, *args, **kw): Frame.__init__(self, parent, *args, **kw) self.project = project self.molTypeEntries = molTypeEntries self.chemCompEntries = chemCompEntries self.selectLinking = selectLinking if (not path): path = getDataPath() self.path = path # Check if all chemComps available locally self.path_allChemComps = getChemCompArchiveDataDir() if not os.path.exists(self.path_allChemComps): self.path_allChemComps = None self.chemCompInfoDict = {} self.chemCompInfoList = [] self.chemCompDownload = False self.chem_comps_shown = {} for entry in chemCompList: self.chemCompClasses[entry] = getattr(ccp.api.molecule.ChemComp, entry) self.grid_columnconfigure(0, weight=1) row = 0 if (molTypeEntries is None): headerText = "Show residues (select molecular type(s)):" else: headerText = "Show %s residues:" % (str(molTypeEntries)) # # # TODO TODO: HERE need to do some niftier stuff for displaying! # # headerTextWidget = Label(self, text = headerText) headerTextWidget.grid(row=row, column=0, sticky=Tkinter.W) row = row + 1 if (molTypeEntries is None): self.mol_type_buttons = CheckButtons(self, entries=molTypeList, select_callback=self.updateTables) self.mol_type_buttons.grid(row=row, column=0, sticky=Tkinter.EW) row = row + 1 else: self.mol_type_buttons = None # # The chemComps to display... # self.showLocalText = 'Show local' self.showWebText = 'Show available via web' self.display_buttons = CheckButtons(self, entries=[self.showLocalText,self.showWebText], select_callback=self.updateTables, selected = [self.showLocalText]) self.display_buttons.grid(row=row, column=0, sticky=Tkinter.EW) row = row + 1 self.grid_rowconfigure(row, weight=2) headings = ('number', 'show details', 'molType', 'ccpCode', 'code1Letter', 'cifCode', 'name') editWidgets = 7 * [ None ] editGetCallbacks = [ None, self.toggleShow, None, None, None, None, None ] editSetCallbacks = 7 * [ None ] self.chem_comp_table = ScrolledMatrix(self, headingList=headings, editWidgets=editWidgets, editGetCallbacks=editGetCallbacks, editSetCallbacks=editSetCallbacks) self.chem_comp_table.grid(row=row, column=0, sticky=Tkinter.NSEW) row = row + 1 texts = [ 'Show all in details window', 'Clear details window' ] commands = [ self.showAll, self.showNone ] buttons = ButtonList(self, texts=texts, commands=commands) buttons.grid(row=row, column=0, sticky=Tkinter.EW) row = row + 1 separator = Separator(self,height = 3) separator.setColor('black', bgColor = 'black') separator.grid(row=row, column=0, sticky=Tkinter.EW) row = row + 1 headerTextWidget = Label(self, text = "Select the residue variant:") headerTextWidget.grid(row=row, column=0, sticky=Tkinter.W) row = row + 1 if (chemCompEntries is None): self.chem_comp_buttons = CheckButtons(self, entries=chemCompList, selected=('ChemComp',), select_callback=self.updateChemCompVarTable) self.chem_comp_buttons.grid(row=row, column=0, sticky=Tkinter.EW) row = row + 1 else: self.chem_comp_buttons = None self.grid_rowconfigure(row, weight=1) headings = ('number', 'molType', 'ccpCode', 'linking', 'descriptor', 'molecularMass', 'formula', 'nonStereoSmiles', 'stereoSmiles') self.chem_comp_var_table = ScrolledMatrix(self, headingList=headings) self.chem_comp_var_table.grid(row=row, column=0, sticky=Tkinter.NSEW) self.chem_comp_var_headings = headings[1:] if selectedChemComps: for chemComp in selectedChemComps: key = (chemComp.molType, chemComp.ccpCode) self.chem_comps_shown[key] = 1 self.updateTables()