def body(self, master): master.grid_rowconfigure(0, weight=1) master.grid_columnconfigure(0, weight=1) # get wild config iterations unless doExtraConfig=False frame = ScrolledFrame(master, doExtraConfig=False, width=600, height=300) frame.grid(row=0, column=0, sticky=Tkinter.NSEW) self.parent_frame = frame.frame self.edit_widget = None self.keyList = getKeyList(self.metaclass, includeRoot=True) self.createWidgets() self.createBottomButtons(master) self.setObject(self.object) self.roleFuncs = {} for name in self.metaclass.roleAllNames: role = self.metaclass.elementDict[name] if (self.showRole(role)): # because of loop need role=role else all get bound to last role f = lambda obj, role=role: self.setRoleValue(role) self.roleFuncs[role] = f if (self.editMode): self.doRegisters()
class ChemCompAtomBondInfoPopup(TemporaryBasePopup): help_url = joinPath(getHelpUrlDir(),'ChemCompAtomBondInfo.html') def __init__(self, parent, chemCompInfo, chemCompAtoms, chemCompBonds): self.chemCompInfo = chemCompInfo self.chemCompAtoms = chemCompAtoms self.chemCompBonds = chemCompBonds self.obligatoryAtoms = [] for molTypeTuple in standardBackboneAtoms.keys(): if self.chemCompInfo[0][1] in molTypeTuple: for atomName in standardBackboneAtoms[molTypeTuple]: if atomName not in self.obligatoryAtoms: self.obligatoryAtoms.append(atomName) self.nonEntryAttributes = { 'chirality': (PulldownMenu,['R','S','unknown']), 'waterExchangeable': (CheckButton,False) } TemporaryBasePopup.__init__(self, parent=parent, title='ChemComp atom and bond creation', modal=False, transient=True) def body(self, master): # # Popup window # self.columnspan = len(self.chemCompAtoms[0]) row = 0 label = Label(master, text= "Molecule type '%s', ccp code '%s'" % (self.chemCompInfo[0][1],self.chemCompInfo[1][1])) label.grid(row=row, column=0, columnspan = self.columnspan, sticky=Tkinter.EW) # # Warning message if necessary! # if self.obligatoryAtoms: row += 1 label = Label(master, text= "Warning: have to define atoms: %s!" % string.join(self.obligatoryAtoms,', '), fg = 'red') label.grid(row=row, column=0, columnspan = self.columnspan, sticky=Tkinter.EW) # # Show top information... # row = row + 1 colNum = 0 self.frameWidth = 0 for chemCompAtomInfo in self.chemCompAtoms[0]: attrName = chemCompAtomInfo[0] label = Label(master, text = attrName, width = len(attrName) + 2) label.grid(row=row, column=colNum, sticky=Tkinter.EW) self.frameWidth += len(attrName) + 2 colNum += 1 # # Separator # row += 1 separator = Separator(master, height = 3) separator.setColor('black', bgColor = 'black') separator.grid(row = row, columnspan = self.columnspan, sticky = Tkinter.EW) # # Separate frame for info (have to be able to scroll) # row += 1 # THIS BIT TELLS MASTER TO CONFIGURE WINDOW ON INSIDE WIDGET!! master.grid_rowconfigure(row,weight = 1) for i in range(self.columnspan): master.grid_columnconfigure(i,weight = 1) self.atomFrame = ScrolledFrame(master, width = self.frameWidth, height = 300, doExtraConfig = False) self.atomFrame.grid(row=row, column=0, columnspan = self.columnspan, sticky=Tkinter.NSEW) self.atomFrameRow = row self.atomFrameMaster = master # # Separator # row += 1 separator = Separator(master, height = 3) separator.setColor('black', bgColor = 'black') separator.grid(row = row, columnspan = self.columnspan, sticky = Tkinter.EW) # # End bit... # row = row + 1 texts = [ 'OK', 'Update' ] commands = [ self.ok, self.update ] # This calls 'ok' in BasePopup, this then calls 'apply' in here buttons = createHelpButtonList(master, texts=texts, commands=commands, help_url=self.help_url) buttons.grid(row=row, column=0, columnspan = self.columnspan) self.setupAtomFrame() def setupAtomFrame(self,resetFrame = False, resetStatus = True): frameRow = 0 self.atomWidgets = [] if resetFrame: self.atomFrame = ScrolledFrame(self.atomFrameMaster, width = self.frameWidth, height = 300, doExtraConfig = False) self.atomFrame.grid(row=self.atomFrameRow, column=0, columnspan = self.columnspan, sticky=Tkinter.NSEW) frame = self.atomFrame.frame # # Make fake info at top for col length... # colNum = 0 for chemCompAtomInfo in self.chemCompAtoms[0]: attrName = chemCompAtomInfo[0] label = Label(frame, text = '', width = len(attrName) + 2) label.grid(row=frameRow, column=colNum, sticky=Tkinter.EW) colNum += 1 # # Now atom info... # for chemCompAtom in self.chemCompAtoms: frameRow += 1 colNum = 0 self.atomWidgets.append([]) for chemCompAtomInfo in chemCompAtom: attrName = chemCompAtomInfo[0] if attrName == 'bondedAtoms': bondedAtomText = "" for otherAtom in chemCompAtomInfo[1]: bondedAtomText += otherAtom[0][1] + ',' label = Label(frame, text = bondedAtomText[:-1]) label.grid(row=frameRow, column=colNum, sticky=Tkinter.EW) else: if attrName in self.nonEntryAttributes: widgetInfo = self.nonEntryAttributes[attrName] if widgetInfo[0] == PulldownMenu: self.atomWidgets[-1].append(PulldownMenu(frame, entries = widgetInfo[1], selected_index = widgetInfo[1].index(chemCompAtomInfo[1]))) elif widgetInfo[0] == CheckButton: self.atomWidgets[-1].append(CheckButton(frame, selected = chemCompAtomInfo[1])) else: text = chemCompAtomInfo[1] if not text: text = '' self.atomWidgets[-1].append(Entry(frame, text = text, width = 5)) self.atomWidgets[-1][-1].grid(row=frameRow, column=colNum) colNum += 1 def update(self): self.apply(checkAtoms = False) self.setupAtomFrame() def apply(self, checkAtoms = True): atomNames = [] duplicateNames = [] if checkAtoms: obligatoryAtoms = self.obligatoryAtoms[:] for atomNum in range(0,len(self.chemCompAtoms)): chemCompAtom = self.chemCompAtoms[atomNum] widgets = self.atomWidgets[atomNum] for widgetNum in range(0,len(widgets)): attrName = chemCompAtom[widgetNum][0] if attrName in self.nonEntryAttributes: widgetInfo = self.nonEntryAttributes[attrName] if widgetInfo[0] in [PulldownMenu,CheckButton]: value = widgets[widgetNum].getSelected() if widgetInfo[0] == CheckButton: if value: value = True else: value = False else: value = widgets[widgetNum].get() if value == '': value = None chemCompAtom[widgetNum] = (attrName,value) if attrName == 'name': if value in atomNames: if value not in duplicateNames: duplicateNames.append(value) else: atomNames.append(value) if checkAtoms: if value in obligatoryAtoms: obligatoryAtoms.pop(obligatoryAtoms.index(value)) if duplicateNames: showWarning(self,"Duplicate atom names: %s - names have to be unique!" % string.join(duplicateNames,', ')) return False if checkAtoms and obligatoryAtoms: showWarning(self,"Obligatory atoms: %s still missing - please rename accordingly." % string.join(obligatoryAtoms,', ')) return False return True
def setupAtomFrame(self,resetFrame = False, resetStatus = True): frameRow = 0 self.atomWidgets = [] if resetFrame: self.atomFrame = ScrolledFrame(self.atomFrameMaster, width = self.frameWidth, height = 300, doExtraConfig = False) self.atomFrame.grid(row=self.atomFrameRow, column=0, columnspan = self.columnspan, sticky=Tkinter.NSEW) frame = self.atomFrame.frame # # Make fake info at top for col length... # colNum = 0 for chemCompAtomInfo in self.chemCompAtoms[0]: attrName = chemCompAtomInfo[0] label = Label(frame, text = '', width = len(attrName) + 2) label.grid(row=frameRow, column=colNum, sticky=Tkinter.EW) colNum += 1 # # Now atom info... # for chemCompAtom in self.chemCompAtoms: frameRow += 1 colNum = 0 self.atomWidgets.append([]) for chemCompAtomInfo in chemCompAtom: attrName = chemCompAtomInfo[0] if attrName == 'bondedAtoms': bondedAtomText = "" for otherAtom in chemCompAtomInfo[1]: bondedAtomText += otherAtom[0][1] + ',' label = Label(frame, text = bondedAtomText[:-1]) label.grid(row=frameRow, column=colNum, sticky=Tkinter.EW) else: if attrName in self.nonEntryAttributes: widgetInfo = self.nonEntryAttributes[attrName] if widgetInfo[0] == PulldownMenu: self.atomWidgets[-1].append(PulldownMenu(frame, entries = widgetInfo[1], selected_index = widgetInfo[1].index(chemCompAtomInfo[1]))) elif widgetInfo[0] == CheckButton: self.atomWidgets[-1].append(CheckButton(frame, selected = chemCompAtomInfo[1])) else: text = chemCompAtomInfo[1] if not text: text = '' self.atomWidgets[-1].append(Entry(frame, text = text, width = 5)) self.atomWidgets[-1][-1].grid(row=frameRow, column=colNum) colNum += 1
def body(self, master): # # Popup window # self.columnspan = len(self.chemCompAtoms[0]) row = 0 label = Label(master, text= "Molecule type '%s', ccp code '%s'" % (self.chemCompInfo[0][1],self.chemCompInfo[1][1])) label.grid(row=row, column=0, columnspan = self.columnspan, sticky=Tkinter.EW) # # Warning message if necessary! # if self.obligatoryAtoms: row += 1 label = Label(master, text= "Warning: have to define atoms: %s!" % string.join(self.obligatoryAtoms,', '), fg = 'red') label.grid(row=row, column=0, columnspan = self.columnspan, sticky=Tkinter.EW) # # Show top information... # row = row + 1 colNum = 0 self.frameWidth = 0 for chemCompAtomInfo in self.chemCompAtoms[0]: attrName = chemCompAtomInfo[0] label = Label(master, text = attrName, width = len(attrName) + 2) label.grid(row=row, column=colNum, sticky=Tkinter.EW) self.frameWidth += len(attrName) + 2 colNum += 1 # # Separator # row += 1 separator = Separator(master, height = 3) separator.setColor('black', bgColor = 'black') separator.grid(row = row, columnspan = self.columnspan, sticky = Tkinter.EW) # # Separate frame for info (have to be able to scroll) # row += 1 # THIS BIT TELLS MASTER TO CONFIGURE WINDOW ON INSIDE WIDGET!! master.grid_rowconfigure(row,weight = 1) for i in range(self.columnspan): master.grid_columnconfigure(i,weight = 1) self.atomFrame = ScrolledFrame(master, width = self.frameWidth, height = 300, doExtraConfig = False) self.atomFrame.grid(row=row, column=0, columnspan = self.columnspan, sticky=Tkinter.NSEW) self.atomFrameRow = row self.atomFrameMaster = master # # Separator # row += 1 separator = Separator(master, height = 3) separator.setColor('black', bgColor = 'black') separator.grid(row = row, columnspan = self.columnspan, sticky = Tkinter.EW) # # End bit... # row = row + 1 texts = [ 'OK', 'Update' ] commands = [ self.ok, self.update ] # This calls 'ok' in BasePopup, this then calls 'apply' in here buttons = createHelpButtonList(master, texts=texts, commands=commands, help_url=self.help_url) buttons.grid(row=row, column=0, columnspan = self.columnspan) self.setupAtomFrame()
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)
class SequenceChemCompSelect(BasePopup): help_url = joinPath(getHelpUrlDir(), 'SequenceChemCompSelect.html') def __init__(self, parent, project, molName, createMoleculeDict, localCreateMoleculeDict): self.molName = molName self.project = project self.createMoleculeDict = createMoleculeDict self.localCreateMoleculeDict = localCreateMoleculeDict self.hasChanged = False self.molecule = self.localCreateMoleculeDict[self.molName][0] self.deleteText = 'Delete' self.okText = 'OK' self.startText = 'Insert at start' self.endText = 'Append to end' self.newMoleculeList = [] for molName in self.localCreateMoleculeDict.keys(): if molName != self.molName and not self.localCreateMoleculeDict[ molName][0]: self.newMoleculeList.append(molName) # modal = true means that it won't continue unless this one returns value BasePopup.__init__(self, parent=parent, title="Project '%s': " % project.name + 'Set chemComps for sequence', modal=True, transient=True) def body(self, master): self.geometry('700x500') # # Setup header # row = 0 label = Label(master, text='Original', width=10) label.grid(row=row, column=0, sticky=Tkinter.EW) label = Label(master, text='Modify ChemCompVar', width=35) label.grid(row=row, column=1, sticky=Tkinter.EW) label = Label(master, text='Status', width=20) label.grid(row=row, column=2, sticky=Tkinter.EW) label = Label(master, text='', width=5) label.grid(row=row, column=3, sticky=Tkinter.EW) row += 1 label = Label(master, text='code', width=10) label.grid(row=row, column=0, sticky=Tkinter.EW) label = Label(master, text='ccpCode (molType): linking, descriptor', width=35) label.grid(row=row, column=1, sticky=Tkinter.EW) label = Tkinter.Button(master, text='Add new molecule', command=self.addNewMolecule) label.grid(row=row, column=2) row += 1 separator = Separator(master, height=3) separator.setColor('black', bgColor='black') separator.grid(row=row, columnspan=3, sticky=Tkinter.EW) row += 1 # THIS BIT TELLS MASTER TO CONFIGURE WINDOW ON INSIDE WIDGET!! master.grid_rowconfigure(row, weight=1) for i in range(4): master.grid_columnconfigure(i, weight=1) self.sequenceFrame = ScrolledFrame(master, width=70, height=300, doExtraConfig=False) self.sequenceFrame.grid(row=row, column=0, columnspan=4, sticky=Tkinter.NSEW) self.sequenceFrameRow = row self.sequenceFrameMaster = master row += 1 separator = Separator(master, height=3) separator.setColor('black', bgColor='black') separator.grid(row=row, columnspan=3, sticky=Tkinter.EW) row += 1 texts = ['Change', 'Change and quit'] commands = [ self.updateMolDict, self.ok ] # This calls 'ok' in BasePopup, this then calls 'apply' in here buttons = createDismissHelpButtonList(master, texts=texts, commands=commands, dismiss_text='Cancel', help_url=self.help_url) buttons.grid(row=row, column=0, columnspan=3, sticky=Tkinter.EW) self.setupSequenceFrame() def setupSequenceFrame(self, resetFrame=False, resetStatus=True): frameRow = 0 x = y = 0 if resetFrame: self.sequenceFrame = ScrolledFrame(self.sequenceFrameMaster, width=70, height=300, doExtraConfig=False) self.sequenceFrame.grid(row=self.sequenceFrameRow, column=0, columnspan=4, sticky=Tkinter.NSEW) frame = self.sequenceFrame.frame # # Just use the first one as reference! # sequences = self.localCreateMoleculeDict[self.molName][1] (self.origSequence, self.origSequenceList) = sequences[0] if len(sequences) > 1: multipleSequences = True else: multipleSequences = False # # Set info... # label = Label(frame, text='', width=10) label.grid(row=frameRow, column=0, sticky=Tkinter.EW) label = Label(frame, text='', width=35) label.grid(row=frameRow, column=1, sticky=Tkinter.EW) label = Label(frame, text='', width=20) label.grid(row=frameRow, column=2, sticky=Tkinter.EW) frameRow += 1 self.ccvButtons = [] if resetStatus or resetFrame: self.statusList = [] self.moveStatus = {} # # Set up a list of status entries # statusEntries = [self.okText, self.deleteText] for newMolName in self.newMoleculeList: for appendCode in [self.startText, self.endText]: statusEntries.append('%s of %s' % (appendCode, newMolName)) self.moveStatus[statusEntries[-1]] = (newMolName, appendCode) # # Start creating all the objects... # for seqIndex in range(0, len(self.origSequenceList)): (seqEl, ccHead, ccVar) = self.origSequenceList[seqIndex] # # Set the original sequence code info... # seqCode = seqEl.seqCode if hasattr(seqEl, 'code3Letter') and seqEl.code3Letter: seqText = seqEl.code3Letter else: seqText = seqEl.code1Letter label = Label(frame, text="%s-%d" % (seqText, seqCode)) label.grid(row=frameRow, column=0, sticky=Tkinter.EW) # # Set the chemCompVar info # keywds = {} if ccHead: textCode = "%s (%s)" % (ccHead.ccpCode, ccHead.molType) if ccVar: textCode += ": %s,%s" % (ccVar.linking, ccVar.descriptor) else: textCode = 'Select chemCompVar for %s' % textCode keywds['fg'] = 'red' else: textCode = 'Select chemCompVar' keywds['fg'] = 'red' self.ccvButtons.append( Tkinter.Button(frame, text=textCode, command=lambda seqIndex=seqIndex: self. selectChemCompVar(seqIndex), **keywds)) self.ccvButtons[-1].grid(row=frameRow, column=1, sticky=Tkinter.EW) # # Set the selector... # if resetStatus or resetFrame: self.statusList.append( PulldownMenu(frame, entries=statusEntries, label_color='red')) self.statusList[-1].grid(row=frameRow, column=2, sticky=Tkinter.EW) frameRow += 1 return True def addNewMolecule(self): molFormat = 'newMolecule_%d' if not hasattr(self, 'molNames'): self.molNames = self.localCreateMoleculeDict.keys() for i in range(0, 10): newMolName = molFormat % (i + 1) if newMolName not in self.molNames and not self.project.findFirstMolecule( name=newMolName): break self.molNames.append(newMolName) for statusPullDown in self.statusList: for appendCode in [self.startText, self.endText]: entryText = '%s of %s' % (appendCode, newMolName) statusPullDown.append(entryText) self.moveStatus[entryText] = (newMolName, appendCode) def updateMolDict(self): hasChanged = False actualSeqIndex = 0 seqLength = len(self.origSequenceList) origSequenceList = self.origSequenceList[:] for seqIndex in range(0, seqLength): (seqEl, ccHead, ccVar) = origSequenceList[seqIndex] newStatus = self.statusList[seqIndex].getSelected() if newStatus != self.okText: hasChanged = True if self.localCreateMoleculeDict == self.createMoleculeDict: self.copyCreateMoleculeDict() self.origSequenceList.pop(actualSeqIndex) if newStatus != self.deleteText: (moveToMoleculeName, appendCode) = self.moveStatus[newStatus] if not self.localCreateMoleculeDict.has_key( moveToMoleculeName): self.localCreateMoleculeDict[moveToMoleculeName] = [ None, [(None, [])] ] sequences = self.localCreateMoleculeDict[ moveToMoleculeName][1] for (tempSequence, tempSequenceList) in sequences: if appendCode == self.startText: tempSequenceList.insert(0, (seqEl, ccHead, ccVar)) elif appendCode == self.endText: tempSequenceList.append((seqEl, ccHead, ccVar)) else: actualSeqIndex += 1 # # Check if changed and do some resets if so... # if hasChanged: self.hasChanged = True # # Reset the linking if appropriate # for molName in self.localCreateMoleculeDict.keys(): if not self.localCreateMoleculeDict[molName][0]: sequences = self.localCreateMoleculeDict[molName][1] for (origSequence, origSequenceList) in sequences: molTypes = [] for (seqEl, ccHead, ccVar) in origSequenceList: if ccHead: if ccHead.molType not in molTypes: molTypes.append(ccHead.molType) if len(molTypes) == 1 and molTypes[0] != 'other': seqLength = len(origSequenceList) for seqIndex in range(0, seqLength): (seqEl, ccHead, ccVar) = origSequenceList[seqIndex] if ccVar: if seqIndex == 0: linking = 'start' elif seqIndex == seqLength - 1: linking = 'end' else: linking = 'middle' if ccVar.linking != linking: ccVar = ccHead.chemComp.findFirstChemCompVar( descriptor=ccVar.descriptor, linking=linking) if ccVar: origSequenceList[seqIndex] = ( seqEl, ccHead, ccVar) self.setupSequenceFrame(resetFrame=True) def selectChemCompVar(self, seqIndex): hasChanged = False (seqEl, ccHead, ccVar) = self.origSequenceList[seqIndex] keywds = {} if ccHead: keywds['molTypeEntries'] = [ccHead.molType] # TODO HAS TO CHANGE!! keywds['selectedChemCompHeads'] = [ccHead] if ccVar: keywds['selectLinking'] = ccVar.linking if hasattr(seqEl, 'code3Letter') and seqEl.code3Letter: keywds['origCode'] = seqEl.code3Letter else: keywds['origCode'] = seqEl.code1Letter popup = ChemCompSelectionPopup(self, self.project, chemCompEntries=['ChemCompVar'], **keywds) self.wait_window(popup) if popup.frame.getSelectedChemComp(): newChemCompVar = popup.frame.getSelectedChemComp() if not ccVar or ccVar != newChemCompVar: if self.localCreateMoleculeDict == self.createMoleculeDict: self.copyCreateMoleculeDict() self.origSequenceList[seqIndex] = ( seqEl, newChemCompVar.chemComp.chemCompHead, newChemCompVar) hasChanged = True if hasChanged: self.setupSequenceFrame(resetStatus=False) self.hasChanged = hasChanged def copyCreateMoleculeDict(self): self.localCreateMoleculeDict = {} for molName in self.createMoleculeDict.keys(): self.localCreateMoleculeDict[molName] = [ self.createMoleculeDict[molName][0], [] ] for (sequence, sequenceList) in self.createMoleculeDict[molName][1]: self.localCreateMoleculeDict[molName][1].append( (sequence, sequenceList[:])) sequences = self.localCreateMoleculeDict[self.molName][1] (self.origSequence, self.origSequenceList) = sequences[0] def apply(self): self.updateMolDict() return True
def setupSequenceFrame(self, resetFrame=False, resetStatus=True): frameRow = 0 x = y = 0 if resetFrame: self.sequenceFrame = ScrolledFrame(self.sequenceFrameMaster, width=70, height=300, doExtraConfig=False) self.sequenceFrame.grid(row=self.sequenceFrameRow, column=0, columnspan=4, sticky=Tkinter.NSEW) frame = self.sequenceFrame.frame # # Just use the first one as reference! # sequences = self.localCreateMoleculeDict[self.molName][1] (self.origSequence, self.origSequenceList) = sequences[0] if len(sequences) > 1: multipleSequences = True else: multipleSequences = False # # Set info... # label = Label(frame, text='', width=10) label.grid(row=frameRow, column=0, sticky=Tkinter.EW) label = Label(frame, text='', width=35) label.grid(row=frameRow, column=1, sticky=Tkinter.EW) label = Label(frame, text='', width=20) label.grid(row=frameRow, column=2, sticky=Tkinter.EW) frameRow += 1 self.ccvButtons = [] if resetStatus or resetFrame: self.statusList = [] self.moveStatus = {} # # Set up a list of status entries # statusEntries = [self.okText, self.deleteText] for newMolName in self.newMoleculeList: for appendCode in [self.startText, self.endText]: statusEntries.append('%s of %s' % (appendCode, newMolName)) self.moveStatus[statusEntries[-1]] = (newMolName, appendCode) # # Start creating all the objects... # for seqIndex in range(0, len(self.origSequenceList)): (seqEl, ccHead, ccVar) = self.origSequenceList[seqIndex] # # Set the original sequence code info... # seqCode = seqEl.seqCode if hasattr(seqEl, 'code3Letter') and seqEl.code3Letter: seqText = seqEl.code3Letter else: seqText = seqEl.code1Letter label = Label(frame, text="%s-%d" % (seqText, seqCode)) label.grid(row=frameRow, column=0, sticky=Tkinter.EW) # # Set the chemCompVar info # keywds = {} if ccHead: textCode = "%s (%s)" % (ccHead.ccpCode, ccHead.molType) if ccVar: textCode += ": %s,%s" % (ccVar.linking, ccVar.descriptor) else: textCode = 'Select chemCompVar for %s' % textCode keywds['fg'] = 'red' else: textCode = 'Select chemCompVar' keywds['fg'] = 'red' self.ccvButtons.append( Tkinter.Button(frame, text=textCode, command=lambda seqIndex=seqIndex: self. selectChemCompVar(seqIndex), **keywds)) self.ccvButtons[-1].grid(row=frameRow, column=1, sticky=Tkinter.EW) # # Set the selector... # if resetStatus or resetFrame: self.statusList.append( PulldownMenu(frame, entries=statusEntries, label_color='red')) self.statusList[-1].grid(row=frameRow, column=2, sticky=Tkinter.EW) frameRow += 1 return True
def body(self, master): self.geometry('700x500') # # Setup header # row = 0 label = Label(master, text='Original', width=10) label.grid(row=row, column=0, sticky=Tkinter.EW) label = Label(master, text='Modify ChemCompVar', width=35) label.grid(row=row, column=1, sticky=Tkinter.EW) label = Label(master, text='Status', width=20) label.grid(row=row, column=2, sticky=Tkinter.EW) label = Label(master, text='', width=5) label.grid(row=row, column=3, sticky=Tkinter.EW) row += 1 label = Label(master, text='code', width=10) label.grid(row=row, column=0, sticky=Tkinter.EW) label = Label(master, text='ccpCode (molType): linking, descriptor', width=35) label.grid(row=row, column=1, sticky=Tkinter.EW) label = Tkinter.Button(master, text='Add new molecule', command=self.addNewMolecule) label.grid(row=row, column=2) row += 1 separator = Separator(master, height=3) separator.setColor('black', bgColor='black') separator.grid(row=row, columnspan=3, sticky=Tkinter.EW) row += 1 # THIS BIT TELLS MASTER TO CONFIGURE WINDOW ON INSIDE WIDGET!! master.grid_rowconfigure(row, weight=1) for i in range(4): master.grid_columnconfigure(i, weight=1) self.sequenceFrame = ScrolledFrame(master, width=70, height=300, doExtraConfig=False) self.sequenceFrame.grid(row=row, column=0, columnspan=4, sticky=Tkinter.NSEW) self.sequenceFrameRow = row self.sequenceFrameMaster = master row += 1 separator = Separator(master, height=3) separator.setColor('black', bgColor='black') separator.grid(row=row, columnspan=3, sticky=Tkinter.EW) row += 1 texts = ['Change', 'Change and quit'] commands = [ self.updateMolDict, self.ok ] # This calls 'ok' in BasePopup, this then calls 'apply' in here buttons = createDismissHelpButtonList(master, texts=texts, commands=commands, dismiss_text='Cancel', help_url=self.help_url) buttons.grid(row=row, column=0, columnspan=3, sticky=Tkinter.EW) self.setupSequenceFrame()
class ProchiralStatusPopup(TemporaryBasePopup): help_url = joinPath(getHelpUrlDir(), 'ProchiralStatus.html') def __init__(self, parent, chainList, chainAtomSetsDict): self.chainList = chainList self.chainAtomSetsDict = chainAtomSetsDict self.resParentDict = {} self.resParentList = [] self.resParentChainLabelDict = {} self.resParentChainLabelList = {} self.chainResonancesDict = {} for resParent in self.chainAtomSetsDict.keys(): if isinstance(resParent, NmrConstraint.NmrConstraintStore): strucGens = resParent.structureGenerations strucGenSerials = [str(sg.serial) for sg in strucGens] strucGenLabel = string.join(strucGenSerials, ',') resParentLabel = "Constraint set %d (strucGens %s)" % ( resParent.serial, strucGenSerials) else: resParentLabel = "Nmr project %s" % resParent.name self.resParentDict[resParentLabel] = resParent self.resParentList.append(resParentLabel) self.chainResonancesDict[resParent] = {} self.resParentChainLabelDict[resParent] = {} self.resParentChainLabelList[resParent] = [] for chain in self.chainList: self.project = chain.root if self.chainAtomSetsDict[resParent].has_key( chain) and self.chainAtomSetsDict[resParent][chain]: chainLabel = "Molecular system '%s':Chain '%s' (molecule '%s')" % ( chain.molSystem.code, chain.code, chain.molecule.name) self.resParentChainLabelList[resParent].append(chainLabel) self.resParentChainLabelDict[resParent][chainLabel] = chain self.chainResonancesDict[resParent][chain] = [] # modal = true means that it won't continue unless this one returns value TemporaryBasePopup.__init__( self, parent=parent, title="Project '%s': " % self.project.name + 'Set status prochiral atoms/resonances', modal=False, transient=True) def body(self, master): # # Setup header # row = 0 label = Label(master, text='Select the resonance list:') label.grid(row=row, column=0, sticky=Tkinter.EW) label = Label(master, text='Select the chain:') label.grid(row=row, column=1, sticky=Tkinter.EW) row += 1 self.resParentSelect = PulldownMenu(master, entries=self.resParentList, callback=self.setupResParentList, do_initial_callback=False) self.resParentSelect.grid(row=row, column=0, sticky=Tkinter.EW) self.chainSelect = PulldownMenu(master, entries=[], callback=self.setupProchiralList, do_initial_callback=False) self.chainSelect.grid(row=row, column=1, sticky=Tkinter.EW) row += 1 separator = Separator(master, height=3) separator.setColor('black', bgColor='black') separator.grid(row=row, columnspan=2, sticky=Tkinter.EW) row += 1 # THIS BIT TELLS MASTER TO CONFIGURE WINDOW ON INSIDE WIDGET!! master.grid_rowconfigure(row, weight=1) for i in range(2): master.grid_columnconfigure(i, weight=1) self.prochiralListFrame = ScrolledFrame(master, width=200, doExtraConfig=False) self.prochiralListFrame.grid(row=row, column=0, columnspan=2, sticky=Tkinter.NSEW) self.prochiralListFrameRow = row self.prochiralListFrameMaster = master row = row + 1 texts = ['Set all', 'Set chain'] commands = [ self.ok, self.setStereo ] # This calls 'ok' in BasePopup, this then calls 'apply' in here buttons = createDismissHelpButtonList(master, texts=texts, commands=commands, dismiss_text='Exit', help_url=self.help_url) buttons.grid(row=row, column=0, columnspan=2, sticky=Tkinter.EW) self.resParentSelect.callback(0, self.resParentList[0]) def setupResParentList(self, listIndex, resParentLabel): resParent = self.resParentDict[resParentLabel] self.resParent = resParent self.chainSelect.setup(self.resParentChainLabelList[self.resParent], 0) self.chainSelect.callback( 0, self.resParentChainLabelList[self.resParent][0]) def setupProchiralList(self, listIndex, chainLabel): chain = self.resParentChainLabelDict[self.resParent][chainLabel] self.chain = chain self.prochiralListFrame.destroy() self.prochiralListFrame = ScrolledFrame(self.prochiralListFrameMaster, width=200, doExtraConfig=False) self.prochiralListFrame.grid(row=self.prochiralListFrameRow, column=0, columnspan=2, sticky=Tkinter.NSEW) # # TODO: also handle case one resonance, two atomSets!?!? # frameRow = 0 x = y = 0 frame = self.prochiralListFrame.frame self.resonanceObjects = {} self.resonanceLabelDict = {} # # Reuse previous settings... # if len(self.chainResonancesDict[self.resParent][chain]) == len( self.chainAtomSetsDict[self.resParent][chain]): usePreviousSettings = True else: usePreviousSettings = False for i in range(0, len(self.chainAtomSetsDict[self.resParent][chain])): atomSetGroup = self.chainAtomSetsDict[self.resParent][chain][i] isStereo = False hasResonances = False isValidCase = False resonances = [] if usePreviousSettings and self.chainResonancesDict[ self.resParent][chain][i]: resonances = self.chainResonancesDict[ self.resParent][chain][i][3] isStereo = self.chainResonancesDict[ self.resParent][chain][i][0] hasResonances = True isValidCase = True else: for atomSet in atomSetGroup: resonanceSets = atomSet.sortedResonanceSets() if resonanceSets: hasResonances = True for resonanceSet in resonanceSets: for resonance in resonanceSet.sortedResonances(): if resonance not in resonances: resonances.append(resonance) if len(resonanceSets) == 1: isValidCase = True if len(resonanceSet.atomSets) == 1: isStereo = True else: # Case only one resonance but stereo assigned resonances.append(0) if len(resonances) == 1: # Case only one resonance, not stereo assigned resonances.append(None) # # Set up only for valid cases # if hasResonances and isValidCase: if not usePreviousSettings: self.chainResonancesDict[self.resParent][chain].append( [isStereo, False, False, resonances]) residue = atomSetGroup[0].findFirstAtom().residue ccpCode = residue.molResidue.ccpCode seqCode = residue.seqCode rowspan = 2 checkButton = CheckButton( frame, selected=isStereo, callback=lambda status=isStereo, fr=frameRow, item=i, setup =False: self.toggleResonances(status, fr, item, setup)) checkButton.grid(row=frameRow, rowspan=rowspan, column=0, sticky=Tkinter.EW) label = Label(frame, text=ccpCode, width=5) label.grid(row=frameRow, rowspan=rowspan, column=1, sticky=Tkinter.E) label = Label(frame, text=str(seqCode), width=5) label.grid(row=frameRow, rowspan=rowspan, column=2, sticky=Tkinter.W) # # Set up the atom names # for j in range(0, len(atomSetGroup)): atomSet = atomSetGroup[j] label = Label(frame, text=atomSet.name) label.grid(row=frameRow + j, column=3, sticky=Tkinter.E, ipadx=4) # # Set up the resonances # self.resonanceObjects[frameRow] = { True: [[], []], False: [[], []] } resonanceLabelList = [] for resonance in resonances: if not resonance: resonanceLabel = 'unknown' else: if hasattr(resonance, 'shifts') and resonance.shifts: shiftLabel = " (shifts: " for shift in resonance.sortedShifts(): shiftLabel += "%.2f, " % shift.value shiftLabel = shiftLabel[:-2] + ")" else: shiftLabel = "" resonanceLabel = "'%d.%s'%s" % ( seqCode, resonance.name, shiftLabel) self.resonanceLabelDict[resonanceLabel] = resonance resonanceLabelList.append(resonanceLabel) separator = Separator(frame, height=1, width=30) separator.setColor('black', bgColor='black') separator.grid(row=frameRow, column=4, sticky=Tkinter.EW) self.resonanceObjects[frameRow][True][0].append(separator) separator = CrossLine(frame, height=20, width=30, canvas_bg=frame['bg'], color='dimgray') self.resonanceObjects[frameRow][False][0].append(separator) resonanceList = PulldownMenu( frame, entries=resonanceLabelList, callback=lambda selInd=x, selItem=y, fr=frameRow, item=i: self.setProchiralLabels(selInd, selItem, fr, item), do_initial_callback=False, label_color='red') resonanceList.grid(row=frameRow, column=5, sticky=Tkinter.EW) self.resonanceObjects[frameRow][True][0].append(resonanceList) resonanceLabel = Label(frame, text="%s" % resonanceLabelList[0], fg='dimgray') self.resonanceObjects[frameRow][False][0].append( resonanceLabel) separator = Separator(frame, height=1, width=30) separator.setColor('black', bgColor='black') separator.grid(row=frameRow + 1, column=4) self.resonanceObjects[frameRow][True][1].append(separator) self.resonanceObjects[frameRow][False][1].append(None) resonanceLabel = Label(frame, text="%s" % resonanceLabelList[1], fg='red') resonanceLabel.grid(row=frameRow + 1, column=5, sticky=Tkinter.EW) self.resonanceObjects[frameRow][True][1].append(resonanceLabel) resonanceLabel = Label(frame, text="%s" % resonanceLabelList[1], fg='dimgray') self.resonanceObjects[frameRow][False][1].append( resonanceLabel) if not isStereo: checkButton.callback(isStereo, setup=True) separator = Separator(frame, height=1) separator.setColor('black', bgColor='black') separator.grid(row=frameRow + rowspan, columnspan=6, sticky=Tkinter.EW) frameRow += rowspan + 1 elif not usePreviousSettings: self.chainResonancesDict[self.resParent][chain].append(None) return True def setProchiralLabels(self, selInd, selItem, fr, item): resonanceLabel = self.resonanceObjects[fr][True][0][1].entries[selInd] self.resonanceObjects[fr][False][0][1].set(resonanceLabel) selInd = not selInd resonanceLabel = self.resonanceObjects[fr][True][0][1].entries[selInd] self.resonanceObjects[fr][True][1][1].set(resonanceLabel) self.resonanceObjects[fr][False][1][1].set(resonanceLabel) self.chainResonancesDict[self.resParent][ self.chain][item][2] = not self.chainResonancesDict[ self.resParent][self.chain][item][2] self.chainResonancesDict[self.resParent][self.chain][item][3].reverse() def toggleResonances(self, status, frameRow, item, setup): if not setup: self.chainResonancesDict[self.resParent][ self.chain][item][0] = status self.chainResonancesDict[self.resParent][ self.chain][item][1] = not self.chainResonancesDict[ self.resParent][self.chain][item][1] for i in range(0, len(self.resonanceObjects[frameRow])): # # Remove other widgets from grid # rpds = self.resonanceObjects[frameRow][not status][i] for rpd in rpds: if rpd: rpd.grid_forget() # # Set current widgets # rpds = self.resonanceObjects[frameRow][status][i] for j in range(0, len(rpds)): rpd = rpds[j] if rpd: keywds = {} if j == 1: keywds['sticky'] = Tkinter.W if j == 0: if not status: keywds['rowspan'] = 2 rpd.grid(row=frameRow + i, column=4 + j, **keywds) def setStereo(self, chain=None): if not chain: chain = self.chain if self.chainResonancesDict[self.resParent][chain]: for i in range( 0, len(self.chainResonancesDict[self.resParent][chain])): atomSetGroup = self.chainAtomSetsDict[self.resParent][chain][i] (stereoStatus, stereoStatusChanged, resChanged, resonances ) = self.chainResonancesDict[self.resParent][chain][i] if stereoStatusChanged or (stereoStatus and resChanged): residue = atomSetGroup[0].findFirstAtom().residue ccpCode = residue.molResidue.ccpCode seqCode = residue.seqCode atomText = "%s/%s" % (atomSetGroup[0].name, atomSetGroup[1].name) if stereoStatusChanged: if stereoStatus: stereoText = "non-stereospecific to stereospecific." else: stereoText = "stereospecific to non-stereospecific." print " Warning: Changed '%s.%d' prochiral resonances for atoms %s from %s" % ( ccpCode, seqCode, atomText, stereoText) self.chainResonancesDict[ self.resParent][chain][i][1] = False self.chainResonancesDict[ self.resParent][chain][i][2] = False if stereoStatus: resonanceSet = atomSetGroup[ 0].findFirstResonanceSet() if resonances[0]: resonanceSet.removeAtomSet(atomSetGroup[1]) if resonances[1]: if not resonances[0]: # Remove right atom set if only one resonance... resonanceSet.removeAtomSet(atomSetGroup[0]) else: # Only create a new resonance set if two resonances present! resonanceSet.removeResonance(resonances[1]) if isinstance( self.resParent, NmrConstraint.NmrConstraintStore): newResonanceSet = self.resParent.newFixedResonanceSet( resonances=[resonances[1]], atomSets=[atomSetGroup[1]]) else: newResonanceSet = self.resParent.newResonanceSet( resonances=[resonances[1]], atomSets=[atomSetGroup[1]]) else: if resonances[0]: resonanceSet = atomSetGroup[ 0].findFirstResonanceSet() if resonances[1]: atomSetGroup[1].findFirstResonanceSet( ).delete() resonanceSet.addResonance(resonances[1]) resonanceSet.addAtomSet(atomSetGroup[1]) elif resonances[1]: resonanceSet = atomSetGroup[1].resonanceSets[0] resonanceSet.addAtomSet(atomSetGroup[0]) elif stereoStatus and resChanged: print " Warning: Changed resonance assignment for '%s.%d' stereospecifically assigned atoms %s." % ( ccpCode, seqCode, atomText) self.chainResonancesDict[ self.resParent][chain][i][2] = False resonanceSets = [] for i in range(0, 2): if atomSetGroup[i].resonanceSets: resonanceSets.append( atomSetGroup[i].findFirstResonanceSet()) else: resonanceSets.append(None) for i in range(0, 2): resonanceSet = resonanceSets[i] if resonanceSet: resonanceSet.addAtomSet(atomSetGroup[not i]) resonanceSet.removeAtomSet(atomSetGroup[i]) def apply(self): for chain in self.chainList: self.setStereo(chain=chain) return True
def setupProchiralList(self, listIndex, chainLabel): chain = self.resParentChainLabelDict[self.resParent][chainLabel] self.chain = chain self.prochiralListFrame.destroy() self.prochiralListFrame = ScrolledFrame(self.prochiralListFrameMaster, width=200, doExtraConfig=False) self.prochiralListFrame.grid(row=self.prochiralListFrameRow, column=0, columnspan=2, sticky=Tkinter.NSEW) # # TODO: also handle case one resonance, two atomSets!?!? # frameRow = 0 x = y = 0 frame = self.prochiralListFrame.frame self.resonanceObjects = {} self.resonanceLabelDict = {} # # Reuse previous settings... # if len(self.chainResonancesDict[self.resParent][chain]) == len( self.chainAtomSetsDict[self.resParent][chain]): usePreviousSettings = True else: usePreviousSettings = False for i in range(0, len(self.chainAtomSetsDict[self.resParent][chain])): atomSetGroup = self.chainAtomSetsDict[self.resParent][chain][i] isStereo = False hasResonances = False isValidCase = False resonances = [] if usePreviousSettings and self.chainResonancesDict[ self.resParent][chain][i]: resonances = self.chainResonancesDict[ self.resParent][chain][i][3] isStereo = self.chainResonancesDict[ self.resParent][chain][i][0] hasResonances = True isValidCase = True else: for atomSet in atomSetGroup: resonanceSets = atomSet.sortedResonanceSets() if resonanceSets: hasResonances = True for resonanceSet in resonanceSets: for resonance in resonanceSet.sortedResonances(): if resonance not in resonances: resonances.append(resonance) if len(resonanceSets) == 1: isValidCase = True if len(resonanceSet.atomSets) == 1: isStereo = True else: # Case only one resonance but stereo assigned resonances.append(0) if len(resonances) == 1: # Case only one resonance, not stereo assigned resonances.append(None) # # Set up only for valid cases # if hasResonances and isValidCase: if not usePreviousSettings: self.chainResonancesDict[self.resParent][chain].append( [isStereo, False, False, resonances]) residue = atomSetGroup[0].findFirstAtom().residue ccpCode = residue.molResidue.ccpCode seqCode = residue.seqCode rowspan = 2 checkButton = CheckButton( frame, selected=isStereo, callback=lambda status=isStereo, fr=frameRow, item=i, setup =False: self.toggleResonances(status, fr, item, setup)) checkButton.grid(row=frameRow, rowspan=rowspan, column=0, sticky=Tkinter.EW) label = Label(frame, text=ccpCode, width=5) label.grid(row=frameRow, rowspan=rowspan, column=1, sticky=Tkinter.E) label = Label(frame, text=str(seqCode), width=5) label.grid(row=frameRow, rowspan=rowspan, column=2, sticky=Tkinter.W) # # Set up the atom names # for j in range(0, len(atomSetGroup)): atomSet = atomSetGroup[j] label = Label(frame, text=atomSet.name) label.grid(row=frameRow + j, column=3, sticky=Tkinter.E, ipadx=4) # # Set up the resonances # self.resonanceObjects[frameRow] = { True: [[], []], False: [[], []] } resonanceLabelList = [] for resonance in resonances: if not resonance: resonanceLabel = 'unknown' else: if hasattr(resonance, 'shifts') and resonance.shifts: shiftLabel = " (shifts: " for shift in resonance.sortedShifts(): shiftLabel += "%.2f, " % shift.value shiftLabel = shiftLabel[:-2] + ")" else: shiftLabel = "" resonanceLabel = "'%d.%s'%s" % ( seqCode, resonance.name, shiftLabel) self.resonanceLabelDict[resonanceLabel] = resonance resonanceLabelList.append(resonanceLabel) separator = Separator(frame, height=1, width=30) separator.setColor('black', bgColor='black') separator.grid(row=frameRow, column=4, sticky=Tkinter.EW) self.resonanceObjects[frameRow][True][0].append(separator) separator = CrossLine(frame, height=20, width=30, canvas_bg=frame['bg'], color='dimgray') self.resonanceObjects[frameRow][False][0].append(separator) resonanceList = PulldownMenu( frame, entries=resonanceLabelList, callback=lambda selInd=x, selItem=y, fr=frameRow, item=i: self.setProchiralLabels(selInd, selItem, fr, item), do_initial_callback=False, label_color='red') resonanceList.grid(row=frameRow, column=5, sticky=Tkinter.EW) self.resonanceObjects[frameRow][True][0].append(resonanceList) resonanceLabel = Label(frame, text="%s" % resonanceLabelList[0], fg='dimgray') self.resonanceObjects[frameRow][False][0].append( resonanceLabel) separator = Separator(frame, height=1, width=30) separator.setColor('black', bgColor='black') separator.grid(row=frameRow + 1, column=4) self.resonanceObjects[frameRow][True][1].append(separator) self.resonanceObjects[frameRow][False][1].append(None) resonanceLabel = Label(frame, text="%s" % resonanceLabelList[1], fg='red') resonanceLabel.grid(row=frameRow + 1, column=5, sticky=Tkinter.EW) self.resonanceObjects[frameRow][True][1].append(resonanceLabel) resonanceLabel = Label(frame, text="%s" % resonanceLabelList[1], fg='dimgray') self.resonanceObjects[frameRow][False][1].append( resonanceLabel) if not isStereo: checkButton.callback(isStereo, setup=True) separator = Separator(frame, height=1) separator.setColor('black', bgColor='black') separator.grid(row=frameRow + rowspan, columnspan=6, sticky=Tkinter.EW) frameRow += rowspan + 1 elif not usePreviousSettings: self.chainResonancesDict[self.resParent][chain].append(None) return True
def body(self, master): # # Setup header # row = 0 label = Label(master, text='Select the resonance list:') label.grid(row=row, column=0, sticky=Tkinter.EW) label = Label(master, text='Select the chain:') label.grid(row=row, column=1, sticky=Tkinter.EW) row += 1 self.resParentSelect = PulldownMenu(master, entries=self.resParentList, callback=self.setupResParentList, do_initial_callback=False) self.resParentSelect.grid(row=row, column=0, sticky=Tkinter.EW) self.chainSelect = PulldownMenu(master, entries=[], callback=self.setupProchiralList, do_initial_callback=False) self.chainSelect.grid(row=row, column=1, sticky=Tkinter.EW) row += 1 separator = Separator(master, height=3) separator.setColor('black', bgColor='black') separator.grid(row=row, columnspan=2, sticky=Tkinter.EW) row += 1 # THIS BIT TELLS MASTER TO CONFIGURE WINDOW ON INSIDE WIDGET!! master.grid_rowconfigure(row, weight=1) for i in range(2): master.grid_columnconfigure(i, weight=1) self.prochiralListFrame = ScrolledFrame(master, width=200, doExtraConfig=False) self.prochiralListFrame.grid(row=row, column=0, columnspan=2, sticky=Tkinter.NSEW) self.prochiralListFrameRow = row self.prochiralListFrameMaster = master row = row + 1 texts = ['Set all', 'Set chain'] commands = [ self.ok, self.setStereo ] # This calls 'ok' in BasePopup, this then calls 'apply' in here buttons = createDismissHelpButtonList(master, texts=texts, commands=commands, dismiss_text='Exit', help_url=self.help_url) buttons.grid(row=row, column=0, columnspan=2, sticky=Tkinter.EW) self.resParentSelect.callback(0, self.resParentList[0])
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
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 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 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])