def __init__(self, parent, matrix=None, boxSize=8, maxVal=None, title=None, xLabels=[], yLabels=[], borderWidth=0.1, canvasOrigin=None, labelAxes=True, barPlot=False, borderColor='grey', zoom=1.0, *args, **kw): ScrolledCanvas.__init__(self, parent, width=250) self.font = 'Helvetica 8' self.boldFont = 'Helvetica 8 bold' self.origin = canvasOrigin or (0, 0) self.labelAxes = labelAxes self.border = None self.indent = 50 self.matrix = matrix self.borderWidth = borderWidth self.borderColor = borderColor self.zoom = zoom self.boxSize = boxSize self.maxVal = maxVal self.minVal = 0 if not self.maxVal: if self.matrix is not None: self.setMatrixMaxVal() else: self.maxVal = 1.0 self.hilightedItems = [] self.barPlot = barPlot self.title = title self.legend = [] self.canvasDict = {} self.boxes = [] self.xGrid = [] self.yGrid = [] self.xLabels = xLabels or [] self.yLabels = yLabels or [] self.xText = None self.yText = None self.xBg = None self.yBg = None self.draw() self.canvas.bind('<Button-1>', self.mouseClick) self.canvas.bind('<Double-1>', self.mouseDoubleClick) self.canvas.bind('<Motion>', self.mouseEnter) self.canvas.bind('<Enter>', self.mouseEnter) self.canvas.bind('<Leave>', self.mouseLeave)
def mouseMotion(self, event): if event.state & 1: # shift - zoom self.removeMenu() dx = event.x - self.initialX dy = self.initialY - event.y if dx == 0 and dy == 0: return if dy < 0: self.zoomOut() else: self.zoomIn() else: ScrolledCanvas.mouseScroll(self, event)
def __init__(self, parent, callback=None, rightCallback=None, width=420, height=440, bgColor='#FFFFFF', showCoords=True, xTicks=True, yTicks=True, xLabel=u'\u03A6', yLabel=u'\u03A8', titleText='', nullColor='#FFFFFF', enterCallback=None, leaveCallback=None, defaultPlot=True, *args, **kw): self.parent = parent ScrolledCanvas.__init__(self, parent, resizeCallback=self.drawCanvas, width=width, height=height) self.bitmapDir = joinPath(getTopDirectory(), 'data', 'ccpnmr', 'ramachandranPlot') self.canvas.config(bg=bgColor) self.rightCallback = rightCallback # handle for change of chosen quadrant self.callback = callback # handle for estimation selection self.enterCallback = enterCallback # handle for mouse enter an estimation self.leaveCallback = leaveCallback # handle for mouse leave an estimation self.defaultPlot = defaultPlot self.showCoords = showCoords self.xTicks = xTicks self.yTicks = yTicks self.xLabel = xLabel self.yLabel = yLabel self.matrix = [] # bin matrix forming the plot self.canvasDict = {} # aaType : a list of color distribution self.intensityDict = {} # aaType : a list of color distribution self.currentObjDict = {} # object : estimation circle on plot self.currentCirDict = {} # circle on plot : object self.residueLabels = {} self.currentObjects = [] self.selectedObjects = [] # a list of selected objects self.binSize = 10 # 10 degree for each bin self.cirTag = "est" # arbitrary tag of estimation circles self.maxInt = 255 # max number of color used self.selectColor = "#00C000" # color of a selected estimation self.unselectColor = "#000000" # color of a unselected estimation self.nullColor = nullColor self.objectColors = [] self.titleText = titleText self.title = None self.phi = None self.psi = None self.sd1 = None self.sd2 = None self.phiPsiList = [] self.labels = [] self.crosshair = [] self.plotCoords = [] self.aminoAcid = None self.binWidth = 10 # Arbitrary deafult - reset dynamically self.binHeight = 10 # Arbitrary deafult - reset dynamically self.cirRadius = 4 self.axisObjects = [] self.zoom = 1.0 # add handle function to mouse events on estimation objects self.canvas.bind("<Button-1>", self.circleClick) #if self.enterCallback: # self.canvas.tag_bind(self.cirTag, "<Enter>", self.circleEnter, "+") #if self.leaveCallback: # self.canvas.tag_bind(self.cirTag, "<Leave>", self.circleLeave, "+") self.canvas.bind('<B2-Motion>', self.mouseMotion) self.canvas.bind('<Button-4>', self.zoomIn) self.canvas.bind('<Button-5>', self.zoomOut) self.canvas.bind('<Motion>', self.mouseEnter) self.canvas.bind('<Enter>', self.mouseEnter) self.canvas.bind('<Leave>', self.mouseLeave) # add handle function to double mouse click on Rama plot #self.canvas.bind("<Button-3>", self.rightClick) self.drawCanvas()
class PopupTemplate(BasePopup): def __init__(self, parent, project=None, *args, **kw): self.project = project self.parent = parent self.objects = self.getObjects() self.object = None BasePopup.__init__(self, parent=parent, title='Popup Template', **kw) self.updateObjects() def body(self, mainFrame): mainFrame.grid_columnconfigure(1, weight=1, minsize=100) mainFrame.config(borderwidth=5, relief='solid') row = 0 label = Label(mainFrame, text="Frame (with sub-widgets):") label.grid(row=row, column=0, sticky=Tkinter.E) frame = Frame(mainFrame, relief='raised', border=2, background='#8080D0') # Frame expands East-West frame.grid(row=row, column=1, sticky=Tkinter.EW) # Last column expands => Widgets pusted to the West frame.grid_columnconfigure(3, weight=1) # Label is within the sub frame label = Label(frame, text='label ') label.grid(row=0, column=0, sticky=Tkinter.W) entry = Entry(frame, text='Entry', returnCallback=self.showWarning) entry.grid(row=0, column=1, sticky=Tkinter.W) self.check = CheckButton(frame, text='Checkbutton', selected=True, callback=self.updateObjects) self.check.grid(row=0, column=2, sticky=Tkinter.W) # stick a button to the East wall button = Button(frame, text='Button', command=self.pressButton) button.grid(row=0, column=3, sticky=Tkinter.E) row += 1 label = Label(mainFrame, text="Text:") label.grid(row=row, column=0, sticky=Tkinter.E) self.textWindow = Text(mainFrame, text='Initial Text\n', width=60, height=5) self.textWindow.grid(row=row, column=1, sticky=Tkinter.NSEW) row += 1 label = Label(mainFrame, text="CheckButtons:") label.grid(row=row, column=0, sticky=Tkinter.E) entries = ['Alpha','Beta','Gamma','Delta'] selected = entries[2:] self.checkButtons = CheckButtons(mainFrame, entries, selected=selected,select_callback=self.changedCheckButtons) self.checkButtons.grid(row=row, column=1, sticky=Tkinter.W) row += 1 label = Label(mainFrame, text="PartitionedSelector:") label.grid(row=row, column=0, sticky=Tkinter.E) labels = ['Bool','Int','Float','String'] objects = [type(0),type(1),type(1.0),type('a')] selected = [type('a')] self.partitionedSelector= PartitionedSelector(mainFrame, labels=labels, objects=objects, colors = ['red','yellow','green','#000080'], callback=self.toggleSelector,selected=selected) self.partitionedSelector.grid(row=row, column=1, sticky=Tkinter.EW) row += 1 label = Label(mainFrame, text="PulldownMenu") label.grid(row=row, column=0, sticky=Tkinter.E) entries = ['Frodo','Pipin','Merry','Sam','Bill','Gandalf','Strider','Gimli','Legolas'] self.pulldownMenu = PulldownMenu(mainFrame, callback=self.selectPulldown, entries=entries, selected_index=2, do_initial_callback=False) self.pulldownMenu.grid(row=row, column=1, sticky=Tkinter.W) row += 1 label = Label(mainFrame, text="RadioButtons in a\nScrolledFrame.frame:") label.grid(row=row, column=0, sticky=Tkinter.EW) frame = ScrolledFrame(mainFrame, yscroll = False, doExtraConfig = True, width=100) frame.grid(row=row, column=1, sticky=Tkinter.EW) frame.grid_columnconfigure(0, weight=1) self.radioButtons = RadioButtons(frame.frame, entries=entries, select_callback=self.checkRadioButtons, selected_index=1, relief='groove') self.radioButtons.grid(row=0, column=0, sticky=Tkinter.W) row += 1 label = Label(mainFrame, text="LabelFrame with\nToggleLabels inside:") label.grid(row=row, column=0, sticky=Tkinter.E) labelFrame = LabelFrame(mainFrame, text='Frame Title') labelFrame.grid(row=row, column=1, sticky=Tkinter.NSEW) labelFrame.grid_rowconfigure(0, weight=1) labelFrame.grid_columnconfigure(3, weight=1) self.toggleLabel1 = ToggleLabel(labelFrame, text='ScrolledMatrix', callback=self.toggleFrame1) self.toggleLabel1.grid(row=0, column=0, sticky=Tkinter.W) self.toggleLabel1.arrowOn() self.toggleLabel2 = ToggleLabel(labelFrame, text='ScrolledGraph', callback=self.toggleFrame2) self.toggleLabel2.grid(row=0, column=1, sticky=Tkinter.W) self.toggleLabel3 = ToggleLabel(labelFrame, text='ScrolledCanvas', callback=self.toggleFrame3) self.toggleLabel3.grid(row=0, column=2, sticky=Tkinter.W) row += 1 mainFrame.grid_rowconfigure(row, weight=1) label = Label(mainFrame, text="changing/shrinking frames:") label.grid(row=row, column=0, sticky=Tkinter.E) self.toggleRow = row self.toggleFrame = Frame(mainFrame) self.toggleFrame.grid(row=row, column=1, sticky=Tkinter.NSEW) self.toggleFrame.grid_rowconfigure(0, weight=1) self.toggleFrame.grid_columnconfigure(0, weight=1) # option 1 self.intEntry = IntEntry(self, returnCallback = self.setNumber, width=8) self.multiWidget = MultiWidget(self, Entry, options=None, values=None, callback=self.setKeywords, minRows=3, maxRows=5) editWidgets = [None, None, self.intEntry, self.multiWidget] editGetCallbacks = [None, None, self.getNumber, self.getKeywords] editSetCallbacks = [None, None, self.setNumber, self.setKeywords] headingList = ['Name','Color','Number','Keywords'] self.scrolledMatrix = ScrolledMatrix(self.toggleFrame, headingList=headingList, editSetCallbacks=editSetCallbacks, editGetCallbacks=editGetCallbacks, editWidgets=editWidgets, callback=self.selectObject, multiSelect=False) self.scrolledMatrix.grid(row=0, column=0, sticky=Tkinter.NSEW) # option 2 self.scrolledGraph = ScrolledGraph(self.toggleFrame, width=400, height=300, symbolSize=5, symbols=['square','circle'], dataColors=['#000080','#800000'], lineWidths=[0,1] ) self.scrolledGraph.setZoom(1.3) dataSet1 = [[0,0],[1,1],[2,4],[3,9],[4,16],[5,25]] dataSet2 = [[0,0],[1,3],[2,6],[3,9],[4,12],[5,15]] self.scrolledGraph.update(dataSets=[dataSet1,dataSet2], xLabel = 'X axis label', yLabel = 'Y axis label', title = 'Main Title') self.scrolledGraph.draw() # option 3 self.scrolledCanvas = ScrolledCanvas(self.toggleFrame,relief = 'groove', borderwidth = 2, resizeCallback=None) canvas = self.scrolledCanvas.canvas font = 'Helvetica 10' box = canvas.create_rectangle(10,10,150,200, outline='grey', fill='grey90') line = canvas.create_line(0,0,200,200,fill='#800000', width=2) text = canvas.create_text(120,50, text='Text', font=font, fill='black') circle = canvas.create_oval(30,30,50,50,outline='#008000',fill='#404040',width=3) row += 1 label = Label(mainFrame, text="FloatEntry:") label.grid(row=row, column=0, sticky=Tkinter.E) self.floatEntry = FloatEntry(mainFrame, text=3.14159265, returnCallback=self.floatEntryReturn) self.floatEntry.grid(row=row, column=1, sticky=Tkinter.W) row += 1 label = Label(mainFrame, text="Scale:") label.grid(row=row, column=0, sticky=Tkinter.E) self.scale = Scale(mainFrame, from_=10, to=90, value=50, orient=Tkinter.HORIZONTAL) self.scale.grid(row=row, column=1, sticky=Tkinter.W) row += 1 label = Label(mainFrame, text="Value Ramp:") label.grid(row=row, column=0, sticky=Tkinter.E) self.valueRamp = ValueRamp(mainFrame, self.valueRampCallback, speed = 1.5, delay = 50) self.valueRamp.grid(row=row, column=1, sticky=Tkinter.W) row += 1 label = Label(mainFrame, text="ButtonList:") label.grid(row=row, column=0, sticky=Tkinter.E) texts = ['Select File','Close','Quit'] commands = [self.selectFile, self.close, self.quit] bottomButtons = ButtonList(mainFrame, texts=texts, commands=commands, expands=True) bottomButtons.grid(row=row, column=1, sticky=Tkinter.EW) self.protocol('WM_DELETE_WINDOW', self.quit) def floatEntryReturn(self, event): value = self.floatEntry.get() self.textWindow.setText('%s\n' % value) def selectObject(self, object, row, col): self.object = object def getKeywords(self, object): if object : values = object.keywords self.multiWidget.set(values) def setKeywords(self, event): values = self.multiWidget.get() self.object.keywords = values self.updateObjects() def getNumber(self, object): if object : self.intEntry.set(object.quantity) def setNumber(self, event): value = self.intEntry.get() self.object.quantity = value self.updateObjects() def toggleFrame1(self, isHidden): if isHidden: self.scrolledMatrix.grid_forget() self.toggleFrame.grid_forget() else: self.scrolledGraph.grid_forget() self.scrolledCanvas.grid_forget() self.scrolledMatrix.grid(row=0, column=0, sticky=Tkinter.NSEW) self.toggleFrame.grid(row=self.toggleRow, column=1,sticky=Tkinter.NSEW) self.toggleLabel2.arrowOff() self.toggleLabel3.arrowOff() def toggleFrame2(self, isHidden): if isHidden: self.scrolledGraph.grid_forget() self.toggleFrame.grid_forget() else: self.scrolledMatrix.grid_forget() self.scrolledCanvas.grid_forget() self.scrolledGraph.grid(row=0, column=0, sticky=Tkinter.NSEW) self.toggleFrame.grid(row=self.toggleRow, column=1,sticky=Tkinter.NSEW) self.toggleLabel1.arrowOff() self.toggleLabel3.arrowOff() def toggleFrame3(self, isHidden): if isHidden: self.scrolledCanvas.grid_forget() self.toggleFrame.grid_forget() else: self.scrolledMatrix.grid_forget() self.scrolledGraph.grid_forget() self.scrolledCanvas.grid(row=0, column=0, sticky=Tkinter.NSEW) self.toggleFrame.grid(row=self.toggleRow, column=1,sticky=Tkinter.NSEW) self.toggleLabel1.arrowOff() self.toggleLabel2.arrowOff() def valueRampCallback(self, value): self.textWindow.setText('%s\n' % value) def checkRadioButtons(self, value): self.textWindow.setText('%s\n' % value) def selectPulldown(self, index, name): self.textWindow.setText('%d, %s\n' % (index, name)) def toggleSelector(self, value): self.textWindow.setText('%s\n' % value) def changedCheckButtons(self, values): self.textWindow.setText(','.join(values) + '\n') def getObjects(self): objects = [] objects.append( Fruit('Lemon', '#FFFF00',1,keywords=['Bitter','Tangy'] ) ) objects.append( Fruit('Orange', '#FF8000',4 ) ) objects.append( Fruit('Banana', '#FFF000',5 ) ) objects.append( Fruit('Pinapple','#FFD000',9 ) ) objects.append( Fruit('Kiwi', '#008000',12) ) objects.append( Fruit('Lime', '#00FF00',2 ) ) objects.append( Fruit('Apple', '#800000',5,keywords=['Crunchy'] ) ) objects.append( Fruit('Pear', '#408000',6 ) ) objects.append( Fruit('Peach', '#FFE0C0',2,keywords=['Sweet','Furry'] ) ) objects.append( Fruit('Plumb', '#800080',7 ) ) return objects def updateObjects(self, event=None): textMatrix = [] objectList = [] colorMatrix = [] for object in self.objects: datum = [] datum.append( object.name ) datum.append( None ) datum.append( object.quantity ) datum.append( ','.join(object.keywords) ) colors = [None, object.color, None, None] textMatrix.append(datum) objectList.append(object) colorMatrix.append(colors) if self.check.get(): self.scrolledMatrix.update(textMatrix=textMatrix, objectList=objectList) else: self.scrolledMatrix.update(textMatrix=textMatrix, objectList=objectList, colorMatrix=colorMatrix) def selectFile(self): fileSelectPopup = FileSelectPopup(self, title = 'Choose file', dismiss_text = 'Cancel', selected_file_must_exist = True) fileName = fileSelectPopup.getFile() self.textWindow.setText('File Selected: %s\n' % fileName) def showWarning(self, eventObject): self.textWindow.setText('Text Entry Return Pressed\n') showWarning('Warning Title','Warning Message') return def pressButton(self): self.textWindow.setText('Button Pressed\n') if showYesNo('Title','Prompt: Clear text window?'): self.textWindow.clear() return def quit(self): BasePopup.destroy(self)
def body(self, mainFrame): mainFrame.grid_columnconfigure(1, weight=1, minsize=100) mainFrame.config(borderwidth=5, relief='solid') row = 0 label = Label(mainFrame, text="Frame (with sub-widgets):") label.grid(row=row, column=0, sticky=Tkinter.E) frame = Frame(mainFrame, relief='raised', border=2, background='#8080D0') # Frame expands East-West frame.grid(row=row, column=1, sticky=Tkinter.EW) # Last column expands => Widgets pusted to the West frame.grid_columnconfigure(3, weight=1) # Label is within the sub frame label = Label(frame, text='label ') label.grid(row=0, column=0, sticky=Tkinter.W) entry = Entry(frame, text='Entry', returnCallback=self.showWarning) entry.grid(row=0, column=1, sticky=Tkinter.W) self.check = CheckButton(frame, text='Checkbutton', selected=True, callback=self.updateObjects) self.check.grid(row=0, column=2, sticky=Tkinter.W) # stick a button to the East wall button = Button(frame, text='Button', command=self.pressButton) button.grid(row=0, column=3, sticky=Tkinter.E) row += 1 label = Label(mainFrame, text="Text:") label.grid(row=row, column=0, sticky=Tkinter.E) self.textWindow = Text(mainFrame, text='Initial Text\n', width=60, height=5) self.textWindow.grid(row=row, column=1, sticky=Tkinter.NSEW) row += 1 label = Label(mainFrame, text="CheckButtons:") label.grid(row=row, column=0, sticky=Tkinter.E) entries = ['Alpha','Beta','Gamma','Delta'] selected = entries[2:] self.checkButtons = CheckButtons(mainFrame, entries, selected=selected,select_callback=self.changedCheckButtons) self.checkButtons.grid(row=row, column=1, sticky=Tkinter.W) row += 1 label = Label(mainFrame, text="PartitionedSelector:") label.grid(row=row, column=0, sticky=Tkinter.E) labels = ['Bool','Int','Float','String'] objects = [type(0),type(1),type(1.0),type('a')] selected = [type('a')] self.partitionedSelector= PartitionedSelector(mainFrame, labels=labels, objects=objects, colors = ['red','yellow','green','#000080'], callback=self.toggleSelector,selected=selected) self.partitionedSelector.grid(row=row, column=1, sticky=Tkinter.EW) row += 1 label = Label(mainFrame, text="PulldownMenu") label.grid(row=row, column=0, sticky=Tkinter.E) entries = ['Frodo','Pipin','Merry','Sam','Bill','Gandalf','Strider','Gimli','Legolas'] self.pulldownMenu = PulldownMenu(mainFrame, callback=self.selectPulldown, entries=entries, selected_index=2, do_initial_callback=False) self.pulldownMenu.grid(row=row, column=1, sticky=Tkinter.W) row += 1 label = Label(mainFrame, text="RadioButtons in a\nScrolledFrame.frame:") label.grid(row=row, column=0, sticky=Tkinter.EW) frame = ScrolledFrame(mainFrame, yscroll = False, doExtraConfig = True, width=100) frame.grid(row=row, column=1, sticky=Tkinter.EW) frame.grid_columnconfigure(0, weight=1) self.radioButtons = RadioButtons(frame.frame, entries=entries, select_callback=self.checkRadioButtons, selected_index=1, relief='groove') self.radioButtons.grid(row=0, column=0, sticky=Tkinter.W) row += 1 label = Label(mainFrame, text="LabelFrame with\nToggleLabels inside:") label.grid(row=row, column=0, sticky=Tkinter.E) labelFrame = LabelFrame(mainFrame, text='Frame Title') labelFrame.grid(row=row, column=1, sticky=Tkinter.NSEW) labelFrame.grid_rowconfigure(0, weight=1) labelFrame.grid_columnconfigure(3, weight=1) self.toggleLabel1 = ToggleLabel(labelFrame, text='ScrolledMatrix', callback=self.toggleFrame1) self.toggleLabel1.grid(row=0, column=0, sticky=Tkinter.W) self.toggleLabel1.arrowOn() self.toggleLabel2 = ToggleLabel(labelFrame, text='ScrolledGraph', callback=self.toggleFrame2) self.toggleLabel2.grid(row=0, column=1, sticky=Tkinter.W) self.toggleLabel3 = ToggleLabel(labelFrame, text='ScrolledCanvas', callback=self.toggleFrame3) self.toggleLabel3.grid(row=0, column=2, sticky=Tkinter.W) row += 1 mainFrame.grid_rowconfigure(row, weight=1) label = Label(mainFrame, text="changing/shrinking frames:") label.grid(row=row, column=0, sticky=Tkinter.E) self.toggleRow = row self.toggleFrame = Frame(mainFrame) self.toggleFrame.grid(row=row, column=1, sticky=Tkinter.NSEW) self.toggleFrame.grid_rowconfigure(0, weight=1) self.toggleFrame.grid_columnconfigure(0, weight=1) # option 1 self.intEntry = IntEntry(self, returnCallback = self.setNumber, width=8) self.multiWidget = MultiWidget(self, Entry, options=None, values=None, callback=self.setKeywords, minRows=3, maxRows=5) editWidgets = [None, None, self.intEntry, self.multiWidget] editGetCallbacks = [None, None, self.getNumber, self.getKeywords] editSetCallbacks = [None, None, self.setNumber, self.setKeywords] headingList = ['Name','Color','Number','Keywords'] self.scrolledMatrix = ScrolledMatrix(self.toggleFrame, headingList=headingList, editSetCallbacks=editSetCallbacks, editGetCallbacks=editGetCallbacks, editWidgets=editWidgets, callback=self.selectObject, multiSelect=False) self.scrolledMatrix.grid(row=0, column=0, sticky=Tkinter.NSEW) # option 2 self.scrolledGraph = ScrolledGraph(self.toggleFrame, width=400, height=300, symbolSize=5, symbols=['square','circle'], dataColors=['#000080','#800000'], lineWidths=[0,1] ) self.scrolledGraph.setZoom(1.3) dataSet1 = [[0,0],[1,1],[2,4],[3,9],[4,16],[5,25]] dataSet2 = [[0,0],[1,3],[2,6],[3,9],[4,12],[5,15]] self.scrolledGraph.update(dataSets=[dataSet1,dataSet2], xLabel = 'X axis label', yLabel = 'Y axis label', title = 'Main Title') self.scrolledGraph.draw() # option 3 self.scrolledCanvas = ScrolledCanvas(self.toggleFrame,relief = 'groove', borderwidth = 2, resizeCallback=None) canvas = self.scrolledCanvas.canvas font = 'Helvetica 10' box = canvas.create_rectangle(10,10,150,200, outline='grey', fill='grey90') line = canvas.create_line(0,0,200,200,fill='#800000', width=2) text = canvas.create_text(120,50, text='Text', font=font, fill='black') circle = canvas.create_oval(30,30,50,50,outline='#008000',fill='#404040',width=3) row += 1 label = Label(mainFrame, text="FloatEntry:") label.grid(row=row, column=0, sticky=Tkinter.E) self.floatEntry = FloatEntry(mainFrame, text=3.14159265, returnCallback=self.floatEntryReturn) self.floatEntry.grid(row=row, column=1, sticky=Tkinter.W) row += 1 label = Label(mainFrame, text="Scale:") label.grid(row=row, column=0, sticky=Tkinter.E) self.scale = Scale(mainFrame, from_=10, to=90, value=50, orient=Tkinter.HORIZONTAL) self.scale.grid(row=row, column=1, sticky=Tkinter.W) row += 1 label = Label(mainFrame, text="Value Ramp:") label.grid(row=row, column=0, sticky=Tkinter.E) self.valueRamp = ValueRamp(mainFrame, self.valueRampCallback, speed = 1.5, delay = 50) self.valueRamp.grid(row=row, column=1, sticky=Tkinter.W) row += 1 label = Label(mainFrame, text="ButtonList:") label.grid(row=row, column=0, sticky=Tkinter.E) texts = ['Select File','Close','Quit'] commands = [self.selectFile, self.close, self.quit] bottomButtons = ButtonList(mainFrame, texts=texts, commands=commands, expands=True) bottomButtons.grid(row=row, column=1, sticky=Tkinter.EW) self.protocol('WM_DELETE_WINDOW', self.quit)
def mouseButton3(self, event): self.stop() ScrolledCanvas.mouseButton3(self, event)
def removeMenu(self, event=None): ScrolledCanvas.removeMenu(self, event) self.drawStructure()
def __init__(self, parent, model=None, zoom=1.0, resizeCallback=None, radiiScale=0.2, bondWidth=2, width=400, height=400, project=None, getPrintOption=None, setPrintOption=None, atomCallback=None, bondCallback=None, *args, **kw): self.project = project self.symbolColor = symbolColor self.getPrintOption = getPrintOption self.setPrintOption = setPrintOption ScrolledCanvas.__init__(self, parent, borderwidth=1, width=width, height=height, relief='solid', **kw) self.atomicColorDict = {'C':'#404040','N':'#0000A0', 'O':'#A00000','H':'#A0A0A0', 'P':'#00A000','S':'#A0A000'} self.radiiScale = radiiScale self.bondWidth = bondWidth self.yRotation = 0.0 self.xRotation = 0.0 self.zoomStep = 1.0 self.width = None self.height = None self.initialX = None self.initialY = None self.model = model self.connections = [] self.anchors = [] self.allAtoms = [] self.selectedAtoms = set() self.atomColors = {} self.cAtomDict = {} self.cBondDict = {} self.backbone = set() self.bbHighlight = False self.seqLabels = True self.center = (width/2.0,height/2.0,0) self.view = [x/zoom for x in (-1,1,-1,1)] self.animate = None self.atomCallback = atomCallback self.bondCallback = bondCallback self.grid_columnconfigure(0, weight=1) self.grid_rowconfigure(0, weight=1) self.cStructure = None # StructStructure.StructStructure() self.cStructureRotate = None self.cStructureZoom = None self.canvas.config(background='black') self.handler = TkHandler.TkHandler(self.canvas) self.bind('<Configure>', self.resize) self.canvas.bind('<Button-1>', self.mouseButton1) self.canvas.bind('<Button-2>', self.mouseButton2) self.canvas.bind('<Button-3>', self.mouseButton3) self.canvas.bind('<Prior>', self.zoomOut) self.canvas.bind('<Next>', self.zoomIn) if not isWindowsOS: self.canvas.bind('<Button-4>', self.zoomIn) self.canvas.bind('<Button-5>', self.zoomOut) else: self.canvas.bind('<MouseWheel>', self.windowsOsZoom) self.canvas.bind('<Up>', self.rotateUp) self.canvas.bind('<Down>', self.rotateDown) self.canvas.bind('<Left>', self.rotateLeft) self.canvas.bind('<Right>', self.rotateRight) self.canvas.bind('<Control-Up>', lambda e: self.translate(0,6)) self.canvas.bind('<Control-Down>', lambda e: self.translate(0,-6)) self.canvas.bind('<Control-Left>', lambda e: self.translate(-6,0)) self.canvas.bind('<Control-Right>',lambda e: self.translate(6,0)) self.canvas.bind('<Leave>', self.stop) self.canvas.bind('<Enter>', self.enter) self.canvas.bind('<ButtonRelease-1>',self.mouseButtonRelease1) self.canvas.bind('<ButtonRelease-2>',self.mouseButtonRelease2) self.canvas.bind('<B2-Motion>', self.mouseMotion) self.bind('<Configure>', self.resize) self.bind('<Expose>', self.expose) self.configMenu()
def __init__(self, parent, dataSets=None, title=None, width=650, height=400, zoom=1.0, xLabels=None, symbolSize=5, xLabel=None, yLabel=None, dataNames=None, showCoords=True, xTicks=True, yTicks=True, yRange=None, xLog=False, yLog=False, reverseX=False, relief='sunken', bgColor='white', mgColor='grey90', fgColor='black', symbols=None, canvasOrigin=(0, 0), dataColors=None, lineWidths=None, graphType='line', *args, **kw): Frame.__init__(self, parent, *args, **kw) if dataSets: nSets = len(dataSets) else: nSets = 0 defaultColors = [ '#800000', '#000080', '#008000', '#808000', '#800080', '#008080', '#808080', '#000000', '#804000', '#004080' ] self.canvasOrigin = canvasOrigin self.showCoords = showCoords self.xTicks = xTicks self.yTicks = yTicks self.dataSets = dataSets self.width = width self.height = height self.title = title or '' self.zoom = zoom or 1.0 self.xLabel = xLabel or 'x' self.yLabel = yLabel or 'y' self.xLabels = xLabels or [] self.xLog = xLog self.yLog = yLog self.bgColor = bgColor self.fgColor = fgColor self.mgColor = mgColor self.graphType = graphType self.symbolSize = symbolSize self.reverseX = reverseX self.dataColors = dataColors or [ defaultColors[i % 10] for i in range(nSets) ] self.dataNames = dataNames or [None] * nSets self.lineWidths = lineWidths or [1 for x in range(nSets)] self.symbols = symbols or ['circle' for x in range(nSets)] self.legend = (1.0, 0.75, {}) self.yRange = yRange self.grid_rowconfigure(0, weight=1) self.grid_columnconfigure(0, weight=1) self.scrolledCanvas = ScrolledCanvas(self, borderwidth=2, relief=relief, width=width + 100, height=height + 100) self.scrolledCanvas.grid(row=0, column=0, sticky=Tkinter.NSEW) self.scrolledCanvas.canvas.config(bg=bgColor) self.inMotion = False self.canvas = self.scrolledCanvas.canvas self.canvasDict = {} self.waiting = 0 self.canvas.bind('<Button-1>', self.mouseClick) self.canvas.bind('<B1-Motion>', self.mouseDrag) self.canvas.bind('<Motion>', self.mouseEnter) self.canvas.bind('<Enter>', self.mouseEnter) self.canvas.bind('<Leave>', self.mouseLeave) if not isWindowsOS: self.canvas.bind('<Button-4>', lambda event: self.setZoom(self.zoom * 1.2)) self.canvas.bind('<Button-5>', lambda event: self.setZoom(self.zoom / 1.2)) else: self.canvas.bind('<MouseWheel>', self.windowsOsZoom) self.configMenu() self.draw()
class ScrolledGraph(Frame): items = [] crosshair = [] dataRegion = (0.0, 0.0, 1.0, 1.0) font = '-schumacher-clean-bold-r-normal--17-120-100-100-c-0-iso646.1991-irv', # category axes # log scale # fix variable bin width # redo ticks esp for category axis def __init__(self, parent, dataSets=None, title=None, width=650, height=400, zoom=1.0, xLabels=None, symbolSize=5, xLabel=None, yLabel=None, dataNames=None, showCoords=True, xTicks=True, yTicks=True, yRange=None, xLog=False, yLog=False, reverseX=False, relief='sunken', bgColor='white', mgColor='grey90', fgColor='black', symbols=None, canvasOrigin=(0, 0), dataColors=None, lineWidths=None, graphType='line', *args, **kw): Frame.__init__(self, parent, *args, **kw) if dataSets: nSets = len(dataSets) else: nSets = 0 defaultColors = [ '#800000', '#000080', '#008000', '#808000', '#800080', '#008080', '#808080', '#000000', '#804000', '#004080' ] self.canvasOrigin = canvasOrigin self.showCoords = showCoords self.xTicks = xTicks self.yTicks = yTicks self.dataSets = dataSets self.width = width self.height = height self.title = title or '' self.zoom = zoom or 1.0 self.xLabel = xLabel or 'x' self.yLabel = yLabel or 'y' self.xLabels = xLabels or [] self.xLog = xLog self.yLog = yLog self.bgColor = bgColor self.fgColor = fgColor self.mgColor = mgColor self.graphType = graphType self.symbolSize = symbolSize self.reverseX = reverseX self.dataColors = dataColors or [ defaultColors[i % 10] for i in range(nSets) ] self.dataNames = dataNames or [None] * nSets self.lineWidths = lineWidths or [1 for x in range(nSets)] self.symbols = symbols or ['circle' for x in range(nSets)] self.legend = (1.0, 0.75, {}) self.yRange = yRange self.grid_rowconfigure(0, weight=1) self.grid_columnconfigure(0, weight=1) self.scrolledCanvas = ScrolledCanvas(self, borderwidth=2, relief=relief, width=width + 100, height=height + 100) self.scrolledCanvas.grid(row=0, column=0, sticky=Tkinter.NSEW) self.scrolledCanvas.canvas.config(bg=bgColor) self.inMotion = False self.canvas = self.scrolledCanvas.canvas self.canvasDict = {} self.waiting = 0 self.canvas.bind('<Button-1>', self.mouseClick) self.canvas.bind('<B1-Motion>', self.mouseDrag) self.canvas.bind('<Motion>', self.mouseEnter) self.canvas.bind('<Enter>', self.mouseEnter) self.canvas.bind('<Leave>', self.mouseLeave) if not isWindowsOS: self.canvas.bind('<Button-4>', lambda event: self.setZoom(self.zoom * 1.2)) self.canvas.bind('<Button-5>', lambda event: self.setZoom(self.zoom / 1.2)) else: self.canvas.bind('<MouseWheel>', self.windowsOsZoom) self.configMenu() self.draw() def configMenu(self): zoom_items = [ \ { 'kind': 'command', 'label': 'In', 'command': lambda event: self.setZoom(self.zoom*1.2) }, { 'kind': 'command', 'label': 'Out', 'command': lambda event: self.setZoom(self.zoom/1.2) }, { 'kind': 'command', 'label': 'Reset', 'command': lambda event: self.setZoom(1.0) }, ] type_items = [ \ { 'kind': 'command', 'label': 'Line', 'command':lambda event: self.setGraphType('line') }, { 'kind': 'command', 'label': 'Scatter', 'command':lambda event: self.setGraphType('scatter') }, { 'kind': 'command', 'label': 'Bar chart', 'command':lambda event: self.setGraphType('bar') }, { 'kind': 'command', 'label': 'Histogram', 'command':lambda event: self.setGraphType('histogram') }, ] symboltype_items = [ \ { 'kind': 'command', 'label': 'Circle', 'command':lambda event: self.setSymbols('circle') }, { 'kind': 'command', 'label': 'Square', 'command':lambda event: self.setSymbols('square') }, { 'kind': 'command', 'label': 'Triangle', 'command':lambda event: self.setSymbols('triangle') }, ] symbolsize_items = [ \ { 'kind': 'command', 'label': '+', 'command':lambda event: self.setSymbolSize( self.symbolSize+1 ) }, { 'kind': 'command', 'label': '-', 'command':lambda event: self.setSymbolSize( max(self.symbolSize-1,1) ) }, { 'kind': 'command', 'label': 'Small', 'command':lambda event: self.setSymbolSize(3) }, { 'kind': 'command', 'label': 'Normal', 'command':lambda event: self.setSymbolSize(5) }, { 'kind': 'command', 'label': 'Big', 'command':lambda event: self.setSymbolSize(7) }, ] _items = [ \ { 'kind': 'command', 'label': '', 'command':'' }, { 'kind': 'command', 'label': '', 'command':'' }, { 'kind': 'command', 'label': '', 'command':'' }, ] items = [ { 'kind': 'cascade', 'label': 'Zoom', 'submenu': zoom_items }, { 'kind': 'cascade', 'label': 'Graph type', 'submenu': type_items }, { 'kind': 'cascade', 'label': 'Symbol type', 'submenu': symboltype_items }, { 'kind': 'cascade', 'label': 'Symbol size', 'submenu': symbolsize_items }, { 'kind': 'command', 'label': 'Set Title', 'command': self.setGraphTitle }, { 'kind': 'command', 'label': 'Print to file', 'command': self.scrolledCanvas.printCanvas }, ] self.scrolledCanvas.menu.setMenuItems(items) def setGraphTitle(self, event): self.title = askString('Text Entry', 'Enter graph title', self.title, self) self.drawAfter() def mouseClick(self, event): self.inMotion = False def mouseDrag(self, event): self.scrolledCanvas.removeMenu() canvas = self.canvas x = canvas.canvasx(event.x) y = canvas.canvasy(event.y) obj = self.canvas.find('closest', x, y)[0] inMotion = self.inMotion xF, yF, itemDict = self.legend if inMotion or itemDict.has_key(obj): plotRegion = self.getPlotRegion() x1 = plotRegion[0] y1 = plotRegion[1] rX = plotRegion[2] - x1 rY = plotRegion[3] - y1 if inMotion: dx, dy = inMotion else: x0 = x1 + (xF * rX) y0 = y1 + (yF * rY) dx = x - x0 dy = y - y0 self.legend = ((x - dx - x1) / rX, (y - dy - y1) / rY, itemDict) for item in itemDict: canvas.delete(item) self.drawLegend(plotRegion) self.inMotion = (dx, dy) def mouseEnter(self, event): canvas = self.canvas cCoords = canvas.coords cLine = canvas.create_line cText = canvas.create_text crosshair = self.crosshair canvas.focus_force() self.scrolledCanvas.removeMenu() x = canvas.canvasx(event.x) y = canvas.canvasy(event.y) plotRegion = self.getPlotRegion() (x0, y0, x1, y1) = plotRegion if (x < x0) or (x > x1) or (y < y1) or (y > y0): self.mouseLeave() else: if self.showCoords: coordStr = '[ %3.3f, %3.3f ]' % self.getPlotCoords( event, self.dataRegion, plotRegion) else: coordStr = '' if crosshair: (itemV, itemH, itemT) = crosshair cCoords(itemV, x, y0, x, y1) cCoords(itemH, x0, y, x1, y) cCoords(itemT, x0 + (0.9 * (x1 - x0)), y0 + y1) canvas.itemconfig(itemT, text=coordStr) else: mgColor = self.mgColor itemV = cLine(x, y0, x, y1, fill=mgColor, width=1) itemH = cLine(x0, y, x1, y, fill=mgColor, width=1) itemT = cText(x0 + (0.9 * (x1 - x0)), y0 + y1, text=coordStr, fill=self.fgColor) self.crosshair = (itemV, itemH, itemT) def mouseLeave(self, *event): if self.crosshair: for item in self.crosshair: self.canvas.delete(item) self.crosshair = [] def drawAfter(self): if not self.waiting: self.waiting = 1 self.after_idle(self.draw) def getMinMaxValues(self, dataSets): if (not dataSets): return [0.0, 1.0, 0.0, 1.0, 1, 1.0, 1.0] maxN = len(dataSets[0]) bigSet = 0 for i in range(len(dataSets)): if (len(dataSets[i]) > maxN): maxN = len(dataSets[i]) bigSet = i if (maxN < 1): return [0.0, 1.0, 0.0, 1.0, 1, 1.0, 1.0] maxX = dataSets[bigSet][0][0] or 0.0 minX = dataSets[bigSet][0][0] or 0.0 maxY = dataSets[bigSet][0][1] or 0.0 minY = dataSets[bigSet][0][1] or 0.0 minDy = None minDx = None for i in range(len(dataSets)): N = len(dataSets[i]) for j in range(N): x, y, e = dataSets[i][j] e = e or 0.0 if x is not None: if x < minX: minX = x if x > maxX: maxX = x if j + 1 < N: x2 = dataSets[i][j + 1][0] if x2 is not None: dX = dataSets[i][j + 1][0] - x if (minDx is None) or (dX < minDx): minDx = dX if y is not None: if y - e < minY: minY = y - e if y + e > maxY: maxY = y + e if j + 1 < N: y2 = dataSets[i][j + 1][1] if y2 is not None: dY = y2 - y if (minDy is None) or (dY < minDy): minDy = dY if self.yRange: yRange = list(self.yRange) yRange.sort() yMin, yMax = yRange if maxX == minX: maxX += 1.0 if maxY == minY: maxY += 1.0 if not minDx: minDx = 1.0 if not minDy: minDy = 1.0 return [minX, maxX, minY, maxY, maxN, minDx, minDy] def checkDataSets(self, dataSets): if not dataSets: return N = len(dataSets) validTypes = (type(float()), type(int())) for i in range(N): c = 0.0 for j in range(len(dataSets[i])): datum = dataSets[i][j] (x, y) = datum[:2] if len(datum) == 2: e = None else: e = datum[2] if (not y) and (y != 0): y = None if (not x) and (x != 0): x = None else: t = type(x) if t not in validTypes: x = c c += 1.0 dataSets[i][j] = (x, y, e) dataSets[i].sort() return dataSets def getDrawCoords(self, dataSet, dataRegion, plotRegion): deltaXplot = plotRegion[2] - plotRegion[0] deltaYplot = plotRegion[3] - plotRegion[1] deltaXdata = dataRegion[2] - dataRegion[0] deltaYdata = dataRegion[3] - dataRegion[1] ppvX = deltaXplot / float(deltaXdata) ppvY = deltaYplot / float(deltaYdata) coords = [] for x, y, e in dataSet: if (y is not None) and (x is not None): x0 = (x - dataRegion[0]) * ppvX y0 = (y - dataRegion[1]) * ppvY x0 += plotRegion[0] y0 += plotRegion[1] if e is None: e1 = e2 = None else: e0 = e * ppvY e1 = y0 + e0 e2 = y0 - e0 coords.append((x0, y0, e1, e2)) return coords def getPlotCoords(self, event, dataRegion, plotRegion): x = self.canvas.canvasx(event.x) - plotRegion[0] y = self.canvas.canvasy(event.y) - plotRegion[1] deltaXplot = plotRegion[2] - plotRegion[0] deltaYplot = plotRegion[3] - plotRegion[1] deltaXdata = dataRegion[2] - dataRegion[0] deltaYdata = dataRegion[3] - dataRegion[1] vppX = deltaXdata / float(deltaXplot) vppY = deltaYdata / float(deltaYplot) plotX = dataRegion[0] + x * vppX plotY = dataRegion[1] + y * vppY return (plotX, plotY) def getBoxSize(self, plotRegion, numBoxes, numSets=1): deltaXplot = plotRegion[2] - plotRegion[0] size = deltaXplot / float(numBoxes * numSets) return size def drawBoxes(self, plotRegion, coords, size, outline='black', fill='grey', setSel=0, numSets=1, graphType='bar'): create_rectangle = self.canvas.create_rectangle create_line = self.canvas.create_line d = size / 2.0 m = 0.0 if self.xLabels: if graphType == 'bar': m = size * (numSets / 2.0) else: m = d d1 = (setSel - ((numSets - 1) / 2.0)) * size maxX, minY, minX, maxY = self.dataRegion if (minY < 0) and (maxY > 0): f = maxY / (maxY - minY) y1 = plotRegion[3] + (f * (plotRegion[1] - plotRegion[3])) elif (minY < 0) and (maxY < 0): y1 = plotRegion[3] else: y1 = plotRegion[1] items = [] for (x, y0, yU, yL) in coords: if graphType == 'bar': x0 = x + d1 - d + m x1 = x + d1 + d + m else: x0 = x - d + m x1 = x + d + m item = create_rectangle(x0, y0, x1, y1, outline=outline, fill=fill) items.append(item) if yU is not None: xm = (x1 + x0) / 2.0 item = create_line(xm, y0, xm, yU, fill=outline) items.append(item) item = create_line(x0, yU, x1, yU, fill=outline) items.append(item) if yL is not None: xm = (x1 + x0) / 2.0 item = create_line(xm, y0, xm, yL, fill=outline) items.append(item) item = create_line(x0, yL, x1, yL, fill=outline) items.append(item) return items def drawLines(self, coords, outline, lineWidth): create_line = self.canvas.create_line N = len(coords) items = [] for i in range(N - 1): (x0, y0, y0a, y0b) = coords[i] (x1, y1, y1a, y1b) = coords[i + 1] item = create_line(x0, y0, x1, y1, fill=outline, width=lineWidth) items.append(item) return items def drawSymbols(self, coords, size, lineWidth, shape='circle', outline='black', fill='grey'): d = size / 2.0 d1 = sqrt3over2 * d d2 = size / 4.0 items = [] create_line = self.canvas.create_line if shape == 'triangle': create_polygon = self.canvas.create_polygon for (x, y, yU, yL) in coords: x0 = x x1 = x + d1 x2 = x - d1 y0 = y - d y1 = y + d2 if yU is not None: item = create_line(x, y, x, yU, fill=outline) items.append(item) item = create_line(x1, yU, x2, yU, fill=outline) items.append(item) if yL is not None: item = create_line(x, y, x, yL, fill=outline) items.append(item) item = create_line(x1, yL, x2, yL, fill=outline) items.append(item) item = create_polygon(x0, y0, x1, y1, x2, y1, x0, y0, outline=outline, fill=fill, width=lineWidth) items.append(item) else: if shape == 'square': create_rectangle = self.canvas.create_rectangle for (x, y, yU, yL) in coords: x0 = x - d x1 = x + d y0 = y - d y1 = y + d if yU is not None: item = create_line(x, y, x, yU, fill=outline) items.append(item) item = create_line(x0, yU, x1, yU, fill=outline) items.append(item) if yL is not None: item = create_line(x, y, x, yL, fill=outline) items.append(item) item = create_line(x0, yL, x1, yL, fill=outline) items.append(item) item = create_rectangle(x0, y0, x1, y1, outline=outline, fill=fill, width=lineWidth) items.append(item) else: create_oval = self.canvas.create_oval for (x, y, yU, yL) in coords: x0 = x - d x1 = x + d y0 = y - d y1 = y + d if yU is not None: item = create_line(x, y, x, yU, fill=outline) items.append(item) item = create_line(x0, yU, x1, yU, fill=outline) items.append(item) if yL is not None: item = create_line(x, y, x, yL, fill=outline) items.append(item) item = create_line(x0, yL, x1, yL, fill=outline) items.append(item) item = create_oval(x0, y0, x1, y1, outline=outline, fill=fill, width=lineWidth) items.append(item) return items def getPlotRegion(self): zoom = self.zoom x0, y0 = self.canvasOrigin plotRegion = (x0 + 75, y0 + 50 + (self.height * zoom), x0 + 75 + (self.width * zoom), y0 + 50) return plotRegion def draw(self): zoom = self.zoom canvas = self.canvas canvasDict = self.canvasDict dataSets = self.dataSets for item in self.items: canvas.delete(item) self.items = [] dataSets = self.checkDataSets(dataSets) if not dataSets: return [minX, maxX, minY, maxY, maxN, minDx, minDy] = self.getMinMaxValues(dataSets) if self.reverseX: dataRegion = (maxX, minY, minX, maxY) else: dataRegion = (minX, minY, maxX, maxY) plotRegion = self.getPlotRegion() symbolSize = self.symbolSize # max(1,int(zoom*self.symbolSize)) self.dataRegion = dataRegion diffX = float(maxX - minX) or 1.0 diffY = float(maxY - minY) or 1.0 width = self.width * zoom height = self.height * zoom xpad = 75 ypad = 50 binLabels = [''] * (maxN + 1) N = float(len(dataSets)) M = len(dataSets[0]) step = diffX / maxN for n in range(maxN): x = minX + (n * step) binLabels[n] = '%4.2f' % x bins = diffX / min(1.0, minDx) if self.graphType == 'bar': size = self.getBoxSize(plotRegion, bins, N) else: size = self.getBoxSize(plotRegion, bins, 1) self.items.extend(self.drawAxes(plotRegion, dataRegion, 1)) i = 0 for dataSet in dataSets: color = self.dataColors[i] lineWidth = 1 # max(1,int(self.lineWidths[i]*zoom)) coords = self.getDrawCoords(dataSet, dataRegion, plotRegion) symbol = self.symbols[i] if self.graphType == 'line': items = self.drawLines(coords, color, lineWidth) self.items.extend(items) items = self.drawSymbols(coords, symbolSize, lineWidth, shape=symbol, outline=color, fill='grey') self.items.extend(items) elif self.graphType == 'scatter': items = self.drawSymbols(coords, symbolSize, lineWidth, shape=symbol, outline=color, fill='grey') self.items.extend(items) else: items = self.drawBoxes(plotRegion, coords, size, outline=self.fgColor, fill=color, setSel=i, numSets=N, graphType=self.graphType) self.items.extend(items) i += 1 self.scrolledCanvas.refresh() self.waiting = 0 def windowsOsZoom(self, event): delta = event.delta if delta > 0: self.setZoom(self.zoom * 1.2) elif delta < 0: self.setZoom(self.zoom / 1.2) def setZoom(self, factor=1.0): if factor: self.zoom = min(20, max(0.25, factor)) self.drawAfter() def setTitle(self, title): if title: self.title = str(title) else: self.title = '' self.drawAfter() def setXLabel(self, label): if label: self.xLabel = label else: self.xLabel = '' self.drawafter() def setYLabel(self, label): if label: self.yLabel = label else: self.yLabel = '' self.drawafter() def setYLog(self, boolean=True): self.yLog = boolean self.drawAfter() def setXLog(self, boolean=True): self.xLog = boolean self.drawAfter() def setDataColors(self, dataColors): self.dataColors = [] for i in range(len(self.dataSets)): if i < len(dataColors): self.dataColors.append(dataColors[i]) else: self.dataColors.append('black') self.drawAfter() def setLineWidths(self, widthsList): N = len(self.dataSets) if not widthsList: self.lineWidths = [1 for x in range(N)] else: self.lineWidths = [] for i in range(N): if i < len(widthsList): self.lineWidths.append(widthsList[i]) else: self.lineWidths.append(1) self.drawAfter() def setSymbols(self, symbolName): self.symbols = [symbolName for x in range(len(self.dataSets))] self.drawAfter() def setSymbolSize(self, size): self.symbolSize = size self.drawAfter() def setDataNames(self, names): self.dataNames = names self.drawAfter() def setGraphType(self, graphType): if graphType in ('line', 'bar', 'histogram', 'scatter'): self.graphType = graphType self.drawAfter() def update(self, dataSets=None, dataColors=None, lineWidths=None, title=None, xLabel=None, yLabel=None, dataNames=None, symbols=None): if dataSets: self.dataSets = dataSets self.setLineWidths(lineWidths) if dataNames: self.dataNames = dataNames if symbols: self.symbols = symbols if title: self.title = title if xLabel: self.xLabel = xLabel if yLabel: self.yLabel = yLabel if dataColors: self.setDataColors(dataColors) if len(self.dataSets) > len(self.dataColors): for i in range(len(self.dataColors), len(self.dataSets)): self.dataColors.append('red') else: self.dataColors = self.dataColors[:len(self.dataSets)] if len(self.dataSets) > len(self.symbols): for i in range(len(self.symbols), len(self.dataSets)): self.symbols.append('circle') else: self.symbols = self.symbols[:len(self.dataSets)] self.drawAfter() def drawAxes(self, plotRegion, dataRegion, lineWidth): items = [] (x0, y0, x1, y1) = plotRegion outline = self.canvas.create_rectangle(0, 0, 1, 1, outline=self.bgColor, width=1) background = self.canvas.create_rectangle(x0, y0, x1, y1, outline='#FFFFFF', fill='#FFFFFF', width=lineWidth) self.canvas.lower(outline) items.append(outline) items.extend(self.drawTicks(plotRegion, dataRegion)) items.append( self.canvas.create_line(x0, y0, x1, y0, fill=self.fgColor, width=lineWidth)) items.append( self.canvas.create_line(x0, y0, x0, y1, fill=self.fgColor, width=lineWidth)) items.extend(self.drawTitle(plotRegion)) items.extend(self.drawLegend(plotRegion)) return items def drawTicks(self, plotRegion, dataRegion): if not (self.xTicks or self.yTicks): return [] createLine = self.canvas.create_line createText = self.canvas.create_text deltaXplot = plotRegion[2] - plotRegion[0] deltaYplot = plotRegion[3] - plotRegion[1] deltaXdata = dataRegion[2] - dataRegion[0] deltaYdata = dataRegion[3] - dataRegion[1] x0 = plotRegion[0] y0 = plotRegion[1] x1 = plotRegion[2] y1 = plotRegion[3] size = 7 if self.xLabels: sizes = [len(x) for x in self.xLabels] size = max(sizes) item = createText(0, 0, text='A' * size) bbox = self.canvas.bbox(item) self.canvas.delete(item) dy = bbox[3] - bbox[1] dx = bbox[2] - bbox[0] yClose = 2 * dy xClose = dx * 1.5 items = [] lineWidth = 1 # max(1,self.zoom) # calculate major and minor lines # minor lines will be equispaced between major and of a suitable size. 2, 5, 10 target numbers # major lines # in the data range find the non fractional points - not too close and enough # given the plot range we know the delta # split the delta into adequately,minimally spaced chunks # split the plot range into the same number chunks # round up the plot diff to the nearest round point with the accuracy # specified by the data delta # 100 in 8 chunks => 12.5/chumk round to 10 # 0.3 in 5 chunks => 0.06/chunk round to 0.05 # 21 in 7 = 3/chunk round to 2 or 5 or 3 # 0.16 in 10 = 0.016 per chunk => round to 0.01 or 0.02 xt = x0 - 10 yt = y0 + 10 xs = x0 - 8 ys = y0 + 8 ppvX = deltaXplot / float(deltaXdata) ppvY = deltaYplot / float(deltaYdata) spaceXdata = xClose / ppvX spaceYdata = yClose / ppvY sciX = '%e' % abs(spaceXdata) sciY = '%e' % abs(spaceYdata) deciX = int(sciX[-3:]) deciY = int(sciY[-3:]) sigDX = int(sciX[0]) sigDY = int(sciY[0]) nX = 10.0 nY = 10.0 sX = abs(sigDX - nX) sY = abs(sigDY - nY) for n in (1.0, 2.0, 5.0): s = abs(sigDX - n) if s < sX: sX = s nX = n s = abs(sigDY - n) if s < sY: sY = s nY = n incX = (abs(spaceXdata) / spaceXdata) * nX * 10**(deciX) incY = (abs(spaceYdata) / spaceYdata) * -nY * 10**(deciY) valX = dataRegion[0] - (dataRegion[0] % incX) valY = dataRegion[1] - (dataRegion[1] % incY) if self.xTicks: for i in range(int(round(deltaXdata / incX)) + 2): tickX = round(valX, -deciX) x = plotRegion[0] + (tickX - dataRegion[0]) * ppvX valX += incX if x > plotRegion[2]: continue if x < plotRegion[0]: continue if self.xLabels and (i < len(self.xLabels)): if self.graphType in ('bar', 'histogram'): mid = (tickX + round(valX, -deciX)) / 2.0 x2 = plotRegion[0] + (mid - dataRegion[0]) * ppvX else: x2 = x text = self.xLabels[i] item = createText(x2, yt, text=text, anchor='n') else: text = self.formatText(tickX) item = createText(x, yt, text=text, anchor='n') items.append(item) item = createLine(x, y0, x, ys, fill=self.mgColor, width=lineWidth) items.append(item) item = createLine(x, y0, x, ys, fill=self.fgColor, width=lineWidth) items.append(item) if self.yTicks: for i in range(int(round(deltaYdata / incY)) + 2): tickY = round(valY, -deciY) y = plotRegion[1] + (tickY - dataRegion[1]) * ppvY valY += incY if y < plotRegion[3]: continue if y > plotRegion[1]: continue item = createText(xt, y, text=self.formatText(tickY), anchor='e') items.append(item) item = createLine(x0, y, x1, y, fill=self.mgColor, width=lineWidth) items.append(item) item = createLine(x0, y, xs, y, fill=self.fgColor, width=lineWidth) items.append(item) return items def formatText(self, text): if type(text) == type(float(1)): if text == 0: text = '0' elif abs(text) > 999999 or abs(text) < 0.01: text = '%5.2e' % text else: text = str(text) elif type(text) == type(int(1)): text = str(text) if text and text[0:1] == '@': text = '' return text def drawLegend(self, plotRegion): pad = 2 drawSymbols = self.drawSymbols createText = self.canvas.create_text createRect = self.canvas.create_rectangle symbolSize = max(5, int(self.zoom * self.symbolSize)) lineWidth = 1 graphType = self.graphType canvasBbox = self.canvas.bbox symbols = self.symbols fgColor = self.fgColor delete = self.canvas.delete x0, y0, x1, y1 = plotRegion canvasCoords = self.canvas.coords dataColors = self.dataColors outline = None dX = x1 - x0 dY = y1 - y0 fX, fY, itemDict = self.legend for item in itemDict: delete(item) xMax = 0 items = [] x = xS = x0 + (fX * dX) y = yS = y0 + (fY * dY) i = 0 for dataName in self.dataNames: if dataName is not None: if outline is None: outline = createRect(0, 0, 0, 0, fill=self.bgColor, outline=self.mgColor) color = dataColors[i] item = createText(x, y, text=dataName, fill=fgColor, anchor='nw') bbox = canvasBbox(item) items.append(item) h = bbox[3] - bbox[1] h2 = h / 2 canvasCoords(item, x + h + 2, y) coordsA = [ (x + h2, y + h2, None, None), ] if bbox[2] + h + 2 > xMax: xMax = bbox[2] + h + 2 if graphType == 'line': symbol = symbols[i] items0 = drawSymbols(coordsA, symbolSize, lineWidth, shape=symbol, outline=color, fill='grey') elif graphType == 'scatter': symbol = symbols[i] items0 = drawSymbols(coordsA, symbolSize, lineWidth, shape=symbol, outline=color, fill='grey') else: symbol = 'square' items0 = drawSymbols( coordsA, h, lineWidth, shape=symbol, outline=fgColor, fill=color, ) items.extend(items0) y += h + pad i += 1 if outline is not None: canvasCoords(outline, xS - 4, yS - 4, xMax + 2, y + 2) items.append(outline) itemDict = {} for item in items: itemDict[item] = True self.legend = fX, fY, itemDict return items def drawTitle(self, plotRegion): (x0, y0, x1, y1) = plotRegion createText = self.canvas.create_text fgColor = self.fgColor item0 = createText((x0 + x1) / 2.0, y1 / 2.0, text=self.title, fill=fgColor, font=self.font) item1 = createText((x0 + x1) / 2.0, y0 + y1, text=self.xLabel, fill=fgColor) item2 = createText(x0, y1 - 5, text=self.yLabel, fill=fgColor, anchor='se') return (item0, item1, item2)
class ViewChemicalShiftsPopup(BasePopup): """ **A Table of Chemical Shifts for Export** This section is designed to make a layout of a table for chemical shifts on a per-residue basis which may them be exported as either PostScript, for printing and graphical manipulation, or as plain text for import into other software or computer scripts. The user chooses the molecular chain (which sequence) and the shift list to use at the top of the popup, together with a few other options that control how things are rendered. Then buttons are toggled to select which kinds of atom will be displayed in aligned columns; other kinds will simply be listed to the right of the columns. Thus for example if the shift list does not contain any carbonyl resonances in a protein chain then the user may toggle the empty "C" column off. Once the desired layout is achieved the user then uses the [Export PostScript] or [Export Text] buttons to write the data into a file of the appropriate type. The user will be presented wit ha file browser to specify the location and the name of the file to be saved. It should be noted that although the graphical display in the popup itself is somewhat limited, e.g. the gaps and spacing doesn't always look perfect, the PostScript version that is exported is significantly neater. **Caveats & Tips** If you need a chemical shift list represented in a particular format, specific for a particular external NMR program then you should use the FormatConverter software. Chemical shifts may also be exported from any table in Analysis that contains such data by clicking the right mouse button over the table and selecting the export option. """ def __init__(self, parent, *args, **kw): self.shiftList = None self.font = 'Helvetica 10' self.boldFont = 'Helvetica 10 bold' self.symbolFont = 'Symbol 8' self.smallFont = 'Helvetica 8' self.chain = None self.textOut = '' self.textMatrix = [] BasePopup.__init__(self, parent=parent, title='Chart : Chemical Shifts Table') def body(self, guiFrame): row = 0 frame = Frame(guiFrame, grid=(row, 0)) frame.expandGrid(None, 6) label = Label(frame, text='Chain:', grid=(0, 0)) tipText = 'Selects which molecular chain to show residues and chemical shift values for' self.chainPulldown = PulldownList(frame, callback=self.changeChain, grid=(0, 1), tipText=tipText) label = Label(frame, text=' Shift List:', grid=(0, 2)) tipText = 'Selects which shift list is used to derive the displayed chemical shift values' self.shiftListPulldown = PulldownList(frame, callback=self.changeShiftList, grid=(0, 3), tipText=tipText) label = Label(frame, text=' List all shifts:', grid=(0, 4)) tipText = 'Sets whether to display all the chemical shifts for residues or just for the nominated atom types in columns' self.otherShiftsSelect = CheckButton(frame, callback=self.draw, grid=(0, 5), tipText=tipText) utilButtons = UtilityButtonList(frame, helpUrl=self.help_url, grid=(0, 7)) row += 1 frame = Frame(guiFrame, grid=(row, 0)) frame.expandGrid(None, 6) label = Label(frame, text=' 1-letter codes:', grid=(0, 0)) tipText = 'Whether to use 1-letter residue codes in the table, or otherwise Ccp/three-letter codes' self.oneLetterSelect = CheckButton(frame, callback=self.draw, grid=(0, 1), selected=False, tipText=tipText) precisions = [0.1, 0.01, 0.001] texts = [str(t) for t in precisions] label = Label(frame, text=' 1H precision:', grid=(0, 2)) tipText = 'Specifies how many decimal places to use when displaying 1H chemical shift values' self.protonPrecisionSelect = PulldownList(frame, texts=texts, objects=precisions, callback=self.draw, index=1, grid=(0, 3), tipText=tipText) label = Label(frame, text=' Other precision:') label.grid(row=0, column=4, sticky='w') tipText = 'Specifies how many decimal places to use when displaying chemical shift values for isotopes other than 1H' self.otherPrecisionSelect = PulldownList(frame, texts=texts, objects=precisions, callback=self.draw, index=1, grid=(0, 5), tipText=tipText) row += 1 frame = Frame(guiFrame, grid=(row, 0)) frame.expandGrid(None, 1) label = Label(frame, text='Column\nAtoms:', grid=(0, 0)) tipText = 'Selects which kinds of atoms are displayed in aligned columns, or otherwise displayed at the end of the residue row (if "List all shifts" is set)' self.optSelector = PartitionedSelector(frame, self.toggleOpt, tipText=tipText, maxRowObjects=10, grid=(0, 1), sticky='ew') options = ['H', 'N', 'C', 'CA', 'CB', 'CG'] self.optSelector.update(objects=options, labels=options, selected=['H', 'N', 'CA']) row += 1 guiFrame.expandGrid(row, 0) self.canvasFrame = ScrolledCanvas(guiFrame, relief='groove', width=650, borderwidth=2, resizeCallback=None, grid=(row, 0), padx=1, pady=1) self.canvas = self.canvasFrame.canvas #self.canvas.bind('<Button-1>', self.toggleResidue) row += 1 tipTexts = [ 'Output information from the table as PostScript file, for printing etc.', 'Output information from the table as a whitespace separated plain text file' ] commands = [self.makePostScript, self.exportText] texts = ['Export PostScript', 'Export Text'] buttonList = ButtonList(guiFrame, commands=commands, texts=texts, grid=(row, 0), tipTexts=tipTexts) chains = self.getChains() if len(chains) > 1: self.chain = chains[1] else: self.chain = None self.updateShiftLists() self.updateChains() self.otherShiftsSelect.set(True) self.update() for func in ('__init__', 'delete'): self.registerNotify(self.updateChains, 'ccp.molecule.MolSystem.Chain', func) for func in ('__init__', 'delete'): self.registerNotify(self.updateShiftLists, 'ccp.nmr.Nmr.ShiftList', func) def changeShiftList(self, shiftList): if shiftList is not self.shiftList: self.shiftList = shiftList self.update() def updateShiftLists(self, *opt): names = [] index = 0 shiftLists = getShiftLists(self.nmrProject) shiftList = self.shiftList if shiftLists: names = [ '%s [%d]' % (sl.name or '<No name>', sl.serial) for sl in shiftLists ] if shiftList not in shiftLists: shiftList = shiftLists[0] index = shiftLists.index(shiftList) if self.shiftList is not shiftList: self.shiftList = shiftList self.shiftListPulldown.setup(names, shiftLists, index) def getChains(self): chains = [ None, ] for molSystem in self.project.sortedMolSystems(): for chain in molSystem.sortedChains(): if len(chain.residues) > 1: chains.append(chain) return chains def changeChain(self, chain): if chain is not self.chain: self.chain = chain self.update() def updateChains(self, *opt): names = [] index = -1 chains = self.getChains() chain = self.chain if len(chains) > 1: names = [ 'None', ] + ['%s:%s' % (ch.molSystem.code, ch.code) for ch in chains[1:]] if chain not in chains: chain = chains[1] index = chains.index(chain) else: chain = None self.chainPulldown.setup(names, chains, index) def destroy(self): for func in ('__init__', 'delete'): self.unregisterNotify(self.updateChains, 'ccp.molecule.MolSystem.Chain', func) for func in ('__init__', 'delete'): self.unregisterNotify(self.updateShiftLists, 'ccp.nmr.Nmr.ShiftList', func) BasePopup.destroy(self) def exportText(self, *event): from memops.gui.FileSelect import FileType from memops.gui.FileSelectPopup import FileSelectPopup if self.textOut: fileTypes = [ FileType('Text', ['*.txt']), FileType('CSV', ['*.csv']), FileType('All', ['*']) ] fileSelectPopup = FileSelectPopup(self, file_types=fileTypes, title='Save table as text', dismiss_text='Cancel', selected_file_must_exist=False) fileName = fileSelectPopup.getFile() if fileName: file = open(fileName, 'w') if fileName.endswith('.csv'): for textRow in self.textMatrix: file.write(','.join(textRow) + '\n') else: file.write(self.textOut) def toggleOpt(self, selected): self.draw() def makePostScript(self): self.canvasFrame.printCanvas() def update(self): colors = [] selected = set() atomNames = set() if self.chain: for residue in self.chain.sortedResidues(): for atom in residue.atoms: chemAtom = atom.chemAtom if colorDict.get(chemAtom.elementSymbol) is None: continue if chemAtom.waterExchangeable: continue atomNames.add(atom.name[:2]) molType = residue.molResidue.molType if molType == 'protein': selected.add('H') selected.add('N') selected.add('CA') selected.add('C') elif molType == 'DNA': selected.add("C1'") elif molType == 'RNA': selected.add("C1'") elif molType == 'carbohydrate': selected.add("C1") else: for spinSystem in self.shiftList.nmrProject.resonanceGroups: if not spinSystem.residue: for resonance in spinSystem.resonances: for name in resonance.assignNames: atomNames.add(name) options = list(atomNames) molType = 'protein' if self.chain: molType = self.chain.molecule.molType options = greekSortAtomNames(options, molType=molType) if 'H' in options: options.remove('H') options = [ 'H', ] + options colors = [colorDict.get(n[0]) for n in options] if options and not selected: selected = [ options[0], ] self.optSelector.update(objects=options, labels=options, colors=colors, selected=list(selected)) self.draw() def draw(self, *opt): if not self.shiftList: return nmrProject = self.shiftList.nmrProject shiftList = self.shiftList font = self.font bfont = self.boldFont symbolFont = self.symbolFont sFont = self.smallFont bbox = self.canvas.bbox doOthers = self.otherShiftsSelect.get() spc = 4 gap = 14 x = gap y = gap ct = self.canvas.create_text cl = self.canvas.create_line cc = self.canvas.coords self.canvas.delete('all') ssDict = {} formatDict = { 0.1: '%.1f', 0.01: '%.2f', 0.001: '%.3f', } protonFormat = formatDict[self.protonPrecisionSelect.getObject()] otherFormat = formatDict[self.otherPrecisionSelect.getObject()] uSpinSystems = [] chains = set() molSystems = set() for spinSystem in nmrProject.resonanceGroups: residue = spinSystem.residue if residue: ssDict[residue] = ssDict.get(residue, []) + [ spinSystem, ] else: uSpinSystems.append((spinSystem.serial, spinSystem)) uSpinSystems.sort() commonAtoms = self.optSelector.getSelected() N = len(commonAtoms) chain = self.chain if chain: spinSystems = [] for residue in chain.sortedResidues(): spinSystems0 = ssDict.get(residue, []) for spinSystem in spinSystems0: if spinSystem and spinSystem.resonances: spinSystems.append([residue, spinSystem]) else: spinSystems = uSpinSystems strings = [] doOneLetter = self.oneLetterSelect.get() if spinSystems: x = gap y += gap numItems = [] codeItems = [] commonItems = [] otherItems = [] numWidth = 0 codeWidth = 0 commonWidths = [0] * N commonCounts = [0] * N for residue, spinSystem in spinSystems: if type(residue) is type(1): seqNum = '{%d}' % residue if doOneLetter: ccpCode = '-' else: ccpCode = spinSystem.ccpCode or '' else: if doOneLetter: ccpCode = residue.chemCompVar.chemComp.code1Letter else: ccpCode = getResidueCode(residue) seqNum = str(residue.seqCode) subStrings = [] subStrings.append(seqNum) subStrings.append(ccpCode) item = ct(x, y, text=seqNum, font=font, anchor='se') box = bbox(item) iWidth = box[2] - box[0] numWidth = max(numWidth, iWidth) numItems.append(item) item = ct(x, y, text=ccpCode, font=font, anchor='sw') box = bbox(item) iWidth = box[2] - box[0] codeWidth = max(codeWidth, iWidth) codeItems.append(item) commonShifts, commonElements, otherShifts = self.getShiftData( spinSystem, shiftList, commonAtoms) items = [] for i in range(N): values = commonShifts[i] element = commonElements[i] if element == 'H': shiftFormat = protonFormat else: shiftFormat = otherFormat subItems = [] for value in values: text = shiftFormat % value if text: item = ct(x, y, text=text, font=font, anchor='se') box = bbox(item) iWidth = box[2] - box[0] commonWidths[i] = max(commonWidths[i], iWidth) commonCounts[i] += 1 subItems.append(item) subStrings.append( ','.join([shiftFormat % v for v in values]) or '-') items.append(subItems) commonItems.append(items) if doOthers: items0 = [] i = 0 I = len(otherShifts) for atomLabel, element, value in otherShifts: label = atomLabel if label[0] == '?': label = label[3:-1] if element == 'H': shiftFormat = protonFormat else: shiftFormat = otherFormat subStrings.append('%6s:%-4s' % (shiftFormat % value, label)) i += 1 atoms = atomLabel.split('|') items = [] j = 0 for atom in atoms: text = element if j > 0: text = '/' + text item = ct(x, y, text=text, font=font, anchor='sw') box = bbox(item) iWidth = box[2] - box[0] - 3 items.append((iWidth, item, 0)) p = len(element) if len(atom) > p: letter = atom[p] if letter not in ('0123456789'): item = ct(x, y, text=letter.lower(), font=symbolFont, anchor='sw') box = bbox(item) iWidth = box[2] - box[0] - 2 items.append((iWidth, item, -4)) p += 1 text = atom[p:] if text: item = ct(x, y, text=text, font=sFont, anchor='sw') box = bbox(item) iWidth = box[2] - box[0] - 2 items.append((iWidth, item, -4)) j += 1 text = ' ' + shiftFormat % value if i != I: text += ',' item = ct(x, y, text=text, font=font, anchor='sw') box = bbox(item) iWidth = box[2] - box[0] - 4 items.append((iWidth, item, 0)) items0.append(items) otherItems.append(items0) strings.append(subStrings) y0 = y x = x0 = gap + numWidth + codeWidth + spc + spc for i in range(N): if not commonCounts[i]: continue x += commonWidths[i] + spc + spc element = commonElements[i] iWidth = 0 text = commonAtoms[i][len(element):].lower() if text: item = ct(x, y, text=text, font=symbolFont, anchor='se') box = bbox(item) iWidth = box[2] - box[0] - 2 ct(x - iWidth, y, text=element, font=font, anchor='se') y += gap for i in range(len(numItems)): x = gap + numWidth + spc cc(numItems[i], x, y) x += spc cc(codeItems[i], x, y) x += codeWidth x1 = x + spc yM = y for j in range(N): if not commonCounts[j]: continue x += commonWidths[j] + spc + spc items = commonItems[i][j] yB = y - gap for item in items: yB += gap cc(item, x, yB) yM = max(yB, yM) x += gap if doOthers: x += spc x3 = x for items in otherItems[i]: if x > 550: x = x3 y += gap for iWidth, item, dy in items: cc(item, x, y + dy) x += iWidth y = max(y, yM) y += gap x = x0 for i in range(N): if not commonCounts[i]: continue x += commonWidths[i] + spc + spc cl(x + 8, y0, x + 8, y - gap, width=0.3, fill='#808080') cl(x1, y0, x1, y - gap, width=0.3, fill='#808080') cl(0, 0, 550, 0, width=0.3, fill='#FFFFFF') y += gap textWidths = {} for subStrings in strings: for i, text in enumerate(subStrings): if text and len(text) > textWidths.get(i, 0): textWidths[i] = len(text) else: textWidths[i] = 0 formats = {} for i in textWidths.keys(): formats[i] = ' %%%ds' % max(6, textWidths[i]) textOut = '!' textRow = ['', ''] textMatrix = [textRow] textOut += ' ' * (max(6, textWidths.get(0, 6)) + max(6, textWidths.get(1, 6)) + 1) i = 2 for atom in commonAtoms: if i in formats: textOut += formats[i] % atom textRow.append((formats[i] % atom).strip()) i += 1 textOut += '\n' for subStrings in strings: textRow = [] textMatrix.append(textRow) i = 0 for text in subStrings: textOut += formats[i] % text textRow.append((formats[i] % text).strip()) i += 1 textOut += '\n' self.textOut = textOut self.textMatrix = textMatrix def getShiftData(self, spinSystem, shiftList, commonAtoms=('H', 'N', 'CA', 'CB')): commonShifts = [] commonResonances = {} commonElements = [] for atomName in commonAtoms: elements = set() resonances = [] for resonance in spinSystem.resonances: resonanceSet = resonance.resonanceSet if resonanceSet: for atomSet in resonanceSet.atomSets: for atom in atomSet.atoms: if atomName == atom.name[:2]: resonances.append(resonance) break else: continue break else: for assignName in resonance.assignNames: if atomName == assignName[:2]: resonances.append(resonance) break shiftValues = [] for resonance in resonances: isotope = resonance.isotope if isotope: elements.add(isotope.chemElement.symbol) commonResonances[resonance] = True shift = resonance.findFirstShift(parentList=shiftList) if shift: shiftValues.append(shift.value) if not elements: element = atomName[0] else: element = elements.pop() commonElements.append(element) commonShifts.append(shiftValues) otherShifts = [] for resonance in spinSystem.resonances: if not commonResonances.get(resonance): shift = resonance.findFirstShift(parentList=shiftList) if shift: isotope = resonance.isotope if isotope: element = isotope.chemElement.symbol else: element = '??' if resonance.assignNames or resonance.resonanceSet: name = getResonanceName(resonance) else: name = '??[%d]' % resonance.serial otherShifts.append((name, element, shift.value)) molType = 'protein' if spinSystem.residue: molType = spinSystem.residue.molResidue.molType otherShifts = greekSortAtomNames(otherShifts, molType) return commonShifts, commonElements, otherShifts
def body(self, guiFrame): row = 0 frame = Frame(guiFrame, grid=(row, 0)) frame.expandGrid(None, 6) label = Label(frame, text='Chain:', grid=(0, 0)) tipText = 'Selects which molecular chain to show residues and chemical shift values for' self.chainPulldown = PulldownList(frame, callback=self.changeChain, grid=(0, 1), tipText=tipText) label = Label(frame, text=' Shift List:', grid=(0, 2)) tipText = 'Selects which shift list is used to derive the displayed chemical shift values' self.shiftListPulldown = PulldownList(frame, callback=self.changeShiftList, grid=(0, 3), tipText=tipText) label = Label(frame, text=' List all shifts:', grid=(0, 4)) tipText = 'Sets whether to display all the chemical shifts for residues or just for the nominated atom types in columns' self.otherShiftsSelect = CheckButton(frame, callback=self.draw, grid=(0, 5), tipText=tipText) utilButtons = UtilityButtonList(frame, helpUrl=self.help_url, grid=(0, 7)) row += 1 frame = Frame(guiFrame, grid=(row, 0)) frame.expandGrid(None, 6) label = Label(frame, text=' 1-letter codes:', grid=(0, 0)) tipText = 'Whether to use 1-letter residue codes in the table, or otherwise Ccp/three-letter codes' self.oneLetterSelect = CheckButton(frame, callback=self.draw, grid=(0, 1), selected=False, tipText=tipText) precisions = [0.1, 0.01, 0.001] texts = [str(t) for t in precisions] label = Label(frame, text=' 1H precision:', grid=(0, 2)) tipText = 'Specifies how many decimal places to use when displaying 1H chemical shift values' self.protonPrecisionSelect = PulldownList(frame, texts=texts, objects=precisions, callback=self.draw, index=1, grid=(0, 3), tipText=tipText) label = Label(frame, text=' Other precision:') label.grid(row=0, column=4, sticky='w') tipText = 'Specifies how many decimal places to use when displaying chemical shift values for isotopes other than 1H' self.otherPrecisionSelect = PulldownList(frame, texts=texts, objects=precisions, callback=self.draw, index=1, grid=(0, 5), tipText=tipText) row += 1 frame = Frame(guiFrame, grid=(row, 0)) frame.expandGrid(None, 1) label = Label(frame, text='Column\nAtoms:', grid=(0, 0)) tipText = 'Selects which kinds of atoms are displayed in aligned columns, or otherwise displayed at the end of the residue row (if "List all shifts" is set)' self.optSelector = PartitionedSelector(frame, self.toggleOpt, tipText=tipText, maxRowObjects=10, grid=(0, 1), sticky='ew') options = ['H', 'N', 'C', 'CA', 'CB', 'CG'] self.optSelector.update(objects=options, labels=options, selected=['H', 'N', 'CA']) row += 1 guiFrame.expandGrid(row, 0) self.canvasFrame = ScrolledCanvas(guiFrame, relief='groove', width=650, borderwidth=2, resizeCallback=None, grid=(row, 0), padx=1, pady=1) self.canvas = self.canvasFrame.canvas #self.canvas.bind('<Button-1>', self.toggleResidue) row += 1 tipTexts = [ 'Output information from the table as PostScript file, for printing etc.', 'Output information from the table as a whitespace separated plain text file' ] commands = [self.makePostScript, self.exportText] texts = ['Export PostScript', 'Export Text'] buttonList = ButtonList(guiFrame, commands=commands, texts=texts, grid=(row, 0), tipTexts=tipTexts) chains = self.getChains() if len(chains) > 1: self.chain = chains[1] else: self.chain = None self.updateShiftLists() self.updateChains() self.otherShiftsSelect.set(True) self.update() for func in ('__init__', 'delete'): self.registerNotify(self.updateChains, 'ccp.molecule.MolSystem.Chain', func) for func in ('__init__', 'delete'): self.registerNotify(self.updateShiftLists, 'ccp.nmr.Nmr.ShiftList', func)