def __init__(self, parent, windows, **args): tk.Frame.__init__(self, parent, bg='white', **args) self.windows = windows self.manager = windows.manager self.root = windows.root #tkFont.Font(size=12, family='verdana', weight='bold') bigSize = pwgui.cfgFontSize + 2 smallSize = pwgui.cfgFontSize - 2 fontName = pwgui.cfgFontName self.projNameFont = tkFont.Font(size=bigSize, family=fontName, weight='bold') self.projDateFont = tkFont.Font(size=smallSize, family=fontName) self.projDelFont = tkFont.Font(size=smallSize, family=fontName, weight='bold') self.manager = Manager() btn = HotButton(self, text=Message.LABEL_CREATE_PROJECT, font=self.projNameFont, command=self._onCreateProject) btn.grid(row=0, column=0, sticky='nw', padx=10, pady=10) self.columnconfigure(0, weight=1) self.rowconfigure(1, weight=1) text = TaggedText(self, width=40, height=15, bd=0, bg='white') text.grid(row=1, column=0, sticky='news') self.createProjectList(text) text.setReadOnly(True) self.text = text
def _fillButtonsFrame(self, frame): subframe = tk.Frame(frame) subframe.grid(row=0, column=0, sticky='nw') frame.columnconfigure(1, weight=1) imgPlainBtn = Button(subframe, "View plain images", command=self._viewPlainImages) imgPlainBtn.grid(row=0, column=0, sticky='nw', padx=(0, 5)) if self._getModel() is None: imgPlainBtn['state'] = 'disabled' imgOverlaidBtn = Button(subframe, "View images with spots", command=self._viewOverlaidImages) imgOverlaidBtn.grid(row=0, column=1, sticky='nw', padx=(0, 5)) if None in {self._getModel(), self._getRefls()}: imgOverlaidBtn['state'] = 'disabled' reciprocalBtn = Button(subframe, "View reciprocal lattice", command=self._viewReciprocal) reciprocalBtn.grid(row=0, column=2, sticky='nw', padx=(0, 5)) if None in {self._getModel(), self._getRefls()}: reciprocalBtn['state'] = 'disabled' htmlBtn = HotButton(subframe, 'Open HTML Report', command=self._openHTML) htmlBtn.grid(row=0, column=3, sticky='nw', padx=(0, 5)) if self._getHtml() is None: htmlBtn['state'] = 'disabled' closeBtn = self.createCloseButton(frame) closeBtn.grid(row=0, column=1, sticky='ne')
def __init__(self, parent, windows, **kwargs): tk.Frame.__init__(self, parent, bg='white', **kwargs) self.windows = windows self.root = windows.root self.vars = {} self.checkvars = [] bigSize = pwgui.cfgFontSize + 2 smallSize = pwgui.cfgFontSize - 2 fontName = pwgui.cfgFontName self.bigFont = tkFont.Font(size=bigSize, family=fontName) self.bigFontBold = tkFont.Font(size=bigSize, family=fontName, weight='bold') self.projDateFont = tkFont.Font(size=smallSize, family=fontName) self.projDelFont = tkFont.Font(size=smallSize, family=fontName, weight='bold') # Header section headerFrame = tk.Frame(self, bg='white') headerFrame.grid(row=0, column=0, sticky='new') headerText = "Enter your desired values" label = tk.Label(headerFrame, text=headerText, font=self.bigFontBold, borderwidth=0, anchor='nw', bg='white', fg=pwgui.Color.DARK_GREY_COLOR) label.grid(row=0, column=0, sticky='nw', padx=(20, 5), pady=10) # Body section bodyFrame = tk.Frame(self, bg='white') bodyFrame.grid(row=1, column=0, sticky='news') self._fillContent(bodyFrame) # Add the create project button btnFrame = tk.Frame(self, bg='white') btn = HotButton(btnFrame, text="Start demo", font=self.bigFontBold, command=self._onAction) btn.grid(row=0, column=1, sticky='ne', padx=10, pady=10) # Add the Import project button btn = Button(btnFrame, Message.LABEL_BUTTON_CANCEL, Icon.ACTION_CLOSE, font=self.bigFontBold, command=self.windows.close) btn.grid(row=0, column=0, sticky='ne', padx=10, pady=10) btnFrame.grid(row=2, column=0, sticky='sew') btnFrame.columnconfigure(0, weight=1) self.columnconfigure(0, weight=1) self.rowconfigure(1, weight=1)
def visualizeClasses(self, e=None): classTemplate = "class_%03d" averages = '%03d@' + self.protocol._getFileName('averages') def getInfo2(level, classNo): return classTemplate % classNo, averages % classNo node = self.protocol.buildDendrogram() g = Graph(root=node) self.graph = g self.win = Window("Select classes", self.formWindow, minsize=(1000, 600)) root = self.win.root canvas = Canvas(root) canvas.grid(row=0, column=0, sticky='nsew') root.grid_columnconfigure(0, weight=1) root.grid_rowconfigure(0, weight=1) self.buttonframe = tk.Frame(root) self.buttonframe.grid(row=2, column=0, columnspan=2) self.win.createCloseButton(self.buttonframe).grid(row=0, column=0, sticky='n', padx=5, pady=5) saveparticlesbtn = HotButton(self.buttonframe, "Particles", Icon.PLUS_CIRCLE, command=lambda: self.askCreateSubset('Particles', self.getSelectedNodesCount(2))) saveparticlesbtn.grid(row=0, column=1, sticky='n', padx=5, pady=5) btn = HotButton(self.buttonframe, "Classes", Icon.PLUS_CIRCLE, command=lambda: self.askCreateSubset('Classes', self.getSelectedNodesCount(1))) btn.grid(row=0, column=2, sticky='n', padx=5, pady=5) lt = LevelTree(g) lt.DY = 135 # TODO: change in percent of the image size lt.setCanvas(canvas) lt.paint(self._createNode, maxLevel=self.maxLevel.get()-1) canvas.updateScrollRegion() return [self.win]
def _fillButtonsFrame(self, frame): subframe = tk.Frame(frame) subframe.grid(row=0, column=0, sticky='nw') frame.columnconfigure(1, weight=1) ctfBtn = Button(subframe, "CTF Monitor", command=self._monitorCTF) ctfBtn.grid(row=0, column=0, sticky='nw', padx=(0, 5)) if self.protocol.createCtfMonitor() is None: ctfBtn['state'] = 'disabled' movieGainBtn = Button(subframe, "Movie Gain Monitor", command=self._monitorMovieGain) movieGainBtn.grid(row=0, column=1, sticky='nw', padx=(0, 5)) if self.protocol.createMovieGainMonitor() is None: movieGainBtn['state'] = 'disabled' sysBtn = Button(subframe, "System Monitor", command=self._monitorSystem) sysBtn.grid(row=0, column=2, sticky='nw', padx=(0, 5)) if self.protocol.createSystemMonitor() is None: sysBtn['state'] = 'disabled' htmlBtn = HotButton(subframe, 'Open HTML Report', command=self._openHTML) htmlBtn.grid(row=0, column=3, sticky='nw', padx=(0, 5)) closeBtn = self.createCloseButton(frame) closeBtn.grid(row=0, column=1, sticky='ne')
def _createControls(self, frame): self._vars = {} inputFrame = tk.Frame(frame) inputFrame.grid(row=0, column=0) for i, varName in enumerate(CUSTOMMASK_VARS): self._createVarWidgets(inputFrame, varName, CUSTOMMASK_VARS[varName], i%2, i/2) previewBtn = HotButton(frame, text='Preview', command=self._computeRightPreview) previewBtn.grid(row=1, column=1, padx=5, pady=5)
def __init__(self, title, parent=None, weight=True, minsize=(400, 150), icon="scipion_bn.xbm", **args): """ We assume the parent should be of ProjectsView """ Window.__init__(self, title, parent.windows, weight=weight, icon=icon, minsize=minsize, enableQueue=True) self.parent = parent self.projectsPath = self.parent.manager.PROJECTS self.projName = tk.StringVar() self.projName.set('') self.projLocation = tk.StringVar() self.projLocation.set(self.projectsPath) content = tk.Frame(self.root) content.columnconfigure(0, weight=1) content.columnconfigure(1, weight=1) content.config(bg='white') content.grid(row=0, column=0, sticky='news', padx=5, pady=5) labelName = tk.Label(content, text=Message.LABEL_PROJECT, bg='white', bd=0) labelName.grid(row=0, column=0, sticky='nw', padx=5, pady=5) entryName = tk.Entry(content, bg=cfgEntryBgColor, width=20, textvariable=self.projName) entryName.grid(row=0, column=1, sticky='nw', padx=5, pady=5) labelCheck = tk.Label(content, text="Use default location", bg='white', bd=0) labelCheck.grid(row=1, column=0, sticky='nw', padx=5, pady=5) self.tkCheckVar = tk.IntVar() btnCheck = tk.Checkbutton(content, variable=self.tkCheckVar, bg='white', bd=0) btnCheck.grid(row=1, column=1, sticky='nw', padx=5, pady=5) self.browseFrame = tk.Frame(content, bg='white') #self.browseFrame.columnconfigure(1, weight=1) self.browseFrame.grid(row=2, column=0, padx=0, pady=0, columnspan=2, sticky='nw') self.entryBrowse = tk.Entry(self.browseFrame, bg=cfgEntryBgColor, width=40, textvariable=self.projLocation) self.entryBrowse.grid(row=0, column=0, sticky='nw', padx=5, pady=5) self.btnBrowse = IconButton(self.browseFrame, 'Browse', Icon.ACTION_BROWSE, command=self._browsePath) self.btnBrowse.grid(row=0, column=1, sticky='e', padx=5, pady=5) self.initial_focus = entryName self.tkCheckVar.trace('w', self._onVarChanged) btnCheck.select() btnFrame = tk.Frame(content) btnFrame.columnconfigure(0, weight=1) btnFrame.grid(row=3, column=0, sticky='sew', padx=5, pady=(0, 5), columnspan=2) btnFrame.config(bg='white') # Create buttons btnSelect = HotButton(btnFrame, 'Create', Icon.BUTTON_SELECT, command=self._select) btnSelect.grid(row=0, column=0, sticky='e', padx=5, pady=5) btnCancel = Button(btnFrame, 'Cancel', Icon.BUTTON_CANCEL, command=self.close) btnCancel.grid(row=0, column=1, sticky='e', padx=5, pady=5)
def _createControls(self, frame): self._vars = {} inputFrame = tk.Frame(frame) inputFrame.grid(row=0, column=0) for i, varName in enumerate(CUSTOMMASK_VARS): self._createVarWidgets(inputFrame, varName, CUSTOMMASK_VARS[varName], i % 2, i // 2) previewBtn = HotButton(frame, text='Preview', command=self._computeRightPreview) previewBtn.grid(row=1, column=1, padx=5, pady=5)
def _createFigureBox(self, content): from pyworkflow.gui.matplotlib_image import FigureFrame figFrame = FigureFrame(content, figsize=(6, 6)) figFrame.grid(row=0, column=0, padx=5, columnspan=2) self.figure = figFrame.figure applyBtn = HotButton(content, text='Apply B-factor', command=self._onApplyBfactorClick) applyBtn.grid(row=1, column=0, sticky='ne', padx=5, pady=5) closeBtn = Button(content, text='Close', imagePath=Icon.ACTION_CLOSE, command=self.close) closeBtn.grid(row=1, column=1, sticky='ne', padx=5, pady=5)
def __init__(self, title, parent=None, weight=True, minsize=(400, 110), icon="scipion_bn.xbm", **args): """ We assume the parent should be of ProjectsView """ Window.__init__(self, title, parent.windows, weight=weight, icon=icon, minsize=minsize, enableQueue=True) self.root['background'] = 'white' self.parent = parent self.projectsPath = self.parent.manager.PROJECTS self.projName = tk.StringVar() self.projName.set('') self.projLocation = tk.StringVar() self.projLocation.set(self.projectsPath) content = tk.Frame(self.root) content.columnconfigure(0, weight=1) content.columnconfigure(1, weight=3) content.config(bg='white') content.grid(row=0, column=0, sticky='news', padx=5, pady=5) # Project name line labelName = tk.Label(content, text=Message.LABEL_PROJECT + ' name', bg='white', bd=0) labelName.grid(row=0, sticky=tk.W, padx=5, pady=5) entryName = tk.Entry(content, bg=cfgEntryBgColor, width=20, textvariable=self.projName) entryName.grid(row=0, column=1, columnspan=2, sticky=tk.W, padx=5, pady=5) # Project location line labelLocation = tk.Label(content, text=Message.LABEL_PROJECT + ' location', bg='white', bd=0) labelLocation.grid(row=1, column=0, sticky='nw', padx=5, pady=5) self.entryBrowse = tk.Entry(content, bg=cfgEntryBgColor, width=40, textvariable=self.projLocation) self.entryBrowse.grid(row=1, column=1, sticky='nw', padx=5, pady=5) self.btnBrowse = IconButton(content, 'Browse', Icon.ACTION_BROWSE, highlightthickness=0, command=self._browsePath) self.btnBrowse.grid(row=1, column=2, sticky='e', padx=5, pady=5) self.initial_focus = entryName btnFrame = tk.Frame(content) btnFrame.columnconfigure(0, weight=1) btnFrame.grid(row=2, column=0, sticky='sew', padx=5, pady=(0, 5), columnspan=2) btnFrame.config(bg='white') # Create buttons btnSelect = HotButton(btnFrame, 'Create', Icon.BUTTON_SELECT, command=self._select) btnSelect.grid(row=0, column=0, sticky='e', padx=5, pady=5) btnCancel = Button(btnFrame, 'Cancel', Icon.BUTTON_CANCEL, command=self.close) btnCancel.grid(row=0, column=1, sticky='e', padx=5, pady=5)
def visualizeClasses(self, e=None): classTemplate = "class_%03d" averages = '%03d@' + self.protocol._getFileName('averages') def getInfo2(level, classNo): return classTemplate % classNo, averages % classNo node = self.protocol.buildDendrogram(writeAverages=False) g = Graph(root=node) self.graph = g self.win = Window("Select classes", self.formWindow, minsize=(1000, 600)) root = self.win.root canvas = Canvas(root) canvas.grid(row=0, column=0, sticky='nsew') root.grid_columnconfigure(0, weight=1) root.grid_rowconfigure(0, weight=1) self.buttonframe = tk.Frame(root) self.buttonframe.grid(row=2, column=0, columnspan=2) self.win.createCloseButton(self.buttonframe).grid(row=0, column=0, sticky='n', padx=5, pady=5) saveparticlesbtn = HotButton(self.buttonframe, "Particles", Icon.PLUS_CIRCLE, command=self._askCreateParticles) saveparticlesbtn.grid(row=0, column=1, sticky='n', padx=5, pady=5) btn = HotButton(self.buttonframe, "Classes", Icon.PLUS_CIRCLE, command=self._askCreateClasses) btn.grid(row=0, column=2, sticky='n', padx=5, pady=5) lt = LevelTree(g) lt.DY = 135 # TODO: change in percent of the image size lt.setCanvas(canvas) lt.paint(self._createNode, maxLevel=self.maxLevel.get() - 1) canvas.updateScrollRegion() return [self.win]
def _fillButtonsFrame(self, frame): subframe = tk.Frame(frame) subframe.grid(row=0, column=0, sticky='nw') frame.columnconfigure(1, weight=1) ctfBtn = Button(subframe, "CTF Monitor", command=self._monitorCTF) ctfBtn.grid(row=0, column=0, sticky='nw', padx=(0, 5)) sysBtn = Button(subframe, "System Monitor", command=self._monitorSystem) sysBtn.grid(row=0, column=1, sticky='nw', padx=(0, 5)) htmlBtn = HotButton(subframe, 'Generate HTML Report', command=self._generateHTML) htmlBtn.grid(row=0, column=2, sticky='nw', padx=(0, 5)) closeBtn = self.createCloseButton(frame) closeBtn.grid(row=0, column=1, sticky='ne')
def addActionsFrame(self): """ Add the "toolbar" for actions like create project, import project or filter""" # Add the create project button bg = "white" btnFrame = tk.Frame(self, bg=bg) btn = HotButton(btnFrame, text=Message.LABEL_CREATE_PROJECT, font=self.projNameFont, command=self._onCreateProject) btn.grid(row=0, column=0, sticky='nw', padx=10, pady=10) # Add the Import project button btn = Button(btnFrame, text=Message.LABEL_IMPORT_PROJECT, font=self.projNameFont, command=self._onImportProject) btn.grid(row=0, column=1, sticky='nw', padx=10, pady=10) btnFrame.grid(row=0, column=0, sticky='nw') # Add a filter box # Add the Import project button btn = tk.Label(btnFrame, bg=bg, text="Filter:", font=self.projNameFont) btn.grid(row=0, column=2, sticky='nse', padx=10, pady=10) self.filterBox = tk.Entry(btnFrame, font=self.projNameFont, textvariable=self.filter) self.filterBox.grid(row=0, column=3, sticky='ne', padx=10, pady=12) self.filterBox.bind('<Return>', self._onFilter) self.filterBox.bind('<KP_Enter>', self._onFilter)
class PopulationWindow(gui.Window): """ """ def __init__(self, **kwargs): gui.Window.__init__(self, minsize=(620, 200), **kwargs) self.population = kwargs.get('population') self.callback = kwargs.get('callback', None) self.plotter = None self._variables = OrderedDict() self._variablesDict = {} self._loadVariables(self.population) content = tk.Frame(self.root) self._createContent(content) content.grid(row=0, column=0, sticky='news') gui.configureWeigths(content) def _loadVariables(self, population): self.observations = population.getAllParameters() mu, sigma, self.R, percentiles = population.getStats(self.observations) for i, varName in enumerate(population.modelParameters): v = PopulationVar(index=i, varName=varName, unitStr=PKPDUnit.codeToString(population.modelParameterUnits[i]), mu=mu[i], sigma=sigma[i], percentiles=[p[i] for p in percentiles]) self._variables[varName] = v def _createContent(self, content): # Create top frame with the variables list self._createTopFrame(content) # Create button frame with Plot button self._createButtonsFrame(content) # Create an info frame self._createBottomFrame(content) def _createTopFrame(self, content): frame = tk.Frame(content) lfSamples = tk.LabelFrame(frame, text='Plot') gui.configureWeigths(frame) lfSamples.grid(row=0, column=0, sticky='news', padx=5, pady=5) # Create tree for Population Variables tp = PopulationVariablesTreeProvider(self._variables.values()) self.tree = BoundTree(frame, tp, height=10) self.tree.grid(row=0, column=0, sticky='news', padx=5, pady=5) gui.configureWeigths(frame) frame.grid(row=0, column=0, sticky='news', padx=5, pady=(10, 5)) def _createButtonsFrame(self, content): frame = tk.Frame(content) self.plotButton = HotButton(frame, ' Plot ', font=self.fontBold, command=self._onPlotClick, tooltip='Select one or two variables to plot ') self.plotButton.grid(row=0, column=0, sticky='se', padx=5) frame.grid(row=1, column=0, sticky='sew', padx=5, pady=5) gui.configureWeigths(frame) def _createBottomFrame(self, content): frame = tk.Frame(content) t = TaggedText(frame, height=10) t.grid(row=0, column=0, sticky='news', padx=5, pady=5) t.addLine("*Correlation Matrix*") t.addText(np.array2string(self.R)) frame.grid(row=2, column=0, sticky='sew', padx=5, pady=5) gui.configureWeigths(frame) def _onPlotClick(self, e=None): selection = self.tree.selection() n = len(selection) if n < 1 or n > 2: self.showError("Select one or two variables to plot.") else: plotter = EmPlotter() varX = self._variables[selection[0]] xValues = self.observations[:, varX.index] def _label(var): return "%s [%s]" % (var.varName, var.unitStr) if n == 1: plotter.createSubPlot("Histogram", _label(varX), "Count") plotter.plotHist(xValues, 50) else: # n == 2 varY = self._variables[selection[1]] yValues = self.observations[:, varY.index] ax = plotter.createSubPlot("Scatter Plot", _label(varX), _label(varY)) ax.plot(xValues, yValues, '.') plotter.show()
def __init__(self, parent, windows, **kwargs): tk.Frame.__init__(self, parent, bg='white', **kwargs) self.windows = windows self.manager = windows.manager self.root = windows.root self.vars = {} self.checkvars = [] self.microscope = None self.configDict = self.windows.config # Regular expression to validate username and sample name self.re = re.compile('\A[a-zA-Z0-9][a-zA-Z0-9_-]+[a-zA-Z0-9]\Z') # tkFont.Font(size=12, family='verdana', weight='bold') bigSize = pwgui.cfgFontSize + 2 smallSize = pwgui.cfgFontSize - 2 fontName = pwgui.cfgFontName self.bigFont = tkFont.Font(size=bigSize, family=fontName) self.bigFontBold = tkFont.Font(size=bigSize, family=fontName, weight='bold') self.projDateFont = tkFont.Font(size=smallSize, family=fontName) self.projDelFont = tkFont.Font(size=smallSize, family=fontName, weight='bold') self.manager = Manager() # Header section headerFrame = tk.Frame(self, bg='white') headerFrame.grid(row=0, column=0, sticky='new') headerText = "Create New Session" headerText += " %s" % pwutils.prettyTime(dateFormat='%Y-%m-%d') label = tk.Label(headerFrame, text=headerText, font=self.bigFontBold, borderwidth=0, anchor='nw', bg='white', fg=pwgui.Color.DARK_GREY_COLOR) label.grid(row=0, column=0, sticky='nw', padx=(20, 5), pady=10) # Body section bodyFrame = tk.Frame(self, bg='white') bodyFrame.grid(row=1, column=0, sticky='news') self._fillContent(bodyFrame) # Add the create project button btnFrame = tk.Frame(self, bg='white') btn = HotButton(btnFrame, text="Create New Session", activebackground="dark grey", activeforeground='black', font=self.bigFontBold, command=self._onAction) btn.grid(row=0, column=1, sticky='ne', padx=10, pady=10) # Add the Cancel project button btn = Button(btnFrame, Message.LABEL_BUTTON_CANCEL, Icon.ACTION_CLOSE, font=self.bigFontBold, command=self.windows.close) btn.grid(row=0, column=0, sticky='ne', padx=10, pady=10) btnFrame.grid(row=2, column=0, sticky='sew') btnFrame.columnconfigure(0, weight=1) self.columnconfigure(0, weight=1) self.rowconfigure(1, weight=1)
class TrajectoriesWindow(gui.Window): """ This class creates a Window that will display some Point's contained in a Data object. It will allow to draw and adjust trajectories along 2D axes. """ def __init__(self, **kwargs): gui.Window.__init__(self, minsize=(420, 200), **kwargs) self.dim = kwargs.get('dim') self.data = kwargs.get('data') self.pathData = PathData(dim=self.dim) self.callback = kwargs.get('callback', None) self.loadCallback = kwargs.get('loadCallback', None) self.numberOfPoints = kwargs.get('numberOfPoints', 10) self.plotter = None content = tk.Frame(self.root) self._createContent(content) content.grid(row=0, column=0, sticky='news') content.columnconfigure(0, weight=1) #content.rowconfigure(1, weight=1) def _createContent(self, content): self._createFigureBox(content) self._createTrajectoriesBox(content) def _addLabel(self, parent, text, r, c): label = tk.Label(parent, text=text, font=self.fontBold) label.grid(row=r, column=c, padx=5, pady=5, sticky='ne') return label def _createFigureBox(self, content): frame = tk.LabelFrame(content, text='Figure') frame.columnconfigure(0, minsize=50) frame.columnconfigure(1, weight=1)#, minsize=30) # Create the 'Axes' label self._addLabel(frame, 'Axes', 0, 0) # Create a listbox with x1, x2 ... listbox = tk.Listbox(frame, height=5, selectmode=tk.MULTIPLE, bg='white') for x in range(1, self.dim+1): listbox.insert(tk.END, 'x%d' % x) listbox.grid(row=0, column=1, padx=5, pady=5, sticky='nw') self.listbox = listbox # Selection controls self._addLabel(frame, 'Rejection', 1, 0) # Selection label self.selectionVar = tk.StringVar() self.clusterLabel = tk.Label(frame, textvariable=self.selectionVar) self.clusterLabel.grid(row=1, column=1, sticky='nw', padx=5, pady=(10, 5)) self._updateSelectionLabel() # --- Expression expressionFrame = tk.Frame(frame) expressionFrame.grid(row=2, column=1, sticky='news') tk.Label(expressionFrame, text='Expression').grid(row=0, column=0, sticky='ne') self.expressionVar = tk.StringVar() expressionEntry = tk.Entry(expressionFrame, textvariable=self.expressionVar, width=30, bg='white') expressionEntry.grid(row=0, column=1, sticky='nw') helpText = 'e.g. x1>0 and x1<100 or x3>20' tk.Label(expressionFrame, text=helpText).grid(row=1, column=1, sticky='nw') # Buttons buttonFrame = tk.Frame(frame) buttonFrame.grid(row=5, column=1, sticky='sew', pady=(10, 5)) buttonFrame.columnconfigure(0, weight=1) resetBtn = Button(buttonFrame, text='Reset', command=self._onResetClick) resetBtn.grid(row=0, column=0, sticky='ne', padx=(5, 0)) updateBtn = Button(buttonFrame, text='Update Plot', imagePath='fa-refresh.png', command=self._onUpdateClick) updateBtn.grid(row=0, column=1, sticky='ne', padx=5) frame.grid(row=0, column=0, sticky='new', padx=5, pady=(10, 5)) def _createTrajectoriesBox(self, content): frame = tk.LabelFrame(content, text='Trajectories') frame.columnconfigure(0, minsize=50) frame.columnconfigure(1, weight=1)#, minsize=30) # Animation name self._addLabel(frame, 'Name', 0, 0) self.animationVar = tk.StringVar() clusterEntry = tk.Entry(frame, textvariable=self.animationVar, width=30, bg='white') clusterEntry.grid(row=0, column=1, sticky='nw', pady=5) buttonsFrame = tk.Frame(frame) buttonsFrame.grid(row=1, column=1, sticky='se', padx=5, pady=5) buttonsFrame.columnconfigure(0, weight=1) self.generateBtn = HotButton(buttonsFrame, text='Generate Animation', state=tk.DISABLED, tooltip='Select trajectory points to generate the animations', imagePath='fa-plus-circle.png', command=self._onCreateClick) self.generateBtn.grid(row=0, column=1, padx=5) self.loadBtn = Button(buttonsFrame, text='Load', imagePath='fa-folder-open.png', tooltip='Load a generated animation.',command=self._onLoadClick) self.loadBtn.grid(row=0, column=2, padx=5) self.closeBtn = Button(buttonsFrame, text='Close', imagePath=Icon.ACTION_CLOSE, tooltip='Close window', command=self.close) self.closeBtn.grid(row=0, column=3, padx=(5, 10)) frame.grid(row=1, column=0, sticky='new', padx=5, pady=(5, 10)) def _onResetClick(self, e=None): """ Clean the expression and the current selection. """ self.expressionVar.set('') self.pathData.clear() for point in self.data.iterAll(): point.setState(Point.NORMAL) self._onUpdateClick() self.generateBtn.config(state=tk.DISABLED) def _onCreateClick(self, e=None): if self.callback: self.callback() def _onLoadClick(self, e=None): if self.loadCallback: self.loadCallback() def setPathData(self, data): self.pathData = data def _evalExpression(self): """ Evaluate the input expression and add matching points to the selection. """ value = self.expressionVar.get().strip() if value: for point in self.data: if point.eval(value): point.setState(Point.DISCARDED) def setDataIndex(self, indexName, value): """ Set which point data index will be used as X, Y or Z. """ setattr(self.data, indexName, value) setattr(self.pathData, indexName, value) def _onUpdateClick(self, e=None): components = self.listbox.curselection() dim = len(components) if not dim: self.showWarning("Please select some Axis before update plots.") else: modeList = components modeNameList = ['x%d' % (m+1) for m in components] missingList = [] if missingList: return [self.errorMessage("Invalid mode(s) *%s*\n." % (', '.join(missingList)), title="Invalid input")] if self.plotter is None or self.plotter.isClosed(): self.plotter = FlexNmaPlotter(data=self.data) doShow = True #self.plotter.useLastPlot = True else: self.plotter.clear() doShow = False # Actually plot baseList = [basename(n) for n in modeNameList] self.setDataIndex('XIND', modeList[0]) self.ps = None if dim == 1: self.plotter.plotArray1D("Histogram for %s" % baseList[0], "Deformation value", "Number of images") else: self.setDataIndex('YIND', modeList[1]) if dim == 2: self._evalExpression() self._updateSelectionLabel() ax = self.plotter.createSubPlot("Click and drag to add points to the Cluster", *baseList) self.ps = PointPath(ax, self.data, self.pathData, callback=self._checkNumberOfPoints) elif dim == 3: #del self.ps # Remove PointSelector self.setDataIndex('ZIND', modeList[2]) self.plotter.plotArray3D("%s %s %s" % tuple(baseList), *baseList) if doShow: self.plotter.show() else: self.plotter.draw() def _updateSelectionLabel(self): self.selectionVar.set('%d / %d points' % (self.data.getDiscardedSize(), self.data.getSize())) def _checkNumberOfPoints(self): """ Check that if the number of points was selected and add new ones if needed. """ while (self.pathData.getSize() < self.numberOfPoints): self.pathData.splitLongestSegment() self._onUpdateClick() self.generateBtn.config(state=tk.NORMAL) def getAnimationName(self): return self.animationVar.get().strip() def setAnimationName(self, value): self.animationVar.set(value) def _onClosing(self): if self.plotter: self.plotter.close() gui.Window._onClosing(self)
def __init__(self, parent, windows, **kwargs): tk.Frame.__init__(self, parent, **kwargs) self.windows = windows self.manager = windows.manager self.data = windows.data self.root = windows.root self.vars = {} self.checkvars = [] self._createStatus = 'disabled' # Regular expression to validate username and sample name self.re = re.compile('\A[a-zA-Z][a-zA-Z0-9_-]+\Z') # tkFont.Font(size=12, family='verdana', weight='bold') bigSize = pwgui.cfgFontSize + 2 smallSize = pwgui.cfgFontSize - 2 fontName = pwgui.cfgFontName self.bigFont = tkFont.Font(size=bigSize, family=fontName) self.bigFontBold = tkFont.Font(size=bigSize, family=fontName, weight='bold') self.projDateFont = tkFont.Font(size=smallSize, family=fontName) self.projDelFont = tkFont.Font(size=smallSize, family=fontName, weight='bold') bigfont = tkFont.Font(family="Helvetica", size=12) #self.option_add("*TCombobox*Listbox*Font", bigfont) self.option_add("*Font", bigfont) self.manager = Manager() # Header section headerFrame = tk.Frame(self) headerFrame.grid(row=0, column=0, sticky='new') headerText = "Create New Session" headerText += " %s" % pwutils.prettyTime(dateFormat='%Y-%m-%d') label = tk.Label( headerFrame, text=headerText, font=self.bigFontBold, borderwidth=0, anchor='nw', #bg='white', fg=pwgui.Color.DARK_GREY_COLOR) label.grid(row=0, column=0, sticky='nw', padx=(20, 5), pady=10) versionText = 'version: %s' % VERSION label2 = tk.Label( headerFrame, text=versionText, font=self.bigFontBold, borderwidth=0, anchor='nw', # bg='white', fg=pwgui.Color.DARK_GREY_COLOR) headerFrame.columnconfigure(1, weight=1) label2.grid(row=0, column=1, sticky='ne', padx=(20, 5), pady=10) # Body section bodyFrame = tk.Frame(self, bg='white') bodyFrame.grid(row=1, column=0, sticky='news') self._fillContent(bodyFrame) # Add the create project button btnFrame = tk.Frame(self, bg='white') btn = HotButton(btnFrame, text="Create New Session", font=self.bigFontBold, command=self._onAction, state=self._createStatus) btn.grid(row=0, column=1, sticky='ne', padx=10, pady=10) self._newSessionBtn = btn # Add the Import project button btn = Button(btnFrame, Message.LABEL_BUTTON_CANCEL, Icon.ACTION_CLOSE, font=self.bigFontBold, command=self.windows.close) btn.grid(row=0, column=0, sticky='ne', padx=10, pady=10) btnFrame.grid(row=2, column=0, sticky='sew') btnFrame.columnconfigure(0, weight=1) self.columnconfigure(0, weight=1) self.rowconfigure(1, weight=1)
def __init__(self, title, parent=None, weight=True, minsize=(400, 150), icon="scipion_bn.xbm", **args): """ We assume the parent should be ProjectsView """ Window.__init__(self, title, parent.windows, weight=weight, icon=icon, minsize=minsize, enableQueue=True) self.root['background'] = 'white' self.parent = parent # Dirty hack, need to add a slash for the explorer to pick up the right default path. self.projectsPath = getHomePath()+"/" self.projLocation = tk.StringVar() self.projLocation.set(self.projectsPath) self.projName = tk.StringVar() self.projName.set('') self.searchLocation = tk.StringVar() self.searchLocation.set('') content = tk.Frame(self.root) content.columnconfigure(0, weight=1) content.columnconfigure(1, weight=1) content.config(bg='white') content.grid(row=0, column=0, sticky='news', padx=5, pady=5) # Path explorer labelProjectLocation = tk.Label(content, text="Project location", bg='white', bd=0) labelProjectLocation.grid(row=0, column=0, sticky='nw', padx=5, pady=5) self.entryBrowse = tk.Entry(content, bg=cfgEntryBgColor, width=40, textvariable=self.projLocation) self.entryBrowse.grid(row=0, column=1, sticky='nw', padx=5, pady=5) self.btnBrowse = IconButton(content, 'Browse', Icon.ACTION_BROWSE, highlightthickness=0, command=self._browseProjectLocation) self.btnBrowse.grid(row=0, column=2, sticky='e', padx=5, pady=5) # Copy files check labelCheck = tk.Label(content, text="Copy project", bg='white', borderwidth=0) labelCheck.grid(row=1, column=0, sticky='nw', padx=5, pady=5) self.tkCheckVar = tk.IntVar() btnCheck = tk.Checkbutton(content, variable=self.tkCheckVar, highlightthickness=0, activebackground='white', bg='white', bd=0) btnCheck.grid(row=1, column=1, sticky='nw', padx=0, pady=5) btnCopyHelp = IconButton(content, Message.LABEL_BUTTON_HELP, Icon.ACTION_HELP, highlightthickness=0, command=lambda: self.showInfo('If checked, \"Project location\" will be copied. Otherwise a soft link to it will be created.')) btnCopyHelp.grid(row=1, column=3, sticky='e', padx=2, pady=2) # Project name labelName = tk.Label(content, text='Project name (Optional)', bg='white', bd=0) labelName.grid(row=2, column=0, sticky='nw', padx=5, pady=5) entryName = tk.Entry(content, bg='white', width=20, textvariable=self.projName) entryName.grid(row=2, column=1, sticky='nw', padx=5, pady=5) # Path to search for raw data and restore broken links. labelSearchLocation = tk.Label(content, text="Raw files location (Optional)", bg='white', bd=0) labelSearchLocation.grid(row=3, column=0, sticky='nw', padx=5, pady=5) self.entrySearchLocation = tk.Entry(content, bg='white', width=40, textvariable=self.searchLocation) self.entrySearchLocation.grid(row=3, column=1, sticky='nw', padx=5, pady=5) self.btnSearch = IconButton(content, 'Browse', Icon.ACTION_BROWSE, highlightthickness=0, command=self._browseSearchLocation) self.btnSearch.grid(row=3, column=2, sticky='e', padx=5, pady=5) btnSearchHelp = IconButton(content, Message.LABEL_BUTTON_HELP, Icon.ACTION_HELP, highlightthickness=0, command=lambda: self.showInfo('Optional: Folder where raw files, binaries (movies, migcrographs,..) can be found. Used to repair broken links.')) btnSearchHelp.grid(row=3, column=3, sticky='e', padx=2, pady=2) self.initial_focus = entryName btnCheck.select() btnFrame = tk.Frame(content) btnFrame.columnconfigure(0, weight=1) btnFrame.grid(row=4, column=0, sticky='sew', padx=5, pady=(0, 5), columnspan=2) btnFrame.config(bg='white') # Create buttons btnSelect = HotButton(btnFrame, 'Import', Icon.BUTTON_SELECT, command=self._select) btnSelect.grid(row=0, column=0, sticky='e', padx=5, pady=5) btnCancel = Button(btnFrame, 'Cancel', Icon.BUTTON_CANCEL, command=self.close) btnCancel.grid(row=0, column=1, sticky='e', padx=5, pady=5)
class ExperimentWindow(gui.Window): """ This class creates a Window that will display some Point's contained in a Data object. It will allow to launch 1D, 2D and 3D plots by selecting any combination of the x1, x2...xn from the Point dimension. Points can be selected by either Click and Drag in the Scatter plot or.. by creating an Expression. Finally, there is a button 'Create Cluster' that will call a callback fuction to take care of it. """ def __init__(self, **kwargs): gui.Window.__init__(self, minsize=(420, 200), **kwargs) self.experiment = kwargs.get('experiment') self.fitting = kwargs.get('fitting', None) self.callback = kwargs.get('callback', None) content = tk.Frame(self.root) self._createContent(content) content.grid(row=0, column=0, sticky='news') content.columnconfigure(0, weight=1) content.rowconfigure(0, weight=1) self.plotter = None def _createContent(self, content): # Create and fill the frame containing the Experiment # info, variables and doses p = tk.PanedWindow(content, orient=tk.VERTICAL, bg='white') p.grid(row=0, column=0, sticky='news', padx=5, pady=5) self._createTopFrame(p) # Create the middle frame containing the Samples Box self._createSamplesFrame(p) # Create the last frame with the buttons self._createButtonsFrame(content) #self._updateSelectionLabel() def _createTopFrame(self, content): frame = tk.Frame(content) frame.columnconfigure(0, weight=1) frame.rowconfigure(0, weight=1) tab = ttk.Notebook(frame) tab.grid(row=0, column=0, sticky='news', padx=5, pady=5) def addTab(label): lf = tk.Frame(tab) tab.add(lf, text=label) return lf lfGeneral = addTab('General') self._addLabel(lfGeneral, 'Title', 0, 0) self._titleVar = tk.StringVar() self._titleVar.set(self.experiment.general['title']) titleEntry = tk.Entry(lfGeneral, width=26, textvariable=self._titleVar, bg='white') titleEntry.grid(row=0, column=1, sticky='nw', padx=5, pady=(5, 0)) self._addLabel(lfGeneral, 'Comment', 1, 0) commentText = gui.text.Text(lfGeneral, width=30, height=3, bg='white') commentText.setText(self.experiment.general['comment']) commentText.grid(row=1, column=1, sticky='nw', padx=5, pady=(5, 0)) self._commentText = commentText lfVars = addTab('Variables') self.varsTree = self._addBoundTree(lfVars, VariablesTreeProvider, 5) lfVias = addTab('Vias') self.viasTree = self._addBoundTree(lfVias, ViasTreeProvider, 5) lfDoses = addTab('Doses') self.dosesTree = self._addBoundTree(lfDoses, DosesTreeProvider, 5) lfGroups = addTab('Groups') self.groupsTree = self._addBoundTree(lfGroups, GroupsTreeProvider, 5) # Fitting tab if self.fitting: tabFitting = addTab('Fitting') t = TaggedText(tabFitting, width=80, height=10, bg='white') t.grid(row=0, column=0, sticky='nw', padx=10, pady=10) t.setText('Select one of the samples to see more information.') t.setReadOnly(True) self.fittingText = t # Buttons for fitting buttonsFrame = self._createFittingButtonsFrame(tabFitting) buttonsFrame.grid(row=0, column=1, sticky='news', padx=5, pady=5) #frame.grid(row=0, column=0, sticky='news', padx=5, pady=(10, 5)) content.add(frame, sticky='news', padx=5, pady=5) def _createSamplesFrame(self, content): frame = tk.Frame(content) #frame = tk.LabelFrame(content, text='General') lfSamples = tk.LabelFrame(frame, text='Samples') gui.configureWeigths(frame) lfSamples.grid(row=0, column=0, sticky='news', padx=5, pady=5) self.samplesTree = self._addBoundTree(lfSamples, SamplesTreeProvider, 10, fitting=self.fitting) self.samplesTree.itemDoubleClick = self._onSampleDoubleClick self.samplesTree.itemClick = self._onSampleClick plotFrame = tk.Frame(lfSamples) plotFrame.grid(row=1, column=0, sticky='ws', padx=5, pady=5) # Add a combobox with the variable for time timeVars = [v.varName for v in self.experiment.variables.values() if v.role == v.ROLE_TIME] timeVars += [v.varName for v in self.experiment.variables.values() if v.role == v.ROLE_MEASUREMENT] measureVars = [v.varName for v in self.experiment.variables.values() if v.role == v.ROLE_MEASUREMENT] def addVar(text, col, choices): varFrame = tk.Frame(plotFrame) varFrame.grid(row=0, column=col, sticky='new') label = tk.Label(varFrame, text=text, font=self.fontBold) label.grid(row=0, column=0, padx=5, pady=2, sticky='nw') combo = ComboBox(varFrame, choices, width=10) combo.grid(row=0, column=1, sticky='nw', padx=5, pady=5) radioVar = tk.IntVar() radio = tk.Checkbutton(varFrame, text='Log10', variable=radioVar) radio.grid(row=0, column=2, sticky='nw', padx=5, pady=5) return combo, radio, radioVar self.timeWidget = addVar('Time variable', 0, timeVars) self.measureWidget = addVar('Measure variable', 1, measureVars) self.measureWidget[2].set(True) self.plotButton = Button(plotFrame, ' Plot ', font=self.fontBold, command=self._onPlotClick, tooltip='Select one or more samples to plot ' 'their measures of the selected ' 'variables (optionally in log).') self.plotButton.grid(row=0, column=2, sticky='ne', padx=5) self.plotSummaryButton = Button(plotFrame, ' Summary Plot ', font=self.fontBold, command=self._onPlotSummaryClick, tooltip='Select several samples to plot' ' their statistics' ' (min, max, avg and std).') self.plotSummaryButton.grid(row=1, column=2, sticky='ne', padx=5, pady=5) #frame.grid(row=1, column=0, sticky='news', padx=5, pady=5) content.add(frame, sticky='news', padx=5, pady=5) def _createButtonsFrame(self, content): frame = tk.Frame(content) gui.configureWeigths(frame) buttonsFrame = tk.Frame(frame) buttonsFrame.grid(row=0, column=0, sticky='ne') closeButton = Button(buttonsFrame, 'Close', command=self.close, imagePath='fa-times.png') closeButton.grid(row=0, column=0, sticky='ne', padx=5) self.newButton = HotButton(buttonsFrame, ' New Experiment ', command=self._onCreateClick, tooltip='Create a new experiment with the ' 'selected samples. You can also edit' 'title and comment.') self.newButton.grid(row=0, column=1, sticky='ne', padx=5) frame.grid(row=1, column=0, sticky='news', padx=5, pady=5) def _createFittingButtonsFrame(self, content): buttonsFrame = tk.Frame(content) buttonsFrame.grid(row=0, column=0, sticky='ne') plotValuesButton = Button(buttonsFrame, 'Plot Fit', command=self._onPlotFitClick) plotValuesButton.grid(row=0, column=0, sticky='sew', padx=5, pady=5) openValuesButton = Button(buttonsFrame, 'Open Fit', command=self._onOpenFitClick) openValuesButton.grid(row=1, column=0, sticky='sew', padx=5, pady=5) return buttonsFrame def _addLabel(self, parent, text, r, c): label = tk.Label(parent, text=text, font=self.fontBold) label.grid(row=r, column=c, padx=5, pady=5, sticky='ne') return label def _addBoundTree(self, parent, ProviderClass, height, **kwargs): bt = BoundTree(parent, ProviderClass(self.experiment, **kwargs), height=height) bt.grid(row=0, column=0, sticky='news', padx=5, pady=5) gui.configureWeigths(parent) return bt def getUnits(self, varName): return self.experiment.variables[varName].getUnitsString() def getLabel(self, varName, useLog): varLabel = '%s [%s]' % (varName, self.getUnits(varName)) if useLog: varLabel = "log10(%s)" % varLabel return varLabel def getTimeVarName(self): return self.timeWidget[0].getText() def useTimeLog(self): return self.timeWidget[2].get() def getTimeLabel(self): return self.getLabel(self.getTimeVarName(), self.useTimeLog()) def getMeasureVarName(self): return self.measureWidget[0].getText() def useMeasureLog(self): return self.measureWidget[2].get() def getMeasureLabel(self): return self.getLabel(self.getMeasureVarName(), self.useMeasureLog()) def getPlotValues(self, sample): xValues, yValues = sample.getXYValues(self.getTimeVarName(), self.getMeasureVarName()) xValues=xValues[0] # From [array(...)] to array(...) yValues=yValues[0] useMeasureLog = self.useMeasureLog() useTimeLog = self.useTimeLog() if not (useMeasureLog or useTimeLog): return xValues, yValues # If log will be used either for time or measure var # we need to filter elements larger than 0 newXValues = [] newYValues = [] def _value(v, useLog): if useLog: return math.log10(v) if v > 0 else None return v for x, y in izip(xValues, yValues): x = _value(x, useTimeLog) y = _value(y, useMeasureLog) if x is not None and y is not None: newXValues.append(x) newYValues.append(y) return newXValues, newYValues def _onPlotClick(self, e=None): sampleKeys = self.samplesTree.selection() if sampleKeys: if self.plotter is None or self.plotter.isClosed(): self.plotter = EmPlotter() doShow = True ax = self.plotter.createSubPlot("Plot", self.getTimeLabel(), self.getMeasureLabel()) self.plotDict = {} else: doShow = False ax = self.plotter.getLastSubPlot() samples = [self.experiment.samples[k] for k in sampleKeys] for s in samples: if not s.sampleName in self.plotDict: x, y = self.getPlotValues(s) ax.plot(x, y, label=s.sampleName) self.plotDict[s.sampleName] = True leg = ax.legend() if leg: leg.draggable() if doShow: self.plotter.show() else: self.plotter.draw() else: self.showInfo("Please select some sample(s) to plot.") def _onPlotSummaryClick(self, e=None): sampleKeys = self.samplesTree.selection() n = len(sampleKeys) if n == 1: self.showInfo("Please select several samples to plot.") else: if n > 1: samples = [self.experiment.samples[k] for k in sampleKeys] else: samples = self.experiment.samples.values() dataDict = {} # key will be time values for s in samples: xValues, yValues = self.getPlotValues(s) for x, y in izip(xValues, yValues): if x in dataDict: dataDict[x].append(y) else: dataDict[x] = [y] sortedTime = sorted(dataDict.keys()) # We will store five values (min, 25%, 50%, 75%, max) # for each of the time entries computed percentileList = [0, 25, 50, 75, 100] Y = np.zeros((len(sortedTime), 5)) for i, t in enumerate(sortedTime): Y[i,:] = np.percentile(dataDict[t], percentileList) plotter = EmPlotter() ax = plotter.createSubPlot("Summary Plot", self.getTimeLabel(), self.getMeasureLabel()) ax.plot(sortedTime, Y[:, 0], 'r--', label="Minimum") ax.plot(sortedTime, Y[:, 1], 'b--', label="25%") ax.plot(sortedTime, Y[:, 2], 'g', label="50% (Median)") ax.plot(sortedTime, Y[:, 3], 'b--', label="75%") ax.plot(sortedTime, Y[:, 4], 'r--', label="Maximum") ax.legend() plotter.show() def _onCreateClick(self, e=None): sampleKeys = self.samplesTree.selection() if sampleKeys and self.callback: self.callback() else: self.showInfo("Please select some sample(s) to create a new experiment.") def _onSampleClick(self, obj): # In fitting mode we need to display some information for # the given sample fit if self.fitting: selection = self.samplesTree.selection() if selection: sampleKey = selection[0] sampleFit = self.fitting.getSampleFit(sampleKey) textMsg = sampleFit.getBasicInfo() else: textMsg = 'Select one of the samples to see more information.' self.fittingText.setReadOnly(False) self.fittingText.setText(textMsg) self.fittingText.setReadOnly(True) if not (self.plotter is None or self.plotter.isClosed()): self._onPlotClick() def _onSampleDoubleClick(self, obj): sampleKeys = self.samplesTree.selection() if sampleKeys: MeasureWindow(masterWindow=self, sample=self.experiment.samples[sampleKeys[0]]).show() def _onPlotFitClick(self, e=None): sampleKeys = self.samplesTree.selection() if sampleKeys: def _value(v, useLog): if useLog: return math.log10(v) if v > 0 else None return v def _values(values, useLog=self.useMeasureLog()): return [_value(float(x), useLog) for x in values] def _plot(varLabelX, varLabelY, x, y, yp): plotter = EmPlotter() ax = plotter.createSubPlot("Plot", varLabelX, varLabelY) xValues = _values(x, useLog=self.useTimeLog()) ax.plot(xValues, _values(y), 'x', label="Observations") idx = np.argsort(xValues) ypValues = _values(yp) ax.plot(np.asarray(xValues)[idx], np.asarray(ypValues)[idx], 'g', label="Fit") leg = ax.legend() if leg: leg.draggable() plotter.show() # Get first selected element fit = self.fitting.getSampleFit(sampleKeys[0]) if fit==None: return varLabelX = self.getLabel(self.fitting.predictor.varName, self.useTimeLog()) if type(self.fitting.predicted)==list: i=0 for v in self.fitting.predicted: varLabelY = self.getLabel(v.varName, self.useMeasureLog()) _plot(varLabelX, varLabelY, fit.x[i], fit.y[i], fit.yp[i]) i+=1 else: varLabelY = self.getLabel(self.fitting.predicted.varName, self.useMeasureLog()) _plot(varLabelX, varLabelY, fit.x[0], fit.y[0], fit.yp[0]) else: self.showInfo("Please select some sample(s) to plot.") def _onOpenFitClick(self, e=None): sampleKeys = self.samplesTree.selection() if sampleKeys: # Get first selected element fit = self.fitting.getSampleFit(sampleKeys[0]) FitWindow(masterWindow=self, fitting=self.fitting, sampleFit=fit).show() else: self.showInfo("Please select some sample(s) to plot.") def _onClosing(self): if self.plotter: self.plotter.close() gui.Window._onClosing(self)
class ClusteringWindow(gui.Window): """ This class creates a Window that will display some Point's contained in a Data object. It will allow to launch 1D, 2D and 3D plots by selecting any combination of the x1, x2...xn from the Point dimension. Points can be selected by either Click and Drag in the Scatter plot or.. by creating an Expression. Finally, there is a button 'Create Cluster' that will call a callback fuction to take care of it. """ def __init__(self, **kwargs): gui.Window.__init__(self, minsize=(420, 200), **kwargs) self.dim = kwargs.get('dim') self.data = kwargs.get('data') self.callback = kwargs.get('callback', None) self.plotter = None content = tk.Frame(self.root) self._createContent(content) content.grid(row=0, column=0, sticky='news') content.columnconfigure(0, weight=1) #content.rowconfigure(1, weight=1) def _createContent(self, content): self._createFigureBox(content) self._createClusteringBox(content) self._updateSelectionLabel() def _addLabel(self, parent, text, r, c): label = tk.Label(parent, text=text, font=self.fontBold) label.grid(row=r, column=c, padx=5, pady=5, sticky='ne') return label def _createFigureBox(self, content): frame = tk.LabelFrame(content, text='Figure') frame.columnconfigure(0, minsize=50) frame.columnconfigure(1, weight=1) #, minsize=30) # Create the 'Axes' label self._addLabel(frame, 'Axes', 0, 0) # Create a listbox with x1, x2 ... listbox = tk.Listbox(frame, height=5, selectmode=tk.MULTIPLE, bg='white') for x in range(1, self.dim + 1): listbox.insert(tk.END, 'x%d' % x) listbox.grid(row=0, column=1, padx=5, pady=5, sticky='nw') self.listbox = listbox # Selection controls self._addLabel(frame, 'Selection', 1, 0) # Selection label self.selectionVar = tk.StringVar() self.clusterLabel = tk.Label(frame, textvariable=self.selectionVar) self.clusterLabel.grid(row=1, column=1, sticky='nw', padx=5, pady=(10, 5)) # --- Expression expressionFrame = tk.Frame(frame) expressionFrame.grid(row=2, column=1, sticky='news') tk.Label(expressionFrame, text='Expression').grid(row=0, column=0, sticky='ne') self.expressionVar = tk.StringVar() expressionEntry = tk.Entry(expressionFrame, textvariable=self.expressionVar, width=30, bg='white') expressionEntry.grid(row=0, column=1, sticky='nw') helpText = 'e.g. x1>0 and x1<100 or x3>20' tk.Label(expressionFrame, text=helpText).grid(row=1, column=1, sticky='nw') # Buttons buttonFrame = tk.Frame(frame) buttonFrame.grid(row=5, column=1, sticky='sew', pady=(10, 5)) buttonFrame.columnconfigure(0, weight=1) resetBtn = Button(buttonFrame, text='Reset', command=self._onResetClick) resetBtn.grid(row=0, column=0, sticky='ne', padx=(5, 0)) updateBtn = Button(buttonFrame, text='Update Plot', imagePath='fa-refresh.png', command=self._onUpdateClick) updateBtn.grid(row=0, column=1, sticky='ne', padx=5) frame.grid(row=0, column=0, sticky='new', padx=5, pady=(10, 5)) def _createClusteringBox(self, content): frame = tk.LabelFrame(content, text='Cluster') frame.columnconfigure(0, minsize=50) frame.columnconfigure(1, weight=1) #, minsize=30) # Cluster line self._addLabel(frame, 'Cluster name', 0, 0) self.clusterVar = tk.StringVar() clusterEntry = tk.Entry(frame, textvariable=self.clusterVar, width=30, bg='white') clusterEntry.grid(row=0, column=1, sticky='nw', pady=5) buttonsFrame = tk.Frame(frame, bg='green') buttonsFrame.grid(row=1, column=1, sticky='se', padx=5, pady=5) buttonsFrame.columnconfigure(0, weight=1) self.createBtn = HotButton( buttonsFrame, text='Create Cluster', tooltip="Select some points to create the cluster", imagePath='fa-plus-circle.png', command=self._onCreateClick) self.createBtn.grid(row=0, column=1) frame.grid(row=1, column=0, sticky='new', padx=5, pady=(5, 10)) def _onResetClick(self, e=None): """ Clean the expression and the current selection. """ self.expressionVar.set('') for point in self.data: point.setState(Point.NORMAL) self._onUpdateClick() def _onCreateClick(self, e=None): if self.callback: self.callback() def _evalExpression(self): """ Evaluate the input expression and add matching points to the selection. """ value = self.expressionVar.get().strip() if value: for point in self.data: if point.eval(value): point.setState(Point.SELECTED) def _onUpdateClick(self, e=None): components = self.listbox.curselection() dim = len(components) if not dim: self.showWarning("Please select some Axis before update plots.") else: modeList = components modeNameList = ['x%d' % (m + 1) for m in components] missingList = [] if missingList: return [ self.errorMessage("Invalid mode(s) *%s*\n." % (', '.join(missingList)), title="Invalid input") ] if self.plotter is None or self.plotter.isClosed(): self.plotter = FlexNmaPlotter(data=self.data) doShow = True else: self.plotter.clear() doShow = False # Actually plot baseList = [basename(n) for n in modeNameList] self.data.XIND = modeList[0] if dim == 1: self.plotter.plotArray1D("Histogram for %s" % baseList[0], "Deformation value", "Number of images") else: self.data.YIND = modeList[1] if dim == 2: self._evalExpression() self._updateSelectionLabel() ax = self.plotter.createSubPlot( "Click and drag to add points to the Cluster", *baseList) self.ps = PointSelector( ax, self.data, callback=self._updateSelectionLabel) elif dim == 3: del self.ps # Remove PointSelector self.data.ZIND = modeList[2] self.plotter.plotArray3D("%s %s %s" % tuple(baseList), *baseList) if doShow: self.plotter.show() else: self.plotter.draw() def _updateSelectionLabel(self): selected = self.data.getSelectedSize() self.selectionVar.set('%d / %d points' % (selected, self.data.getSize())) if selected: self.createBtn.config(state=tk.NORMAL) else: self.createBtn.config(state=tk.DISABLED) def getClusterName(self): return self.clusterVar.get().strip() def _onClosing(self): if self.plotter: self.plotter.close() gui.Window._onClosing(self)
class PopulationWindow(gui.Window): """ """ def __init__(self, **kwargs): gui.Window.__init__(self, minsize=(620, 200), **kwargs) self.population = kwargs.get('population') self.callback = kwargs.get('callback', None) self.plotter = None self._variables = OrderedDict() self._variablesDict = {} self._loadVariables(self.population) content = tk.Frame(self.root) self._createContent(content) content.grid(row=0, column=0, sticky='news') gui.configureWeigths(content) def _loadVariables(self, population): self.observations = population.getAllParameters() mu, sigma, self.R, percentiles = population.getStats(self.observations) for i, varName in enumerate(population.modelParameters): v = PopulationVar(index=i, varName=varName, unitStr=PKPDUnit.codeToString( population.modelParameterUnits[i]), mu=mu[i], sigma=sigma[i], percentiles=[p[i] for p in percentiles]) self._variables[varName] = v def _createContent(self, content): # Create top frame with the variables list self._createTopFrame(content) # Create button frame with Plot button self._createButtonsFrame(content) # Create an info frame self._createBottomFrame(content) def _createTopFrame(self, content): frame = tk.Frame(content) lfSamples = tk.LabelFrame(frame, text='Plot') gui.configureWeigths(frame) lfSamples.grid(row=0, column=0, sticky='news', padx=5, pady=5) # Create tree for Population Variables tp = PopulationVariablesTreeProvider(self._variables.values()) self.tree = BoundTree(frame, tp, height=10) self.tree.grid(row=0, column=0, sticky='news', padx=5, pady=5) gui.configureWeigths(frame) frame.grid(row=0, column=0, sticky='news', padx=5, pady=(10, 5)) def _createButtonsFrame(self, content): frame = tk.Frame(content) self.plotButton = HotButton( frame, ' Plot ', font=self.fontBold, command=self._onPlotClick, tooltip='Select one or two variables to plot ') self.plotButton.grid(row=0, column=0, sticky='se', padx=5) frame.grid(row=1, column=0, sticky='sew', padx=5, pady=5) gui.configureWeigths(frame) def _createBottomFrame(self, content): frame = tk.Frame(content) t = TaggedText(frame, height=10) t.grid(row=0, column=0, sticky='news', padx=5, pady=5) t.addLine("*Correlation Matrix*") t.addText(np.array2string(self.R)) frame.grid(row=2, column=0, sticky='sew', padx=5, pady=5) gui.configureWeigths(frame) def _onPlotClick(self, e=None): selection = self.tree.selection() n = len(selection) if n < 1 or n > 2: self.showError("Select one or two variables to plot.") else: plotter = EmPlotter() varX = self._variables[selection[0]] xValues = self.observations[:, varX.index] def _label(var): return "%s [%s]" % (var.varName, var.unitStr) if n == 1: plotter.createSubPlot("Histogram", _label(varX), "Count") plotter.plotHist(xValues, 50) else: # n == 2 varY = self._variables[selection[1]] yValues = self.observations[:, varY.index] ax = plotter.createSubPlot("Scatter Plot", _label(varX), _label(varY)) ax.plot(xValues, yValues, '.') plotter.show()
class ExperimentWindow(gui.Window): """ This class creates a Window that will display some Point's contained in a Data object. It will allow to launch 1D, 2D and 3D plots by selecting any combination of the x1, x2...xn from the Point dimension. Points can be selected by either Click and Drag in the Scatter plot or.. by creating an Expression. Finally, there is a button 'Create Cluster' that will call a callback fuction to take care of it. """ def __init__(self, **kwargs): gui.Window.__init__(self, minsize=(420, 200), **kwargs) self.experiment = kwargs.get('experiment') self.fitting = kwargs.get('fitting', None) self.callback = kwargs.get('callback', None) content = tk.Frame(self.root) self._createContent(content) content.grid(row=0, column=0, sticky='news') content.columnconfigure(0, weight=1) content.rowconfigure(0, weight=1) self.plotter = None def _createContent(self, content): # Create and fill the frame containing the Experiment # info, variables and doses p = tk.PanedWindow(content, orient=tk.VERTICAL, bg='white') p.grid(row=0, column=0, sticky='news', padx=5, pady=5) self._createTopFrame(p) # Create the middle frame containing the Samples Box self._createSamplesFrame(p) # Create the last frame with the buttons self._createButtonsFrame(content) #self._updateSelectionLabel() def _createTopFrame(self, content): frame = tk.Frame(content) frame.columnconfigure(0, weight=1) frame.rowconfigure(0, weight=1) tab = ttk.Notebook(frame) tab.grid(row=0, column=0, sticky='news', padx=5, pady=5) def addTab(label): lf = tk.Frame(tab) tab.add(lf, text=label) return lf lfGeneral = addTab('General') self._addLabel(lfGeneral, 'Title', 0, 0) self._titleVar = tk.StringVar() if 'title' in self.experiment.general: self._titleVar.set(self.experiment.general['title']) else: self._titleVar.set("") titleEntry = tk.Entry(lfGeneral, width=26, textvariable=self._titleVar, bg='white') titleEntry.grid(row=0, column=1, sticky='nw', padx=5, pady=(5, 0)) self._addLabel(lfGeneral, 'Comment', 1, 0) commentText = gui.text.Text(lfGeneral, width=30, height=3, bg='white') if 'comment' in self.experiment.general: commentText.setText(self.experiment.general['comment']) else: commentText.setText("") commentText.grid(row=1, column=1, sticky='nw', padx=5, pady=(5, 0)) self._commentText = commentText lfVars = addTab('Variables') self.varsTree = self._addBoundTree(lfVars, VariablesTreeProvider, 5) lfVias = addTab('Vias') self.viasTree = self._addBoundTree(lfVias, ViasTreeProvider, 5) lfDoses = addTab('Doses') self.dosesTree = self._addBoundTree(lfDoses, DosesTreeProvider, 5) lfGroups = addTab('Groups') self.groupsTree = self._addBoundTree(lfGroups, GroupsTreeProvider, 5) # Fitting tab if self.fitting: tabFitting = addTab('Fitting') t = TaggedText(tabFitting, width=80, height=10, bg='white') t.grid(row=0, column=0, sticky='nw', padx=10, pady=10) t.setText('Select one of the samples to see more information.') t.setReadOnly(True) self.fittingText = t # Buttons for fitting buttonsFrame = self._createFittingButtonsFrame(tabFitting) buttonsFrame.grid(row=0, column=1, sticky='news', padx=5, pady=5) #frame.grid(row=0, column=0, sticky='news', padx=5, pady=(10, 5)) content.add(frame, sticky='news', padx=5, pady=5) def _createSamplesFrame(self, content): frame = tk.Frame(content) #frame = tk.LabelFrame(content, text='General') lfSamples = tk.LabelFrame(frame, text='Samples') gui.configureWeigths(frame) lfSamples.grid(row=0, column=0, sticky='news', padx=5, pady=5) self.samplesTree = self._addBoundTree(lfSamples, SamplesTreeProvider, 10, fitting=self.fitting) self.samplesTree.itemDoubleClick = self._onSampleDoubleClick self.samplesTree.itemClick = self._onSampleClick plotFrame = tk.Frame(lfSamples) plotFrame.grid(row=1, column=0, sticky='ws', padx=5, pady=5) # Add a combobox with the variable for time timeVars = [ v.varName for v in self.experiment.variables.values() if v.role == v.ROLE_TIME ] timeVars += [ v.varName for v in self.experiment.variables.values() if v.role == v.ROLE_MEASUREMENT ] measureVars = [ v.varName for v in self.experiment.variables.values() if v.role == v.ROLE_MEASUREMENT ] def addVar(text, col, choices): varFrame = tk.Frame(plotFrame) varFrame.grid(row=0, column=col, sticky='new') label = tk.Label(varFrame, text=text, font=self.fontBold) label.grid(row=0, column=0, padx=5, pady=2, sticky='nw') if len(choices) == 0: choices = [''] combo = ComboBox(varFrame, choices, width=10) combo.grid(row=0, column=1, sticky='nw', padx=5, pady=5) radioVar = tk.IntVar() radio = tk.Checkbutton(varFrame, text='Log10', variable=radioVar) radio.grid(row=0, column=2, sticky='nw', padx=5, pady=5) return combo, radio, radioVar self.timeWidget = addVar('Time variable', 0, timeVars) self.measureWidget = addVar('Measure variable', 1, list(set(measureVars + timeVars))) self.measureWidget[2].set(True) self.plotButton = Button(plotFrame, ' Plot ', font=self.fontBold, command=self._onPlotClick, tooltip='Select one or more samples to plot ' 'their measures of the selected ' 'variables (optionally in log).') self.plotButton.grid(row=0, column=2, sticky='ne', padx=5) self.useCurrentPlotVar = tk.IntVar() self.useCurrentPlot = tk.Checkbutton(plotFrame, text='Use current plot', variable=self.useCurrentPlotVar) self.useCurrentPlot.grid(row=1, column=0, sticky='nw', padx=5, pady=5) self.plotSummaryButton = Button( plotFrame, ' Summary Plot ', font=self.fontBold, command=self._onPlotSummaryClick, tooltip='Select several samples to plot' ' their statistics' ' (min, max, avg and std).') self.plotSummaryButton.grid(row=1, column=2, sticky='ne', padx=5, pady=5) #frame.grid(row=1, column=0, sticky='news', padx=5, pady=5) content.add(frame, sticky='news', padx=5, pady=5) def _createButtonsFrame(self, content): frame = tk.Frame(content) gui.configureWeigths(frame) buttonsFrame = tk.Frame(frame) buttonsFrame.grid(row=0, column=0, sticky='ne') closeButton = Button(buttonsFrame, 'Close', command=self.close, imagePath='fa-times.png') closeButton.grid(row=0, column=0, sticky='ne', padx=5) self.newButton = HotButton(buttonsFrame, ' New Experiment ', command=self._onCreateClick, tooltip='Create a new experiment with the ' 'selected samples. You can also edit' 'title and comment.') self.newButton.grid(row=0, column=1, sticky='ne', padx=5) frame.grid(row=1, column=0, sticky='news', padx=5, pady=5) def _createFittingButtonsFrame(self, content): buttonsFrame = tk.Frame(content) buttonsFrame.grid(row=0, column=0, sticky='ne') plotValuesButton = Button(buttonsFrame, 'Plot Fit', command=self._onPlotFitClick) plotValuesButton.grid(row=0, column=0, sticky='sew', padx=5, pady=5) openValuesButton = Button(buttonsFrame, 'Open Fit', command=self._onOpenFitClick) openValuesButton.grid(row=1, column=0, sticky='sew', padx=5, pady=5) return buttonsFrame def _addLabel(self, parent, text, r, c): label = tk.Label(parent, text=text, font=self.fontBold) label.grid(row=r, column=c, padx=5, pady=5, sticky='ne') return label def _addBoundTree(self, parent, ProviderClass, height, **kwargs): bt = BoundTree(parent, ProviderClass(self.experiment, **kwargs), height=height) bt.grid(row=0, column=0, sticky='news', padx=5, pady=5) gui.configureWeigths(parent) return bt def getUnits(self, varName): return self.experiment.variables[varName].getUnitsString() def getLabel(self, varName, useLog): varLabel = '%s [%s]' % (varName, self.getUnits(varName)) if useLog: varLabel = "log10(%s)" % varLabel return varLabel def getTimeVarName(self): return self.timeWidget[0].getText() def useTimeLog(self): return self.timeWidget[2].get() def getTimeLabel(self): return self.getLabel(self.getTimeVarName(), self.useTimeLog()) def getMeasureVarName(self): return self.measureWidget[0].getText() def useMeasureLog(self): return self.measureWidget[2].get() def getMeasureLabel(self): return self.getLabel(self.getMeasureVarName(), self.useMeasureLog()) def getPlotValues(self, sample): xValues, yValues = sample.getXYValues(self.getTimeVarName(), self.getMeasureVarName()) xValues = xValues[0] # From [array(...)] to array(...) yValues = yValues[0] useMeasureLog = self.useMeasureLog() useTimeLog = self.useTimeLog() if not (useMeasureLog or useTimeLog): return xValues, yValues # If log will be used either for time or measure var # we need to filter elements larger than 0 newXValues = [] newYValues = [] def _value(v, useLog): if useLog: return math.log10(v) if v > 0 else None return v for x, y in izip(xValues, yValues): x = _value(x, useTimeLog) y = _value(y, useMeasureLog) if x is not None and y is not None: newXValues.append(x) newYValues.append(y) return newXValues, newYValues def reuseFigure(self): return None if not self.useCurrentPlotVar.get() else 'active' def _onPlotClick(self, e=None): sampleKeys = self.samplesTree.selection() if sampleKeys: if self.plotter is None or self.plotter.isClosed(): self.plotter = EmPlotter(style='seaborn-whitegrid', figure=self.reuseFigure()) doShow = True ax = self.plotter.createSubPlot("Plot", self.getTimeLabel(), self.getMeasureLabel()) self.plotDict = {} else: doShow = False ax = self.plotter.getLastSubPlot() samples = [self.experiment.samples[k] for k in sampleKeys] for s in samples: if not s.sampleName in self.plotDict or not doShow: x, y = self.getPlotValues(s) label = s.sampleName if not doShow: label += " " + self.getTimeVarName( ) + " vs " + self.getMeasureVarName() ax.plot(x, y, label=label) self.plotDict[s.sampleName] = True leg = ax.legend() if leg: leg.set_draggable(True) if doShow: self.plotter.show() else: self.plotter.draw() else: self.showInfo("Please select some sample(s) to plot.") def _onPlotSummaryClick(self, e=None): sampleKeys = self.samplesTree.selection() n = len(sampleKeys) if n == 1: self.showInfo("Please select several samples to plot.") else: if n > 1: samples = [self.experiment.samples[k] for k in sampleKeys] else: samples = list(self.experiment.samples.values()) xmin = 1e38 xmax = -1e38 for s in samples: xValues, _ = self.getPlotValues(s) xmin = min(xmin, min(xValues)) xmax = max(xmax, max(xValues)) dataDict = {} # key will be time values xrange = np.arange(xmin, xmax, (xmax - xmin) / 300.0) for s in samples: xValues, yValues = self.getPlotValues(s) xValuesUnique, yValuesUnique = uniqueFloatValues( xValues, yValues) B = InterpolatedUnivariateSpline(xValuesUnique, yValuesUnique, k=1) yrange = B(xrange) for x, y in izip(xrange, yrange): if x in dataDict: dataDict[x].append(y) else: dataDict[x] = [y] sortedTime = sorted(dataDict.keys()) # We will store five values (min, 25%, 50%, 75%, max) # for each of the time entries computed percentileList = [0, 25, 50, 75, 100] Y = np.zeros((len(sortedTime), 5)) for i, t in enumerate(sortedTime): Y[i, :] = np.percentile(dataDict[t], percentileList) plotter = EmPlotter(style='seaborn-whitegrid', figure=self.reuseFigure()) # *** Pending ax = plotter.createSubPlot("Summary Plot", self.getTimeLabel(), self.getMeasureLabel()) ax.plot(sortedTime, Y[:, 0], 'r--', label="Minimum") ax.plot(sortedTime, Y[:, 1], 'b--', label="25%") ax.plot(sortedTime, Y[:, 2], 'g', label="50% (Median)") ax.plot(sortedTime, Y[:, 3], 'b--', label="75%") ax.plot(sortedTime, Y[:, 4], 'r--', label="Maximum") ax.grid(True) ax.legend() plotter.show() def _onCreateClick(self, e=None): sampleKeys = self.samplesTree.selection() if sampleKeys and self.callback: self.callback() else: self.showInfo( "Please select some sample(s) to create a new experiment.") def _onSampleClick(self, obj): # In fitting mode we need to display some information for # the given sample fit if self.fitting: selection = self.samplesTree.selection() if selection: sampleKey = selection[0] sampleFit = self.fitting.getSampleFit(sampleKey) textMsg = sampleFit.getBasicInfo() else: textMsg = 'Select one of the samples to see more information.' self.fittingText.setReadOnly(False) self.fittingText.setText(textMsg) self.fittingText.setReadOnly(True) if not (self.plotter is None or self.plotter.isClosed()): self._onPlotClick() def _onSampleDoubleClick(self, obj): sampleKeys = self.samplesTree.selection() if sampleKeys: MeasureWindow( masterWindow=self, sample=self.experiment.samples[sampleKeys[0]]).show() def _onPlotFitClick(self, e=None): sampleKeys = self.samplesTree.selection() if sampleKeys: def _value(v, useLog): if useLog: return math.log10(v) if v > 0 else None return v def _values(values, useLog=self.useMeasureLog()): return [_value(float(x), useLog) for x in values] def _plot(varLabelX, varLabelY, x, y, yp): plotter = EmPlotter(style='seaborn-whitegrid', figure=self.reuseFigure()) ax = plotter.createSubPlot("Plot", varLabelX, varLabelY) xValues = _values(x, useLog=self.useTimeLog()) ax.plot(xValues, _values(y), 'x', label="Observations") idx = np.argsort(xValues) ypValues = _values(yp) ax.plot(np.asarray(xValues)[idx], np.asarray(ypValues)[idx], 'g', label="Fit") leg = ax.legend() if leg: leg.set_draggable(True) plotter.show() # Get first selected element fit = self.fitting.getSampleFit(sampleKeys[0]) if fit == None: return varLabelX = self.getLabel(self.fitting.predictor.varName, self.useTimeLog()) if type(self.fitting.predicted) == list: i = 0 for v in self.fitting.predicted: varLabelY = self.getLabel(v.varName, self.useMeasureLog()) _plot(varLabelX, varLabelY, fit.x[i], fit.y[i], fit.yp[i]) i += 1 else: varLabelY = self.getLabel(self.fitting.predicted.varName, self.useMeasureLog()) _plot(varLabelX, varLabelY, fit.x[0], fit.y[0], fit.yp[0]) else: self.showInfo("Please select some sample(s) to plot.") def _onOpenFitClick(self, e=None): sampleKeys = self.samplesTree.selection() if sampleKeys: # Get first selected element fit = self.fitting.getSampleFit(sampleKeys[0]) FitWindow(masterWindow=self, fitting=self.fitting, sampleFit=fit).show() else: self.showInfo("Please select some sample(s) to plot.") def _onClosing(self): if self.plotter: self.plotter.close() gui.Window._onClosing(self)
class TrajectoriesWindow(gui.Window): """ This class creates a Window that will display some Point's contained in a Data object. It will allow to draw and adjust trajectories along 2D axes. """ def __init__(self, **kwargs): gui.Window.__init__(self, minsize=(420, 200), **kwargs) self.dim = kwargs.get('dim') self.data = kwargs.get('data') self.pathData = PathData(dim=self.dim) self.callback = kwargs.get('callback', None) self.loadCallback = kwargs.get('loadCallback', None) self.numberOfPoints = kwargs.get('numberOfPoints', 10) self.plotter = None content = tk.Frame(self.root) self._createContent(content) content.grid(row=0, column=0, sticky='news') content.columnconfigure(0, weight=1) #content.rowconfigure(1, weight=1) def _createContent(self, content): self._createFigureBox(content) self._createTrajectoriesBox(content) def _addLabel(self, parent, text, r, c): label = tk.Label(parent, text=text, font=self.fontBold) label.grid(row=r, column=c, padx=5, pady=5, sticky='ne') return label def _createFigureBox(self, content): frame = tk.LabelFrame(content, text='Figure') frame.columnconfigure(0, minsize=50) frame.columnconfigure(1, weight=1)#, minsize=30) # Create the 'Axes' label self._addLabel(frame, 'Axes', 0, 0) # Create a listbox with x1, x2 ... listbox = tk.Listbox(frame, height=5, selectmode=tk.MULTIPLE, bg='white') for x in range(1, self.dim+1): listbox.insert(tk.END, 'x%d' % x) listbox.grid(row=0, column=1, padx=5, pady=5, sticky='nw') self.listbox = listbox # Selection controls self._addLabel(frame, 'Rejection', 1, 0) # Selection label self.selectionVar = tk.StringVar() self.clusterLabel = tk.Label(frame, textvariable=self.selectionVar) self.clusterLabel.grid(row=1, column=1, sticky='nw', padx=5, pady=(10, 5)) self._updateSelectionLabel() # --- Expression expressionFrame = tk.Frame(frame) expressionFrame.grid(row=2, column=1, sticky='news') tk.Label(expressionFrame, text='Expression').grid(row=0, column=0, sticky='ne') self.expressionVar = tk.StringVar() expressionEntry = tk.Entry(expressionFrame, textvariable=self.expressionVar, width=30, bg='white') expressionEntry.grid(row=0, column=1, sticky='nw') helpText = 'e.g. x1>0 and x1<100 or x3>20' tk.Label(expressionFrame, text=helpText).grid(row=1, column=1, sticky='nw') # Buttons buttonFrame = tk.Frame(frame) buttonFrame.grid(row=5, column=1, sticky='sew', pady=(10, 5)) buttonFrame.columnconfigure(0, weight=1) resetBtn = Button(buttonFrame, text='Reset', command=self._onResetClick) resetBtn.grid(row=0, column=0, sticky='ne', padx=(5, 0)) updateBtn = Button(buttonFrame, text='Update Plot', imagePath='fa-refresh.png', command=self._onUpdateClick) updateBtn.grid(row=0, column=1, sticky='ne', padx=5) frame.grid(row=0, column=0, sticky='new', padx=5, pady=(10, 5)) def _createTrajectoriesBox(self, content): frame = tk.LabelFrame(content, text='Trajectories') frame.columnconfigure(0, minsize=50) frame.columnconfigure(1, weight=1)#, minsize=30) # Animation name self._addLabel(frame, 'Name', 0, 0) self.animationVar = tk.StringVar() clusterEntry = tk.Entry(frame, textvariable=self.animationVar, width=30, bg='white') clusterEntry.grid(row=0, column=1, sticky='nw', pady=5) buttonsFrame = tk.Frame(frame) buttonsFrame.grid(row=1, column=1, sticky='se', padx=5, pady=5) buttonsFrame.columnconfigure(0, weight=1) self.generateBtn = HotButton(buttonsFrame, text='Generate Animation', state=tk.DISABLED, tooltip='Select trajectory points to generate the animations', imagePath='fa-plus-circle.png', command=self._onCreateClick) self.generateBtn.grid(row=0, column=1, padx=5) self.loadBtn = Button(buttonsFrame, text='Load', imagePath='fa-folder-open.png', tooltip='Load a generated animation.',command=self._onLoadClick) self.loadBtn.grid(row=0, column=2, padx=5) self.closeBtn = Button(buttonsFrame, text='Close', imagePath=Icon.ACTION_CLOSE, tooltip='Close window', command=self.close) self.closeBtn.grid(row=0, column=3, padx=(5, 10)) frame.grid(row=1, column=0, sticky='new', padx=5, pady=(5, 10)) def _onResetClick(self, e=None): """ Clean the expression and the current selection. """ self.expressionVar.set('') self.pathData.clear() for point in self.data.iterAll(): point.setState(Point.NORMAL) self._onUpdateClick() self.generateBtn.config(state=tk.DISABLED) def _onCreateClick(self, e=None): if self.callback: self.callback() def _onLoadClick(self, e=None): if self.loadCallback: self.loadCallback() def setPathData(self, data): self.pathData = data def _evalExpression(self): """ Evaluate the input expression and add matching points to the selection. """ value = self.expressionVar.get().strip() if value: for point in self.data: if point.eval(value): point.setState(Point.DISCARDED) def setDataIndex(self, indexName, value): """ Set which point data index will be used as X, Y or Z. """ setattr(self.data, indexName, value) setattr(self.pathData, indexName, value) def _onUpdateClick(self, e=None): components = self.listbox.curselection() dim = len(components) if not dim: self.showWarning("Please select some Axis before update plots.") else: modeList = components modeNameList = ['x%d' % (m+1) for m in components] missingList = [] if missingList: return [self.errorMessage("Invalid mode(s) *%s*\n." % (', '.join(missingList)), title="Invalid input")] if self.plotter is None or self.plotter.isClosed(): self.plotter = XmippNmaPlotter(data=self.data) doShow = True #self.plotter.useLastPlot = True else: self.plotter.clear() doShow = False # Actually plot baseList = [basename(n) for n in modeNameList] self.setDataIndex('XIND', modeList[0]) self.ps = None if dim == 1: self.plotter.plotArray1D("Histogram for %s" % baseList[0], "Deformation value", "Number of images") else: self.setDataIndex('YIND', modeList[1]) if dim == 2: self._evalExpression() self._updateSelectionLabel() ax = self.plotter.createSubPlot("Click and drag to add points to the Cluster", *baseList) self.ps = PointPath(ax, self.data, self.pathData, callback=self._checkNumberOfPoints) elif dim == 3: #del self.ps # Remove PointSelector self.setDataIndex('ZIND', modeList[2]) self.plotter.plotArray3D("%s %s %s" % tuple(baseList), *baseList) if doShow: self.plotter.show() else: self.plotter.draw() def _updateSelectionLabel(self): self.selectionVar.set('%d / %d points' % (self.data.getDiscardedSize(), self.data.getSize())) def _checkNumberOfPoints(self): """ Check that if the number of points was selected and add new ones if needed. """ while (self.pathData.getSize() < self.numberOfPoints): self.pathData.splitLongestSegment() self._onUpdateClick() self.generateBtn.config(state=tk.NORMAL) def getAnimationName(self): return self.animationVar.get().strip() def setAnimationName(self, value): self.animationVar.set(value) def _onClosing(self): if self.plotter: self.plotter.close() gui.Window._onClosing(self)
class PreWhiteningDialog(dialog.Dialog): def __init__(self, form, workingDir, **kwargs): """ Params: parent: parent windows of the dialog. provider: the TreeProvider to populate items tree. """ self.form = form self.workingDir = workingDir buttons = [('Select', dialog.RESULT_YES), ('Cancel', dialog.RESULT_CANCEL)] dialog.Dialog.__init__(self, form.root, "Pre-whitening", buttons=buttons, default='Select', **kwargs) def _runBeforePreWhitening(self): prot = self.form.protocol # Convert input volumes ih = ImageHandler() if prot.useSplitVolume: ih.convert(prot.volumeHalf1.get(), join(self.workingDir, 'volume1.map')) ih.convert(prot.volumeHalf2.get(), join(self.workingDir, 'volume2.map')) else: ih.convert(prot.inputVolume.get(), join(self.workingDir, 'volume1.map')) self.results = prot.runResmap(self.workingDir, wizardMode=True) def _runPreWhitening(self, newElbowAngstrom, newRampWeight): # Add resmap libraries to the path results = self.results self.figure.clear() myCreatePrewhiteningFigure(results, self.figure, newElbowAngstrom, newRampWeight) def body(self, bodyFrame): figFrame = FigureFrame(bodyFrame, figsize=(18, 9)) figFrame.grid(row=0, column=0, columnspan=5) #self._runBeforePreWhitening(self.prot) dialog.FlashMessage(self.form.root, "Running Pre-Whitening tool...", func=self._runBeforePreWhitening) results = self.results self.figure = figFrame.getFigure() #plt.figure(figsize=(18, 9)) self._runPreWhitening(results['newElbowAngstrom'], results['newRampWeight']) #bodyFrame.config() bodyFrame.columnconfigure(0, weight=1) bodyFrame.rowconfigure(0, weight=1) controlsFrame = tk.Frame(bodyFrame) controlsFrame.grid(row=1, column=0) self.elbowSlider = LabelSlider(controlsFrame, "Angstroms", from_=2.1 * results['vxSize'], to=100, value=results['newElbowAngstrom']) self.elbowSlider.grid(row=1, column=0, padx=5, pady=5) self.rampSlider = LabelSlider(controlsFrame, "Ramp weight", from_=0.0, to=1., value=results['newRampWeight']) self.rampSlider.grid(row=1, column=1, padx=5, pady=5) self.updateBtn = HotButton( controlsFrame, " Update ", command=self._onUpdate, tooltip="Update plots with new pre-whitening parameters.") self.updateBtn.grid(row=1, column=2, padx=10, pady=5) def getElbowValue(self): return self.elbowSlider.get() def getRampValue(self): return self.rampSlider.get() def _onUpdate(self, e=None): self._runPreWhitening(self.getElbowValue(), self.getRampValue())
class ClusteringWindow(gui.Window): """ This class creates a Window that will display some Point's contained in a Data object. It will allow to launch 1D, 2D and 3D plots by selecting any combination of the x1, x2...xn from the Point dimension. Points can be selected by either Click and Drag in the Scatter plot or.. by creating an Expression. Finally, there is a button 'Create Cluster' that will call a callback fuction to take care of it. """ def __init__(self, **kwargs): gui.Window.__init__(self, minsize=(420, 200), **kwargs) self.dim = kwargs.get('dim') self.data = kwargs.get('data') self.callback = kwargs.get('callback', None) self.plotter = None content = tk.Frame(self.root) self._createContent(content) content.grid(row=0, column=0, sticky='news') content.columnconfigure(0, weight=1) #content.rowconfigure(1, weight=1) def _createContent(self, content): self._createFigureBox(content) self._createClusteringBox(content) self._updateSelectionLabel() def _addLabel(self, parent, text, r, c): label = tk.Label(parent, text=text, font=self.fontBold) label.grid(row=r, column=c, padx=5, pady=5, sticky='ne') return label def _createFigureBox(self, content): frame = tk.LabelFrame(content, text='Figure') frame.columnconfigure(0, minsize=50) frame.columnconfigure(1, weight=1)#, minsize=30) # Create the 'Axes' label self._addLabel(frame, 'Axes', 0, 0) # Create a listbox with x1, x2 ... listbox = tk.Listbox(frame, height=5, selectmode=tk.MULTIPLE, bg='white') for x in range(1, self.dim+1): listbox.insert(tk.END, 'x%d' % x) listbox.grid(row=0, column=1, padx=5, pady=5, sticky='nw') self.listbox = listbox # Selection controls self._addLabel(frame, 'Selection', 1, 0) # Selection label self.selectionVar = tk.StringVar() self.clusterLabel = tk.Label(frame, textvariable=self.selectionVar) self.clusterLabel.grid(row=1, column=1, sticky='nw', padx=5, pady=(10, 5)) # --- Expression expressionFrame = tk.Frame(frame) expressionFrame.grid(row=2, column=1, sticky='news') tk.Label(expressionFrame, text='Expression').grid(row=0, column=0, sticky='ne') self.expressionVar = tk.StringVar() expressionEntry = tk.Entry(expressionFrame, textvariable=self.expressionVar, width=30, bg='white') expressionEntry.grid(row=0, column=1, sticky='nw') helpText = 'e.g. x1>0 and x1<100 or x3>20' tk.Label(expressionFrame, text=helpText).grid(row=1, column=1, sticky='nw') # Buttons buttonFrame = tk.Frame(frame) buttonFrame.grid(row=5, column=1, sticky='sew', pady=(10, 5)) buttonFrame.columnconfigure(0, weight=1) resetBtn = Button(buttonFrame, text='Reset', command=self._onResetClick) resetBtn.grid(row=0, column=0, sticky='ne', padx=(5, 0)) updateBtn = Button(buttonFrame, text='Update Plot', imagePath='fa-refresh.png', command=self._onUpdateClick) updateBtn.grid(row=0, column=1, sticky='ne', padx=5) frame.grid(row=0, column=0, sticky='new', padx=5, pady=(10, 5)) def _createClusteringBox(self, content): frame = tk.LabelFrame(content, text='Cluster') frame.columnconfigure(0, minsize=50) frame.columnconfigure(1, weight=1)#, minsize=30) # Cluster line self._addLabel(frame, 'Cluster name', 0, 0) self.clusterVar = tk.StringVar() clusterEntry = tk.Entry(frame, textvariable=self.clusterVar, width=30, bg='white') clusterEntry.grid(row=0, column=1, sticky='nw', pady=5) buttonsFrame = tk.Frame(frame, bg='green') buttonsFrame.grid(row=1, column=1, sticky='se', padx=5, pady=5) buttonsFrame.columnconfigure(0, weight=1) self.createBtn = HotButton(buttonsFrame, text='Create Cluster', tooltip="Select some points to create the cluster", imagePath='fa-plus-circle.png', command=self._onCreateClick) self.createBtn.grid(row=0, column=1) frame.grid(row=1, column=0, sticky='new', padx=5, pady=(5, 10)) def _onResetClick(self, e=None): """ Clean the expression and the current selection. """ self.expressionVar.set('') for point in self.data: point.setState(Point.NORMAL) self._onUpdateClick() def _onCreateClick(self, e=None): if self.callback: self.callback() def _evalExpression(self): """ Evaluate the input expression and add matching points to the selection. """ value = self.expressionVar.get().strip() if value: for point in self.data: if point.eval(value): point.setState(Point.SELECTED) def _onUpdateClick(self, e=None): components = self.listbox.curselection() dim = len(components) if not dim: self.showWarning("Please select some Axis before update plots.") else: modeList = components modeNameList = ['x%d' % (m+1) for m in components] missingList = [] if missingList: return [self.errorMessage("Invalid mode(s) *%s*\n." % (', '.join(missingList)), title="Invalid input")] if self.plotter is None or self.plotter.isClosed(): self.plotter = XmippNmaPlotter(data=self.data) doShow = True else: self.plotter.clear() doShow = False # Actually plot baseList = [basename(n) for n in modeNameList] self.data.XIND = modeList[0] if dim == 1: self.plotter.plotArray1D("Histogram for %s" % baseList[0], "Deformation value", "Number of images") else: self.data.YIND = modeList[1] if dim == 2: self._evalExpression() self._updateSelectionLabel() ax = self.plotter.createSubPlot("Click and drag to add points to the Cluster", *baseList) self.ps = PointSelector(ax, self.data, callback=self._updateSelectionLabel) elif dim == 3: del self.ps # Remove PointSelector self.data.ZIND = modeList[2] self.plotter.plotArray3D("%s %s %s" % tuple(baseList), *baseList) if doShow: self.plotter.show() else: self.plotter.draw() def _updateSelectionLabel(self): selected = self.data.getSelectedSize() self.selectionVar.set('%d / %d points' % (selected, self.data.getSize())) if selected: self.createBtn.config(state=tk.NORMAL) else: self.createBtn.config(state=tk.DISABLED) def getClusterName(self): return self.clusterVar.get().strip() def _onClosing(self): if self.plotter: self.plotter.close() gui.Window._onClosing(self)
class PreWhiteningDialog(dialog.Dialog): def __init__(self, form, workingDir, **kwargs): """ Params: parent: parent windows of the dialog. provider: the TreeProvider to populate items tree. """ self.form = form self.workingDir = workingDir buttons = [('Select', dialog.RESULT_YES), ('Cancel', dialog.RESULT_CANCEL)] dialog.Dialog.__init__(self, form.root, "Pre-whitening", buttons=buttons, default='Select', **kwargs) def _runBeforePreWhitening(self): prot = self.form.protocol # Convert input volumes ih = ImageHandler() if prot.useSplitVolume: ih.convert(prot.volumeHalf1.get(), join(self.workingDir, 'volume1.map')) ih.convert(prot.volumeHalf2.get(), join(self.workingDir, 'volume2.map')) else: ih.convert(prot.inputVolume.get(), join(self.workingDir, 'volume1.map')) self.results = prot.runResmap(self.workingDir, wizardMode=True) def _runPreWhitening(self, newElbowAngstrom, newRampWeight): # Add resmap libraries to the path results = self.results self.figure.clear() myCreatePrewhiteningFigure(results, self.figure, newElbowAngstrom, newRampWeight) def body(self, bodyFrame): figFrame = FigureFrame(bodyFrame, figsize=(18, 9)) figFrame.grid(row=0, column=0, columnspan=5) #self._runBeforePreWhitening(self.prot) dialog.FlashMessage(self.form.root, "Running Pre-Whitening tool...", func=self._runBeforePreWhitening) results = self.results self.figure = figFrame.getFigure() #plt.figure(figsize=(18, 9)) self._runPreWhitening(results['newElbowAngstrom'], results['newRampWeight']) #bodyFrame.config() bodyFrame.columnconfigure(0, weight=1) bodyFrame.rowconfigure(0, weight=1) controlsFrame = tk.Frame(bodyFrame) controlsFrame.grid(row=1, column=0) self.elbowSlider = LabelSlider(controlsFrame, "Angstroms", from_=2.1*results['vxSize'], to=100, value=results['newElbowAngstrom']) self.elbowSlider.grid(row=1, column=0, padx=5, pady=5) self.rampSlider = LabelSlider(controlsFrame, "Ramp weight", from_=0.0, to=1., value=results['newRampWeight']) self.rampSlider.grid(row=1, column=1, padx=5, pady=5) self.updateBtn = HotButton(controlsFrame, " Update ", command=self._onUpdate, tooltip="Update plots with new pre-whitening parameters.") self.updateBtn.grid(row=1, column=2, padx=10, pady=5) def getElbowValue(self): return self.elbowSlider.get() def getRampValue(self): return self.rampSlider.get() def _onUpdate(self, e=None): self._runPreWhitening(self.getElbowValue(), self.getRampValue())
def __init__(self, parent, windows, **kwargs): tk.Frame.__init__(self, parent, bg='white', **kwargs) self.windows = windows self.manager = windows.manager self.root = windows.root self.vars = {} self.checkvars = [] self.microscope = None # Regular expression to validate username and sample name self.re = re.compile('\A[a-zA-Z][a-zA-Z0-9_-]+\Z') # tkFont.Font(size=12, family='verdana', weight='bold') bigSize = pwgui.cfgFontSize + 2 smallSize = pwgui.cfgFontSize - 2 fontName = pwgui.cfgFontName self.bigFont = tkFont.Font(size=bigSize, family=fontName) self.bigFontBold = tkFont.Font(size=bigSize, family=fontName, weight='bold') self.projDateFont = tkFont.Font(size=smallSize, family=fontName) self.projDelFont = tkFont.Font(size=smallSize, family=fontName, weight='bold') self.manager = Manager() # Header section headerFrame = tk.Frame(self, bg='white') headerFrame.grid(row=0, column=0, sticky='new') headerText = "Create New Session" headerText += " %s" % pwutils.prettyTime(dateFormat='%Y-%m-%d') label = tk.Label(headerFrame, text=headerText, font=self.bigFontBold, borderwidth=0, anchor='nw', bg='white', fg=pwgui.Color.DARK_GREY_COLOR) label.grid(row=0, column=0, sticky='nw', padx=(20, 5), pady=10) # Body section bodyFrame = tk.Frame(self, bg='white') bodyFrame.grid(row=1, column=0, sticky='news') self._fillContent(bodyFrame) # Add the create project button btnFrame = tk.Frame(self, bg='white') btn = HotButton(btnFrame, text="Create New Session", font=self.bigFontBold, command=self._onAction) btn.grid(row=0, column=1, sticky='ne', padx=10, pady=10) # Add the Import project button btn = Button(btnFrame, Message.LABEL_BUTTON_CANCEL, Icon.ACTION_CLOSE, font=self.bigFontBold, command=self.windows.close) btn.grid(row=0, column=0, sticky='ne', padx=10, pady=10) btnFrame.grid(row=2, column=0, sticky='sew') btnFrame.columnconfigure(0, weight=1) self.columnconfigure(0, weight=1) self.rowconfigure(1, weight=1)
def __init__(self, parent, windows, template=None, argsList=[], showScheduleOption=True, schedule=True, showProjectOption=True, showProject=True, showProjectName=True, **kwargs): tk.Frame.__init__(self, parent, bg='white', **kwargs) self.windows = windows self.root = windows.root self.vars = {} self.checkvars = [] self.template = template self.argsList = argsList self.showScheduleOption = showScheduleOption self.schedule = schedule self.showProjectOption = showProjectOption self.showProject = showProject self.showProjectName = showProjectName bigSize = pwgui.cfgFontSize + 2 smallSize = pwgui.cfgFontSize - 2 fontName = pwgui.cfgFontName self.bigFont = tkFont.Font(size=bigSize, family=fontName) self.bigFontBold = tkFont.Font(size=bigSize, family=fontName, weight='bold') self.projDateFont = tkFont.Font(size=smallSize, family=fontName) self.projDelFont = tkFont.Font(size=smallSize, family=fontName, weight='bold') # Body section bodyFrame = tk.Frame(self, bg='white') bodyFrame.columnconfigure(0, minsize=120) bodyFrame.columnconfigure(1, minsize=120, weight=1) bodyFrame.grid(row=0, column=0, sticky='news') self._fillContent(bodyFrame) # Add the create project button btnFrame = tk.Frame(self, bg='white') btn = HotButton(btnFrame, text=ACCEPT_BUTTON, font=self.bigFontBold, command=self._onReadDataFromTemplateForm) btn.grid(row=0, column=1, sticky='ne', padx=10, pady=10) # Add the Import project button btn = Button(btnFrame, Message.LABEL_BUTTON_CANCEL, font=self.bigFontBold, command=self._closeCallback) btn.grid(row=0, column=0, sticky='ne', pady=10) btnFrame.columnconfigure(0, weight=1) btnFrame.grid(row=1, column=0, sticky='news') self.columnconfigure(0, weight=1)