class AutoAssignIOCyclePopup(BasePopup): help_url = joinPath(getHelpUrlDir(), 'AutoAssignIOCycle.html') def __init__(self, parent, project): self.project = project self.guiParent = parent self.autoAssignFormat = AutoAssignFormat(project, guiParent=parent) self.format = 'autoAssign' self.chainStampSep = '-' self.dateTimeFlag = time.strftime("%Y%m%d.%H:%M") self.getPreviousDateTimeStamps() self.getChainsAndChainStamps() self.importFileName = self.exportFileName = None BasePopup.__init__(self, parent=parent, title="Project '%s': " % project.name + 'AutoAssign export/import cycle.', modal=True, transient=True) def getPreviousDateTimeStamps(self): self.dateTimeStamps = [] appData = self.project.findAllApplicationData(application=self.format, keyword=dateTimeStamp_kw) for appDatum in appData: self.dateTimeStamps.append(appDatum.value) def getChainsAndChainStamps(self): self.chains = [] self.chainDateTimeStamps = [] self.chainDateTimeStampDict = {} for molSys in self.project.sortedMolSystems(): for chain in molSys.sortedChains(): self.chains.append(chain) appData = chain.findFirstApplicationData( application=self.format, keyword=dateTimeStamp_kw) if appData and appData.value in self.dateTimeStamps: (tlist, tdict) = createSelection([chain]) cdtsTag = "%s%s%s" % (tlist[0], self.chainStampSep, appData.value) self.chainDateTimeStamps.append(cdtsTag) self.chainDateTimeStampDict[cdtsTag] = chain def body(self, master): self.geometry('600x400') # # Quick check # if not self.chains: showError("No chains", "No chains available - cannot use export/import cycle.") self.destroy() # # Set it all up # columnspan = 2 row = 0 label = Label(master, text="AutoAssign export/import cycle.") label.grid(row=row, column=0, columnspan=columnspan, sticky=Tkinter.EW) row += 1 separator = Separator(master, height=3) separator.setColor('black', bgColor='black') separator.grid(row=row, column=0, columnspan=columnspan, sticky=Tkinter.EW) row += 1 label = Label( master, fg='red', text= "Popup to export %s data from the CCPN data model,\nrun %s, then re-import the output." % (self.format, self.format)) label.grid(row=row, column=0, columnspan=columnspan, sticky=Tkinter.EW) # # Make a break... # row += 1 separator = Separator(master, height=3) separator.setColor('black', bgColor='black') separator.grid(row=row, column=0, columnspan=columnspan, sticky=Tkinter.EW) # # Set up export file info # row += 1 label = Label(master, text="Export menu (using date/time label '%s')" % self.dateTimeFlag) label.grid(row=row, column=0, columnspan=columnspan, sticky=Tkinter.EW) row += 1 (chainList, self.chainDict) = createSelection(self.chains) label = Label(master, text="Select chain to export:") label.grid(row=row, column=0, sticky=Tkinter.W) self.chainSelect = PulldownMenu(master, entries=chainList) self.chainSelect.grid(row=row, column=1, sticky=Tkinter.W) row += 1 label = Label(master, text="Export %s project file:" % self.format) label.grid(row=row, column=0, sticky=Tkinter.W) self.selectExportFileButton = Tkinter.Button( master, text='Select export file', command=(lambda: self.selectExportProjectFile())) self.selectExportFileButton.grid(row=row, column=1, sticky=Tkinter.W) row += 1 self.exportButton = Tkinter.Button(master, text='Export', command=(lambda: self.doExport())) self.exportButton.grid(row=row, column=0, columnspan=columnspan, sticky=Tkinter.EW) # # Make a break... # row += 1 separator = Separator(master, height=3) separator.setColor('black', bgColor='black') separator.grid(row=row, column=0, columnspan=columnspan, sticky=Tkinter.EW) # # Set up import file info # row += 1 label = Label(master, text="Re-import menu") label.grid(row=row, column=0, columnspan=columnspan, sticky=Tkinter.EW) row += 1 # # Select the right chain with the right date/time flag... # label = Label(master, text="Select chain with correct date/time flag:") label.grid(row=row, column=0, sticky=Tkinter.W) self.chainDateTimeSelect = PulldownMenu( master, entries=self.chainDateTimeStamps) self.chainDateTimeSelect.grid(row=row, column=1, sticky=Tkinter.W) # TODO UPDATE THIS WHEN EXPORT BUTTON PRESSED AND GETTING OK FROM EXPORT ITSELF! # Probably also need just a message if no importDateTimeStamp available... row += 1 label = Label(master, text="Import %s output file:" % self.format) label.grid(row=row, column=0, sticky=Tkinter.W) self.selectImportFileButton = Tkinter.Button( master, text='Select import file', command=(lambda: self.selectImportShiftFile())) self.selectImportFileButton.grid(row=row, column=1, sticky=Tkinter.W) row += 1 self.importButton = Tkinter.Button(master, text='Import', command=(lambda: self.doImport())) self.importButton.grid(row=row, column=0, columnspan=columnspan, sticky=Tkinter.EW) # # Make a break... # row += 1 separator = Separator(master, height=3) separator.setColor('black', bgColor='black') separator.grid(row=row, column=0, columnspan=columnspan, sticky=Tkinter.EW) row += 1 buttons = createDismissHelpButtonList(master, texts=[], commands=[], help_url=self.help_url) buttons.grid(row=row, columnspan=columnspan, column=0) def selectExportProjectFile(self): if self.exportFileName: fileName = self.exportFileName else: fileName = 'table.aat' popup = FormatFilePopup( self, file=fileName, component='project', format=self.format, title='Select name for %s project file to export.' % self.format) if popup.fileSelected: self.selectExportFileButton.config(text=popup.file) self.exportFileName = popup.file def selectImportShiftFile(self): if self.exportFileName: fileName = self.exportFileName else: fileName = 'autoAssign.out' popup = FormatFilePopup( self, file=fileName, component='shifts', format=self.format, title='Select name for %s output file to re-import.' % self.format) if popup.fileSelected: self.selectImportFileButton.config(text=popup.file) self.importFileName = popup.file def doExport(self): if self.exportFileName: chain = self.chainDict[self.chainSelect.getSelected()] returnValue = self.autoAssignFormat.writeProject( self.exportFileName, chain=chain, setTag=self.dateTimeFlag) if not returnValue: showError( "No export file written", "There were problems while exporting the %s project file." % self.format) else: showInfo("File written", "File written successfully") cdtsTag = "%s-%s" % (self.chainSelect.getSelected(), self.dateTimeFlag) if not cdtsTag in self.chainDateTimeSelect.entries: if "<None>" in self.chainDateTimeSelect.entries: self.chainDateTimeSelect.entries.pop( self.chainDateTimeSelect.entries.index("<None>")) self.chainDateTimeSelect.replace( [cdtsTag] + self.chainDateTimeSelect.entries) self.chainDateTimeStampDict[cdtsTag] = chain else: showError( "No export file defined", "Please define a name for the %s project file to export to." % self.format) def doImport(self): if self.importFileName: cdtsTag = self.chainDateTimeSelect.getSelected() if not self.chainDateTimeStampDict.has_key(cdtsTag): showError( "No import tag defined", "No chain with date/time stamp defined - cannot re-import." ) else: chain = self.chainDateTimeStampDict[cdtsTag] (chainText, curDateTimeStamp) = cdtsTag.split(self.chainStampSep) # # Get relevant info from data model (not immediately necessary but as example) # # Note that could in principle use the normal peakNum tag, but dangerous in case # multiple exports were done... this is more laborious though. # peakLists = [] rootPeakListTag = str((curDateTimeStamp, 'isRoot')) rootPeakNumToPeak = {} for nmrExp in self.project.currentNmrProject.sortedExperiments( ): for ds in nmrExp.sortedDataSources(): for peakList in ds.sortedPeakLists(): appData = peakList.findAllApplicationData( application=self.format, keyword=dateTimeStamp_kw) for appDatum in appData: if appDatum and appDatum.value == curDateTimeStamp: peakLists.append(peakList) if peakList.findFirstApplicationData( application=self.format, keyword=ioCycleTag_kw, value=rootPeakListTag): for peak in peakList.sortedPeaks(): appData = peak.findFirstApplicationData( application=self.format, keyword=ioCycleTag_kw) if appData: (curTag, peakNum) = eval(appData.value) if curTag == curDateTimeStamp: rootPeakNumToPeak[ peakNum] = peak # # Now get the actual chemical shift info from the AutoAssign output file # autoAssignChemShiftFile = AutoAssignChemShiftFile( self.importFileName) autoAssignChemShiftFile.read() # # Set the mapping between the chain residues and the seqCode in the chem shift file # residues = list(chain.sortedResidues()) seqCodeToResidue = {} for i in range(0, len(residues)): residue = residues[i] (seqCode, code1Letter) = autoAssignChemShiftFile.seqCodes[i] seqCode = returnInt(seqCode) seqCodeToResidue[seqCode] = residue for rawChemShift in autoAssignChemShiftFile.chemShifts: peak = None residue = None prevResidue = None seqCode = rawChemShift.seqCode atomName = rawChemShift.atomName #allValues = rawChemShift.allValues #rawChemShift.spinSystemId if seqCodeToResidue.has_key(seqCode): residue = seqCodeToResidue[seqCode] else: # THIS SHOULD NEVER HAPPEN! print " Error: no match for seqCode %d while re-importing project." % seqCode continue # # Set info on residue/atom level # atom = self.findMatchingAtom(residue, atomName) self.autoAssignFormat.setSeqAssignTag( atom, rawChemShift.value, AppDataClass=Implementation.AppDataFloat) # # Set info on peak level # if rawChemShift.peakId: (peakNum, rootName) = rawChemShift.peakId.split( '.') # TODO set this somewhere? peakNum = returnInt(peakNum) if rootPeakNumToPeak.has_key(peakNum): peak = rootPeakNumToPeak[peakNum] self.autoAssignFormat.setSeqAssignTag( peak, str((chain.code, residue.seqId))) else: showError( "No import file defined", "Please define a name for the %s shift output file to import." % self.format) def findMatchingAtom(self, residue, atomName): atom = residue.findFirstAtom(name=atomName) if not atom: # Rough search but should be OK for bb atoms namingSystem = residue.chemCompVar.chemComp.findFirstNamingSystem( name='XPLOR') chemAtomSysName = findChemAtomSysName(namingSystem, {'sysName': atomName}) atom = residue.findFirstAtom(name=chemAtomSysName.atomName) return atom def apply(self): if not 0: showError("No root spectrum", "Can't continue: need a root spectrum...") return False return True
class RegionSelector(Frame): def __init__(self, parent, label='', world_region=None, view_region=None, orient=Tkinter.HORIZONTAL, allow_resize=True, width=20, callback=None, borderwidth=1, show_text=True, text_color='#000000', text_decimals=2, units_scroll=0.1, pages_scroll=1.0, menu_entries=None, menu_callback=None, min_thickness=None, *args, **kw): self.menu_entries = menu_entries self.myCallback = callback Frame.__init__(self, parent, *args, **kw) self.text_decimals = text_decimals self.label = Label(self, text=label, width=4) self.menu = PulldownMenu(self, callback=menu_callback, entries=menu_entries) self.entry = FloatEntry(self, width=6, returnCallback=self.adjustScrollbar) self.region_scrollbar = RegionScrollbar(self, world_region=world_region, view_region=view_region, orient=orient, allow_resize=allow_resize, width=width, callback=self.doCallback, borderwidth=borderwidth, show_text=show_text, text_color=text_color, text_decimals=text_decimals, units_scroll=units_scroll, pages_scroll=pages_scroll, min_thickness=min_thickness) self.gridAll() def gridAll(self): col = 0 if (self.menu_entries and len(self.menu_entries) > 1): self.menu.grid(row=0, column=col, sticky=Tkinter.EW) col = col + 1 else: self.menu.grid_forget() self.label.grid(row=0, column=col, sticky=Tkinter.EW) col = col + 1 self.entry.grid(row=0, column=col, sticky=Tkinter.EW) self.grid_columnconfigure(col, weight=0) col = col + 1 self.region_scrollbar.grid(row=0, column=col, sticky=Tkinter.NSEW) self.grid_columnconfigure(col, weight=1) col = col + 1 self.grid_columnconfigure(col, weight=0) def setMinThickness(self, min_thickness): self.region_scrollbar.setMinThickness(min_thickness) def setMenuEntries(self, menu_entries): self.menu_entries = menu_entries self.menu.replace(menu_entries) self.gridAll() def getMenuEntry(self): return self.menu.getSelected() def adjustScrollbar(self, *event): try: x = float(self.entry.get()) except: showError('Entry error', 'Need to enter float in scrollbar box') self.setEntry() return (v0, v1) = self.region_scrollbar.view_region d = 0.5 * (v1 - v0) self.region_scrollbar.setViewRegion(x - d, x + d, do_callback=True) def doCallback(self, view_region): if (self.myCallback): self.myCallback(view_region) #print 'doCallback', view_region self.setEntry(view_region) def setEntry(self, view_region=None): if (not view_region): view_region = self.region_scrollbar.view_region (v0, v1) = view_region x = 0.5 * (v0 + v1) s = formatDecimals(x, decimals=self.text_decimals) self.entry.set(s) def __getattr__(self, name): # dispatch everything not defined by RegionSelector to scrollbar widget try: return getattr(self.__dict__['region_scrollbar'], name) except: raise AttributeError, "RegionSelector instance has no attribute '%s'" % name
class HelpFrame(Frame): def __init__(self, parent, width=70, height=20, xscroll=False, yscroll=True, *args, **kw): apply(Frame.__init__, (self, parent) + args, kw) self.grid_columnconfigure(1, weight=1) row = 0 texts = ('back', 'forward', 'load') commands = (self.prevUrl, self.nextUrl, self.loadUrl) self.buttons = ButtonList(self, texts=texts, commands=commands) self.buttons.grid(row=row, column=0) self.url_entry = Entry(self, returnCallback=self.loadUrl) self.url_entry.grid(row=row, column=1, columnspan=2, sticky=Tkinter.EW) row = row + 1 frame = Frame(self) frame.grid(row=row, column=0, columnspan=3, sticky=Tkinter.W) self.createFindFrame(frame) row = row + 1 self.grid_rowconfigure(row, weight=1) self.help_text = ScrolledHtml(self, width=width, height=height, xscroll=xscroll, yscroll=yscroll, startUrlCallback=self.startOpenUrl, endUrlCallback=self.endOpenUrl, enterLinkCallback=self.setLinkLabel, leaveLinkCallback=self.setLinkLabel) self.help_text.grid(row=row, column=0, columnspan=3, sticky=Tkinter.NSEW) row = row + 1 self.link_label = Label(self) self.link_label.grid(row=row, column=0, columnspan=2, sticky=Tkinter.W) button = memops.gui.Util.createDismissButton(self, dismiss_cmd=self.close) button.grid(row=row, column=2) self.urls = [] self.current = -1 self.updateUrlList = True self.setButtonState() def close(self): if (self.popup): if (self.popup.modal): self.popup.do_grab() popup = self.parent while (not hasattr(popup, 'top')): popup = popup.parent popup.close() def createFindFrame(self, master): frame = Frame(master) frame.grid(row=0, column=0, sticky=Tkinter.W) arrow = ToggleArrow(frame, callback=self.toggleFindFrame) arrow.grid(row=0, column=0) button = Button(frame, text='find:', command=self.findPhrase) button.grid(row=0, column=1) self.find_entry = Entry(frame, width=20, returnCallback=self.findPhrase) self.find_entry.grid(row=0, column=2) self.find_frame = frame = Frame(master) entries = ('search forwards', 'search backwards') self.direction_buttons = PulldownMenu(frame, entries=entries) self.direction_buttons.grid(row=0, column=0, sticky=Tkinter.W, padx=5) self.forwards_entries = entries = ('wrap search', 'stop at end') self.backwards_entries = ('wrap search', 'stop at beginning') self.wrap_buttons = PulldownMenu(frame, entries=entries) self.wrap_buttons.grid(row=0, column=1, sticky=Tkinter.W, padx=5) self.direction_buttons.callback = self.setWrapText entries = ('case insensitive', 'case sensitive') self.case_buttons = PulldownMenu(frame, entries=entries) self.case_buttons.grid(row=0, column=2, sticky=Tkinter.W, padx=5) entries = ('literal search', 'regex search') self.pattern_buttons = PulldownMenu(frame, entries=entries) self.pattern_buttons.grid(row=0, column=3, sticky=Tkinter.W, padx=5) self.countVar = Tkinter.IntVar() def setWrapText(self, entry_ind, entry): if (entry_ind == 0): entries = self.forwards_entries else: entries = self.backwards_entries self.wrap_buttons.replace( entries, selected_index=self.wrap_buttons.getSelectedIndex()) def findPhrase(self, *extra): phrase = self.find_entry.get() if (not phrase): showError('No find phrase', 'Enter phrase in entry box.') return if (self.direction_buttons.getSelectedIndex() == 0): forwards = 1 backwards = 0 else: forwards = 0 backwards = 1 if (self.case_buttons.getSelectedIndex() == 0): nocase = 1 else: nocase = 0 if (self.pattern_buttons.getSelectedIndex() == 0): exact = 1 regexp = 0 else: exact = 0 regexp = 1 start = self.help_text.tag_nextrange(Tkinter.SEL, '1.0') if (start): start = start[0] if (forwards): start = '%s+1c' % start else: start = '%s-1c' % start else: start = Tkinter.CURRENT if (self.wrap_buttons.getSelectedIndex() == 0): match = self.help_text.search(phrase, start, count=self.countVar, forwards=forwards, backwards=backwards, nocase=nocase, exact=exact, regexp=regexp) elif (forwards): match = self.help_text.search(phrase, start, count=self.countVar, forwards=forwards, backwards=backwards, nocase=nocase, exact=exact, regexp=regexp, stopindex=Tkinter.END) else: match = self.help_text.search(phrase, start, count=self.countVar, forwards=forwards, backwards=backwards, nocase=nocase, exact=exact, regexp=regexp, stopindex='1.0') if (match): self.help_text.see(match) self.help_text.setSelection( match, '%s+%dc' % (match, self.countVar.get())) self.help_text.tag_config(Tkinter.SEL, background='gray70') else: showInfo('No match', 'No match found for phrase.') def toggleFindFrame(self, isClosed): if (isClosed): self.find_frame.grid_forget() else: self.find_frame.grid(row=1, column=0, sticky=Tkinter.W) def setButtonState(self): n = len(self.urls) if ((n >= 2) and (self.current > 0)): state = Tkinter.NORMAL else: state = Tkinter.DISABLED self.buttons.buttons[0].config(state=state) if ((n >= 2) and (self.current < (n - 1))): state = Tkinter.NORMAL else: state = Tkinter.DISABLED self.buttons.buttons[1].config(state=state) def setLinkLabel(self, url=''): self.link_label.set(url) def loadUrl(self, *extra): url = self.url_entry.get() if (url): if (url.find(':') == -1): if (url[:2] != '//'): url = '//' + url url = 'http:' + url self.showUrl(url, forceLoad=True) def newUrl(self, url): self.current = self.current + 1 self.urls[self.current:] = [[url, 0.0]] self.setButtonState() #print 'newUrl', self.current, self.urls def prevUrl(self): if (self.current > 0): # True if called via button (url, offset) = self.urls[self.current - 1] self.updateUrlList = False self.showUrl(url, offset=offset, allowModifyPath=False) self.updateUrlList = True self.current = self.current - 1 self.setButtonState() #print 'prevUrl', self.current, self.urls def nextUrl(self): if (self.current < (len(self.urls) - 1)): # True if called via button (url, offset) = self.urls[self.current + 1] self.updateUrlList = False self.showUrl(url, offset=offset, allowModifyPath=False) self.updateUrlList = True self.current = self.current + 1 self.setButtonState() #print 'nextUrl', self.current, self.urls def showText(self, message, popup=None): self.popup = popup if (popup): self.parent.modal = popup.modal self.help_text.setState(Tkinter.NORMAL) # so that can add text self.help_text.clear() # clear existing text self.help_text.append(message) self.help_text.setState(Tkinter.DISABLED) # make text read-only self.open() def startOpenUrl(self, yview): if (self.urls): self.urls[self.current][1] = yview[0] def endOpenUrl(self, url): #print 'endOpenUrl', url, self.updateUrlList self.url_entry.set(url) if (self.updateUrlList): self.newUrl(url) self.setLinkLabel() self.open() def showUrl(self, url, offset=None, forceLoad=False, allowModifyPath=True, popup=None): self.popup = popup if (popup): self.parent.modal = popup.modal self.help_text.openUrl(url, forceLoad=forceLoad, allowModifyPath=allowModifyPath) if (offset is not None): self.help_text.yview(Tkinter.MOVETO, str(offset))
class GroupChemShiftsPopup(BasePopup): help_url = joinPath(getHelpUrlDir(), 'GroupChemShifts.html') def __init__(self, parent, project): # # Info for writing file... # self.groupText = {} # # Set up molSystem information # self.project = project self.molSysList = list(project.sortedMolSystems()) self.molSystems = None self.molSysLabelList = [] self.molSysLabelDict = {} self.molSysRelationDict = {} molSysLabel = 'All molSystems' if self.setChainLabels(molSysLabel, self.molSysList): self.molSysLabelList.append(molSysLabel) self.molSysLabelDict[molSysLabel] = self.molSysList for molSys in self.molSysList: molSysLabel = '%s' % molSys.code if self.setChainLabels(molSysLabel, [molSys]): self.molSysLabelList.append(molSysLabel) self.molSysLabelDict[molSysLabel] = [molSys] if not self.molSysLabelList: showWarning('Warning', 'No chemical shift lists available! Exiting...') return # # Some initializing... # self.chains = None self.shiftList = None self.shiftListLabel = None self.results = None # modal = true means that it won't continue unless this one returns value BasePopup.__init__(self, parent=parent, title="Project '%s': " % project.name + 'Group chemical shift values', modal=False, transient=True) def setChainLabels(self, molSysLabel, molSysList): # # Set up chain information # chainLabelList = [] chainLabelDict = {} chainLabelShiftListDict = {} self.molSysRelationDict[molSysLabel] = [ chainLabelList, chainLabelDict, chainLabelShiftListDict ] chains = [] for molSys in molSysList: chains.extend(list(molSys.sortedChains())) chainLabel = 'All chains' if self.setShiftListLabels(chainLabel, chains, self.molSysRelationDict[molSysLabel][2]): self.molSysRelationDict[molSysLabel][0].append(chainLabel) self.molSysRelationDict[molSysLabel][1][chainLabel] = chains for chain in chains: chainLabel = "'%s' (mol. '%s')" % (chain.code, chain.molecule.name) if self.setShiftListLabels( chainLabel, [chain], self.molSysRelationDict[molSysLabel][2]): self.molSysRelationDict[molSysLabel][0].append(chainLabel) self.molSysRelationDict[molSysLabel][1][chainLabel] = [chain] return self.molSysRelationDict[molSysLabel][0] def setShiftListLabels(self, chainLabel, chains, chainLabelShiftListDict): # # Set up chemical shift list information (slooooww so done at start) # shiftLists = [] shiftListCount = {} resonanceTracker = [] shiftListLabels = [] shiftListLabelsDict = {} atomCount = 0 for chain in chains: for residue in chain.residues: for atom in residue.atoms: atomCount += 1 if atom.atomSet: for resonanceSet in atom.atomSet.resonanceSets: for resonance in resonanceSet.resonances: if resonance in resonanceTracker: continue resonanceTracker.append(resonance) for shift in resonance.shifts: if shift.parentList not in shiftLists: shiftLists.append(shift.parentList) shiftListCount[shift.parentList] = 0 shiftListCount[shift.parentList] += 1 for shiftList in shiftLists: percentage = (shiftListCount[shift.parentList] * 100.0) / atomCount shiftListLabel = "%d:%s (%.1f%%)" % (shiftList.serial, shiftList.name, percentage) shiftListLabels.append(shiftListLabel) shiftListLabelsDict[shiftListLabel] = shiftList chainLabelShiftListDict[chainLabel] = [ shiftListLabels, shiftListLabelsDict ] return shiftListLabels def body(self, master): # # Setup header # row = 0 self.columnSpan = 3 label = Label( master, text= 'Select molecular system, chains and chemical shift list to be analyzed:' ) label.grid(row=row, column=0, columnspan=self.columnSpan, sticky=Tkinter.EW) row += 1 self.molSysSelect = PulldownMenu(master, entries=self.molSysLabelList, callback=self.setupChains) self.molSysSelect.grid(row=row, column=0, sticky=Tkinter.W) self.chainSelect = PulldownMenu(master, entries=self.chainLabelList, callback=self.setupShiftList) self.chainSelect.grid(row=row, column=1, sticky=Tkinter.W) self.shiftListSelect = PulldownMenu(master, entries=self.shiftListLabels, callback=self.setupPercentageFrame, do_initial_callback=False) self.shiftListSelect.grid(row=row, column=2, sticky=Tkinter.W) row += 1 separator = Separator(master, height=3) separator.setColor('black', bgColor='black') separator.grid(row=row, columnspan=self.columnSpan, sticky=Tkinter.EW) row += 1 master.grid_rowconfigure(row, weight=1) for i in range(self.columnSpan): master.grid_columnconfigure(i, weight=1) self.percentageFrame = ScrolledFrame(master, height=180, doExtraConfig=False) self.percentageFrame.grid(row=row, columnspan=self.columnSpan, sticky=Tkinter.NSEW) self.percentageFrameRow = row self.percentageFrameMaster = master row += 1 separator = Separator(master, height=3) separator.setColor('black', bgColor='black') separator.grid(row=row, columnspan=self.columnSpan, sticky=Tkinter.EW) row += 1 master.grid_rowconfigure(row, weight=1) self.resultsFrame = ScrolledFrame(master, height=180, doExtraConfig=False) self.resultsFrame.grid(row=row, columnspan=self.columnSpan, sticky=Tkinter.NSEW) self.resultsFrameRow = row self.resultsFrameMaster = master row += 1 separator = Separator(master, height=3) separator.setColor('black', bgColor='black') separator.grid(row=row, columnspan=self.columnSpan, sticky=Tkinter.EW) row += 1 texts = ['Recalculate', 'Write to file'] commands = [ self.recalc, self.writeFile ] # This calls 'ok' in BasePopup, this then calls 'apply' in here buttons = createDismissHelpButtonList(master, texts=texts, commands=commands, dismiss_text='Exit', help_url=self.help_url) buttons.grid(row=row, columnspan=self.columnSpan, sticky=Tkinter.EW) self.shiftListSelect.callback(0, self.shiftListLabels[0]) def setupChains(self, listIndex, molSysLabel): molSystems = self.molSysLabelDict[molSysLabel] if self.molSystems == molSystems: return self.molSystems = molSystems self.chainLabelList = self.molSysRelationDict[molSysLabel][0] self.chainLabelDict = self.molSysRelationDict[molSysLabel][1] self.chainLabelShiftListDict = self.molSysRelationDict[molSysLabel][2] if hasattr(self, 'chainSelect'): self.chains = None self.chainSelect.callback(0, self.chainLabelList[0]) def setupShiftList(self, listIndex, chainLabel): chains = self.chainLabelDict[chainLabel] if self.chains == chains: return self.chains = chains # # Reset the pulldown menu # if hasattr(self, 'chainSelect'): self.chainSelect.replace(self.chainLabelList) # # Set up chemical shift lists # self.shiftListLabels = self.chainLabelShiftListDict[chainLabel][0] self.shiftListLabelsDict = self.chainLabelShiftListDict[chainLabel][1] if hasattr(self, 'percentageFrame'): self.shiftList = None self.shiftListLabel = None self.setupPercentageFrame(0, self.shiftListLabels[0]) def setupPercentageFrame(self, listIndex, shiftListLabel): if self.shiftListLabel == shiftListLabel: return self.shiftList = self.shiftListLabelsDict[shiftListLabel] self.shiftListLabel = shiftListLabel # # Reset chemical shift groups... # self.shiftGroupsList = [] for i in range(1, 10): shiftGroupLabel = 'Group_%s' % i self.shiftGroupsList.append(shiftGroupLabel) # # Reset the pulldown menu # if hasattr(self, 'shiftListSelect'): if hasattr(self.shiftListSelect, 'entries') and tuple(self.shiftListLabels) != tuple( self.shiftListSelect.entries): # HACK # otherwise can get infinite recursion but even with above could # if no self.shiftListLabels because of "None" entry in PulldownMenu self.shiftListSelect.replace(self.shiftListLabels) self.shiftListSelect.setSelected(shiftListLabel) # # Reset frame... # self.percentageFrame.destroy() self.percentageFrame = ScrolledFrame(self.percentageFrameMaster, height=180, doExtraConfig=False) self.percentageFrame.grid(row=self.percentageFrameRow, columnspan=self.columnSpan, sticky=Tkinter.NSEW) # # Recalculate results # self.results = makeChemShiftSelections(self.parent, self.chains, self.shiftList) resultKeys = self.results.keys() resultKeys.sort() # # Set up the information # frameRow = 0 frame = self.percentageFrame.frame self.shiftGroupObjects = {} for resultKey in resultKeys: allAtoms = self.results[resultKey][0] shiftAtoms = self.results[resultKey][1] percentage = shiftAtoms * 100.0 / allAtoms label = Label(frame, text=resultKey) label.grid(row=frameRow, column=0, sticky=Tkinter.W) label = Label(frame, text="%.1f%%" % percentage) label.grid(row=frameRow, column=1, sticky=Tkinter.W) label = Label(frame, text="(%d/%d)" % (shiftAtoms, allAtoms)) label.grid(row=frameRow, column=2, sticky=Tkinter.W) self.shiftGroupObjects[resultKey] = PulldownMenu( frame, entries=self.shiftGroupsList) self.shiftGroupObjects[resultKey].grid(row=frameRow, column=3, sticky=Tkinter.E) frameRow += 1 return True def recalc(self): groups = {} groupsInfo = {} for resultKey in self.shiftGroupObjects: group = self.shiftGroupObjects[resultKey].getSelected() if not groups.has_key(group): groups[group] = [] groupsInfo[group] = [0, 0] (allAtoms, shiftAtoms) = self.results[resultKey] groupsInfo[group][0] += allAtoms groupsInfo[group][1] += shiftAtoms groups[group].append(resultKey) # # Reset frame... # self.resultsFrame.destroy() self.resultsFrame = ScrolledFrame(self.resultsFrameMaster, height=180, doExtraConfig=False) self.resultsFrame.grid(row=self.resultsFrameRow, columnspan=self.columnSpan, sticky=Tkinter.NSEW) # # Set info in lower frame # frameRow = 0 frame = self.resultsFrame.frame groupKeys = groups.keys() groupKeys.sort() self.groupText = {} for group in groupKeys: percentage = groupsInfo[group][1] * 100.0 / groupsInfo[group][0] label = Label(frame, text=group) label.grid(row=frameRow, column=0, sticky=Tkinter.W) label = Label(frame, text=groups[group][0]) label.grid(row=frameRow, column=1, sticky=Tkinter.W) label = Label(frame, text="%.1f%%" % percentage) label.grid(row=frameRow, column=2, sticky=Tkinter.W) label = Label(frame, text="(%d/%d)" % (groupsInfo[group][1], groupsInfo[group][0])) label.grid(row=frameRow, column=3, sticky=Tkinter.W) self.groupText[group] = "%-10s %-20s %8.1f%% (%d/%d)%s" % ( group, groups[group][0], percentage, groupsInfo[group][1], groupsInfo[group][0], newline) frameRow += 1 for otherResultKey in groups[group][1:]: label = Label(frame, text=otherResultKey) label.grid(row=frameRow, column=2, sticky=Tkinter.W) self.groupText[group] += "%-10s %-20s%s" % ('', otherResultKey, newline) frameRow += 1 return True def writeFile(self): filePopup = FormatFilePopup(self, component='text') if filePopup.fileSelected: groupKeys = self.groupText.keys() groupKeys.sort() fout = open(filePopup.file, 'w') fout.write("Project: %s" % self.project.name + newline) fout.write("Molsystems: %s" % self.molSysSelect.getSelected() + newline) fout.write("Chains: %s" % self.chainSelect.getSelected() + newline) fout.write("Shiftlist: %s" % self.shiftListSelect.getSelected() + newline * 2) for group in groupKeys: fout.write(self.groupText[group]) print "Wrote file %s..." % filePopup.file def apply(self): return True