class WriteBmrbChemShiftDepPopup(BasePopup): help_url = joinPath(getHelpUrlDir(), 'WriteBmrbChemShiftDep.html') def __init__(self, parent, project): self.project = project self.guiParent = parent self.selectedFormats = [] self.defaultText = 'Select file' self.chainDict = {} self.chainList = [] self.shiftListDict = {} self.shiftLists = [] for shiftList in self.project.currentNmrProject.findAllMeasurementLists( className='ShiftList'): if shiftList.measurements != (): label = str(shiftList.serial) + ':' + str(shiftList.name) self.shiftListDict[label] = shiftList self.shiftLists.append(label) if not self.shiftLists: showError('Error', 'No shift lists available!') return BasePopup.__init__(self, parent=parent, title="Project '%s': " % project.name + 'Write BMRB chemical shift deposition file', modal=False, transient=True) def body(self, master): row = 0 label = Label(master, text="BMRB chemical shift deposition file writer.") label.grid(row=row, column=0, columnspan=2, sticky=Tkinter.W) row += 1 label = Label(master, text="Shift lists:") label.grid(row=row, column=0, sticky=Tkinter.W) self.shiftListSelect = PulldownMenu(master, entries=self.shiftLists, callback=self.setChainList, do_initial_callback=False) self.shiftListSelect.grid(row=row, column=1, sticky=Tkinter.EW) row += 1 label = Label(master, text="Chains (only one per file):") label.grid(row=row, column=0, sticky=Tkinter.W) self.chainListSelect = PulldownMenu(master, entries=self.chainList) self.chainListSelect.grid(row=row, column=1, sticky=Tkinter.EW) self.setChainList(0, self.shiftLists[0]) row += 1 label = Label(master, text="Chemical shift deposition file:") label.grid(row=row, column=0, sticky=Tkinter.W) self.fileButton = Tkinter.Button(master, text=self.defaultText, command=self.selectFile) self.fileButton.grid(row=row, column=1, sticky=Tkinter.W) row += 1 texts = ['Write file'] commands = [ self.ok ] # This calls 'ok' in BasePopup, this then calls 'apply' in here buttons = createDismissHelpButtonList(master, texts=texts, commands=commands, help_url=self.help_url) buttons.grid(row=row, columnspan=2, column=0) def setChainList(self, shiftListIndex, shiftListLabel): # # Has to be done... very slow this. # shiftList = self.shiftListDict[shiftListLabel] self.chainDict = {} self.chainList = [] for shift in shiftList.measurements: if shift.resonance: rs = shift.resonance.resonanceSet if rs: atom = rs.findFirstAtomSet().findFirstAtom() chain = atom.residue.chain if chain not in self.chainDict.values(): label = chain.molSystem.code + ":'" + chain.code + "'" self.chainDict[label] = chain self.chainList.append(label) self.chainListSelect.clearMenuItems() if self.chainList: self.chainListSelect.setup(self.chainList, 0) def selectFile(self): fileName = self.fileButton.__getitem__('text') if fileName == self.defaultText: fileName = 'bmrb.csdep' popup = FormatFilePopup(self, file=fileName, component='csdep', format='bmrb') if popup.fileSelected: self.fileButton.config(text=popup.file) popup.destroy() def apply(self): shiftListLabel = self.shiftListSelect.getSelected() shiftList = self.shiftListDict[shiftListLabel] try: chainLabel = self.chainListSelect.getSelected() chain = self.chainDict[chainLabel] except: showError( "No chains", "No chains were present or selected. Try running linkResonances first." ) return False fileName = self.fileButton.__getitem__('text') if fileName == self.defaultText: return False fileCreated = writeBmrbChemShiftDeposition(self.guiParent, chain, shiftList, fileName) if fileCreated: showInfo("Success", "Succesfully wrote chemical shift deposition file") else: showError("Not written", "Error writing file %s. File not written" % fileName) return False return True
class 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.clearMenuItems() self.chainSelect.entries = self.chainLabelList self.chainSelect.addMenuItems() # # 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'): 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