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 _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 _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 __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 _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 _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 __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 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)
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 _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 _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') frame.grid(row=2, 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 __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() # Add the create project button btnFrame = tk.Frame(self, bg='white') 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') 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, columnspan=2, 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) 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 _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 _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))
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 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)
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)
def _fillContent(self, content): frame = tk.Frame(content, bg='white') frame.grid(row=0, column=0, sticky='news', padx=10, pady=15) frame.columnconfigure(0, minsize=200) self._lastRow = 0 def _createLabel(text, bold=False): boldStr = 'bold' if bold else '' return tk.Label(frame, text=text, font="helvetica 12 %s" % boldStr, bg='white') def __addLabeledWidget(text, widget=None, pady=5, bold=False): label = _createLabel(text, bold) label.grid(row=self._lastRow, column=0, sticky='ne', pady=pady) if widget is not None: widget.grid(row=self._lastRow, column=1, sticky='nw', pady=pady, padx=5) self._lastRow += 1 return label def __createCombobox(options, readOnly=True, callback=None, width=38): var = tk.StringVar() s = ttk.Style() state = 'readonly' if readOnly else 'edit' combo = ttk.Combobox(frame, textvariable=var, state=state, width=width) combo['values'] = options combo.var = var if callback: combo.bind('<<ComboboxSelected>>', callback) return combo def _getSessionAction(): micIndex = self._micChooser.getSelectedIndex() if micIndex is None: return "Select Microscope" camIndex = self._switchCam.widgets[micIndex].getSelectedIndex() if camIndex is None: return "Select Camera" resourceId = self._micChooser.getSelectedIndex() + 1 if resourceId in self._bookings: b = self._bookings[resourceId] values = { 'CEM': b['application_code'], 'Owner': b['owner']['name'], 'Creator': b['creator']['name'] } else: values = {} b = None for k, v in self._textVars.items(): v.set(values.get(k, '-')) self._current_booking = b if b is None: return ("There is no booking for this microscope. " "Check the booking system. ") return None def _checkSessionAction(): action = _getSessionAction() if action is None: msg = self._createSession().getId() else: msg = action self._sessionLabel.config(fg='red' if action else 'green') self._sessionVar.set(msg) self._createStatus = 'disabled' if action else 'normal' btn = getattr(self, '_newSessionBtn', None) if btn is not None: btn.config(state=self._createStatus) class Switcher(tk.Frame): def __init__(self, *args, **kwargs): tk.Frame.__init__(self, *args, **kwargs) self._index = -1 self.widgets = [] def add(self, widget): self.widgets.append(widget) def set(self, i): if i < 0 or i >= len(self.widgets): raise Exception("Invalid index") if self._index >= 0: self.widgets[self._index].grid_forget() self.widgets[i].grid(row=0, column=0, sticky='news') self._index = i def _showCameraOptions(chooser): """ Show the correct camera options depending on the selected microscope. """ i = chooser.getSelectedIndex() self._switchCam.set(i) _checkSessionAction() def _onChange(*args): if hasattr(self, '_sessionLabel'): _checkSessionAction() def _onChangePreprocessing(*args): """ Called when the selection is changed. """ i = self._prepChooser.getSelectedIndex() self._switchPre.set(i) EXTRA_PAD = 30 f1 = OptionChooser(frame, bg='white', optionWidth=200) f1.onSelectionChanged(_showCameraOptions) f1.addOption('Krios α', self.data.getResourceFile("titan_small.gif")) f1.addOption('Krios β', self.data.getResourceFile("titan_small.gif")) f1.addOption('Talos', self.data.getResourceFile("talos_small.gif")) __addLabeledWidget("Microscope", f1, bold=True) self._micOrder = {TITAN_A: 0, TITAN_B: 1, TALOS: 2} self._micChooser = f1 self._switchCam = Switcher(frame) def _addCamChooser(*options): oc = OptionChooser(self._switchCam, bg='white', optionWidth=200) for o in options: oc.addOption(o) self._switchCam.add(oc) oc.selectIndex(0) oc.onSelectionChanged(_onChange) for mic in MICROSCOPES: _addCamChooser(*MIC_CAMERAS[mic]) #camChoosers = [_createChooser(*MIC_CAMERAS[mic]) for mic in MICROSCOPES] # f2 = camChoosers[0] # self._camRow = self._lastRow __addLabeledWidget("Camera", self._switchCam) # --------- Load some data --------------- from emhub.client import DataClient from emhub.utils import datetime_to_isoformat apiJsonFile = getDataFile('api.json') with open(apiJsonFile) as f: apiJson = json.load(f) dc = DataClient(apiJson['emhub']['url']) dc.login(apiJson['emhub']['user'], apiJson['emhub']['password']) start = datetime_to_isoformat(self.data.date.replace(hour=0)) end = datetime_to_isoformat(self.data.date.replace(hour=23, minute=59)) r = dc.request('get_bookings_range', jsonData={ 'start': start, 'end': end }) self._bookings = { b['resource']['id']: b for b in r.json() if b['type'] == 'booking' } users = {} def get_user(user_id): if user_id not in users: r = dc.request('get_users', jsonData={'condition': 'id=%s' % user_id}) users[user_id] = r.json()[0] return users[user_id] def get_application_code(b): # Take only the first part of the application label # (because it can contains the alias in parenthesis) m = re.search("\([^,]+(,([^,]*))\)", b['title']) return 'fac' if m is None else m.group(2).upper().strip() for b in self._bookings.values(): b['owner'] = get_user(b['owner']['id']) b['creator'] = get_user(b['creator']['id']) b['application_code'] = get_application_code(b) dc.logout() self._textVars = {} def _addLabeledText(label, text): var = tk.StringVar() var.set(text) labelWidget = _createLabel(text) labelWidget.config(textvariable=var) self._textVars[label] = var __addLabeledWidget(label, labelWidget, bold=True) _addLabeledText("CEM", '') _addLabeledText("Owner", '') _addLabeledText("Creator", '') # --------- Session block ---------------- self._sessionVar = tk.StringVar() self._sessionLabel = tk.Label(frame, textvariable=self._sessionVar, bg='white', fg='red') __addLabeledWidget("Session ID", self._sessionLabel, pady=(EXTRA_PAD, 0), bold=True) # --------- Preprocessing block ---------------- f4 = OptionChooser(frame, bg='white', optionWidth=200) f4.addOption('Scipion', self.data.getResourceFile("scipion_logo.gif")) f4.addOption('Scipion (custom)', self.data.getResourceFile("scipion_logo.gif")) f4.addOption(LABEL_NONE, self.data.getResourceFile("none.gif")) f4.onSelectionChanged(_onChangePreprocessing) self._prepChooser = f4 __addLabeledWidget("Pre-processing", f4, pady=(EXTRA_PAD, 0), bold=True) self._switchPre = Switcher(frame, bg='white') def _addFrame(): preFrame = tk.Frame(self._switchPre, bg='white') self._switchPre.add(preFrame) return preFrame preFrame1 = _addFrame() preOptions = [("Motion correction", ['relion - motioncor', 'motioncor2']), ("CTF estimation", ['ctffind4', 'gctf'])] self._preDict = {} for row, (text, options) in enumerate(preOptions): label = tk.Label(preFrame1, text=text, font="helvetica 12", bg='white') label.grid(row=row, column=0, sticky='ne') v = tk.StringVar() for i, o in enumerate(options): rb = tk.Radiobutton(preFrame1, text=o, variable=v, value=o, bg='white') rb.grid(row=row, column=i + 1, sticky='nw') v.set(options[0]) self._preDict[text] = v preFrame2 = _addFrame() self._workflowVar = tk.StringVar() entry = ttk.Entry(preFrame2, width=50, textvariable=self._workflowVar) entry.grid(column=0, row=0) def _onChoose(fileInfo): self._workflowVar.set(fileInfo.getPath()) def _chooseWorkflow(): browser = FileBrowserWindow( "Select the one of the predefined MTF files", self.windows, getDataFile('workflows'), onSelect=_onChoose) browser.show() button = Button(preFrame2, text="Browse", command=_chooseWorkflow) button.grid(column=1, row=0) preFrame3 = _addFrame() __addLabeledWidget('', self._switchPre) f4.selectIndex(0) f1.selectIndex(self._micOrder[self.data.microscope]) # Select Scipion as default for pre-processing _checkSessionAction()
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 = 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)
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)
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, 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)
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')