def test_get_from_int(self): v = DoubleVar(self.root, 1.23, "name") self.assertAlmostEqual(1.23, v.get()) self.root.globalsetvar("name", "3.45") self.assertAlmostEqual(3.45, v.get()) self.root.globalsetvar("name", "456") self.assertAlmostEqual(456, v.get())
def test_get_from_int(self): v = DoubleVar(self.root, 1.23, "name") self.assertAlmostEqual(1.23, v.get()) self.root.globalsetvar("name", "3.45") self.assertAlmostEqual(3.45, v.get()) self.root.globalsetvar("name", "456") self.assertAlmostEqual(456, v.get())
def test_get_from_int(self): v = DoubleVar(self.root, 1.23, 'name') self.assertAlmostEqual(1.23, v.get()) self.root.globalsetvar('name', '3.45') self.assertAlmostEqual(3.45, v.get()) self.root.globalsetvar('name', '456') self.assertAlmostEqual(456, v.get())
def test_get_from_int(self): v = DoubleVar(self.root, 1.23, 'name') self.assertAlmostEqual(1.23, v.get()) self.root.globalsetvar('name', '3.45') self.assertAlmostEqual(3.45, v.get()) self.root.globalsetvar('name', '456') self.assertAlmostEqual(456, v.get())
class RotatePanel(CtxSubPanel): name = 'RotatePanel' def __init__(self, parent): CtxSubPanel.__init__(self, parent) self.angle = DoubleVar(self.mw.root) self.angle.set(0) label = TLabel(self.panel, image='context_R') label.pack(side=LEFT) self.entry_width = TSpinbox(self.panel, var=0, vartype=1, textvariable=self.angle, min=-360, max=360, step=1, width=6, command=self.applyRotate) tooltips.AddDescription(self.entry_width, _('Rotation angle')) self.entry_width.pack(side=LEFT, padx=5) b = TButton(self.panel, command=self.rotLeft, style='Toolbutton', image='context_rotate_ccw') tooltips.AddDescription(b, _(u'Rotate -90°')) b.pack(side=LEFT) b = TButton(self.panel, command=self.rot180, style='Toolbutton', image='context_rotate') tooltips.AddDescription(b, _(u'Rotate 180°')) b.pack(side=LEFT) b = TButton(self.panel, command=self.rotRight, style='Toolbutton', image='context_rotate_cw') tooltips.AddDescription(b, _(u'Rotate 90°')) b.pack(side=LEFT) def rot180(self): self.rotation(180) def rotLeft(self): self.rotation(90) def rotRight(self): self.rotation(-90) def applyRotate(self, *arg): self.rotation(self.angle.get()) def rotation(self, angle): if angle < 0: if angle < -360: angle += int(angle / 360) * 360 angle += 360 self.doc.RotateSelected(angle)
class RotatePanel(CtxSubPanel): name='RotatePanel' def __init__(self, parent): CtxSubPanel.__init__(self, parent) self.angle=DoubleVar(self.mw.root) self.angle.set(0) label = TLabel(self.panel, image='context_R') label.pack(side = LEFT) self.entry_width = TSpinbox(self.panel, var=0, vartype=1, textvariable = self.angle, min = -360, max = 360, step = 1, width = 6, command = self.applyRotate) tooltips.AddDescription(self.entry_width, _('Rotation angle')) self.entry_width.pack(side = LEFT, padx=5) b = TButton(self.panel, command=self.rotLeft, style='Toolbutton', image='context_rotate_ccw') tooltips.AddDescription(b, _(u'Rotate -90°')) b.pack(side = LEFT) b = TButton(self.panel, command=self.rot180, style='Toolbutton', image='context_rotate') tooltips.AddDescription(b, _(u'Rotate 180°')) b.pack(side = LEFT) b = TButton(self.panel, command=self.rotRight, style='Toolbutton', image='context_rotate_cw') tooltips.AddDescription(b, _(u'Rotate 90°')) b.pack(side = LEFT) def rot180(self): self.rotation(180) def rotLeft(self): self.rotation(90) def rotRight(self): self.rotation(-90) def applyRotate(self, *arg): self.rotation(self.angle.get()) def rotation(self, angle): if angle<0: if angle<-360: angle+=int(angle/360)*360 angle+=360 self.doc.RotateSelected(angle)
class TrainingError(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent training_error_laber = Label(self, text = 'Training Error: ') training_error_laber.pack(side = 'left') error_options = [round(0.1 + i*0.1, 2) for i in range(25)] self.selected_error = DoubleVar(self, value = DEFAULT_TRAINING_ERROR) option_menu = OptionMenu(self, self.selected_error, *error_options, command = self._on_error_selection) option_menu.pack(side = 'right') def get(self): return self.selected_error.get() def reset(self): self.selected_error.set(DEFAULT_TRAINING_ERROR) def _on_error_selection(self, selected_error): print "Selected training error: ", selected_error
class TrainingError(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent training_error_laber = Label(self, text='Training Error: ') training_error_laber.pack(side='left') error_options = [round(0.1 + i * 0.1, 2) for i in range(25)] self.selected_error = DoubleVar(self, value=DEFAULT_TRAINING_ERROR) option_menu = OptionMenu(self, self.selected_error, *error_options, command=self._on_error_selection) option_menu.pack(side='right') def get(self): return self.selected_error.get() def reset(self): self.selected_error.set(DEFAULT_TRAINING_ERROR) def _on_error_selection(self, selected_error): print "Selected training error: ", selected_error
class Application(Frame): def __init__(self, master=None): Frame.__init__(self, master) self.DEFAULT_SECTION = 'DEFAULT' self.grid() self.createWidgets() def createWidgets(self): self.__config = ConfigParser.ConfigParser() self.__config.set(self.DEFAULT_SECTION, 'input', '~/input.jpg') self.__config.set(self.DEFAULT_SECTION, 'inverted', '0') self.__config.set(self.DEFAULT_SECTION, 'output', '~/output.svg') self.__config.set(self.DEFAULT_SECTION, 'preamble', 'G17 G21 G90 G64 P0.1 S4500 M3 M8') self.__config.set(self.DEFAULT_SECTION, 'size', '256') self.__config.set(self.DEFAULT_SECTION, 'scale', '1') self.__config.set(self.DEFAULT_SECTION, 'width', '152.4') self.__config.set(self.DEFAULT_SECTION, 'height', '101.6') self.__config.set(self.DEFAULT_SECTION, 'columns', '3') self.__config.set(self.DEFAULT_SECTION, 'rows', '2') self.__config.set(self.DEFAULT_SECTION, 'margin', '10.0') self.__config.set(self.DEFAULT_SECTION, 'thickness', '6.35') self.__config.set(self.DEFAULT_SECTION, 'tool_diameter', '3.175') self.__config.read(os.path.expanduser('~/.py-art.cfg')) self.EntryFrame = Frame(self,bd=5) self.EntryFrame.grid(row=0, column=1) i = 0 Label(self.EntryFrame, text='Engrave an image\n').grid(row=i, column=0, columnspan=2) i += 1 Label(self.EntryFrame, text='Input file').grid(row=i, column=0, sticky=E) self.InputVar = StringVar() self.InputVar.set(self.__config.get(self.DEFAULT_SECTION, 'input')) Entry(self.EntryFrame, textvariable=self.InputVar ,width=50).grid(row=i, column=1) i += 1 Label(self.EntryFrame, text='Size').grid(row=i, column=0, sticky=E) self.SizeVar = IntVar() self.SizeVar.set(self.__config.get(self.DEFAULT_SECTION, 'size')) Entry(self.EntryFrame, textvariable=self.SizeVar ,width=50).grid(row=i, column=1) i += 1 Label(self.EntryFrame, text='Scale').grid(row=i, column=0, sticky=E) self.ScaleVar = IntVar() self.ScaleVar.set(self.__config.get(self.DEFAULT_SECTION, 'scale')) Entry(self.EntryFrame, textvariable=self.ScaleVar ,width=50).grid(row=i, column=1) i += 1 Label(self.EntryFrame, text='Rows').grid(row=i, column=0, sticky=E) self.RowsVar = IntVar() self.RowsVar.set(self.__config.get(self.DEFAULT_SECTION, 'rows')) Entry(self.EntryFrame, textvariable=self.RowsVar ,width=50).grid(row=i, column=1) i += 1 Label(self.EntryFrame, text='Columns').grid(row=i, column=0, sticky=E) self.ColumnsVar = IntVar() self.ColumnsVar.set(self.__config.get(self.DEFAULT_SECTION, 'columns')) Entry(self.EntryFrame, textvariable=self.ColumnsVar ,width=50).grid(row=i, column=1) i += 1 Label(self.EntryFrame, text='Image effects').grid(row=i, column=0, sticky=E) self.InvertedVar = IntVar() self.InvertedVar.set(self.__config.getint(self.DEFAULT_SECTION, 'inverted')) Checkbutton(self.EntryFrame, text='Inverted', variable=self.InvertedVar).grid(row=i, column=1,sticky=W) if IN_AXIS: i += 1 Label(self.EntryFrame, text='Preamble').grid(row=i, column=0, sticky=E) self.PreambleVar = StringVar() self.PreambleVar.set(self.__config.get(self.DEFAULT_SECTION, 'preamble')) Entry(self.EntryFrame, textvariable=self.PreambleVar ,width=50).grid(row=i, column=1) i += 1 Label(self.EntryFrame, text='Width').grid(row=i, column=0, sticky=E) self.WidthVar = DoubleVar() self.WidthVar.set(self.__config.get(self.DEFAULT_SECTION, 'width')) Entry(self.EntryFrame, textvariable=self.WidthVar ,width=50).grid(row=i, column=1) i += 1 Label(self.EntryFrame, text='Height').grid(row=i, column=0, sticky=E) self.HeightVar = DoubleVar() self.HeightVar.set(self.__config.get(self.DEFAULT_SECTION, 'height')) Entry(self.EntryFrame, textvariable=self.HeightVar ,width=50).grid(row=i, column=1) i += 1 Label(self.EntryFrame, text='Margin').grid(row=i, column=0, sticky=E) self.MarginVar = DoubleVar() self.MarginVar.set(self.__config.get(self.DEFAULT_SECTION, 'margin')) Entry(self.EntryFrame, textvariable=self.MarginVar ,width=50).grid(row=i, column=1) i += 1 Label(self.EntryFrame, text='Tool diameter').grid(row=i, column=0, sticky=E) self.ToolDiameterVar = DoubleVar() self.ToolDiameterVar.set(self.__config.get(self.DEFAULT_SECTION, 'tool_diameter')) Entry(self.EntryFrame, textvariable=self.ToolDiameterVar ,width=50).grid(row=i, column=1) i += 1 Label(self.EntryFrame, text='Thickness').grid(row=i, column=0, sticky=E) self.ThicknessVar = DoubleVar() self.ThicknessVar.set(self.__config.get(self.DEFAULT_SECTION, 'thickness')) Entry(self.EntryFrame, textvariable=self.ThicknessVar ,width=50).grid(row=i, column=1) i += 1 Button(self.EntryFrame, text='Trace boundary in AXIS and Quit',command=self.WriteBoundaryTraceToAxis).grid(row=i, column=1, sticky=E) i += 1 Button(self.EntryFrame, text='Engrave in AXIS and Quit',command=self.WriteEngravingToAxis).grid(row=i, column=1, sticky=E) i += 1 Button(self.EntryFrame, text='Cut boundary in AXIS and Quit',command=self.WriteBoundaryCutToAxis).grid(row=i, column=1, sticky=E) else: i += 1 Label(self.EntryFrame, text='Output file').grid(row=i, column=0, sticky=E) self.OutputVar = StringVar() self.OutputVar.set(self.__config.get(self.DEFAULT_SECTION, 'output')) Entry(self.EntryFrame, textvariable=self.OutputVar ,width=50).grid(row=i, column=1) i += 1 Button(self.EntryFrame, text='Write to SVG and Quit', command=self.WriteToSvg).grid(row=i, column=1, sticky=E) def WriteConfig(self): with open(os.path.expanduser('~/.py-art.cfg'), 'wb') as configfile: self.__config.set(self.DEFAULT_SECTION, 'input', self.InputVar.get()) self.__config.set(self.DEFAULT_SECTION, 'inverted', self.InvertedVar.get()) self.__config.set(self.DEFAULT_SECTION, 'size', self.SizeVar.get()) self.__config.set(self.DEFAULT_SECTION, 'scale', self.ScaleVar.get()) self.__config.set(self.DEFAULT_SECTION, 'rows', self.RowsVar.get()) self.__config.set(self.DEFAULT_SECTION, 'columns', self.ColumnsVar.get()) if IN_AXIS: self.__config.set(self.DEFAULT_SECTION, 'height', self.ToolDiameterVar.get()) self.__config.set(self.DEFAULT_SECTION, 'margin', self.ToolDiameterVar.get()) self.__config.set(self.DEFAULT_SECTION, 'preamble', self.PreambleVar.get()) self.__config.set(self.DEFAULT_SECTION, 'tool_diameter', self.ToolDiameterVar.get()) self.__config.set(self.DEFAULT_SECTION, 'thickness', self.ThicknessVar.get()) self.__config.set(self.DEFAULT_SECTION, 'width', self.ToolDiameterVar.get()) else: self.__config.set(self.DEFAULT_SECTION, 'output', self.OutputVar.get()) self.__config.write(configfile) def DisplayAndQuit(self, display, size): image = Image.open(os.path.expanduser(self.InputVar.get())) rows = self.RowsVar.get() columns = self.ColumnsVar.get() curve = Curve(display, image) curve.scale = (self.ScaleVar.get(), self.ScaleVar.get()) curve.is_inverted = self.InvertedVar.get() curve.calculate_levels(5, 0, 0, columns * size, rows * size) self.display_nxm_with_border(rows, columns, size, display, curve) display.close() self.WriteConfig() self.quit() def WriteToSvg(self): size = int(self.SizeVar.get()) display = SvgDisplay( os.path.expanduser(self.OutputVar.get()), self.ColumnsVar.get()*size + 22, self.RowsVar.get()*size + 22) # display = TurtleDisplay() display.offset = (11,11) self.DisplayAndQuit(display, size) def WriteBoundaryMoves(self, display, cut_depth): width = self.WidthVar.get() height = self.HeightVar.get() tool_radius = self.ToolDiameterVar.get() / 2 corner_radius = 1.0 display.add_point((-tool_radius, -corner_radius)) print "g1 y%f z%f" % (-height + corner_radius, -cut_depth) print "g3 x%f y%f i%f" % ( corner_radius, -height - tool_radius, tool_radius + corner_radius) print "g1 x%f" % (width - corner_radius) print "g3 x%f y%f j%f" % ( width + tool_radius, -height + corner_radius, tool_radius + corner_radius) print "g1 y%f" % (-corner_radius) print "g3 x%f y%f i%f" % ( width - corner_radius, tool_radius, -tool_radius - corner_radius) print "g1 x%f" % (corner_radius) print "g3 x%f y%f j%f" % ( -tool_radius, -corner_radius, -tool_radius - corner_radius) def WriteBoundaryTraceToAxis(self): display = self.CreateGCodeDisplay() self.WriteBoundaryMoves(display, cut_depth=0) display.close_curve() display.close() self.WriteConfig() self.quit() def WriteBoundaryCutToAxis(self): display = self.CreateGCodeDisplay() tool_radius = self.ToolDiameterVar.get() / 2 thickness = self.ThicknessVar.get() zstart = 0.05 zstep = -tool_radius / 2 zstop = -thickness - 0.5 display.depth = -zstart for cut_depth in range(zstart, zstop, zstep): self.WriteBoundaryMoves(display, cut_depth) display.close_curve() display.close() self.WriteConfig() self.quit() def CreateGCodeDisplay(self): display = GCodeDisplay() display.preamble = self.PreambleVar.get() display.feed_rate = 1200 return display def WriteEngravingToAxis(self): display = self.CreateGCodeDisplay() width = self.WidthVar.get() height = self.HeightVar.get() margin = self.MarginVar.get() size = self.SizeVar.get() xscale = (width - 2*margin) / (3*size) yscale = (height - 2*margin) / (2*size) scale = min(xscale, yscale) xoff = width/2 + 1.5*size*scale yoff = -height/2 + size*scale display.scale = (-scale, -scale) display.offset = (xoff, yoff) self.DisplayAndQuit(display, size) def display_rectangle(self, size, display, curve): display.add_point((-1, -1)) display.add_point((-1, size)) display.add_point((size * 2, size)) display.add_point((size * 2, -1)) display.close_curve() curve.draw_cell((size - 1, 0), (size - 1, size - 1), -1) display.add_point((size, size - 1)) curve.draw_cell((size, size - 1), (size, 0), -1) display.add_point((size - 1, 0)) display.close_curve() def display_square(self, size, display, curve): display.add_point((-1, -1)) display.add_point((-1, size)) display.add_point((size, size)) display.add_point((size, -1)) display.close_curve() curve.draw_cell((size/2 - 1, 0), (size/2 - 1, size/2 - 1), -1) display.add_point((size/2 - 1, size/2)) curve.draw_cell((size/2 - 1, size/2), (size/2 - 1, size-1), -1) display.add_point((size/2, size - 1)) curve.draw_cell((size/2, size - 1), (size/2, size/2), -1) display.add_point((size/2, size/2 - 1)) curve.draw_cell((size/2, size/2 - 1), (size/2, 0), -1) display.add_point((size/2 - 1, 0)) display.close_curve() def display_nxm_with_border(self, n, m, size, display, curve): """ Draw the curve using n rows and m columns. n - the number of rows must be even. m - the number of columns. size - the size of each row and column. display - the place to draw the curve. curve - the curve to draw. """ display.add_point((-1, n/2*size)) display.add_point((-1, n*size)) display.add_point((m*size, n*size)) display.add_point((m*size, -1)) display.add_point((-1, -1)) display.add_point((-1, n/2*size - 1)) self.display_nxm(n, m, size, display, curve) def display_nxm(self, n, m, size, display, curve): for i in range(n/2 - 1): display.add_point((0, (n/2 - i)*size - 1)) curve.draw_cell((0, (n/2 - i)*size - 1), (0, (n/2 - i - 1)*size), -1) for i in range(m): display.add_point((i*size, size - 1)) curve.draw_cell((i*size, size - 1), ((i+1)*size - 1, size - 1), 1) for i in range(n/2 - 1): for j in range(m-2): display.add_point(((m-j)*size - 1, (2*i+1)*size)) curve.draw_cell( ((m-j)*size - 1, (2*i+1)*size), ((m-j-1)*size, (2*i+1)*size), 1) for j in range(2): display.add_point((2*size - 1, (2*i+j+1)*size)) curve.draw_cell( (2*size - 1, (2*i+j+1)*size), (2*size - 1, (2*i+j+2)*size - 1), -1) for j in range(m-2): display.add_point(((2+j)*size, (2*i+3)*size)) curve.draw_cell( ((2+j)*size, (2*i+3)*size - 1), ((3+j)*size-1, (2*i+3)*size - 1), 1) for i in range(m): display.add_point(((m-i)*size-1, (n-1)*size)) curve.draw_cell( ((m-i)*size-1, (n-1)*size), ((m-i-1)*size, (n-1)*size), 1) for i in range(n/2 - 1): display.add_point((0, (n - i - 1)*size - 1)) curve.draw_cell((0, (n - i - 1)*size - 1), (0, (n - i - 2)*size), -1) display.close_curve()
class FontPanel(StylePropertyPanel): title = _("Fonts") def __init__(self, master, main_window, doc): self.family_to_fonts = font.make_family_to_fonts() self.families = self.family_to_fonts.keys() self.families.sort() StylePropertyPanel.__init__(self, master, main_window, doc, name='fontdlg') self.family_list.SetList(self.families) index = self.families.index(self.font_family) self.family_list.select_set(index) self.family_list.yview(index) def build_dlg(self): top = self.top buttons = self.create_std_buttons(top) buttons.grid(row=3, column=4, columnspan=2, sticky="news") self.sample = FontPreview(top) self.sample.grid(column=0, row=3, columnspan=4, sticky="news") # XXX: the background color of the sample text should be # configurable label = Label(top, text=_("Font Family:"), anchor=W) label.grid(column=0, row=0, columnspan=2, sticky="ew") sb_vert = Scrollbar(top, takefocus=0) sb_vert.grid(column=1, row=1, rowspan=2, sticky="news") family_list = UpdatedListbox(top, name='families', height=8) family_list.grid(column=0, row=1, rowspan=2, sticky="news") family_list.Subscribe(SELECTION, self.family_selected) sb_vert['command'] = (family_list, 'yview') family_list['yscrollcommand'] = (sb_vert, 'set') self.family_list = family_list label = Label(top, text=_("Font Style:"), anchor=W) label.grid(column=2, row=0, sticky="ew") sb_vert = Scrollbar(top, takefocus=0) sb_vert.grid(column=3, row=1, rowspan=2, sticky="news") self.font_attr_list = UpdatedListbox(top, name='weights', height=4, width=15) self.font_attr_list.grid(column=2, row=1, rowspan=2, sticky="news") self.font_attr_list.Subscribe(SELECTION, self.attr_selected) sb_vert['command'] = (self.font_attr_list, 'yview') self.font_attr_list['yscrollcommand'] = (sb_vert, 'set') label = Label(top, text=_("Size:"), anchor=W) label.grid(column=4, row=0, columnspan=2, sticky="ew") frame = Frame(top) frame.grid(column=4, row=1, columnspan=2, sticky='ew') self.var_size = DoubleVar(top) scroll = MiniScroller(frame, variable=self.var_size, min=0.0, max=None, step=1) scroll.pack(side=RIGHT, fill=Y) self.size_entry = MyEntry(frame, textvariable=self.var_size, width=4, command=self.apply_size, justify=RIGHT) self.size_entry.pack(side=LEFT, expand=1, fill=BOTH) sb_vert = Scrollbar(top, takefocus=0) sb_vert.grid(column=5, row=2, sticky="news") self.size_list = UpdatedListbox(top, name='sizes', width=4, height=5) self.size_list.grid(column=4, row=2, sticky="news") self.size_list.Subscribe(SELECTION, self.size_selected) self.size_list.SetList(std_sizes) sb_vert['command'] = (self.size_list, 'yview') self.size_list['yscrollcommand'] = (sb_vert, 'set') top.columnconfigure(0, weight=1000) top.columnconfigure(4, weight=1) top.rowconfigure(2, weight=1) def init_from_doc(self): object = self.document.CurrentObject() if object is not None and object.is_Text: self.update_from_object_cb(object) else: default = font.GetFont(config.preferences.default_font) self.font_family = default.family self.font_attr = default.font_attrs self.update_from_family() self.update_size(properties.default_text_style.font_size) def Update(self): self.update_from_object_cb(self.document.CurrentObject()) def update_from_object_cb(self, obj): if obj is not None and obj.is_Text: font = obj.Font() self.font_family = font.family self.font_attr = font.font_attrs self.update_size(obj.FontSize()) self.update_from_family() def do_apply(self): name = self.current_font_ps() if not name: if __debug__: pdebug(None, 'FontPanel.do_apply: no ps name!') return kw = { 'font': font.GetFont(name), 'font_size': self.var_size.get(), # set if_type_present to one to make sure that font # properties are only set on objects that can have font # properties. This is not ideal, but it works and needed # only simple changes to base.py 'if_type_present': 1 } self.set_properties(_("Set Font `%s'") % name, 'font', kw) def update_from_family(self, set_view=1): index = self.families.index(self.font_family) self.family_list.Select(index, set_view) fonts = self.family_to_fonts[self.font_family] attrs = [] for name in fonts: attrs.append(font.fontmap[name][1]) attrs.sort() self.set_font_attrs(attrs) self.update_sample() def update_size(self, size): self.var_size.set(size) if size in std_sizes: self.size_list.Select(list(std_sizes).index(size), 1) else: self.size_list.SelectNone() def update_sample(self): self.sample.SetFont(self.current_font_ps()) def set_font_attrs(self, attrs): self.font_attrs = attrs self.font_attr_list.SetList(attrs) self.font_attr = get_from_list(self.font_attr, attrs) self.font_attr_list.Select(attrs.index(self.font_attr), 1) def current_font_xlfd(self): fonts = self.family_to_fonts[self.font_family] for name in fonts: family, attrs, xlfd_start, encoding = font.fontmap[name] if attrs == self.font_attr: return font.xlfd_template % (xlfd_start, 24, encoding) return '' def current_font_ps(self): fonts = self.family_to_fonts[self.font_family] for name in fonts: family, attrs, xlfd_start, encoding = font.fontmap[name] if attrs == self.font_attr: return name return '' def family_selected(self): sel = self.family_list.curselection() if sel: index = sel[0] self.font_family = self.families[index] self.update_from_family(set_view=0) def attr_selected(self): sel = self.font_attr_list.curselection() if sel: index = sel[0] self.font_attr = self.font_attrs[index] self.update_sample() def size_selected(self): sel = self.size_list.curselection() if sel: self.var_size.set(self.size_list.get(sel[0])) def apply_size(self, *args): if self.can_apply(): size = self.var_size.get() self.document.CallObjectMethod(text.CommonText, _("Set Font Size %.1f") % size, 'SetFontSize', size) def save_prefs(self): StylePropertyPanel.save_prefs(self) config.preferences.sample_text = self.sample.Text()
# get interpolated opacity data for this temperature and density # first check to see if the data is valid (non-zero) mgr_valid = ip_reader.check_valid_data(mgr_grid) mgp_valid = ip_reader.check_valid_data(mgp_grid) mgs_valid = ip_reader.check_valid_data(mgs_grid) mgrt_valid = ip_reader.check_valid_data(mgrt_grid) name = selected_ID.get() print("-------------------- BEGIN DATA PRINT FOR {0} ---------------------".format(name)) print("Group structure for {0} groups:".format(len(hnu_grid) - 1)) print(hnu_grid) # if valid, interpolate data at target rho and target T if (mgr_valid): mgr_interp = ip_reader.interpolate_mg_opacity_data( T_grid, rho_grid, hnu_grid, mgr_grid, target_rho.get(), target_T.get(), "multigroup absorption Rosseland") if (mgp_valid): mgp_interp = ip_reader.interpolate_mg_opacity_data( T_grid, rho_grid, hnu_grid, mgp_grid, target_rho.get(), target_T.get(), "multigroup absorption Planckian") if (mgs_valid): mgs_interp = ip_reader.interpolate_mg_opacity_data( T_grid, rho_grid, hnu_grid, mgs_grid, target_rho.get(), target_T.get(), "multigroup scattering") if (mgrt_valid): # mgrt_interp = ip_reader.interpolate_mg_opacity_data( T_grid, rho_grid, hnu_grid, mgrt_grid, target_rho.get(), target_T.get(), "total rosseland") print("-------------------- END DATA PRINT FOR {0} ---------------------".format(name))
class SystemProperties: """Gets the flow and contaminant properties.""" def __init__(self, master, system): """Constructor method. Defines the parameters to be obtained in this window.""" self.master = master self.system = system self.fonttype = system.fonttype self.version = system.version self.superfont = get_superfont(self.fonttype) #superscript font self.tframe = Frame(master.tframe) self.frame = Frame(master.frame) self.bframe = Frame(master.bframe) self.advs = ['None', 'Steady flow', 'Period oscillation'] self.bios = ['None', 'Uniform', 'Depth-dependent'] self.cons = ['None', 'Consolidation'] self.adv = StringVar(value=self.advs[0]) #tidal flag self.bio = StringVar(value=self.bios[0]) #bioturbation flag self.con = StringVar(value=self.cons[0]) #consolidation flag self.hbio = DoubleVar(value=10.) #bioturbation depth self.sigma = DoubleVar(value=10.) #bioturbation depth self.Dbiop = DoubleVar(value=1.) #particle bioturbation coeff self.Dbiopw = DoubleVar(value=100.) #pore water bioturbation coeff self.Vdar = DoubleVar(value=0.) #Darcy velocity self.Vtidal = DoubleVar(value=0.) #Tidal velocity self.ptidal = DoubleVar(value=0.0014) #Tidal frequency self.hcon = DoubleVar(value=0) #total consolidation self.t90 = DoubleVar(value=1.) #time to 90% consolidation self.top = None #flag for existence of toplevel if system.layers[0].number == 0: self.toplayer_h = system.layers[1].h else: self.toplayer_h = system.layers[0].h self.lengthunit = system.lengthunit self.timeunit = system.timeunit self.diffunit = system.diffunit self.diffunits = system.diffunits try: self.adv.set(system.adv) self.bio.set(system.bio) self.con.set(system.con) self.Vdar.set(system.Vdar) self.hbio.set(system.hbio) self.sigma.set(system.sigma) self.Dbiop.set(system.Dbiop) self.Dbiopw.set(system.Dbiopw) self.Vtidal.set(system.Vtidal) self.ptidal.set(system.ptidal) self.hcon.set(system.hcon) self.t90.set(system.t90) except: pass def make_widgets(self): """Make the widgets for the window.""" self.bgcolor = self.frame.cget('bg') self.instructions = Label( self.frame, text= ' Please provide the information of the following system properties: ' ) self.blank1 = Label(self.frame, width=30) self.blank2 = Label(self.frame, width=20) self.blank3 = Label(self.frame, width=15) self.blank4 = Label(self.frame, width=20) self.headings1 = Label(self.frame, text='Parameter') self.headings2 = Label(self.frame, text='Value') self.headings3 = Label(self.frame, text='Units') self.advlabel = Label(self.frame, text='Upwelling groundwater flow') self.advwidget = OptionMenu(self.frame, self.adv, *self.advs, command=self.updatesystem) self.Vdarlabel = Label(self.frame, text='Darcy velocity:') self.Vtidallabel = Label(self.frame, text='Oscillation maximum velocity:') self.ptidallabel = Label(self.frame, text='Oscillation period:') self.Vdarwidget = Entry(self.frame, width=10, textvariable=self.Vdar, justify='center') self.Vtidalwidget = Entry(self.frame, width=10, textvariable=self.Vtidal, justify='center') self.ptidalwidget = Entry(self.frame, width=10, textvariable=self.ptidal, justify='center') self.Vdarunits = Label(self.frame, text=self.lengthunit + '/' + self.timeunit) self.Vtidalunits = Label(self.frame, text=self.lengthunit + '/' + self.timeunit) self.ptidalunits = Label(self.frame, text=self.timeunit) self.biolabel = Label(self.frame, text='Modeling bioturbation') self.biowidget = OptionMenu(self.frame, self.bio, *self.bios, command=self.updatesystem) self.hbiolabel = Label(self.frame, text='Bioturbation depth:') self.sigmalabel = Label(self.frame, text='Gaussian model coefficient:') self.Dbioplabel = Label(self.frame, text='Particle biodiffusion coefficient:') self.Dbiopwlabel = Label(self.frame, text='Pore water biodiffusion coefficient:') self.hbiowidget = Entry(self.frame, width=10, textvariable=self.hbio, justify='center') self.sigmawidget = Entry(self.frame, width=10, textvariable=self.sigma, justify='center') self.Dbiopwidget = Entry(self.frame, width=10, textvariable=self.Dbiop, justify='center') self.Dbiopwwidget = Entry(self.frame, width=10, textvariable=self.Dbiopw, justify='center') self.hbiounits = Label(self.frame, text=self.lengthunit) self.Dbiopunits = Label(self.frame, text=self.diffunits[1]) self.Dbiopwunits = Label(self.frame, text=self.diffunits[1]) self.conlabel = Label(self.frame, text='Modeling consolidation') self.conwidget = OptionMenu(self.frame, self.con, *self.cons, command=self.updatesystem) self.hconlabel = Label(self.frame, text='Maximum consolidation depth:') self.t90label = Label(self.frame, text='Time to 90% consolidation:') self.hconwidget = Entry(self.frame, width=10, textvariable=self.hcon, justify='center') self.t90widget = Entry(self.frame, width=10, textvariable=self.t90, justify='center') self.hconunits = Label(self.frame, text=self.lengthunit) self.t90units = Label(self.frame, text=self.timeunit) self.advwidget.config(width=20) self.biowidget.config(width=20) self.conwidget.config(width=20) #self.okbutton = Button(self.frame, text = 'OK', command = self.OK, width = 20) #show the widgets on the grid self.instructions.grid(row=0, column=0, columnspan=3, padx=6, sticky='W') self.blank1.grid(row=1, column=0) self.blank2.grid(row=1, column=1) self.blank3.grid(row=1, column=2) self.row = 3 self.focusbutton = None self.updatesystem() def updatesystem(self, event=None): try: self.advlabel.grid_forget() self.advwidget.grid_forget() self.Vdarlabel.grid_forget() self.Vdarwidget.grid_forget() self.Vdarunits.grid_forget() self.Vtidallabel.grid_forget() self.Vtidalwidget.grid_forget() self.Vtidalunits.grid_forget() self.ptidallabel.grid_forget() self.ptidalwidget.grid_forget() self.ptidalunits.grid_forget() self.biolabel.grid_forget() self.biowidget.grid_forget() self.sigmalabel.grid_forget() self.sigmawidget.grid_forget() self.hbiolabel.grid_forget() self.hbiowidget.grid_forget() self.hbiounits.grid_forget() self.Dbioplabel.grid_forget() self.Dbiopwidget.grid_forget() self.Dbiopunits.grid_forget() self.Dbiopwlabel.grid_forget() self.Dbiopwwidget.grid_forget() self.Dbiopwunits.grid_forget() self.conlabel.grid_forget() self.conwidget.grid_forget() self.hconlabel.grid_forget() self.hconwidget.grid_forget() self.hconunits.grid_forget() self.t90label.grid_forget() self.t90widget.grid_forget() self.t90units.grid_forget() except: pass row = self.row self.advlabel.grid(row=row, column=0, sticky='E', padx=4) self.advwidget.grid(row=row, column=1, sticky='W', padx=4, columnspan=2) row = row + 1 if self.adv.get() == self.advs[1] or self.adv.get() == self.advs[2]: self.Vdarlabel.grid(row=row, column=0, sticky='E', padx=4) self.Vdarwidget.grid(row=row, column=1, pady=1) self.Vdarunits.grid(row=row, column=2, sticky='W', padx=4) row = row + 1 if self.adv.get() == self.advs[2]: self.Vtidallabel.grid(row=row, column=0, sticky='E', padx=4) self.Vtidalwidget.grid(row=row, column=1, pady=1) self.Vtidalunits.grid(row=row, column=2, sticky='W', padx=4) row = row + 1 self.ptidallabel.grid(row=row, column=0, sticky='E', padx=4) self.ptidalwidget.grid(row=row, column=1, pady=1) self.ptidalunits.grid(row=row, column=2, sticky='W', padx=4) row = row + 1 self.biolabel.grid(row=row, column=0, sticky='E', padx=4) self.biowidget.grid(row=row, column=1, sticky='W', padx=4, columnspan=2) row = row + 1 if self.bio.get() == self.bios[1]: self.hbiolabel.grid(row=row, column=0, sticky='E', padx=4) self.hbiowidget.grid(row=row, column=1, pady=1) self.hbiounits.grid(row=row, column=2, sticky='W', padx=4) row = row + 1 if self.bio.get() == self.bios[2]: self.sigmalabel.grid(row=row, column=0, sticky='E', padx=4) self.sigmawidget.grid(row=row, column=1, pady=1) self.hbiounits.grid(row=row, column=2, sticky='W', padx=4) row = row + 1 if self.bio.get() == self.bios[1] or self.bio.get() == self.bios[2]: self.Dbioplabel.grid(row=row, column=0, sticky='E', padx=4) self.Dbiopwidget.grid(row=row, column=1, pady=1) self.Dbiopunits.grid(row=row, column=2, sticky='W', padx=4) row = row + 1 self.Dbiopwlabel.grid(row=row, column=0, sticky='E', padx=4) self.Dbiopwwidget.grid(row=row, column=1, pady=1) self.Dbiopwunits.grid(row=row, column=2, sticky='W', padx=4) row = row + 1 self.conlabel.grid(row=row, column=0, sticky='E', padx=4) self.conwidget.grid(row=row, column=1, sticky='W', padx=4, columnspan=2) row = row + 1 if self.con.get() == self.cons[1]: self.hconlabel.grid(row=row, column=0, sticky='E', padx=4) self.hconwidget.grid(row=row, column=1, pady=1) self.hconunits.grid(row=row, column=2, sticky='W', padx=4) row = row + 1 self.t90label.grid(row=row, column=0, sticky='E', padx=4) self.t90widget.grid(row=row, column=1, pady=1) self.t90units.grid(row=row, column=2, sticky='W', padx=4) row = row + 1 self.blank4.grid(row=row) row = row + 1 self.focusbutton = None self.master.geometry() def error_check(self, event=None): """Finish and move on. Checks that the number chemicals are less than the total number of chemicals in database.""" error = 0 #if self.bio.get() == self.bios[1] and self.hbio.get() > self.toplayer_h: error = 1 return error def warning(self): tkmb.showerror( title=self.version, message='The bioturbation ' + 'depth (%.1f cm) ' % self.hbio.get() + 'cannot exceed the ' + 'thickness of the top layer (%.1f). ' % self.toplayer_h + 'Automatically increasing ' + 'the thickness of the top layer to the bioturbation ' + 'depth.') self.hbio.set(self.toplayer_h) self.focusbutton = None self.master.tk.lift()
class plotter(Frame): def __init__(self,mainframe): # Initiate t a blank figure self.figure_created=False # A bool to represent if the figure was created or not self.mainframe=mainframe # Asign a variable ofr the aminframe self.fig=Figure() # This is a dummy figure that will be overwrited but it will grant the space for the real one self.canvas=FigureCanvasTkAgg(self.fig,master=mainframe) # The canvas where all the plots will be made self.canvas.show() self.canvas.get_tk_widget().grid(column=5,row=0,rowspan=12,columnspan=4) # Create the widget that will mange the pots # Create the number of columns and rows ttk.Label(mainframe,text="Set number of columns ").grid(column=0,row=0) self.total_columns=IntVar() # The variable that will store the number of total columns self.total_columns.set(1) # We give it an initial value # Combobox with the Possible values for the total number of columns in the main figure self.box_total_columns=ttk.Combobox(mainframe,textvariable=self.total_columns,state="readonly",width=3) self.box_total_columns['values']=range(1,10) self.box_total_columns.grid(column=1,row=0) ttk.Label(mainframe,text=" Set number of rows ").grid(column=2,row=0) # The same taht with the columns but with the rows self.total_rows=IntVar() self.total_rows.set(1) self.box_total_rows=ttk.Combobox(mainframe,textvariable=self.total_rows,state="readonly",width=3) self.box_total_rows['values']=range(1,10) self.box_total_rows.grid(column=3,row=0) # Create the figure with the subplots ttk.Button(mainframe,command=self.init_program,text="Create").grid(column=4,row=0) # This button will initiate all the features # The next lines will allow to change between the subplots ttk.Label(mainframe,text="Select Column ").grid(column=0,row=1) self.current_column=IntVar() # The variable storing the current Column # The next lines will setup the combobox for making this change self.box_current_column=ttk.Combobox(mainframe,textvariable=self.current_column,state="readonly",width=3) self.box_current_column["values"]=["--"] self.box_current_column.grid(column=1,row=1) ttk.Label(mainframe,text=" Select Row ").grid(column=2,row=1) self.current_row=IntVar() # The variable storing th current row self.box_current_row=ttk.Combobox(mainframe,textvariable=self.current_row,state="readonly",width=3) self.box_current_row["values"]=["--"] self.box_current_row.grid(column=3,row=1) self.box_current_row.bind("<<ComboboxSelected>>",self.change_subplot) # Now we make that when you choose one column or a row self.box_current_column.bind("<<ComboboxSelected>>",self.change_subplot) # the prgram will auto load the presets for that subplot # Open File ttk.Button(mainframe,text="Open file",command=self.open_file).grid(column=0,row=3) self.filename=StringVar() # Variable to store the path to the data file self.entry_filename=ttk.Entry(mainframe,textvar=self.filename,width=30).grid(column=1,row=3,columnspan=3,sticky=E) # Options for the plot # The label for the legend self.label=StringVar() # Variable storing the label ttk.Label(mainframe,text="Label").grid(column=0,row=4) ttk.Entry(mainframe,textvar=self.label,width=30).grid(column=1,row=4,columnspan=3,sticky=E) # Entry to enter the label # Select The column where the data is stored in the file self.column_x=IntVar() # This variable stores the column where the x data is in the file (0 is the first one) self.column_x.set(0) # Give the variable an initial value self.column_y=IntVar() # This variable stores the column where the y data is in the file (0 is the first one) self.column_y.set(1) # Give the variable an initial value ttk.Label(text="Column for x data").grid(column=0,row=5) ttk.Entry(textvar=self.column_x,width=3).grid(column=1,row=5) ttk.Label(text="Column for y data").grid(column=2,row=5) ttk.Entry(textvar=self.column_y,width=3).grid(column=3,row=5) # Combobox for selecting the maker self.marker=StringVar() # Variable storing the marker configuration self.marker.set("None") # The preset value for the marker (no marker on the points) ttk.Label(mainframe,text="Marker").grid(column=0,row=6) combo_marker=ttk.Combobox(mainframe,textvariable=self.marker,state="readonly",width=5) combo_marker["values"]=["None",".",",","o","+","*",'x',"custom"] # Since there is quite a lot of markers i only preload the combo_marker.grid(column=1,row=6) # esentials, but with the option custom it's posible to use wichever matplotlib supports self.marker_custom=StringVar() # Variable storing the marker type ttk.Entry(mainframe,textvar=self.marker_custom,width=5).grid(column=3,row=6,sticky=E) # Entry for the option of the custom ttk.Button(mainframe,text="Custom Marker",command=self.set_custom_marker).grid(column=2,row=6) # Button to aply the custom config # Combobox for the line Style self.linestyle=StringVar() # Variable storing the linestyle configuration self.linestyle.set("-") # Preset value for the linestyle (solid line) ttk.Label(mainframe,text="Line Style").grid(column=0,row=7) combo_linestyle=ttk.Combobox(mainframe,textvariable=self.linestyle,state="readonly",width=5) combo_linestyle["values"]=["None","-","--","-.",":"] # Those are all the posible options for the linestyle combo_linestyle.grid(column=1,row=7) # Change the color, this is a test version for a quick need ttk.Label(mainframe,text="Color").grid(column=2,row=7) self.color=StringVar() ttk.Entry(textvar=self.color,width=5).grid(column=3,row=7) # Change the axis labels ttk.Label(mainframe,text="X axis Label").grid(column=0,row=8,columnspan=2) ttk.Label(mainframe,text="Y axis Label").grid(column=2,row=8,columnspan=2) self.x_label=StringVar() # Variable storing the label for the x axis self.y_label=StringVar() # Variable storing the label for the y axis ttk.Entry(mainframe,textvar=self.x_label).grid(column=0,row=9,columnspan=2) ttk.Entry(mainframe,textvar=self.y_label).grid(column=2,row=9,columnspan=2) ttk.Button(mainframe,text="Update Labels",command=self.update_labels).grid(column=4,row=8) # This button aplies the labels in the axis # Limits for the x and y axes # Label with information ttk.Label(text="Minimun Value of the axis").grid(column=0,row=10,columnspan=2) ttk.Label(text="Minimun Value of the axis").grid(column=2,row=10,columnspan=2) self.xmin=DoubleVar() # Variable with the value of the minimun x self.xmax=DoubleVar() # Variable with the value of the maximun x self.ymin=DoubleVar() # Variable with the value of the minimun y self.ymax=DoubleVar() # Variable with the value of the maximun y ttk.Entry(mainframe,textvar=self.xmin).grid(column=0,row=11,columnspan=2) # Entry for the minimal value ttk.Entry(mainframe,textvar=self.xmax).grid(column=2,row=11,columnspan=2) # Entry for the maximun value ttk.Button(mainframe,text="x axis",command=self.change_x_axe).grid(column=4,row=11) # Update x axe ttk.Entry(mainframe,textvar=self.ymin).grid(column=0,row=12,columnspan=2) # The same for the y axis ttk.Entry(mainframe,textvar=self.ymax).grid(column=2,row=12,columnspan=2) ttk.Button(mainframe,text="y axis",command=self.change_y_axe).grid(column=4,row=12) # Make the plot ttk.Button(mainframe,text="Plot",command=self.make_plot).grid(column=0,row=13) # Save the figure ttk.Button(mainframe,text="Save",command=self.save_plot).grid(column=1,row=13) # Options of subplots # Reset one of the subplots ttk.Button(mainframe,text="Reset Subplot",command=self.reset_subplot).grid(column=4,row=1) # Export a configuration file of the plots, this will allow to redo the figure ttk.Button(mainframe,text="Export",command=self.export_logfile).grid(column=2,row=13) # Import a configuration file of the plots, this will allow to redo a previous exported figure using the logfile ttk.Button(mainframe,text="import",command=self.read_logfile).grid(column=3,row=13) # Join the x axis ttk.Button(mainframe,text="join x axes",command=self.fix_x_ticks).grid(column=5,row=12) ttk.Button(mainframe,text="join y axes",command=self.fix_y_ticks).grid(column=6,row=12) ttk.Button(mainframe,text="join x and y axes",command=self.fix_x_and_y_ticks).grid(column=7,row=12) def init_program(self,*args): # This functions set all the presets for the program to work self.create_subplots() # First we create the subplots required by self.total_rows/columns self.current_column.set(1) # We set the focus on the self.current_row.set(1) # (1,1) subplot (remember that we start to count in 1 ,not 0. self.change_subplot() # Aply the changes in the focus of the subplot def create_subplots(self,*args): self.sharex=True self.sharey=False # This function will create the subplot axes, and the needed variables self.fig=Figure() # This will replace the figure in the main routine (its necesary to change the size of the figure without closing # the program self.canvas=FigureCanvasTkAgg(self.fig,master=self.mainframe) # We have to redefine the canvas self.canvas.show() self.canvas.get_tk_widget().grid(column=5,row=0,rowspan=12,columnspan=4) self.axes=[[]] # This variable will store the axes of each subplots. Th axe os a subplot is what allow to make the plot in that subplot # self.fig.subplots_adjust(hspace=0.001) self.file_index=[[]] # This will save wich data files were plotted in each subplot, its necessary in order to write the logfile self.label_index=[[]] # This variable store the labels for making the logfile self.marker_index=[[]] # This one store the marker for each data set self.linestyle_index=[[]] # This one stores line style self.color_index=[[]] # This one stores the color self.xcolumn_index=[[]] # This one store the column of the file used as x data self.xlabel_index=[[]] # This will save the labels used for the x axis self.ycolumn_index=[[]] # This one store the column of the file used as y data self.ylabel_index=[[]] # This will save the labels used for the y axis self.xlimit_index=[[]] self.ylimit_index=[[]] # Now we will append an axe inside self.axes for each subplot, it will be stored so it is accesible with [row][column] # We need to append also a list for each subplot in the other variables for j in range(self.total_columns.get()): # First we make a lopp throw the first row self.axes[0].append(self.fig.add_subplot(self.total_rows.get(),self.total_columns.get(),j+1)) # Append an axe subplot in each column self.file_index[0].append([]) # Append a list for each column self.label_index[0].append([]) self.marker_index[0].append([]) self.linestyle_index[0].append([]) self.color_index[0].append([]) self.xcolumn_index[0].append([]) self.ycolumn_index[0].append([]) self.xlabel_index[0].append("") # Append a blank string for each column self.ylabel_index[0].append("") # Append a blank string for each column self.xlimit_index[0].append(["",""]) self.ylimit_index[0].append(["",""]) if (self.total_rows.get()-1)!=0: # If we have more than one row we repeat the previous steps for each row for i in range(1,self.total_rows.get()): self.axes.append([]) # We need to append a list for each row here self.file_index.append([]) # also in this one self.label_index.append([]) # And this one self.marker_index.append([]) # and this one self.linestyle_index.append([]) # and this one self.xcolumn_index.append([]) self.ycolumn_index.append([]) self.color_index.append([]) self.xlabel_index.append([]) self.ylabel_index.append([]) self.xlimit_index.append([]) self.ylimit_index.append([]) for j in range(self.total_columns.get()): # The next steps are the same than in the previous loop self.axes[i].append(self.fig.add_subplot(self.total_rows.get(),self.total_columns.get(),1+j+self.total_columns.get()*i)) self.file_index[i].append([]) self.label_index[i].append([]) self.marker_index[i].append([]) self.linestyle_index[i].append([]) self.color_index[i].append([]) self.xlabel_index[i].append("") self.xcolumn_index[i].append([]) self.ycolumn_index[i].append([]) self.ylabel_index[i].append("") self.xlimit_index[i].append(["",""]) self.ylimit_index[i].append(["",""]) self.fig.tight_layout() # We let maplotlib to optimize the space around the subplots # for i in range(self.total_rows.get()-1): # self.axes[0][0].xaxis.set_visible(False) self.canvas.draw() # We draw the changes, now the main figure is divided in the subplots self.box_current_column["values"]=range(1,self.total_columns.get()+1) # Update the possible values in the combobox self.box_current_row["values"]=range(1,self.total_rows.get()+1) # of the columns and rows to make the change posiible self.figure_created=True # We save that we have created a figure with subplots def stick_x_axis(self,*args): # This function will create the subplot axes, and the needed variables self.fig=Figure() # This will replace the figure in the main routine (its necesary to change the size of the figure without closing # the program self.canvas=FigureCanvasTkAgg(self.fig,master=self.mainframe) # We have to redefine the canvas self.canvas.show() self.canvas.get_tk_widget().grid(column=5,row=0,rowspan=12) self.axes=[[]] # This variable will store the axes of each subplots. Th axe os a subplot is what allow to make the plot in that subplot self.file_index=[[]] # This will save wich data files were plotted in each subplot, its necessary in order to write the logfile self.label_index=[[]] # This variable store the labels for making the logfile self.marker_index=[[]] # This one store the marker for each data set self.linestyle_index=[[]] # This one stores line style self.color_index=[[]] self.xcolumn_index=[[]] self.ycolumn_index=[[]] self.xlabel_index=[[]] # This will save the labels used for the x axis self.ylabel_index=[[]] # This will save the labels used for the y axis self.xlimit_index=[[]] self.ylimit_index=[[]] # Now we will append an axe inside self.axes for each subplot, it will be stored so it is accesible with [row][column] # We need to append also a list for each subplot in the other variables for j in range(self.total_columns.get()): # First we make a lopp throw the first row self.axes[0].append(self.fig.add_subplot(self.total_rows.get(),self.total_columns.get(),j+1)) # Append an axe subplot in each column self.file_index[0].append([]) # Append a list for each column self.label_index[0].append([]) self.marker_index[0].append([]) self.linestyle_index[0].append([]) self.color_index[0].append([]) self.xcolumn_index[0].append([]) self.ycolumn_index[0].append([]) self.xlabel_index[0].append("") # Append a blank string for each column self.ylabel_index[0].append("") # Append a blank string for each column self.xlimit_index[0].append(["",""]) self.ylimit_index[0].append(["",""]) if (self.total_rows.get()-1)!=0: # If we have more than one row we repeat the previous steps for each row for i in range(1,self.total_rows.get()): self.axes.append([]) # We need to append a list for each row here self.file_index.append([]) # also in this one self.label_index.append([]) # And this one self.marker_index.append([]) # and this one self.linestyle_index.append([]) # and this one self.color_index.append([]) self.xcolumn_index.append([]) self.ycolumn_index.append([]) self.xlabel_index.append([]) self.ylabel_index.append([]) self.xlimit_index.append([]) self.ylimit_index.append([]) for j in range(self.total_columns.get()): # The next steps are the same than in the previous loop self.axes[i].append(self.fig.add_subplot(self.total_rows.get(),self.total_columns.get(),1+j+self.total_columns.get()*i)) self.file_index[i].append([]) self.label_index[i].append([]) self.marker_index[i].append([]) self.linestyle_index[i].append([]) self.color_index[i].append([]) self.xcolumn_index[i].append([]) self.ycolumn_index[i].append([]) self.xlabel_index[i].append("") self.ylabel_index[i].append("") self.xlimit_index[i].append(["",""]) self.ylimit_index[i].append(["",""]) self.fig.tight_layout() # We let maplotlib to optimize the space around the subplots self.canvas.draw() # We draw the changes, now the main figure is divided in the subplots self.box_current_column["values"]=range(1,self.total_columns.get()+1) # Update the possible values in the combobox self.box_current_row["values"]=range(1,self.total_rows.get()+1) # of the columns and rows to make the change posiible self.figure_created=True # We save that we have created a figure with subplots def fix_x_ticks(self,*args): # First set for the maximun of each column and set all the graphs to it for j in range(self.total_columns.get()): max=self.axes[0][j].xaxis.get_majorticklocs()[-1] min=self.axes[0][j].xaxis.get_majorticklocs()[0] for i in range(1,self.total_rows.get()): if (self.axes[i][j].xaxis.get_majorticklocs()[-1]>max): max=self.axes[i][j].xaxis.get_majorticklocs()[-1] if self.axes[i][j].xaxis.get_majorticklocs()[0]<min: min=self.axes[i][j].xaxis.get_majorticklocs()[0] for u in range(self.total_rows.get()): self.axes[i][j].set_xlim([min,max]) for i in range(self.total_rows.get()-1): for j in range(self.total_columns.get()): # self.axes[i][j].xaxis.set_visible(False) self.axes[i][j].set_xticklabels('') self.axes[i+1][j].get_shared_x_axes().join(self.axes[0][j],self.axes[i+1][j]) for j in range(self.total_columns.get()): label=(self.axes[0][j].yaxis.get_majorticklocs()) self.axes[0][j].set_yticklabels(label) for i in range(1,self.total_rows.get()): for j in range(self.total_columns.get()): label=(self.axes[i][j].yaxis.get_majorticklocs()) label=label[0:-1] self.axes[i][j].set_yticklabels(label) self.fig.tight_layout() self.fig.subplots_adjust(hspace=0.001) self.canvas.draw() def fix_y_ticks(self,*args): # First search for the maximun and minimun of y in each row: for i in range(self.total_rows.get()): max=self.axes[i][0].yaxis.get_majorticklocs()[-1] min=self.axes[i][0].yaxis.get_majorticklocs()[0] for j in range(1,self.total_columns.get()): if (self.axes[i][j].yaxis.get_majorticklocs()[-1]>max): max=self.axes[i][j].yaxis.get_majorticklocs()[-1] if self.axes[i][j].yaxis.get_majorticklocs()[0]<min: min=self.axes[i][j].yaxis.get_majorticklocs()[0] for j in range(self.total_columns.get()): self.axes[i][j].set_ylim([min,max]) for i in range(self.total_rows.get()): for j in range(self.total_columns.get()-1): # self.axes[i][j].xaxis.set_visible(False) self.axes[i][j+1].get_shared_y_axes().join(self.axes[i][0],self.axes[i][j+1]) self.axes[i][j+1].set_yticklabels('') self.axes[i][j+1].get_shared_y_axes().join(self.axes[i][0],self.axes[i][j+1]) for i in range(self.total_rows.get()): label=(self.axes[i][-1].xaxis.get_majorticklocs()) self.axes[i][0].set_xticklabels(label) for i in range(self.total_rows.get()): for j in range(self.total_columns.get()-1): label=(self.axes[i][j].xaxis.get_majorticklocs()) label=label[0:-1] self.axes[i][j].set_xticklabels(label) self.fig.tight_layout() self.fig.subplots_adjust(wspace=0.001) self.canvas.draw() def fix_x_and_y_ticks(self,*args): # First set for the maximun of each column and set all the graphs to it for j in range(self.total_columns.get()): max=self.axes[0][j].xaxis.get_majorticklocs()[-1] min=self.axes[0][j].xaxis.get_majorticklocs()[0] for i in range(1,self.total_rows.get()): if (self.axes[i][j].xaxis.get_majorticklocs()[-1]>max): max=self.axes[i][j].xaxis.get_majorticklocs()[-1] if self.axes[i][j].xaxis.get_majorticklocs()[0]<min: min=self.axes[i][j].xaxis.get_majorticklocs()[0] for u in range(self.total_rows.get()): self.axes[i][j].set_xlim([min,max]) for i in range(self.total_rows.get()-1): for j in range(self.total_columns.get()): # self.axes[i][j].xaxis.set_visible(False) self.axes[i][j].set_xticklabels('') self.axes[i+1][j].get_shared_x_axes().join(self.axes[0][j],self.axes[i+1][j]) for j in range(self.total_columns.get()): label=(self.axes[0][j].yaxis.get_majorticklocs()) self.axes[0][j].set_yticklabels(label) for i in range(1,self.total_rows.get()): for j in range(self.total_columns.get()): label=(self.axes[i][j].yaxis.get_majorticklocs()) label=label[0:-1] self.axes[i][j].set_yticklabels(label) # First search for the maximun and minimun of y in each row: for i in range(self.total_rows.get()): max=self.axes[i][0].yaxis.get_majorticklocs()[-1] min=self.axes[i][0].yaxis.get_majorticklocs()[0] for j in range(1,self.total_columns.get()): if (self.axes[i][j].yaxis.get_majorticklocs()[-1]>max): max=self.axes[i][j].yaxis.get_majorticklocs()[-1] if self.axes[i][j].xaxis.get_majorticklocs()[0]<min: min=self.axes[i][j].yaxis.get_majorticklocs()[0] for j in range(self.total_columns.get()): self.axes[i][j].set_ylim([min,max]) for i in range(self.total_rows.get()): for j in range(self.total_columns.get()-1): # self.axes[i][j].xaxis.set_visible(False) self.axes[i][j+1].get_shared_y_axes().join(self.axes[i][0],self.axes[i][j+1]) self.axes[i][j+1].set_yticklabels('') for i in range(self.total_rows.get()): label=(self.axes[i][-1].xaxis.get_majorticklocs()) self.axes[i][0].set_xticklabels(label) for i in range(self.total_rows.get()): for j in range(self.total_columns.get()-1): label=(self.axes[i][j].xaxis.get_majorticklocs()) label=label[0:-1] self.axes[i][j].set_xticklabels(label) for i in range(self.total_rows.get()-1): for j in range(self.total_columns.get()): self.axes[i][j].set_xticklabels('') self.fig.tight_layout() self.fig.subplots_adjust(hspace=0.001) self.fig.subplots_adjust(wspace=0.001) self.canvas.draw() def change_subplot(self,*args): # This function will set the focus on the proper subplot self.current_axe=self.axes[self.current_row.get()-1][self.current_column.get()-1] # We marke as the current axe the one we have chosen self.label.set("") # Reset the values of the labels self.x_label.set(self.xlabel_index[self.current_row.get()-1][self.current_column.get()-1]) # This set the correct x label self.y_label.set(self.ylabel_index[self.current_row.get()-1][self.current_column.get()-1]) # This set the correct ylabel self.column_x.set(0) # Give the variable an initial value self.column_y.set(1) # Give the variable an initial value def save_plot(self,*args): # This function save the figure into a file self.fig.savefig(tkFileDialog.asksaveasfilename(filetypes=(('Portable Document Format','*.pdf'), # Theese are the preset file types ('Portable Network Graphics','*.png'), # Its possible to insert more ('All files','*.*')))) def update_labels(self,*args): # This will change the x and y labels of a subplot to a new value self.current_axe.set_xlabel(self.x_label.get()) # This set the value ox the x label to the one inserted in the entry for that purpouse self.current_axe.set_ylabel(self.y_label.get()) # This do the same for the y axe self.xlabel_index[self.current_row.get()-1][self.current_column.get()-1]=self.x_label.get() # This two senteces save the new values self.ylabel_index[self.current_row.get()-1][self.current_column.get()-1]=self.y_label.get() # of the labels for making the logfile self.fig.tight_layout() # We let matplotlib to arrage the spaces between subplots self.canvas.draw() # Update the canvas def reset_subplot(self,*args): # This will reset the current subplot self.current_axe.clear() # This erase all the information of the subplot self.linestyle_index[self.current_row.get()-1][self.current_column.get()-1]=[] # Empty the values of the log variables self.marker_index[self.current_row.get()-1][self.current_column.get()-1]=[] self.label_index[self.current_row.get()-1][self.current_column.get()-1]=[] self.file_index[self.current_row.get()-1][self.current_column.get()-1]=[] self.canvas.draw() # Update the changes on the canvas def set_custom_marker(self,*args): # This function allows as to refine a custom marker self.marker.set(self.marker_custom.get()) # This will update the value of the marker variable to the one we have entered def open_file(self,*args): # This will open a window for choosing the file where to read the data self.filename.set(tkFileDialog.askopenfilename()) # This stores in the variable of the data file the path to the file self.label.set("") # Set the label to a blank value def make_plot(self,*args): # This will make the plot in the current selected subplot self.file_index[self.current_row.get()-1][self.current_column.get()-1].append(self.filename.get()) # Update the log variable self.label_index[self.current_row.get()-1][self.current_column.get()-1].append(self.label.get()) # With the information of the self.marker_index[self.current_row.get()-1][self.current_column.get()-1].append(self.marker.get()) # new plot self.linestyle_index[self.current_row.get()-1][self.current_column.get()-1].append(self.linestyle.get()) self.color_index[self.current_row.get()-1][self.current_column.get()-1].append(self.color.get()) self.xcolumn_index[self.current_row.get()-1][self.current_column.get()-1].append(self.column_x.get()) self.ycolumn_index[self.current_row.get()-1][self.current_column.get()-1].append(self.column_y.get()) f=open(self.filename.get(),'r') # Open the file in read mode x=[] # This variable will store the data for the x axis y=[] # This will store the data of the y axis for l in f: # We goe throw the lines of the file try: # We try to add a couple of values to the x and y, this fill only succed if both are numbers x.append(float(l.split()[self.column_x.get()])) # We read the data from the column we have previously selected y.append(float(l.split()[self.column_y.get()])) # For both x and y axes except: # I should insert here only to except some kind of errors, this maybe will be changed in a future, I have to see pass # which are the errors that I should allow (the ones of trying to convert string to float) if self.color.get()!='': # We plot the data with the color self.current_axe.plot(x,y,marker=self.marker.get(),linestyle=self.linestyle.get(),label=self.label.get(),color=self.color.get()) else: self.current_axe.plot(x,y,marker=self.marker.get(),linestyle=self.linestyle.get(),label=self.label.get()) self.current_axe.legend(loc="best",prop={'size':10}) # current settings, and place a legend. The legend will search for the best location # The location of the legend may be customizable in the future self.fig.tight_layout() self.canvas.draw() f.close() # We close the file def export_logfile(self,*args): # This will export what we have done to make our graphics, so it will be easy to redo or continue our work # from that point. filename=(tkFileDialog.asksaveasfilename()) # This will open a window to ask for a location to save the file f=open(filename,'w+') # We open the file # The first line of the log will be the size of the subplots (how many rows and column) f.write("Total Rows "+str(self.total_rows.get())+" Total Columns "+str(self.total_columns.get())+"\n") # Now the loop in the rows and the columns for i in range(self.total_rows.get()): for j in range(self.total_columns.get()): # Insert 1 black lines to improve readablity f.write("\n") # For each row and column, we write its "coordinates" (row and column) f.write('row= ') f.write(str(i+1)) f.write(' column= ') f.write(str(j+1)) f.write('\n') # We write the value of the labels of the axis f.write("\txlabel "+self.xlabel_index[i][j]+"\n") f.write("\tylabel "+self.ylabel_index[i][j]+"\n") f.write("\txlimits "+str(self.xlimit_index[i][j][0])+" "+str(self.xlimit_index[i][j][1])+"\n") f.write("\tylimits "+str(self.ylimit_index[i][j][0])+" "+str(self.ylimit_index[i][j][1])+"\n") # Now we loop in the files we have plotted for k in range(len(self.file_index[i][j])): # We frite file 1,2,3... before each configuration of a data ser, this number doesn't have any use at all, but maybe # in the future will, and it helps to struturize the logfile f.write('\n\tfile ') f.write(str(k+1)) f.write('\n') # Wtite a line with the marker, the program is case sensitive f.write('\t\tMarker '+self.marker_index[i][j][k]+'\n') # Another with the linestyle f.write('\t\tLinestyle '+self.linestyle_index[i][j][k]+'\n') f.write('\t\tColor '+self.color_index[i][j][k]+'\n') # The label of the file f.write('\t\tLabel '+self.label_index[i][j][k]+'\n') # the columns with the data to plot f.write('\t\tXcolumn '+str(self.xcolumn_index[i][j][k])+'\n') f.write('\t\tYcolumn '+str(self.ycolumn_index[i][j][k])+'\n') # The path to the file f.write('\t\tData '+self.file_index[i][j][k]+'\n') def read_logfile(self,*args): # This function will get the path to the logfile we want to import filename=(tkFileDialog.askopenfilename()) # This will open a window to select the path self.load_logfile(filename) # We call the function that will actually load the logfile def load_logfile(self,filename): # This function will load the logfile # This function takes more arguments than the ones of the class. This was done in order to simplify # The load of the logfile directly from terminal f=open(filename,'r') # Open the logfile for l in f: # Loop throw the lines looking for some key words that will load the configuration # All the words are case sensitive, so if you want to make yourself the logfile you must notice that l=l.strip() if l.startswith("Total Row"): # This should be the first config line of the logfile total_rows=int(l.split()[2]) # Read the total number of rows total_columns=int(l.split()[5]) # And columns if (total_rows>self.total_rows.get() or total_columns>self.total_columns.get() or (not self.figure_created)): # This will be executed if the subplots were not created or if the subplots created are not big enought. # If the created subplots can fit the newones they will add to the current ones self.total_rows.set(total_rows) # We set the total number of rows and columns self.total_columns.set(total_columns) # to the value of the logfile self.create_subplots() # Execute the function that create the subplots elif l.startswith("row"): # This line is the one with the information of wich subplot are we editing self.current_row.set(int(l.split()[1])) # We set the variables to that value self.current_column.set(int(l.split()[3])) self.change_subplot() # And change the subplot to that set elif l.startswith("xlabel"): # This line is the one with the label o the x axis xlabel="" if len(l.split())>2: # If the label is more than 1 word we add all the words within a separation of 1 space for palabra in l.split()[1:-1]: xlabel+=palabra+" " xlabel+=l.split()[-1] # And the las word whiout a separation elif len(l.split())==2: # If it's only one word wen just xlabel=l.split()[1] # set the correct value self.x_label.set(xlabel) self.update_labels() # Run the function to make the change elif l.startswith("ylabel"): # The same with the y axis ylabel="" if len(l.split())>2: for palabra in l.split()[1:-1]: ylabel+=palabra+" " ylabel+=l.split()[-1] elif len(l.split())==2: ylabel=l.split()[1] self.y_label.set(ylabel) self.update_labels() elif l.startswith("xlimit"): if len(l.split())==3: self.xmin.set(float(l.split()[1])) self.xmax.set(float(l.split()[2])) self.change_x_axe() elif l.startswith("ylimit"): # The same with the y axis if len(l.split())==3: self.ymin.set(float(l.split()[1])) self.ymax.set(float(l.split()[2])) self.change_y_axe() elif l.startswith("Marker"): # This line have the marker self.marker.set(l.split()[1]) # Set the marker to the correct value # If this line is not finded the value of this variable will be the last one used or, if it wasn't used before, the # preset value, this aplies also to the linestyle elif l.startswith("Linestyle"): # This line have the linestyle wanted self.linestyle.set(l.split()[1]) # set the variable to it's proper value elif l.startswith("Color"): if len(l.split())==2: self.color.set(l.split()[1]) else: self.color.set("") elif l.startswith("Xcolumn"): self.column_x.set(int(l.split()[1])) elif l.startswith("Ycolumn"): self.column_y.set(int(l.split()[1])) elif l.startswith("Label"): # This lane have the value of the label label="" if len(l.split())>2: # We make the same trick than for reading the x and y labels for palabra in l.split()[1:-1]: label=label+palabra+" " label=label+l.split()[-1] elif len(l.split())==2: label=l.split()[1] self.label.set(label) # Update the calue of the label variable elif l.startswith("Data"): # This line have the path to the file with the data, it can be absolute or relative path # In oreder to avoid errors is better to use absolute paths (the ones the program writes with the export logfile) filename2="" if len(l.split())>2: # We make the same trick than with the labels for palabra in l.split()[1:-1]: filename2=filename2+palabra+" " filename2=filename2+l.split()[-1] elif len(l.split())==2: filename2=l.split()[1] self.filename.set(filename2) # Update the variable with the path to the data file self.make_plot() # We make the plot f.close() # Finally we close the file # This functions will allow to choose the range of the x and y axe def change_x_axe(self,*args): self.current_axe.set_xlim([self.xmin.get(),self.xmax.get()]) # This line set the axes to the value entered self.xlimit_index[self.current_row.get()-1][self.current_column.get()-1]=[self.xmin.get(),self.xmax.get()] self.fig.tight_layout() # This fit all the changes self.canvas.draw() # This draws the new figure def change_y_axe(self,*args): self.current_axe.set_ylim([self.ymin.get(),self.ymax.get()]) self.ylimit_index[self.current_row.get()-1][self.current_column.get()-1]=[self.ymin.get(),self.ymax.get()] self.fig.tight_layout() self.canvas.draw()
class Cockpit(ttkFrame): ''' Remote device GUI ''' #TODO: 20160415 DPM - Set these values from configuration file #--- config THROTTLE_BY_USER = True THROTTLE_RESOLUTION = 0.1 # Joystick enabled or not, if any JOYSTICK_ENABLED = True DEFAULT_DRONE_IP = "192.168.1.130" DEFAULT_DRONE_PORT = 2121 #--- end config KEY_ANG_SPEED = "ang-speed" KEY_ANGLES = "angles" KEY_ACCEL = "accel" PID_KEYS = ["P", "I", "D"] DIR_NONE = 0 DIR_VERTICAL = 1 DIR_HORIZONTAL = 2 def __init__(self, parent, isDummy = False, droneIp = DEFAULT_DRONE_IP, dronePort = DEFAULT_DRONE_PORT): ''' Constructor ''' ttkFrame.__init__(self, parent) self._target = [0.0] * 4 self._selectedPidConstats = "--" self._pidConstants = { Cockpit.KEY_ANG_SPEED:{ "X":{ "P": 0.0, "I": 0.0, "D": 0.0 }, "Y":{ "P": 0.0, "I": 0.0, "D": 0.0 }, "Z":{ "P": 0.0, "I": 0.0, "D": 0.0 } }, Cockpit.KEY_ANGLES: { "X":{ "P": 0.0, "I": 0.0, "D": 0.0 }, "Y":{ "P": 0.0, "I": 0.0, "D": 0.0 } }, Cockpit.KEY_ACCEL:{ "X":{ "P": 0.0, "I": 0.0, "D": 0.0 }, "Y":{ "P": 0.0, "I": 0.0, "D": 0.0 }, "Z":{ "P": 0.0, "I": 0.0, "D": 0.0 } } } self.parent = parent self.initUI() self._controlKeysLocked = False if not isDummy: self._link = INetLink(droneIp, dronePort) else: self._link = ConsoleLink() self._link.open() self._updateInfoThread = Thread(target=self._updateInfo) self._updateInfoThreadRunning = False self._readingState = False self._start() def initUI(self): self.parent.title("Drone control") self.style = Style() self.style.theme_use("default") self.pack(fill=BOTH, expand=1) self.parent.bind_all("<Key>", self._keyDown) self.parent.bind_all("<KeyRelease>", self._keyUp) if system() == "Linux": self.parent.bind_all("<Button-4>", self._onMouseWheelUp) self.parent.bind_all("<Button-5>", self._onMouseWheelDown) else: #case of Windows self.parent.bind_all("<MouseWheel>", self._onMouseWheel) #Commands commandsFrame = tkFrame(self) commandsFrame.grid(column=0, row=0, sticky="WE") self._started = IntVar() self._startedCB = Checkbutton(commandsFrame, text="On", variable=self._started, command=self._startedCBChanged) self._startedCB.pack(side=LEFT, padx=4) # self._integralsCB = Checkbutton(commandsFrame, text="Int.", variable=self._integralsEnabled, \ # command=self._integralsCBChanged, state=DISABLED) # self._integralsCB.pack(side=LEFT, padx=4) self._quitButton = Button(commandsFrame, text="Quit", command=self.exit) self._quitButton.pack(side=LEFT, padx=2, pady=2) # self._angleLbl = Label(commandsFrame, text="Angle") # self._angleLbl.pack(side=LEFT, padx=4) # # self._angleEntry = Entry(commandsFrame, state=DISABLED) # self._angleEntry.pack(side=LEFT) #Info infoFrame = tkFrame(self) infoFrame.grid(column=1, row=1, sticky="NE", padx=4) #Throttle Label(infoFrame, text="Throttle").grid(column=0, row=0, sticky="WE") self._throttleTexts = [StringVar(),StringVar(),StringVar(),StringVar()] Entry(infoFrame, textvariable=self._throttleTexts[3], state=DISABLED, width=5).grid(column=0, row=1) Entry(infoFrame, textvariable=self._throttleTexts[0], state=DISABLED, width=5).grid(column=1, row=1) Entry(infoFrame, textvariable=self._throttleTexts[2], state=DISABLED, width=5).grid(column=0, row=2) Entry(infoFrame, textvariable=self._throttleTexts[1], state=DISABLED, width=5).grid(column=1, row=2) #Angles Label(infoFrame, text="Angles").grid(column=0, row=3, sticky="WE") self._angleTexts = [StringVar(),StringVar(),StringVar()] for index in range(3): Entry(infoFrame, textvariable=self._angleTexts[index], state=DISABLED, width=5).grid(column=index, row=4) #Accels Label(infoFrame, text="Accels").grid(column=0, row=5, sticky="WE") self._accelTexts = [StringVar(),StringVar(),StringVar()] for index in range(3): Entry(infoFrame, textvariable=self._accelTexts[index], state=DISABLED, width=5).grid(column=index, row=6) #Speeds Label(infoFrame, text="Speeds").grid(column=0, row=7, sticky="WE") self._speedTexts = [StringVar(),StringVar(),StringVar()] for index in range(3): Entry(infoFrame, textvariable=self._speedTexts[index], state=DISABLED, width=5).grid(column=index, row=8) #Height Label(infoFrame, text="Height").grid(column=0, row=9, sticky="E") self._heightText = StringVar() Entry(infoFrame, textvariable=self._heightText, state=DISABLED, width=5).grid(column=1, row=9) #Loop rate Label(infoFrame, text="Loop @").grid(column=0, row=10, sticky="E") self._loopRateText = StringVar() Entry(infoFrame, textvariable=self._loopRateText, state=DISABLED, width=5).grid(column=1, row=10) Label(infoFrame, text="Hz").grid(column=2, row=10, sticky="W") #control controlFrame = tkFrame(self) controlFrame.grid(column=0, row=1, sticky="W") self._throttle = DoubleVar() if Cockpit.THROTTLE_BY_USER: self._thrustScale = Scale(controlFrame, orient=VERTICAL, from_=100.0, to=0.0, \ tickinterval=0, variable=self._throttle, resolution=Cockpit.THROTTLE_RESOLUTION, \ length=200, showvalue=1, \ state=DISABLED, command=self._onThrustScaleChanged) else: self._thrustScale = Scale(controlFrame, orient=VERTICAL, from_=100.0, to=-100.0, \ tickinterval=0, variable=self._throttle, \ length=200, showvalue=1, \ state=DISABLED, command=self._onThrustScaleChanged) self._thrustScale.bind("<Double-Button-1>", self._onThrustScaleDoubleButton1, "+") self._thrustScale.grid(column=0) self._shiftCanvas = Canvas(controlFrame, bg="white", height=400, width=400, \ relief=SUNKEN) self._shiftCanvas.bind("<Button-1>", self._onMouseButton1) #self._shiftCanvas.bind("<ButtonRelease-1>", self._onMouseButtonRelease1) self._shiftCanvas.bind("<B1-Motion>", self._onMouseButton1Motion) self._shiftCanvas.bind("<Double-Button-1>", self._onMouseDoubleButton1) self._shiftCanvas.bind("<Button-3>", self._onMouseButton3) #self._shiftCanvas.bind("<ButtonRelease-3>", self._onMouseButtonRelease3) self._shiftCanvas.bind("<B3-Motion>", self._onMouseButton3Motion) self._shiftCanvas.grid(row=0,column=1, padx=2, pady=2) self._shiftCanvas.create_oval(1, 1, 400, 400, outline="#ff0000") self._shiftCanvas.create_line(200, 2, 200, 400, fill="#ff0000") self._shiftCanvas.create_line(2, 200, 400, 200, fill="#ff0000") self._shiftMarker = self._shiftCanvas.create_oval(196, 196, 204, 204, outline="#0000ff", fill="#0000ff") self._yaw = DoubleVar() self._yawScale = Scale(controlFrame, orient=HORIZONTAL, from_=-100.0, to=100.0, \ tickinterval=0, variable=self._yaw, \ length=200, showvalue=1, \ command=self._onYawScaleChanged) self._yawScale.bind("<Double-Button-1>", self._onYawScaleDoubleButton1, "+") self._yawScale.grid(row=1, column=1) self._controlKeyActive = False #PID calibration pidCalibrationFrame = tkFrame(self) pidCalibrationFrame.grid(column=0, row=2, sticky="WE"); self._pidSelected = StringVar() self._pidSelected.set("--") self._pidListBox = OptionMenu(pidCalibrationFrame, self._pidSelected, "--", \ Cockpit.KEY_ANG_SPEED, Cockpit.KEY_ANGLES, Cockpit.KEY_ACCEL, \ command=self._onPidListBoxChanged) self._pidListBox.pack(side=LEFT, padx=2) self._pidListBox.config(width=10) self._axisSelected = StringVar() self._axisSelected.set("--") self._axisListBox = OptionMenu(pidCalibrationFrame, self._axisSelected, "--", "X", "Y", "Z", \ command=self._onAxisListBoxChanged) self._axisListBox.pack(side=LEFT, padx=2) self._axisListBox.config(state=DISABLED) Label(pidCalibrationFrame, text="P").pack(side=LEFT, padx=(14, 2)) self._pidPString = StringVar() self._pidPString.set("0.00") self._pidPSpinbox = Spinbox(pidCalibrationFrame, width=5, from_=0.0, to=10000.0, increment=0.01, state=DISABLED, \ textvariable=self._pidPString, command=self._onPidSpinboxChanged) self._pidPSpinbox.pack(side=LEFT, padx=2) Label(pidCalibrationFrame, text="I").pack(side=LEFT, padx=(14, 2)) self._pidIString = StringVar() self._pidIString.set("0.00") self._pidISpinbox = Spinbox(pidCalibrationFrame, width=5, from_=0.0, to=10000.0, increment=0.01, state=DISABLED, \ textvariable=self._pidIString, command=self._onPidSpinboxChanged) self._pidISpinbox.pack(side=LEFT, padx=2) Label(pidCalibrationFrame, text="D").pack(side=LEFT, padx=(14, 2)) self._pidDString = StringVar() self._pidDString.set("0.00") self._pidDSpinbox = Spinbox(pidCalibrationFrame, width=5, from_=0.0, to=10000.0, increment=0.01, state=DISABLED, \ textvariable=self._pidDString, command=self._onPidSpinboxChanged) self._pidDSpinbox.pack(side=LEFT, padx=2) #debug debugFrame = tkFrame(self) debugFrame.grid(column=0, row=3, sticky="WE") self._debugMsg = Message(debugFrame, anchor="nw", justify=LEFT, relief=SUNKEN, width=300) self._debugMsg.pack(fill=BOTH, expand=1) def _start(self): self._readDroneConfig() if Cockpit.JOYSTICK_ENABLED: self._joystickManager = JoystickManager.getInstance() self._joystickManager.start() joysticks = self._joystickManager.getJoysticks() if len(joysticks) != 0: self._joystick = joysticks[0] self._joystick.onAxisChanged += self._onJoystickAxisChanged self._joystick.onButtonPressed += self._onJoystickButtonPressed else: self._joystick = None def _onJoystickAxisChanged(self, sender, index): if self._started.get() and sender == self._joystick: axisValue = self._joystick.getAxisValue(index) if index == 0: self._yaw.set(axisValue) self._updateTarget() elif index == 1 and not Cockpit.THROTTLE_BY_USER: thrust = -axisValue self._throttle.set(thrust) self._updateTarget() elif index == 2 and Cockpit.THROTTLE_BY_USER: rowThrottle = (axisValue + 100.0)/2.0 if rowThrottle < 10.0: throttle = rowThrottle * 6.0 elif rowThrottle < 90.0: throttle = 60.0 + ((rowThrottle - 10.0) / 8.0) else: throttle = 70.0 + (rowThrottle - 90.0) * 3.0 self._throttle.set(throttle) self._sendThrottle() elif index == 3: x = 196 + axisValue * 2 lastCoords = self._shiftCanvas.coords(self._shiftMarker) coords = (x, lastCoords[1]) self._plotShiftCanvasMarker(coords) elif index == 4: y = 196 + axisValue * 2 lastCoords = self._shiftCanvas.coords(self._shiftMarker) coords = (lastCoords[0], y) self._plotShiftCanvasMarker(coords) def _onJoystickButtonPressed(self, sender, index): if sender == self._joystick and index == 7: if self._started.get() == 0: self._startedCB.select() else: self._startedCB.deselect() # Tkinter's widgets seem not to be calling the event-handler # when they are changed programmatically. Therefore, the # even-handler is called explicitly here. self._startedCBChanged() def exit(self): self._link.send({"key": "close", "data": None}) self._stopUpdateInfoThread() self._link.close() if Cockpit.JOYSTICK_ENABLED: self._joystickManager.stop() self.quit() def _updateTarget(self): markerCoords = self._shiftCanvas.coords(self._shiftMarker) coords = ((markerCoords[0] + markerCoords[2]) / 2, (markerCoords[1] + markerCoords[3]) / 2) self._target[0] = float(coords[1] - 200) / 2.0 # X-axis angle / X-axis acceleration self._target[1] = float(coords[0] - 200) / 2.0 # Y-axis angle / Y-axis acceleration #Remote control uses clockwise angle, but the drone's referece system uses counter-clockwise angle self._target[2] = -self._yaw.get() # Z-axis angular speed # Z-axis acceleration (thrust). Only when the motor throttle is not controlled by user directly if Cockpit.THROTTLE_BY_USER: self._target[3] = 0.0 else: self._target[3] = self._throttle.get() self._sendTarget() def _keyDown(self, event): if event.keysym == "Escape": self._throttle.set(0) self._started.set(0) self._thrustScale.config(state=DISABLED) self._stopUpdateInfoThread() self._sendIsStarted() elif event.keysym.startswith("Control"): self._controlKeyActive = True elif not self._controlKeysLocked and self._controlKeyActive: if event.keysym == "Up": self._thrustScaleUp() elif event.keysym == "Down": self._thrustScaleDown() elif event.keysym == "Left": self._yawLeft() elif event.keysym == "Right": self._yawRight() elif event.keysym == "space": self._yawReset() if not Cockpit.THROTTLE_BY_USER: self._thrustReset() elif not self._controlKeysLocked and not self._controlKeyActive: if event.keysym == "Up": self._moveShiftCanvasMarker((0,-5)) elif event.keysym == "Down": self._moveShiftCanvasMarker((0,5)) elif event.keysym == "Left": self._moveShiftCanvasMarker((-5,0)) elif event.keysym == "Right": self._moveShiftCanvasMarker((5,0)) elif event.keysym == "space": self._resetShiftCanvasMarker() def _keyUp(self, eventArgs): if eventArgs.keysym.startswith("Control"): self._controlKeyActive = False def _onMouseButton1(self, eventArgs): self._lastMouseCoords = (eventArgs.x, eventArgs.y) def _onMouseButtonRelease1(self, eventArgs): self._shiftCanvas.coords(self._shiftMarker, 196, 196, 204, 204) def _limitCoordsToSize(self, coords, size, width): maxSize = size-(width/2.0) minSize = -(width/2.0) if coords[0] > maxSize: x = maxSize elif coords[0] < minSize: x = minSize else: x = coords[0] if coords[1] > maxSize: y = maxSize elif coords[1] < minSize: y = minSize else: y = coords[1] return (x,y) def _plotShiftCanvasMarker(self, coords): coords = self._limitCoordsToSize(coords, 400, 8) self._shiftCanvas.coords(self._shiftMarker, coords[0], coords[1], coords[0] + 8, coords[1] + 8) self._updateTarget() def _moveShiftCanvasMarker(self, shift): lastCoords = self._shiftCanvas.coords(self._shiftMarker) newCoords = (lastCoords[0] + shift[0], lastCoords[1] + shift[1]) self._plotShiftCanvasMarker(newCoords) def _resetShiftCanvasMarker(self): self._shiftCanvas.coords(self._shiftMarker, 196, 196, 204, 204) self._updateTarget() def _onMouseButton1Motion(self, eventArgs): deltaCoords = (eventArgs.x - self._lastMouseCoords[0], eventArgs.y - self._lastMouseCoords[1]) self._moveShiftCanvasMarker(deltaCoords) self._lastMouseCoords = (eventArgs.x, eventArgs.y) def _onMouseDoubleButton1(self, eventArgs): self._resetShiftCanvasMarker() def _onMouseButton3(self, eventArgs): self._lastMouseCoords = (eventArgs.x, eventArgs.y) self._mouseDirection = Cockpit.DIR_NONE def _onMouseButtonRelease3(self, eventArgs): self._shiftCanvas.coords(self._shiftMarker, 196, 196, 204, 204) def _onMouseButton3Motion(self, eventArgs): deltaCoords = (eventArgs.x - self._lastMouseCoords[0], eventArgs.y - self._lastMouseCoords[1]) if self._mouseDirection == Cockpit.DIR_NONE: if abs(deltaCoords[0]) > abs(deltaCoords[1]): self._mouseDirection = Cockpit.DIR_HORIZONTAL else: self._mouseDirection = Cockpit.DIR_VERTICAL if self._mouseDirection == Cockpit.DIR_HORIZONTAL: deltaCoords = (deltaCoords[0], 0) else: deltaCoords = (0, deltaCoords[1]) self._moveShiftCanvasMarker(deltaCoords) self._lastMouseCoords = (eventArgs.x, eventArgs.y) def _thrustScaleUp(self): #TODO: 20160526 DPM: El valor de incremento de aceleración (1.0) puede ser muy alto if self._started.get(): newValue = self._thrustScale.get() \ + (Cockpit.THROTTLE_RESOLUTION if Cockpit.THROTTLE_BY_USER else 1.0) self._thrustScale.set(newValue) self._updateTarget() def _thrustScaleDown(self): #TODO: 20160526 DPM: El valor de decremento de aceleración (1.0) puede ser muy alto if self._started.get(): newValue = self._thrustScale.get() \ - (Cockpit.THROTTLE_RESOLUTION if Cockpit.THROTTLE_BY_USER else 1.0) self._thrustScale.set(newValue) self._updateTarget() def _thrustReset(self): if self._started.get(): self._thrustScale.set(0.0) self._updateTarget() def _onThrustScaleDoubleButton1(self, eventArgs): self._thrustReset() return "break" def _yawRight(self): newValue = self._yaw.get() + 1 self._yaw.set(newValue) self._updateTarget() def _yawLeft(self): newValue = self._yaw.get() - 1 self._yaw.set(newValue) self._updateTarget() def _yawReset(self): self._yaw.set(0) self._updateTarget() def _onMouseWheelUp(self, eventArgs): if not self._controlKeyActive: self._thrustScaleUp() else: self._yawRight() def _onMouseWheelDown(self, eventArgs): if not self._controlKeyActive: self._thrustScaleDown() else: self._yawLeft() def _onMouseWheel(self, eventArgs): factor = eventArgs.delta/(1200.0 if Cockpit.THROTTLE_BY_USER and not self._controlKeyActive else 120.0) if not self._controlKeyActive: if self._started.get(): newValue = self._thrustScale.get() + factor self._thrustScale.set(newValue) self._updateTarget() else: newValue = self._yaw.get() + factor self._yaw.set(newValue) self._updateTarget() def _onYawScaleChanged(self, eventArgs): self._updateTarget() def _onYawScaleDoubleButton1(self, eventArgs): self._yawReset() return "break" def _startedCBChanged(self): if not self._started.get(): self._throttle.set(0) self._thrustScale.config(state=DISABLED) #self._integralsCB.config(state=DISABLED) self._stopUpdateInfoThread() else: self._thrustScale.config(state="normal") #self._integralsCB.config(state="normal") self._startUpdateInfoThread() self._sendIsStarted() # def _integralsCBChanged(self): # # self._link.send({"key": "integrals", "data":self._integralsEnabled.get() != 0}) # def _onThrustScaleChanged(self, eventArgs): if Cockpit.THROTTLE_BY_USER: self._sendThrottle() else: self._updateTarget() def _sendThrottle(self): self._link.send({"key": "throttle", "data": self._throttle.get()}) def _sendTarget(self): self._link.send({"key": "target", "data": self._target}) def _sendIsStarted(self): isStarted = self._started.get() != 0 self._link.send({"key": "is-started", "data": isStarted}) def _sendPidCalibrationData(self): if self._pidSelected.get() != "--" and self._axisSelected.get() != "--": pidData = { "pid": self._pidSelected.get(), "axis": self._axisSelected.get(), "p": float(self._pidPSpinbox.get()), "i": float(self._pidISpinbox.get()), "d": float(self._pidDSpinbox.get())} self._link.send({"key": "pid-calibration", "data": pidData}) def _updatePidCalibrationData(self): pid = self._pidSelected.get() axis = self._axisSelected.get() if pid != "--" and axis != "--": self._pidConstants[pid][axis]["P"] = float(self._pidPSpinbox.get()) self._pidConstants[pid][axis]["I"] = float(self._pidISpinbox.get()) self._pidConstants[pid][axis]["D"] = float(self._pidDSpinbox.get()) def _readDroneConfig(self): self._link.send({"key": "read-drone-config", "data": None}, self._onDroneConfigRead) def _readDroneState(self): if not self._readingState: self._readingState = True self._link.send({"key": "read-drone-state", "data": None}, self._onDroneStateRead) def _readPidConfigItem(self, message, cockpitKey, axises, configKeys): for i in range(len(axises)): for j in range(len(Cockpit.PID_KEYS)): self._pidConstants[cockpitKey][axises[i]][Cockpit.PID_KEYS[j]] = message[configKeys[j]][i] def _onDroneConfigRead(self, message): #TODO Show current configuration within the GUI (at least relevant settings) if message: #Angle-speeds self._readPidConfigItem(message, Cockpit.KEY_ANG_SPEED, ["X", "Y", "Z"], \ [Configuration.PID_ANGLES_SPEED_KP, \ Configuration.PID_ANGLES_SPEED_KI, \ Configuration.PID_ANGLES_SPEED_KD]) #Angles self._readPidConfigItem(message, Cockpit.KEY_ANGLES, ["X", "Y"], \ [Configuration.PID_ANGLES_KP, \ Configuration.PID_ANGLES_KI, \ Configuration.PID_ANGLES_KD]) #Accels self._readPidConfigItem(message, Cockpit.KEY_ACCEL, ["X", "Y", "Z"], \ [Configuration.PID_ACCEL_KP, \ Configuration.PID_ACCEL_KI, \ Configuration.PID_ACCEL_KD]) def _onDroneStateRead(self, state): if state: for index in range(4): self._throttleTexts[index].set("{0:.3f}".format(state["_throttles"][index])) for index in range(3): self._accelTexts[index].set("{0:.3f}".format(state["_accels"][index])) self._angleTexts[index].set("{0:.3f}".format(state["_angles"][index])) currentPeriod = state["_currentPeriod"] if currentPeriod > 0.0: freq = 1.0/currentPeriod self._loopRateText.set("{0:.3f}".format(freq)) else: self._loopRateText.set("--") else: self._stopUpdateInfoThread() self._readingState = False def _onPidSpinboxChanged(self): self._updatePidCalibrationData() self._sendPidCalibrationData() def _onPidListBoxChanged(self, pid): self._axisSelected.set("--") self._pidPString.set("--") self._pidIString.set("--") self._pidDString.set("--") self._pidPSpinbox.config(state=DISABLED) self._pidISpinbox.config(state=DISABLED) self._pidDSpinbox.config(state=DISABLED) self._selectedPidConstats = pid if pid == "--": self._axisListBox.config(state=DISABLED) self._controlKeysLocked = False else: self._axisListBox.config(state="normal") self._controlKeysLocked = True def _onAxisListBoxChanged(self, axis): if axis == "--" or (self._selectedPidConstats == Cockpit.KEY_ANGLES and axis == "Z"): self._pidPString.set("--") self._pidIString.set("--") self._pidDString.set("--") self._pidPSpinbox.config(state=DISABLED) self._pidISpinbox.config(state=DISABLED) self._pidDSpinbox.config(state=DISABLED) self._controlKeysLocked = axis != "--" else: self._pidPString.set("{:.2f}".format(self._pidConstants[self._selectedPidConstats][axis]["P"])) self._pidIString.set("{:.2f}".format(self._pidConstants[self._selectedPidConstats][axis]["I"])) self._pidDString.set("{:.2f}".format(self._pidConstants[self._selectedPidConstats][axis]["D"])) self._pidPSpinbox.config(state="normal") self._pidISpinbox.config(state="normal") self._pidDSpinbox.config(state="normal") self._controlKeysLocked = True def _updateInfo(self): while self._updateInfoThreadRunning: self._readDroneState() time.sleep(1.0) def _startUpdateInfoThread(self): self._updateInfoThreadRunning = True if not self._updateInfoThread.isAlive(): self._updateInfoThread.start() def _stopUpdateInfoThread(self): self._updateInfoThreadRunning = False if self._updateInfoThread.isAlive(): self._updateInfoThread.join()
class ChemicalImporter: def __init__(self, master, system, database): """The constructor method.""" self.version = system.version self.fonttype = system.fonttype self.sfont = get_superfont(self.fonttype) self.master = master self.frame = Frame(master.frame) self.tframe = Frame(master.tframe) self.bframe = Frame(master.bframe) self.tkfont = tkFont.Font(font=system.fonttype) self.chemicals_list = database.keys() self.chemicals_list.sort() self.name = StringVar() self.formula = StringVar() self.MW = DoubleVar() self.temp = DoubleVar(value=0) self.Dw = DoubleVar(value=0) self.Ref = StringVar(value=0) self.Koc = DoubleVar(value=0) self.Kdoc = DoubleVar(value=0) self.Kf = DoubleVar(value=0) self.N = DoubleVar(value=0) self.importedchemicals = {} for name in self.chemicals_list: self.importedchemicals[name] = ChemicalData(name) self.importedchemicals[name].read_database(database[name]) self.name_width = 10 self.ref_width = 10 for chemical_name in self.chemicals_list: if (self.tkfont.measure(chemical_name) + 10) > self.name_width: self.name_width = self.tkfont.measure(chemical_name) + 10 for temp in self.importedchemicals[chemical_name].temps: if (self.tkfont.measure( self.importedchemicals[chemical_name].Ref[temp]) + 10) > self.name_width: self.name_width = self.tkfont.measure( self.importedchemicals[chemical_name].Ref[temp]) + 10 if self.name_width < 150: self.name_width = 150 if self.ref_width < 150: self.ref_width = 150 self.cancelflag = 0 self.sname = StringVar(self.frame, value='') def make_widgets(self): self.instructions = Label( self.tframe, text='Please select the chemical you would like to add ') self.leftcolumn = Label(self.tframe, text=' ', width=2) self.checkcolumn = Label(self.tframe, text=' ', width=5) self.orinamecolumn = Label( self.tframe, text=' ', width=int(self.name_width * 1.1424219345 / 8) + 1) self.tempcolumn = Label(self.tframe, text=' ', width=15) self.ref1column = Label( self.tframe, text=' ', width=int(self.ref_width * 1.1424219345 / 8 / 2) + 1) self.ref2column = Label( self.tframe, text=' ', width=int(self.ref_width * 1.1424219345 / 8 / 2) + 1) self.rightcolumn = Label(self.tframe, text=' ', width=2) self.search_label = Label(self.tframe, text='Search:') self.search_entry = Entry(self.tframe, textvariable=self.sname) self.namelabel = Label(self.tframe, text='Name') self.templabel = Label(self.tframe, text='Temperature') self.reflabel = Label(self.tframe, text='Reference') self.botleftcolumn = Label(self.frame, text=' ', width=2) self.botcheckcolumn = Label(self.frame, text=' ', width=5) self.botorinamecolumn = Label( self.frame, text=' ', width=int(self.name_width * 1.1424219345 / 8) + 1) self.bottempcolumn = Label(self.frame, text=' ', width=15) self.botref1column = Label( self.frame, text=' ', width=int(self.ref_width * 1.1424219345 / 8 / 2) + 1) self.botref2column = Label( self.frame, text=' ', width=int(self.ref_width * 1.1424219345 / 8 / 2) + 1) self.botrightcolumn = Label(self.frame, text=' ', width=2) self.importbutton = Button(self.bframe, text='Import', command=self.OK, width=20) self.cancelbutton = Button(self.bframe, text='Cancel', command=self.cancel, width=20) self.blank1 = Label(self.tframe, text=' ') self.blank2 = Label(self.frame, text=' ') self.blank3 = Label(self.bframe, text=' ') self.blank4 = Label(self.bframe, text=' ') #show the widgets on the grid (top to bottom and left to right) self.instructions.grid(row=0, columnspan=5, sticky='W', padx=8) self.leftcolumn.grid(row=1, column=0, sticky='WE') self.checkcolumn.grid(row=1, column=1, sticky='WE') self.orinamecolumn.grid(row=1, column=2, sticky='WE') self.tempcolumn.grid(row=1, column=3, sticky='WE') self.ref1column.grid(row=1, column=4, sticky='WE') self.ref2column.grid(row=1, column=5, sticky='WE') self.rightcolumn.grid(row=1, column=6, sticky='WE') self.search_label.grid(row=2, column=1, sticky='E', padx=4) self.search_entry.grid(row=2, column=2, columnspan=4, sticky='WE', padx=4) self.blank1.grid(row=3) self.namelabel.grid(row=4, column=2, sticky='WE') self.templabel.grid(row=4, column=3, sticky='WE') self.reflabel.grid(row=4, column=4, columnspan=2, sticky='WE') self.botleftcolumn.grid(row=1, column=0, sticky='WE') self.botcheckcolumn.grid(row=1, column=1, sticky='WE') self.botorinamecolumn.grid(row=1, column=2, sticky='WE') self.bottempcolumn.grid(row=1, column=3, sticky='WE') self.botref1column.grid(row=1, column=4, sticky='WE') self.botref2column.grid(row=1, column=5, sticky='WE') self.botrightcolumn.grid(row=1, column=6, sticky='WE') self.searchname() self.sname.trace('w', self.searchname) def searchname(self, event=None, *args): row = 2 for name in self.chemicals_list: try: self.importedchemicals[name].remove_selectchemicalwidgets() except: pass if self.sname.get() == '': for name in self.chemicals_list: self.importedchemicals[name].selectchemicalwidgets( self.frame, row=row, master=self.master, namewidth=int(self.name_width * 1.1424219345 / 8) + 1, refwidth=int(self.ref_width * 1.1424219345 / 8) + 1) row = row + 1 else: for name in self.chemicals_list: if name.lower()[:len(self.sname.get())].count( self.sname.get().lower()) >= 1: self.importedchemicals[name].selectchemicalwidgets( self.frame, row=row, master=self.master, namewidth=int(self.name_width * 1.1424219345 / 8) + 1, refwidth=int(self.ref_width * 1.1424219345 / 8) + 1) row = row + 1 else: self.importedchemicals[name].check = IntVar( value=self.importedchemicals[name].check) self.blank2.grid(row=row) row = 2 self.blank3.grid(row=row) row = row + 1 self.importbutton.grid(row=row, column=0, columnspan=5, pady=1) row = row + 1 self.cancelbutton.grid(row=row, column=0, columnspan=5, pady=1) row = row + 1 self.blank4.grid(row=row) self.cancelbutton.bind('<Return>', self.cancel) self.focusbutton = self.cancelbutton def selectchemicaldata(self, name): for othername in self.chemicals_list: if othername <> name: try: self.importedchemicals[othername].check.set(0) except: pass def cancelname(self, event=None): self.sname.set('') self.searchname() def OK(self, event=None): for name in self.chemicals_list: if self.importedchemicals[name].check.get() == 1: self.name.set(name) self.formula.set(self.importedchemicals[name].formula) self.MW.set(self.importedchemicals[name].MW) self.temp.set(self.importedchemicals[name].temp.get()) self.Dw.set(self.importedchemicals[name].Dw[self.temp.get()]) self.Ref.set(self.importedchemicals[name].Ref[self.temp.get()]) self.Koc.set(self.importedchemicals[name].Koc[self.temp.get()]) self.Kdoc.set( self.importedchemicals[name].Kdoc[self.temp.get()]) self.Kf.set(self.importedchemicals[name].Kf[self.temp.get()]) self.N.set(self.importedchemicals[name].N[self.temp.get()]) for name in self.chemicals_list: try: self.importedchemicals[name].remove_selectchemicalwidgets() except: pass self.frame.quit() def cancel(self, event=None): self.cancelflag = 1 self.frame.quit()
class gui(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent self.initUI() self.centerUI(w=600,h=250) def initUI(self): self.parent.title("FIND BLR COEFFICIENT VALUE") self.pack(fill=BOTH, expand=True) self.columnconfigure(0, weight=1) # self.rowconfigure(0, weight=1) # weight attibute is used to make them growable ###### GUI Control Variables ###### self.LIMIT_L = IntVar() self.LIMIT_H = IntVar() self.PULSE_R = IntVar() self.PULSE_L = IntVar() self.pulse_height = DoubleVar() self.hdf5_file = StringVar() self.PMT = IntVar() self.EVENT = IntVar() self.amplitude_range = DoubleVar() self.delta = DoubleVar() self.noise_sigma = DoubleVar() self.coeff = DoubleVar() #self.DRAW = BooleanVar() search = Image.open("next_logo.jpg") search_temp = search.resize((170, 200), Image.ANTIALIAS) search_aux = ImageTk.PhotoImage(search_temp) label1 = Label(self, image=search_aux) label1.image = search_aux label1.grid(row=0, column=0, columnspan=10, rowspan=10, sticky=E+W+S+N) self.hdf5_file.set("2052.h5.z") e1 = Entry(self, textvariable=self.hdf5_file, width=30) e1.grid(row=1,column=1, sticky=W, columnspan=5, pady=5) e1_label = Label(self, text="HDF5 file") e1_label.grid(row=0,column=1,sticky=W, columnspan=5, pady=5) self.PMT.set("0") sb1 = Spinbox(self, from_=0, to=12, width=3, textvariable=self.PMT) sb1.grid(row=3,column=2, sticky=W) sb1_label = Label(self, text="PMT") sb1_label.grid(row=2,column=2, padx=0, sticky=W) self.EVENT.set("0") sb1 = Spinbox(self, from_=0, to=1000, width=5, textvariable=self.EVENT) sb1.grid(row=3,column=3, sticky=W) sb1_label = Label(self, text="EVENT") sb1_label.grid(row=2,column=3, padx=0, sticky=W) self.LIMIT_L.set("19000") sb1 = Spinbox(self, from_=0, to=100000, width=5, textvariable=self.LIMIT_L) sb1.grid(row=5,column=2, sticky=W) sb1_label = Label(self, text="ROI Start ") sb1_label.grid(row=4,column=2, padx=0, sticky=W) self.LIMIT_H.set("22500") sb1 = Spinbox(self, from_=0, to=100000, width=5, textvariable=self.LIMIT_H) sb1.grid(row=5,column=3, sticky=W) sb1_label = Label(self, text="ROI End ") sb1_label.grid(row=4,column=3, padx=0, sticky=W) self.PULSE_R.set("20142") sb1 = Spinbox(self, from_=0, to=100000, width=8, textvariable=self.PULSE_R) sb1.grid(row=5,column=4, sticky=E) sb1_label = Label(self, text=" Pulse Rise") sb1_label.grid(row=4,column=4, padx=0, sticky=E) self.PULSE_L.set("1200") sb1 = Spinbox(self, from_=0, to=5000, width=8, textvariable=self.PULSE_L) sb1.grid(row=5,column=5, sticky=E) sb1_label = Label(self, text=" Pulse Length") sb1_label.grid(row=4,column=5, padx=0, sticky=E) sb1_label = Label(self, text=" ") sb1_label.grid(row=2,column=7, padx=0, sticky=W) sb1_label = Label(self, text=" ") sb1_label.grid(row=6,column=7, padx=0, sticky=W) self.pulse_height.set("545.5") sb1 = Entry(self, width=8, textvariable=self.pulse_height) sb1.grid(row=7,column=3, sticky=E) sb1_label = Label(self, text=" Amplitude") sb1_label.grid(row=6,column=3, padx=0, sticky=E) self.amplitude_range.set("2") sb1 = Entry(self, width=8, textvariable=self.amplitude_range) sb1.grid(row=7,column=4, sticky=E) sb1_label = Label(self, text=" Loop Range") sb1_label.grid(row=6,column=4, padx=0, sticky=E) self.delta.set("0.1") sb1 = Entry(self, width=8, textvariable=self.delta) sb1.grid(row=7,column=5, sticky=E) sb1_label = Label(self, text=" Loop Delta") sb1_label.grid(row=6,column=5, padx=0, sticky=E) self.noise_sigma.set("4") sb1 = Entry(self, width=3, textvariable=self.noise_sigma) sb1.grid(row=5,column=6, sticky=E) sb1_label = Label(self, text=" Noise Threshold") sb1_label.grid(row=4,column=6, padx=0, sticky=E) sb_coeff_label = Label(self, text= "Coefficient ") sb_coeff_label.grid(row=0,column=6, padx=0, sticky=E) self.sb_coeff = Label(self) self.sb_coeff.grid(row=1,column=6, padx=0, sticky=E) # MAIN BUTTONS obtn = Button(self, text="GO!!", command=self.find_C) obtn.grid(row=14, column=4, sticky=E, pady=10) cbtn = Button(self, text="Quit", command=self.quit) cbtn.grid(row=14, column=5, sticky=E, pady=10) hbtn = Button(self, text="Help", command=self.help_f) hbtn.grid(row=14, column=0, sticky=W, pady=10) def help_f(self): top = Toplevel() top.title("HELP") msg = Message(top, width= 500, text="COEFF Calibration Procedure: \n \ Input Start Point and Length of the pulse \n \ Input an initial guess of the pulse amplitude \n \ Use a ROI with at least 1000 samples of baseline \n \ and 1000 samples after pulse end \n \ Adjust loop range and step until a graph error \n \ with a minimum is observed \n \ Refine the search to increase precision") msg.pack() button = Button(top, text="Close", command=top.destroy) button.pack() def find_C(self): draw = False LIMIT_L = self.LIMIT_L.get() #19000 LIMIT_H = self.LIMIT_H.get() #22500 PULSE_R = self.PULSE_R.get() #20142 PULSE_L = self.PULSE_L.get() #1200 pulse_height = self.pulse_height.get() #545 hdf5_file = self.hdf5_file.get() #'2052.h5.z' PMT = self.PMT.get() event = self.EVENT.get() amplitude_range = self.amplitude_range.get() #2 delta = self.delta.get() #0.1 noise_sigma = self.noise_sigma.get() #4 coeff_aux = fc.find_coeff(LIMIT_L, LIMIT_H, PULSE_R, PULSE_L, pulse_height, hdf5_file, PMT, event, amplitude_range, delta, noise_sigma, draw) plt.show() self.sb_coeff.configure(text=str(coeff_aux)) def centerUI(self,w,h): sw = self.parent.winfo_screenwidth() sh = self.parent.winfo_screenheight() x = (sw-w)/2 y = (sh-h)/2 self.parent.geometry('%dx%d+%d+%d' % (w,h,x,y))
class FourBarGUI(object): """ GUI to model a 4-bar mechanism. """ def __init__(self, wdw, r, c): """ Determines layout of the canvas, number of rows and colums is r and c. """ wdw.title('a 4-bar mechanism') self.fbr = FourBar() self.rows = r self.cols = c self.ox = c/3 self.oy = 3*r/4 # print "A =" , (self.ox, self.oy) self.togo = False # the canvas and start, stop, and clear buttons self.c = Canvas(wdw, width=self.cols, height=self.rows, bg='green') self.c.grid(row=1, column=2, columnspan=2) self.startbut = Button(wdw, text='start', command = self.start) self.startbut.grid(row=3, column=2, sticky=W+E) self.stopbut = Button(wdw, text='stop', command = self.stop) self.stopbut.grid(row=3, column=3, sticky=W+E) self.clearbut = Button(wdw, text='clear', command = self.clear) self.clearbut.grid(row=3, column=4, columnspan=3, sticky=W+E) # the length of the crank self.crank_lbl = Label(wdw, text='crank', justify=LEFT) self.crank_lbl.grid(row=0, column=0) self.crank_bar = IntVar() self.L = Scale(wdw, orient='vertical', from_=0, to=self.rows/2, \ tickinterval=20, resolution=1, length=self.rows, \ variable=self.crank_bar, command=self.draw_mechanism) self.L.set(self.fbr.crank) self.L.grid(row=1, column=0) # the angle that drives the crank self.angle_lbl = Label(wdw, text='angle', justify=LEFT) self.angle_lbl.grid(row=0, column=1) self.angle = DoubleVar() self.t = Scale(wdw, orient='vertical', from_=0, to=6.30, \ tickinterval=0.30, resolution=0.01, length=self.rows, \ variable=self.angle, command=self.draw_mechanism) self.t.grid(row=1, column=1) self.angle.set(self.fbr.angle) # the bar at the right self.right_bar_lbl = Label(wdw, text='right bar', justify=LEFT) self.right_bar_lbl.grid(row=0, column=4) self.right_bar = IntVar() self.r = Scale(wdw, orient='vertical', from_=0, to=self.rows/2, \ tickinterval=20, resolution=1, length=self.rows, \ variable=self.right_bar, command=self.draw_mechanism) self.r.grid(row=1, column=4) self.right_bar.set(self.fbr.right) # the top bar attached to the crank self.top_bar_lbl = Label(wdw, text='top bar', justify=LEFT) self.top_bar_lbl.grid(row=0, column=5) self.r_top_bar = IntVar() self.R = Scale(wdw, orient='vertical', from_=0, to=self.rows/2, \ tickinterval=20, resolution=1, length=self.rows, \ variable=self.r_top_bar, command=self.draw_mechanism) self.R.grid(row=1, column=5) self.r_top_bar.set(self.fbr.top) # the scale for the coupler bar self.coupler_bar_lbl = Label(wdw, text='coupler', justify=LEFT) self.coupler_bar_lbl.grid(row=0, column=6) self.coupler_bar = IntVar() self.cpl = Scale(wdw, orient='vertical', from_=0, to=self.rows/2, \ tickinterval=20, resolution=1, length=self.rows, \ variable=self.coupler_bar, command=self.draw_mechanism) self.cpl.grid(row=1, column=6) self.coupler_bar.set(self.fbr.coupler) # the horizontal bottom bar self.flat_lbl = Label(wdw, text='right joint', justify=RIGHT) self.flat_lbl.grid(row=2, column=1) self.flat = IntVar() self.f = Scale(wdw, orient='horizontal', from_=0, to=self.rows/2, \ tickinterval=50, resolution=1, length=self.cols, \ variable=self.flat, command=self.draw_mechanism) self.f.grid(row=2, column=2, columnspan=2) self.flat.set(self.fbr.flat) # coordinates of the coupler point appear on top self.ex = Entry(wdw) # for x value self.ex.grid(row=0, column=2) self.ex.insert(INSERT, "x = ") self.ey = Entry(wdw) # for y value self.ey.grid(row=0, column=3) self.ey.insert(INSERT,"y = ") # check button for drawing of coupler curve self.curve = IntVar() self.cb = Checkbutton(wdw, text='coupler', \ variable=self.curve, onvalue=1, offvalue=0) self.curve.set(1) self.cb.grid(row=3, column=0) # draw the mechanism on canvas self.draw_mechanism(0) def update_values(self): """ Takes all values of the scales and updates the data attributes of self.fbr. """ self.fbr.flat = self.flat.get() self.fbr.crank = self.crank_bar.get() self.fbr.top = self.r_top_bar.get() self.fbr.right = self.right_bar.get() self.fbr.coupler = self.coupler_bar.get() self.fbr.angle = self.angle.get() #self.fbr.print_joints() def draw_coupler_point(self, p): """ Draws coupler point with coordinates in p if the curve checkbox is on. Note that the previous values for the coordinates of the coupler point are stored in the entry fields. """ if self.curve.get() == 1: px = self.ox + p[0] py = self.oy - p[1] eqx = self.ex.get() Lx = eqx.split('=') if Lx[1] == ' ': qx = 0.0 else: qx = float(Lx[1]) eqy = self.ey.get() Ly = eqy.split('=') if Ly[1] == ' ': qy = 0.0 else: qy = float(Ly[1]) if (qx != 0.0) and (qy != 0.0): qx = self.ox + qx qy = self.oy - qy self.c.create_line(qx, qy, px, py, width=1) def fill_entries(self, p): """ Fills the entry fields with the coordinates of the coupler point in p. """ sx = 'x = %f' % p[0] sy = 'y = %f' % p[1] self.ex.delete(0, END) self.ex.insert(INSERT, sx) self.ey.delete(0, END) self.ey.insert(INSERT, sy) def draw_link(self, p, q, s): """ Draws the link from point with coordinates in p to the point with coordinates in q, using s as tag. """ self.c.delete(s) px = self.ox + p[0] py = self.oy - p[1] qx = self.ox + q[0] qy = self.oy - q[1] self.c.create_line(px, py, qx, qy, width=2, tags=s) def draw_mechanism(self, v): """ Fills the canvas with the current model of the planar 4-bar mechanism. Because this command is called by the sliders, the argument v is needed but not used. """ self.update_values() L = self.fbr.joints() for i in range(0, len(L)): p = L[i] px = self.ox + p[0] py = self.oy - p[1] sj = 'joint%d' % i self.c.delete(sj) self.c.create_oval(px-6, py-6, px+6, py+6, width=1, \ outline='black', fill='red', tags=sj) self.draw_link(L[0], L[2], 'link0') self.draw_link(L[1], L[3], 'link1') self.draw_link(L[2], L[3], 'link2') self.draw_link(L[2], L[4], 'link3') self.draw_coupler_point(L[4]) self.fill_entries(L[4]) def start(self): """ Starts the animation, adding 0.01 to angle. """ self.togo = True while self.togo: theta = self.angle.get() theta = theta + 0.01 if theta > 6.28: theta = 0 self.angle.set(theta) self.draw_mechanism(0) self.c.update() def stop(self): """ Stops the animation. """ self.togo = False def clear(self): """ Clears the canvas. """ self.c.delete(ALL)
class channel_plot: ''' ''' def __init__(self, interface, toplevel=False, start_t=False, stop_t=False): ''' ''' self.abort = False if not start_t: start_t = datetime.utcnow() - timedelta(hours=2) if not stop_t: stop_t = datetime.utcnow() self.update_pending = False self.pype = interface self.plot_dicts = {} if isinstance(start_t, datetime): self.start_t = StringVar(value=start_t.strftime(time_format)) elif isinstance(start_t, str): self.start_t = StringVar(value=start_t) else: raise TypeError('start_t must be string or datetime') if isinstance(stop_t, datetime): self.stop_t = StringVar(value=stop_t.strftime(time_format)) elif isinstance(stop_t, str): self.stop_t = StringVar(value=stop_t) else: raise TypeError('stop_t must be string or datetime') self.time_interval = [self.start_t.get(), self.stop_t.get()] self.ymin = DoubleVar() self.ymax = DoubleVar() if toplevel: self.toplevel = toplevel else: self.toplevel = Tk.Tk() self.status_var = StringVar(value='initializing') self._SetupCanvas() self._BuildGui() if not toplevel: Tk.mainloop() def _BuildGui(self): ''' ''' self.removei = IntVar(value=0) self.relative_start_time = BooleanVar(value=False) self.relative_stop_time = BooleanVar(value=False) self.continuous_updates = BooleanVar(value=False) self.ManualLimits = BooleanVar(value=False) self.LogYScale = BooleanVar(value=False) self.ShowGrid = BooleanVar(value=False) self.ConnectedPts = BooleanVar(value=True) Button(self.toplevel, text="Add Line", command=self._AddSubplot ).grid(row=0, column=1) self._AddSubplot() Button(self.toplevel, text="Gas Line Temps", command=self._PlotGasLines ).grid(row=0, column=2) Button(self.toplevel, text="Amps+Cell Temps", command=self._PlotCell ).grid(row=0, column=3) Label(self.toplevel, text='Start Time').grid(row=4, column=1) start_entry = Entry(self.toplevel, textvariable=self.start_t) start_entry.bind('<Return>', self.Update) start_entry.bind('<KP_Enter>', self.Update, '+') start_entry.grid(row=4, column=2, columnspan=2) Checkbutton(self.toplevel, text='Hours ago', variable=self.relative_start_time).grid(row=4, column=4, sticky='W') Label(self.toplevel, text='Stop Time').grid(row=5, column=1) stop_entry = Entry(self.toplevel, textvariable=self.stop_t) stop_entry.bind('<Return>', self.Update) stop_entry.bind('<KP_Enter>', self.Update, '+') stop_entry.grid(row=5, column=2, columnspan=2) Checkbutton(self.toplevel, text='Now', variable=self.relative_stop_time).grid(row=5, column=4, sticky='W') Label(self.toplevel, text='Y limits (min-max)').grid(row=7, column=1) ymin = Entry(self.toplevel, textvariable=self.ymin) ymin.grid(row=7, column=2) ymin.bind('<Return>', self.Update) ymin.bind('<KP_Enter>', self.Update, '+') ymax = Entry(self.toplevel, textvariable=self.ymax) ymax.grid(row=7, column=3) ymax.bind('<Return>', self.Update) ymax.bind('<KP_Enter>', self.Update, '+') Checkbutton(self.toplevel, text='Manual Y-limits', variable=self.ManualLimits ).grid(row=8, column=1) Checkbutton(self.toplevel, text='Log Y-scale', variable=self.LogYScale ).grid(row=8, column=2) Checkbutton(self.toplevel, text='Show Grid', variable=self.ShowGrid ).grid(row=9, column=1) Checkbutton(self.toplevel, text='Connected Points', variable=self.ConnectedPts ).grid(row=9, column=2) Button(self.toplevel, text="Update All", command=self.Update ).grid(row=10, column=1) Button(self.toplevel, text="Save Plot", command=self.SaveFigure ).grid(row=10, column=2) Button(self.toplevel, text="Save Json", command=self.SaveJson ).grid(row=10, column=3) Checkbutton(self.toplevel, text='Continuous (Button above to start)', variable=self.continuous_updates ).grid(row=11, column=1, columnspan=2) self.status_var.set('done') Label(self.toplevel, textvariable=self.status_var).grid(row=20, column=1, columnspan=2) def _SetupCanvas(self): ''' ''' self.figure = Figure() self.figure.subplots_adjust(left=0.15, bottom=0.2) self.subfigure = self.figure.add_subplot(1,1,1) self.notebook = Notebook(self.toplevel) self.notebook.grid(row=1, column=1, rowspan=3, columnspan=3, sticky='nsew') self.canvas = FigureCanvasTkAgg(self.figure, master=self.toplevel) self.canvas.show() self.canvas.get_tk_widget().grid(row=0, column=0, rowspan=10) def _AddSubplot(self): ''' ''' plotnum = len(self.notebook.tabs()) self.plot_dicts[plotnum] = {} frame = Frame(self.notebook) frame.pack(side='top', fill='both', expand='y') self.plot_dicts[plotnum]['xname'] = StringVar(value='None') self.plot_dicts['xunit'] = False self.plot_dicts[plotnum]['yname'] = StringVar(value='None') self.plot_dicts['yunit'] = False Label(frame, text='X Channel').grid(row=0, column=0) Label(frame, text='Y Channel').grid(row=1, column=0) OptionMenu(frame, self.plot_dicts[plotnum]['xname'], "None", "time", "dpph_field", *self.pype.EligibleLoggers() ).grid(row=0, column=1, sticky='ew') OptionMenu(frame, self.plot_dicts[plotnum]['yname'], "None", "dpph_field", *self.pype.EligibleLoggers() ).grid(row=1, column=1, sticky='ew') self.notebook.add(frame, text='line:'+str(plotnum)) def _SetStartStop(self, event=None): ''' ''' try: if self.relative_stop_time.get(): stop_time = datetime.utcnow() else: stop_time = datetime.strptime(self.stop_t.get(), time_format) if self.relative_start_time.get(): hours = float(self.start_t.get()) start = datetime.utcnow() - timedelta(hours=hours) else: start = datetime.strptime(self.start_t.get(), time_format) assert (start < stop_time) self.time_interval[0] = start.strftime(time_format) self.time_interval[1] = stop_time.strftime(time_format) except ValueError: showwarning('Warning', 'invalid time format, must match yyyy-mm-ddThh:mm:ssZ') raise TimeFormatError("invalid start or stop time format") except AssertionError: showwarning('Warning', 'time order error, stop time must be after start time') raise TimeOrderError("stop time must be after start time") def Update(self, event=None, tab='All', unpend=False): ''' Call whatever sequence is needed to update local data and redraw the plot ''' if self.abort: self.abort = False return if unpend: self.update_pending = False self.status_var.set('updating!') if tab == 'All': tab = range(len(self.notebook.tabs())) elif isinstance(tab, int): tab = [tab] else: raise ValueError('tab should be "All" or an int') try: self._SetStartStop(event=None) except: print('SetStartStop problems') self.abort = True self.subfigure.clear() for tabi in tab: if tabi > len(self.subfigure.get_lines()): print('wtf') elif tabi == len(self.subfigure.get_lines()): self._UpdateData(tab=tabi) self._MakePlot(tab=tabi) else: self._UpdateExisting(tab=tabi) self.figure.legends = [] self.figure.legend(*self.subfigure.get_legend_handles_labels()) self.figure.legends[0].draggable(True) self.canvas.draw() self.status_var.set('updated at: ' + datetime.utcnow().strftime(time_format)) if (self.continuous_updates.get() and self.relative_stop_time.get() and not self.update_pending): self.update_pending = True self.toplevel.after(10000, lambda: self.Update(unpend=True)) def _UpdateData(self, tab=0): ''' ''' try: yname = self.plot_dicts[tab]['yname'].get() ychdat = self.pype.GetTimeSeries(yname, self.time_interval[0], self.time_interval[1]) if self.plot_dicts[tab]['xname'].get() == 'time': xchdat = (ychdat[0], ychdat[0], 'time' * len(ychdat[0])) else: xname = self.plot_dicts[tab]['xname'].get() xchdat = self.pype.GetTimeSeries(xname, self.time_interval[0], self.time_interval[1]) if tab > 0 and ychdat[0]: assert xchdat[2][0] == self.plot_dicts['xunit'], 'x units' assert ychdat[2][0] == self.plot_dicts['yunit'], 'y units' self.xdata = [] self.ydata = [] if ychdat[0]: for tx, x in zip(xchdat[0], xchdat[1]): xtmp = False ytmp = False dt = timedelta(seconds=60) for ty, y in zip(ychdat[0], ychdat[1]): if abs(ty - tx) < dt: dt = abs(ty - tx) xtmp = x ytmp = y if xtmp and ytmp: self.xdata.append(xtmp) self.ydata.append(ytmp) [self.xdata, self.ydata] = zip(*sorted(zip(self.xdata, self.ydata))) self.plot_dicts['xunit'] = xchdat[2][0] self.plot_dicts['yunit'] = ychdat[2][0] except AssertionError as e: print('*'*60, '\n the', e[0], 'do not match the 0th line', '*'*60) def _UpdateExisting(self, tab=0): ''' ''' try: yname = self.plot_dicts[tab]['yname'].get() ychdat = self.pype.GetTimeSeries(yname, self.time_interval[0], self.time_interval[1]) if self.plot_dicts[tab]['xname'].get() == 'time': xchdat = (ychdat[0], ychdat[0], 'time' * len(ychdat[0])) else: xname = self.plot_dicts[tab]['xname'].get() xchdat = self.pype.GetTimeSeries(xname, self.time_interval[0], self.time_interval[1]) if tab > 0 and ychdat[0]: assert xchdat[2][0] == self.plot_dicts['xunit'], 'x units' assert ychdat[2][0] == self.plot_dicts['yunit'], 'y units' self.xdata = [] self.ydata = [] if ychdat[0]: for tx, x in zip(xchdat[0], xchdat[1]): xtmp = False ytmp = False dt = timedelta(seconds=60) for ty, y in zip(ychdat[0], ychdat[1]): if abs(ty - tx) < dt: dt = abs(ty - tx) xtmp = x ytmp = y if xtmp and ytmp: self.xdata.append(xtmp) self.ydata.append(ytmp) [self.xdata, self.ydata] = zip(*sorted(zip(self.xdata, self.ydata))) self.plot_dicts['xunit'] = xchdat[2][0] self.plot_dicts['yunit'] = ychdat[2][0] this_line = self.subfigure.get_lines()[tab] this_line.set_xdata(array(self.xdata)) this_line.set_ydata(array(self.ydata)) except AssertionError as e: print('*'*60, '\n the', e[0], 'do not match the 0th line', '*'*60) def _MakePlot(self, tab=0): ''' ''' if self.ConnectedPts.get(): plotformat='o-' else: plotformat='o' if self.plot_dicts[tab]['xname'].get() == 'time': self.subfigure.plot_date(self.xdata, self.ydata, plotformat, label=self.plot_dicts[tab]['yname'].get()) self.subfigure.set_xticklabels(self.subfigure.get_xticklabels(), rotation=-45) self.subfigure.xaxis.set_major_formatter(dates.DateFormatter( "%m/%d %H:%M")) self.subfigure.yaxis.set_major_formatter(ticker.ScalarFormatter( useOffset=False)) else: self.subfigure.plot(self.xdata, self.ydata, plotformat, label=self.plot_dicts[tab]['yname'].get()) self.subfigure.set_title(self.plot_dicts[tab]['yname'].get() + ' vs ' + self.plot_dicts[tab]['xname'].get() + '\n from ' + self.time_interval[0] + ' to ' + self.time_interval[1]) xname = self.plot_dicts[tab]['xname'].get().replace('_', ' ') xunit = '[' + str(self.plot_dicts['xunit']) + ']' self.subfigure.set_xlabel(xname + ' ' + xunit) yname = self.plot_dicts[tab]['yname'].get().replace('_', ' ') yunit = '[' + str(self.plot_dicts['yunit']) + ']' self.subfigure.set_ylabel(yname + ' ' + yunit) tickformat = ticker.ScalarFormatter(useOffset=False) if self.ManualLimits.get(): self.subfigure.set_ylim(bottom=self.ymin.get(), top=self.ymax.get()) if self.LogYScale.get(): self.subfigure.set_yscale('log') if self.ShowGrid.get(): self.subfigure.grid(b=True, which='major') self.subfigure.grid(b=True, which='minor') def _PlotGasLines(self): ''' ''' gas_lines = ['left_gas_line_lower_t', 'left_gas_line_upper_t', 'right_gas_line_lower_t', 'right_gas_line_upper_t'] self._PlotSet(gas_lines) def _PlotCell(self): ''' ''' sensors = ['kh2_temp', 'kh3_temp', 'waveguide_cell_body_temp', 'coldhead_temp'] self._PlotSet(sensors) def _PlotSet(self, channels): ''' Plots a set of channels on common axes ''' for plotn, channel in enumerate(channels): if (len(self.plot_dicts)-2) <= plotn: self._AddSubplot() self.plot_dicts[plotn]['xname'].set('time') self.plot_dicts[plotn]['yname'].set(channel) self.start_t.set('3') self.relative_start_time.set(True) self.relative_stop_time.set(True) self.continuous_updates.set(True) self.Update() def SaveFigure(self): ''' ''' file_extensions = [('vectorized', '.eps'), ('adobe', '.pdf'), ('image', '.png'), ('all', '.*')] outfile = asksaveasfilename(defaultextension='.pdf', filetypes=file_extensions) self.figure.savefig(outfile) def SaveJson(self): ''' ''' outfile = asksaveasfile(defaultextension='.json') outdict = {'xunit':self.plot_dicts['xunit'], 'yunit':self.plot_dicts['yunit'] } for tab in range(len(self.plot_dicts)-2): outdict[tab] = {} outdict[tab]['xname']=self.plot_dicts[tab]['xname'].get() outdict[tab]['yname']=self.plot_dicts[tab]['yname'].get() this_line = self.subfigure.get_lines()[tab] if outdict['xunit'] == 't': outdict[tab]['xdata'] = [str(t) for t in this_line.get_xdata()] else: outdict[tab]['xdata'] = list(this_line.get_xdata()) outdict[tab]['ydata'] = list(this_line.get_ydata()) dump(outdict, outfile, indent=4) outfile.close()
class K_Estimator: def __init__(self, master, system, isotherm, coef): """Constructor method. Makes the GUI using the list of "Layer" objects "layers." """ self.master = master self.fonttype = system.fonttype self.version = system.version self.superfont = get_superfont(self.fonttype) self.tframe = Frame(master.tframe) self.frame = Frame(master.frame) self.bframe = Frame(master.bframe) self.bgcolor = self.frame.cget('bg') self.top = None self.concunit = system.concunit self.timeunit = system.timeunit self.cinit = DoubleVar(value = coef[0]) self.qinit = DoubleVar(value = coef[1]) self.thalf = DoubleVar(value = coef[2]) self.ksorp = DoubleVar(value = coef[3]) self.coef = coef self.isotherms = ['Linear--Kd specified', 'Linear--Kocfoc', 'Freundlich', 'Langmuir'] self.isotherm = isotherm if self.isotherm == self.isotherms[0]: self.Kd = coef[4] if self.isotherm == self.isotherms[1]: self.Kd = 10 ** coef[4]*coef[5] if self.isotherm == self.isotherms[2]: self.Kf = coef[4] self.N = coef[5] if self.isotherm == self.isotherms[3]: self.qmax = coef[4] self.b = coef[5] self.epsilon = coef[6] self.rho = coef[7] def make_widgets(self): self.instructions = Label(self.frame, text = ' Please input the following information to estimate the rate coefficients ') self.leftcolumn = Label(self.frame, text = ' ', width = 2) self.paracolumn = Label(self.frame, text = ' ', width = 20) self.entrycolumn = Label(self.frame, text = ' ', width = 12) self.unitcolumn = Label(self.frame, text = ' ', width = 12) self.thalflabel = Label(self.frame, text = ' Characteristic Half-life Time', width = 24) self.thalfentry = Entry(self.frame, textvariable = self.thalf, width = 12, justify = 'center') self.thalfunit = Label(self.frame, text = self.timeunit, width = 5) self.klabel = Label(self.frame, text = 'Sorption rate coefficient ') self.kentry = Label(self.frame, textvariable = self.ksorp, width = 12) self.ksorpunits = Label(self.frame, text = self.timeunit +u'\u207B\u00b9') self.blank1 = Label(self.frame, text = ' ') self.blank2 = Label(self.frame, text = ' ') self.blank3 = Label(self.frame, text = ' ', width = 20) self.blank4 = Label(self.frame, text = ' ', width = 20) self.updatebutton = Button(self.frame, text = 'Calculate', width = 20, command = self.calculate) self.okbutton = Button(self.frame, text = 'Save', width = 20, command = self.OK) self.cancelbutton = Button(self.frame, text = 'Cancel', width = 20, command = self.Cancel) self.instructions.grid(row = 0, column = 0, columnspan = 6) self.blank1.grid( row = 1, column = 0, columnspan = 6) self.leftcolumn.grid( row = 2, column = 0) self.paracolumn.grid( row = 2, column = 1) self.entrycolumn.grid( row = 2, column = 2) self.unitcolumn.grid( row = 2, column = 3) self.thalflabel.grid( row = 3, column = 1, sticky = 'E') self.thalfentry.grid( row = 3, column = 2) self.thalfunit.grid( row = 3, column = 3, sticky = 'W') self.blank3.grid( row = 4, column = 0, columnspan = 4) self.klabel.grid( row = 5, column = 1, sticky = 'E') self.kentry.grid( row = 5, column = 2) self.ksorpunits.grid( row = 5, column = 3, sticky = 'W') self.blank1.grid( row = 6) self.updatebutton.grid( row = 7, columnspan = 4) self.okbutton.grid( row = 8, columnspan = 4) self.cancelbutton.grid( row = 9, columnspan = 4) self.blank2.grid( row = 10) self.okbutton.bind('<Return>', self.OK) self.focusbutton = self.okbutton self.master.geometry() self.cancelflag = 0 def calculate(self): if self.thalf.get() > 0: if self.isotherm == self.isotherms[0] or self.isotherm == self.isotherms[1]: self.ksorp.set(round((0.693/self.thalf.get()/(1+self.epsilon/self.rho/self.Kd)),4)) elif self.isotherm == self.isotherms[2]: self.ksorp.set(round((0.693/self.thalf.get()/(1+self.epsilon/self.rho/(self.Kf))),4)) elif self.isotherm == self.isotherms[3]: self.ksorp.set(round((0.693/self.thalf.get()/(1+self.epsilon/self.rho/(self.qmax*self.b/(1+self.b*self.cinit.get())))),4)) else: tkmb.showerror(title = self.version, message = 'Please input a non-zero characteristic time and concentration.') self.focusbutton = self.okbutton self.master.tk.lift() self.updateksorption() def updateksorption(self): try: self.kentry.grid_forget() except: pass row = 4 self.kentry.grid( row = 5, column = 2, sticky = 'WE') def OK(self, event = None): self.master.tk.quit() def Cancel(self): try: self.cinit.set(self.coef[0]) self.qinit.set(self.coef[1]) self.thalf.set(self.coef[2]) self.ksorp.set(self.coef[3]) except: self.cancelflag = 1 if self.master.window.top is not None: self.master.open_toplevel() else: self.master.tk.quit()
class SorptionEditor: """Gets the contaminant properties.""" def __init__(self, master, system, sorption): """Constructor method. Defines the parameters to be obtained in this window.""" self.master = master self.fonttype = system.fonttype self.version = system.version self.sfont = get_superfont(self.fonttype) #superscript font self.frame = Frame(master.frame) self.tframe = Frame(master.tframe) self.bframe = Frame(master.bframe) self.top = None #flag for existence of toplevel# self.system = system self.isotherms = ['Linear--Kd specified', 'Linear--Kocfoc', 'Freundlich', 'Langmuir'] self.kinetics = ['Equilibrium', 'Transient'] self.sorption = sorption self.isotherm = StringVar(value = sorption.isotherm) self.kinetic = StringVar(value = sorption.kinetic) self.K = DoubleVar(value = sorption.K) self.Koc = DoubleVar(value = sorption.Koc) self.Kf = DoubleVar(value = sorption.Kf) self.N = DoubleVar(value = sorption.N) self.qmax = DoubleVar(value = sorption.qmax) self.b = DoubleVar(value = sorption.b) self.ksorp = DoubleVar(value = sorption.ksorp) self.cinit = sorption.cinit self.qinit = sorption.qinit self.thalf = sorption.thalf self.concunit = system.concunit self.timeunit = system.timeunit self.tkfont = tkFont.Font(font = self.fonttype) self.cancelflag = 0 def make_widgets(self): """Make the widgets for the window.""" self.bgcolor = self.frame.cget('bg') self.instructions = Label(self.frame, text = ' Please provide the following sorption properties: ') self.leftcolumn = Label(self.frame, width = 2, text = '' ) self.matrixcolumn = Label(self.frame, width = 10, text = '' ) self.chemicalcolumn = Label(self.frame, width = 10, text = '' ) self.isothermcolumn = Label(self.frame, width = 20, text = '' ) self.kineticcolumn = Label(self.frame, width = 15, text = '' ) self.equacolumn = Label(self.frame, width = 17, text = '' ) self.coefcolumn1 = Label(self.frame, width = 6, text = '' ) self.coefcolumn2 = Label(self.frame, width = 9, text = '' ) self.coefcolumn3 = Label(self.frame, width = int(self.tkfont.measure(self.concunit[:-1]+'/kg/('+ self.concunit +')'+ u'\u1d3a')/8)+1, text = '' ) self.coefcolumn4 = Label(self.frame, width = 4, text = '' ) self.coefcolumn5 = Label(self.frame, width = 9, text = '' ) self.coefcolumn6 = Label(self.frame, width = int(self.tkfont.measure(self.concunit)/8)+1, text = '' ) self.coefcolumn7 = Label(self.frame, width = 7, text = '' ) self.coefcolumn8 = Label(self.frame, width = 9, text = '' ) self.coefcolumn9 = Label(self.frame, width = 10, text = '' ) self.rightcolumn = Label(self.frame, width = 2, text = '' ) self.matrixlabel = Label(self.frame, text = 'Matrix') self.chemicallabel = Label(self.frame, text = 'Chemical') self.isothermlabel = Label(self.frame, text = 'Sorption Isotherm') self.kineticlabel = Label(self.frame, text = 'Kinetics') self.matrixwidget = Label(self.frame, text = self.sorption.matrix.name) self.chemicalwidget = Label(self.frame, text = self.sorption.chemical.name) self.isothermwidget = OptionMenu(self.frame, self.isotherm, *self.isotherms, command = self.click_isotherm) self.kineticwidget = OptionMenu(self.frame, self.kinetic, *self.kinetics, command = self.click_kinetic) self.okbutton = Button(self.frame, text = 'OK', width = 20, command = self.OK) self.cancelbutton = Button(self.frame, text = 'Cancel', width = 20, command = self.Cancel) self.blank1 = Label(self.frame, text = ' ') self.blank2 = Label(self.frame, text = ' ') #show the widgets on the grid self.instructions.grid(row = 0, column = 0, columnspan = 15, padx = 2, pady = 8, sticky = 'W') self.leftcolumn.grid( row = 1, column = 0, padx = 2, pady = 1, sticky = 'WE') self.matrixcolumn.grid( row = 1, column = 1, padx = 2, pady = 1, sticky = 'WE') self.chemicalcolumn.grid(row = 1, column = 2, padx = 2, pady = 1, sticky = 'WE') self.isothermcolumn.grid(row = 1, column = 3, padx = 2, pady = 1, sticky = 'WE') self.kineticcolumn.grid( row = 1, column = 4, padx = 2, pady = 1, sticky = 'WE') self.equacolumn.grid( row = 1, column = 5, padx = 2, pady = 1, sticky = 'WE') self.coefcolumn1.grid( row = 1, column = 6, padx = 0, pady = 1) self.coefcolumn2.grid( row = 1, column = 7, padx = 0, pady = 1) self.coefcolumn3.grid( row = 1, column = 8, padx = 0, pady = 1) self.coefcolumn4.grid( row = 1, column = 9, padx = 0, pady = 1) self.coefcolumn5.grid( row = 1, column = 10, padx = 0, pady = 1) self.coefcolumn6.grid( row = 1, column = 11, padx = 0, pady = 1) self.coefcolumn7.grid( row = 1, column = 12, padx = 0, pady = 1) self.coefcolumn8.grid( row = 1, column = 13, padx = 0, pady = 1) self.coefcolumn9.grid( row = 1, column = 14, padx = 0, pady = 1) self.rightcolumn.grid( row = 1, column = 15, padx = 0, pady = 1) self.matrixlabel.grid( row = 2, column = 1, padx = 2, pady = 4, sticky = 'WE') self.chemicallabel.grid( row = 2, column = 2, padx = 2, pady = 4, sticky = 'WE') self.isothermlabel.grid( row = 2, column = 3, padx = 2, pady = 4, sticky = 'WE') self.kineticlabel.grid( row = 2, column = 4, padx = 2, pady = 4, sticky = 'WE') self.matrixwidget.grid( row = 3, column = 1, padx = 2, pady = 1, sticky = 'WE') self.chemicalwidget.grid(row = 3, column = 2, padx = 2, pady = 1, sticky = 'WE') self.isothermwidget.grid(row = 3, column = 3, padx = 2, pady = 1, sticky = 'WE') self.kineticwidget.grid( row = 3, column = 4, padx = 2, pady = 1, sticky = 'WE') self.blank1.grid( row = 4) self.okbutton.grid( row = 5, columnspan = 15) self.cancelbutton.grid( row = 6, columnspan = 15) self.blank2.grid( row = 7) self.okbutton.bind('<Return>', self.OK) self.focusbutton = self.okbutton self.click_isotherm() self.click_kinetic() def click_kinetic(self, event = None): bgcolor = self.frame.cget('bg') try: self.klabel.grid_forget() self.ksorplabel.grid_forget() self.ksorpwidget.grid_forget() self.ksorpunits.grid_forget() except: pass if self.kinetic.get() == self.kinetics[1]: if self.isotherm.get() == self.isotherms[3]: self.klabel = Label(self.frame, text = 'Kinetic rate coefficient:') else: self.klabel = Button(self.frame, text = 'Kinetic rate coefficient:', command = self.k_estimator) self.ksorplabel = Text(self.frame, width = 7, height = 1) self.ksorplabel.insert('end', u'k') self.ksorplabel.insert('end', 'sorp', 'sub') self.ksorplabel.insert('end', u' =') self.ksorplabel.tag_config('sub', offset = -2, font = 'Arial 8') self.ksorplabel.tag_config('right', justify = 'right') self.ksorplabel.config(state = 'disabled', background = bgcolor, borderwidth = 0, spacing3 = 3) self.ksorpwidget = Entry(self.frame, textvariable = self.ksorp, justify = 'center', width = 10) if self.isotherm.get() == self.isotherms[0] or self.isotherm.get() == self.isotherms[1]: self.ksorpunits = Label(self.frame, text = self.timeunit +u'\u207B\u00b9') if self.isotherm.get() == self.isotherms[2]: self.ksorpunits = Label(self.frame, text = self.timeunit +u'\u207B\u00b9') if self.isotherm.get() == self.isotherms[3]: self.ksorpunits = Label(self.frame, text = '(' + self.concunit[:-1] +'kg)'+u'\u207B\u00b9 ' +self.timeunit + u'\u207B\u00b9') self.klabel.grid( row = 2, column = 12, padx = 1, pady = 1, sticky = 'WE', columnspan = 3) self.ksorplabel.grid( row = 3, column = 12, padx = 1, pady = 5, sticky = 'SE') self.ksorpwidget.grid(row = 3, column = 13, padx = 1, pady = 1) self.ksorpunits.grid( row = 3, column = 14, padx = 1, sticky = 'W') def k_estimator(self, event = None): k_error = 0 coef = [] coef.append(self.cinit) coef.append(self.qinit) coef.append(self.thalf) coef.append(self.ksorp.get()) if self.isotherm.get() == self.isotherms[0]: coef.append(self.K.get()) coef.append(0) if self.K.get() == 0: K_error = 1 if self.isotherm.get() == self.isotherms[1]: coef.append(self.Koc.get()) coef.append(self.sorption.matrix.foc) if self.Koc.get() == 0: K_error = 1 if self.isotherm.get() == self.isotherms[2]: coef.append(self.Kf.get()) coef.append(self.N.get()) if self.Kf.get() == 0 or self.N.get() == 0: K_error = 1 if self.isotherm.get() == self.isotherms[3]: coef.append(self.qmax.get()) coef.append(self.b.get()) if self.qmax.get() == 0 or self.b.get() == 0: K_error = 1 coef.append(self.sorption.matrix.e) coef.append(self.sorption.matrix.rho) if self.top is None: self.top = CapSimWindow(master = self.master, buttons = 2) self.top.make_window(K_Estimator(self.top, self.system, self.isotherm.get(), coef)) self.top.tk.mainloop() if self.top.window.cancelflag == 0: self.ksorp.set(self.top.window.ksorp.get()) self.cinit = self.top.window.cinit.get() self.qinit = self.top.window.qinit.get() self.thalf = self.top.window.thalf.get() if self.top is not None: self.top.destroy() self.top = None elif self.top is not None: tkmb.showerror(title = self.version, message = 'Please close the existing parameter input window first.') self.top.tk.focus() def click_isotherm(self, event = None): try: self.equalabel.grid_forget() self.coeflabel.grid_forget() self.eqwidget.grid_forget() except: pass try: self.Klabel.grid_forget() self.Kwidget.grid_forget() self.Kunits.grid_forget() except: pass try: self.Koclabel.grid_forget() self.Kocwidget.grid_forget() self.Kocunits.grid_forget() except: pass try: self.Kflabel.grid_forget() self.Nlabel.grid_forget() self.Kfwidget.grid_forget() self.Nwidget.grid_forget() self.Kfunits.grid_forget() except: pass try: self.qmaxlabel.grid_forget() self.qmaxwidget.grid_forget() self.qmaxunits.grid_forget() self.blabel.grid_forget() self.bwidget.grid_forget() self.bunits.grid_forget() except: pass bgcolor = self.frame.cget('bg') if self.isotherm.get() == self.isotherms[0]: self.equalabel = Label(self.frame, text = 'Isotherm Equation') self.eqwidget = Text(self.frame, width = 7, height = 1) self.eqwidget.insert('end', u'q = K') self.eqwidget.insert('end', 'd', 'sub') self.eqwidget.insert('end', 'C') self.eqwidget.tag_config('sub', offset = -2, font = 'Arial 8') self.eqwidget.tag_config('right', justify = 'center') self.eqwidget.config(state = 'disabled', background = bgcolor, borderwidth = 0, spacing3 = 3) self.coeflabel = Label(self.frame, text = 'Matrix-water partition coefficient') self.Klabel = Text(self.frame, width = 4, height = 1) self.Klabel.insert('end', 'K') self.Klabel.insert('end', 'd', 'sub') self.Klabel.insert('end', ' =') self.Klabel.tag_config('sub', offset = -2, font = 'Arial 8') self.Klabel.tag_config('right', justify = 'right') self.Klabel.config(state = 'disabled', background = bgcolor, borderwidth = 0, spacing3 = 3) self.Kwidget = Entry(self.frame, textvariable = self.K, justify = 'center', width = 10) self.Kunits = Label(self.frame, text = 'L/kg') self.equalabel.grid( row = 2, column = 5, padx = 2, pady = 1, sticky = 'WE') self.coeflabel.grid( row = 2, column = 6, padx = 2, pady = 1, sticky = 'WE', columnspan = 6) self.eqwidget.grid( row = 3, column = 5, padx = 1, pady = 5, sticky = 'S') self.Klabel.grid( row = 3, column = 6, padx = 0, pady = 5, sticky = 'SE') self.Kwidget.grid( row = 3, column = 7, padx = 0) self.Kunits.grid( row = 3, column = 8, padx = 0, sticky = 'W') elif self.isotherm.get() == self.isotherms[1]: self.equalabel = Label(self.frame, text = 'Isotherm Equation') self.eqwidget = Text(self.frame, width = 10, height = 1) self.eqwidget.insert('end', u'q = K') self.eqwidget.insert('end', 'oc', 'sub') self.eqwidget.insert('end', 'f') self.eqwidget.insert('end', 'oc', 'sub') self.eqwidget.insert('end', 'C') self.eqwidget.tag_config('sub', offset = -2, font = 'Arial 8') self.eqwidget.tag_config('right', justify = 'right') self.eqwidget.config(state = 'disabled', background = bgcolor, borderwidth = 0, spacing3 = 3) self.coeflabel = Label(self.frame, text = 'Organic carbon partition coefficient:') self.Koclabel = Text(self.frame, width = 5, height = 1) self.Koclabel.insert('end', 'K') self.Koclabel.insert('end', 'oc', 'sub') self.Koclabel.insert('end', ' =') self.Koclabel.tag_config('sub', offset = -2, font = 'Arial 8') self.Koclabel.tag_config('right', justify = 'right') self.Koclabel.config(state = 'disabled', background = bgcolor, borderwidth = 0, spacing3 = 3) self.Kocwidget = Entry(self.frame, textvariable = self.Koc, justify = 'center', width = 10) self.Kocunits = Label(self.frame, text = 'log(L/kg)') self.equalabel.grid( row = 2, column = 5, padx = 2, pady = 1, sticky = 'WE') self.coeflabel.grid( row = 2, column = 6, padx = 2, pady = 1, sticky = 'WE', columnspan = 6) self.eqwidget.grid( row = 3, column = 5, padx = 1, pady = 5, sticky = 'S') self.Koclabel.grid ( row = 3, column = 6, padx = 0, pady = 5, sticky = 'SE') self.Kocwidget.grid( row = 3, column = 7, padx = 0) self.Kocunits.grid( row = 3, column = 8, padx = 0, sticky = 'W') elif self.isotherm.get() == self.isotherms[2]: self.equalabel = Label(self.frame, text = 'Isotherm Equation') self.eqwidget = Text(self.frame, width = 8, height = 1) self.eqwidget.insert('end', u'q = K') self.eqwidget.insert('end', 'F', 'sub') self.eqwidget.insert('end', 'C') self.eqwidget.insert('end', 'N', 'super') self.eqwidget.tag_config('sub', offset = -2, font = 'Arial 8') self.eqwidget.tag_config('super', offset = 5, font = self.sfont) self.eqwidget.tag_config('right', justify = 'right') self.eqwidget.config(state = 'disabled', background = bgcolor, borderwidth = 0, spacing3 = 3) self.coeflabel = Label(self.frame, text = 'Freudlich isotherm coefficient:') self.Kflabel = Text(self.frame, width = 4, height = 1) self.Kflabel.insert('end', u'K') self.Kflabel.insert('end', 'F', 'sub') self.Kflabel.insert('end', u' =') self.Kflabel.tag_config('sub', offset = -2, font = 'Arial 8') self.Kflabel.tag_config('right', justify = 'right') self.Kflabel.config(state = 'disabled', background = bgcolor, borderwidth = 0, spacing3 = 3) self.Nlabel = Label(self.frame, text = 'N =') self.Kfwidget = Entry(self.frame, textvariable = self.Kf,justify = 'center', width = 10) self.Nwidget = Entry(self.frame, textvariable = self.N, justify = 'center', width = 10) self.Kfunits = Label(self.frame, text = self.concunit[:-1]+'/kg/('+ self.concunit +')'+ u'\u1d3a') self.equalabel.grid( row = 2, column = 5, padx = 2, pady = 1, sticky = 'WE') self.coeflabel.grid( row = 2, column = 6, padx = 2, pady = 1, sticky = 'WE', columnspan = 6) self.eqwidget.grid( row = 3, column = 5, padx = 1, pady = 5, sticky = 'S') self.Kflabel.grid( row = 3, column = 6, padx = 0, pady = 5, sticky = 'SE') self.Kfwidget.grid( row = 3, column = 7, padx = 0) self.Kfunits.grid( row = 3, column = 8, padx = 0, sticky = 'W') self.Nlabel.grid ( row = 3, column = 9, padx = 0, sticky = 'E') self.Nwidget.grid( row = 3, column = 10, padx = 0) elif self.isotherm.get() == self.isotherms[3]: self.equalabel = Label(self.frame, text = 'Isotherm Equation') self.eqwidget = Text(self.frame, width = 17, height = 0.1) self.eqwidget.insert('end', u'q = q') self.eqwidget.insert('end', 'max', 'sub') self.eqwidget.insert('end', 'b*C/(1+b*C)') self.eqwidget.tag_config('sub', offset = -2, font = 'Arial 8') self.eqwidget.tag_config('right', justify = 'right') self.eqwidget.config(state = 'disabled', background = bgcolor, borderwidth = 0, spacing3 = 3) self.coeflabel = Label(self.frame, text = 'Langmuir isotherm coefficient:') self.qmaxlabel = Text(self.frame, width = 7, height = 0.1) self.qmaxlabel.insert('end', ' ', 'sub') self.qmaxlabel.insert('end', u'q') self.qmaxlabel.insert('end', 'max', 'sub') self.qmaxlabel.insert('end', u' =') self.qmaxlabel.tag_config('sub', offset = -3, font = 'Arial 8') self.qmaxlabel.tag_config('right', justify = 'right') self.qmaxlabel.config(state = 'disabled', background = bgcolor, borderwidth = 0, spacing3 = 3) self.qmaxwidget = Entry(self.frame, textvariable = self.qmax, justify = 'center', width = 10) self.qmaxunits = Label(self.frame, text = self.concunit[:-1] + 'kg') self.blabel = Label(self.frame, text = 'b =') self.bwidget = Entry(self.frame, textvariable = self.b, justify = 'center', width = 10) self.bunits = Label(self.frame, text = 'L/' + self.concunit[:-2]) self.equalabel.grid( row = 2, column = 5, padx = 2, pady = 1, sticky = 'WE') self.coeflabel.grid( row = 2, column = 6, padx = 2, pady = 1, sticky = 'WE', columnspan = 6) self.eqwidget.grid( row = 3, column = 5, padx = 1, pady = 5, sticky = 'S') self.qmaxlabel.grid( row = 3, column = 6, padx = 0, pady = 5, sticky = 'SE') self.qmaxwidget.grid( row = 3, column = 7, padx = 0, pady = 1) self.qmaxunits.grid( row = 3, column = 8, padx = 0, pady = 1, sticky = 'W') self.blabel.grid( row = 3, column = 9, padx = 0, pady = 1, sticky = 'E') self.bwidget.grid( row = 3, column = 10, padx = 0, pady = 1) self.bunits.grid( row = 3, column = 11, padx = 0, pady = 1, sticky = 'W') self.click_kinetic() def OK(self, event = None): """Finish and move on. Checks that the number chemicals are less than the total number of chemicals in database.""" if self.master.window.top is not None: self.master.open_toplevel() else: self.master.tk.quit() def Cancel(self): try: self.isotherm.set(self.sorption.isotherm) self.kinetic.set(self.sorption.kinetic) self.K.set(self.sorption.K) self.Koc.set(self.sorption.Koc) self.Kf.set(self.sorption.Kf) self.N.set(self.sorption.N) self.qmax.set(self.sorption.qmax) self.b.set(self.sorption.b) self.ksorp.set(self.sorption.ksorp) except: self.cancelflag = 1 if self.master.window.top is not None: self.master.open_toplevel() else: self.master.tk.quit()
class take_data: ''' ''' def __init__(self, pype, toplevel=False, filename=False, num_sequences=10, run_tag=''): ''' ''' self.pype = pype self.toplevel = toplevel self.keep_runningVar = BooleanVar(value=True) self.extend_runVar = BooleanVar(value=False) self.run_typeVar = StringVar(value="/tmp/") self.run_tagVar = StringVar(value=run_tag) self.num_sequencesVar = IntVar(value=num_sequences) self.sequence_spacingVar = DoubleVar(value=0) self.len_sequenceVar = DoubleVar() self.stateVar = StringVar(value='done') self.conf_filename = StringVar(value='') self.params = {} self.runthread = multiprocessing.Process() self._GetParamFuncs() if toplevel: self._BuildGui() def _BuildGui(self): ''' Setup all of the buttons and user entries ''' # Data Location row = 0 Label(self.toplevel, text='-'*20+'Data Location'+'-'*20).grid(row=row, columnspan=3, column=0) row += 1 Label(self.toplevel, text='/data').grid(row=row, column=0, sticky='E') run_type_options = ["/tmp/", "/commissioning/", "/runs/"] OptionMenu(self.toplevel, self.run_typeVar, *run_type_options).grid( row=row, column=1, sticky='EW') Entry(self.toplevel, textvariable=self.run_tagVar).grid(row=row, column=2) Checkbutton(self.toplevel, text="Extend if Exists", variable=self.extend_runVar).grid(row=row, column=3) row += 1 Label(self.toplevel, text="(raid location)").grid(row=row, column=0, sticky='E') Label(self.toplevel, text="(run type)").grid(row=row, column=1) Label(self.toplevel, text="(run tag)").grid(row=row, column=2) row += 1 # Acquisition Cycle Details Label(self.toplevel, text='-'*20+'Acquisition Cycles'+'-'*20).grid(row=row, columnspan=3, column=0) row += 1 Label(self.toplevel, text='Number of Sequences').grid(row=row, column=0) Entry(self.toplevel, textvariable=self.num_sequencesVar).grid(row=row, column=1) row += 1 Label(self.toplevel, text='Delay Between').grid(row=row, column=0) Entry(self.toplevel, textvariable=self.sequence_spacingVar).grid(row=row, column=1) Label(self.toplevel, text='[s]').grid(row=row, column=2, sticky='W') row += 1 builtins_list = ['default_run', 'noise_analysis_run'] self.conf_filename.set(builtins_list[0]) Button(self.toplevel, text='Load Builtin Run Def', command=self._GetParamFuncs).grid(row=row, column=0) OptionMenu(self.toplevel, self.conf_filename, *builtins_list).grid( row=row, column=1) self.conf_filename.set(builtins_list[0]) row += 1 Label(self.toplevel, text='Load Custom Run Def').grid(row=row, column=0) Button(self.toplevel, text="find file", command=self._ParamFuncFile ).grid(row=row, column=1) row += 1 # Mantis Settings Label(self.toplevel, text='-'*20+'Mantis Settings'+'-'*20).grid(row=row, columnspan=3, column=0) row += 1 Label(self.toplevel, text='(Empty fields use default values)').grid(row=row, columnspan=3, column=0) row += 1 Label(self.toplevel, text='Digitization Time').grid(row=row, column=0) Entry(self.toplevel, textvariable=self.len_sequenceVar).grid(row=row, column=1) Label(self.toplevel, text='[ms]').grid(row=row, column=2, sticky='W') row += 1 Button(self.toplevel, text="Start Run", command=self.DoRun ).grid(row=row, column=0) Button(self.toplevel, text="ABORT", command=self._Abort, bg='red' ).grid(row=row, column=1) Label(self.toplevel, textvariable=self.stateVar).grid(row=row, column=2) def _ParamFuncFile(self): ''' ''' self.conf_filename.set(askopenfilename()) if self.conf_filename.get(): self._GetParamFuncs() def _Abort(self): ''' ''' self.keep_runningVar.set(False) if self.runthread.is_alive(): print('terminating child process') self.runthread.terminate() else: print('no current thread') self.stateVar.set('aborted') def _IsRunning(self): ''' ''' print(self.runthread.is_alive()) def _GetParamFuncs(self): ''' ''' fname = self.conf_filename.get() if not fname or fname == 'default_run': if not 'run_params' in sys.modules: from . import default_run as run_params else: reload(run_params) elif fname == 'noise_analysis_run': from . import noise_analysis_run as run_params else: imp.load_source('run_params', fname) import run_params self.DefaultParams = run_params.DefaultParams self.SequenceParams = run_params.SequenceParams self.FilenamePrefix = run_params.FilenamePrefix self.Mantis_kwargs = run_params.Mantis_kwargs() if 'duration' in self.Mantis_kwargs: self.len_sequenceVar.set(self.Mantis_kwargs['duration']) def DoRun(self): ''' Execute the run ''' self.keep_runningVar.set(True) self.stateVar.set('normal') if self.runthread.is_alive(): print('there is already live process, abort first or let it finish') else: self.runthread = multiprocessing.Process(target=self.__DoRun) self.runthread.start() def __DoRun(self): ''' the run called by DoRun in a subprocess ''' self.params['run_tag'] = self.run_tagVar.get() self.params['num_sequences'] = self.num_sequencesVar.get() print('setting defaults') self._SetParams(self.DefaultParams()) for sequence_num in range(self.params['num_sequences']): print('--> starting sequence {0}/{1}'.format(sequence_num, self.params['num_sequences'] - 1)) if not self.keep_runningVar.get(): print('Aborting!') break self._DoSequence(sequence_num) print('--> sequence {0}/{1} complete.'.format(sequence_num, self.params['num_sequences'] - 1)) sleep(self.sequence_spacingVar.get()) print('-> run (tag: {0}) complete.'.format(self.params['run_tag'])) self.stateVar.set('run complete') def _SetParams(self, params_list): ''' ''' for channel_name, value in params_list: setattempt = self.pype.Set(channel_name, value) setattempt.Wait() if setattempt.Waiting(): raise NoResponseError('setting ' + str(channel_name)) print(channel_name, '->', value) def _DoSequence(self, sequence_number): ''' Do one sequence within the run ''' mantis_kwargs = self.Mantis_kwargs.copy() run_doc = self.pype.NewDump(uuid4().hex, self.params['run_tag'], new_run=((not sequence_number) and not self.extend_runVar.get())) self._SetParams(self.SequenceParams(sequence_number)) for channel in self.pype.ListWithProperty('dump'): run_doc[channel] = self.pype.Get(channel) run_doc[channel].Update() run_doc[channel].Wait() run_doc._UpdateTo() outfilename = '/data/{:s}_{:05d}_{:05d}.egg'.format( self.FilenamePrefix(sequence_number), run_doc['run_number'], run_doc['sequence_number']) print('outputting '+outfilename) run_descrip = ast.literal_eval(mantis_kwargs['description']) for (chan, val) in self.SequenceParams(sequence_number): run_descrip[chan] = val run_descrip['run_tag'] = self.params['run_tag'] run_doc['sequence_tag'] = dumps(run_descrip) mantis_kwargs.update({'output': outfilename, 'description': dumps(run_descrip), 'duration': self.len_sequenceVar.get()}) run = self.pype.RunMantis(**mantis_kwargs) print('mantis run starting') run.Wait() run_doc['mantis'] = run run_doc._UpdateTo()
class _App: ######################################################################### # GUI setup ######################################################################### def __menu(self, master): menubar = Menu(master) def file_menu(): menu = Menu(menubar, tearoff=0) menu.add_command(label="Open ctxt / cbin", command=self.open_file) # menu.add_command(label="Append ctxt", command=self.append_file) menu.add_separator() menu.add_command(label="Exit", command=self.save_settings_and_quit) return menu menubar.add_cascade(label="File", menu=file_menu()) def view_menu(): menu = Menu(menubar, tearoff=0) menu.add_checkbutton(label="Auto-render", variable=self.render_auto) # menu.add_command(label="Filter threads", command=None) return menu menubar.add_cascade(label="View", menu=view_menu()) def analyse_menu(): # def timechart(): # _TimeChart(master, self.output.get("0.0", END)) menu = Menu(menubar, tearoff=0) # menu.add_command(label="Time Chart", command=timechart) return menu # menubar.add_cascade(label="Analyse", menu=analyse_menu()) def help_menu(): def show_about(): t = Toplevel(master) t.title("About") t.transient(master) t.resizable(False, False) Label(t, image=self.img_logo).grid(column=0, row=0, sticky=(E, W)) Label(t, text="Context %s" % VERSION, anchor=CENTER).grid(column=0, row=1, sticky=(E, W)) Label(t, text="(c) 2011-2014 Shish", anchor=CENTER).grid(column=0, row=2, sticky=(E, W)) Button(t, text="Close", command=t.destroy).grid(column=0, row=3, sticky=(E,)) win_center(t) def show_docs(): t = Toplevel(master) t.title("Context Documentation") t.transient(master) scroll = Scrollbar(t, orient=VERTICAL) tx = Text( t, wrap=WORD, yscrollcommand=scroll.set, ) scroll['command'] = tx.yview scroll.pack(side=RIGHT, fill=Y, expand=1) tx.pack(fill=BOTH, expand=1) tx.insert("0.0", b64decode(data.README).replace("\r", "")) tx.configure(state="disabled") tx.focus_set() win_center(t) def show_license(): t = Toplevel(master) t.title("Context Licenses") t.transient(master) scroll = Scrollbar(t, orient=VERTICAL) tx = Text( t, wrap=WORD, yscrollcommand=scroll.set, ) scroll['command'] = tx.yview scroll.pack(side=RIGHT, fill=Y, expand=1) tx.pack(fill=BOTH, expand=1) tx.insert("0.0", b64decode(data.LICENSE).replace("\r", "")) tx.configure(state="disabled") tx.focus_set() win_center(t) menu = Menu(menubar, tearoff=0) menu.add_command(label="About", command=show_about) menu.add_command(label="Documentation", command=show_docs) menu.add_command(label="License", command=show_license) return menu menubar.add_cascade(label="Help", menu=help_menu()) return menubar def __control_box(self, master): f = None def _la(t): Label(f, text=t).pack(side="left") def _sp(fr, t, i, v, w=10): Spinbox(f, from_=fr, to=t, increment=i, textvariable=v, width=w).pack(side="left") f = Frame(master) _la(" Start ") _sp(0, int(time.time()), 10, self.render_start, 15) _la(" Seconds ") _sp(MIN_SEC, MAX_SEC, 1, self.render_len, 3) _la(" Pixels per second ") _sp(MIN_PPS, MAX_PPS, 100, self.scale, 5) _la(" Cutoff (ms) ") _sp(0, 1000, 1, self.render_cutoff, 3) _la(" Coalesce (ms) ") _sp(0, 1000, 1, self.coalesce_threshold, 3) Button(f, text="Render", command=self.update).pack(side=LEFT, fill=Y) # padding=0 f.pack() return f def __bookmarks(self, master): panel = Frame(master) panel.grid_rowconfigure(0, weight=1) bookmarks = Frame(panel) bookmarks.grid_columnconfigure(0, weight=1) bookmarks.grid_rowconfigure(0, weight=1) li = Listbox(bookmarks, width=40) li.grid(column=0, row=0, sticky=(N, E, S, W)) self.bookmarks_list = li sb = Scrollbar(bookmarks, orient=VERTICAL, command=li.yview) sb.grid(column=1, row=0, sticky=(N, S)) li.config(yscrollcommand=sb.set) def _lbox_selected(*args): selected_idx = int(li.curselection()[0]) self.render_start.set(self.bookmarks_values[selected_idx]) self.canvas.xview_moveto(0) if not self.render_auto.get(): self.update() li.bind('<Double-Button-1>', _lbox_selected) bookmarks.grid(column=0, row=0, sticky=(N, E, S, W)) buttons = Frame(panel) Button(buttons, image=self.img_start, command=self.start_event).pack(side="left") Button(buttons, image=self.img_prev, command=self.prev_event).pack(side="left") Button(buttons, image=self.img_end, command=self.end_event).pack(side="right") Button(buttons, image=self.img_next, command=self.next_event).pack(side="right") buttons.grid(column=0, row=1, sticky=(E, W)) return panel def __canvas(self, master): f = Frame(master) f.grid_columnconfigure(0, weight=1) f.grid_rowconfigure(0, weight=1) h = Scrollbar(f, orient=HORIZONTAL) v = Scrollbar(f, orient=VERTICAL) canvas = Canvas( f, background="white", xscrollcommand=h.set, yscrollcommand=v.set, ) h['command'] = canvas.xview v['command'] = canvas.yview canvas.bind("<4>", lambda e: self.scale_view(e, 1.0 * 1.1)) canvas.bind("<5>", lambda e: self.scale_view(e, 1.0 / 1.1)) # in windows, mouse wheel events always go to the root window o_O self.master.bind("<MouseWheel>", lambda e: self.scale_view( e, ((1.0 * 1.1) if e.delta > 0 else (1.0 / 1.1)) )) # Drag based movement # def _sm(e): # self.st = self.render_start.get() # self.sx = e.x # self.sy = e.y # def _cm(e): # self.render_start.set(self.st + float(self.sx - e.x)/self.scale.get()) # self.render() # self.canvas.bind("<1>", _sm) # self.canvas.bind("<B1-Motion>", _cm) canvas.grid(column=0, row=0, sticky=(N, W, E, S)) v.grid(column=1, row=0, sticky=(N, S)) h.grid(column=0, row=1, sticky=(W, E)) self.canvas = canvas return f def __scrubber(self, master): sc = Canvas( master, width=800, height=SCRUBBER_HEIGHT, background="white", ) def sc_goto(e): width_fraction = float(e.x) / sc.winfo_width() ev_s = self.get_earliest_bookmark_after(0) ev_e = self.get_latest_bookmark_before(sys.maxint) ev_l = ev_e - ev_s self.render_start.set(ev_s + ev_l * width_fraction - float(self.render_len.get()) / 2) if not self.render_auto.get(): self.update() self.canvas.xview_moveto(0.5) sc.bind("<1>", sc_goto) def resize(event): if self.c: self.render_scrubber_activity() self.render_scrubber_arrow() # sc.coords(line, 0, 0, event.width, event.height) sc.bind("<Configure>", resize) return sc def __init__(self, master, database_file): self.master = master self.bookmarks_values = [] self.bookmarks_list = None self.canvas = None self.scrubber = None # render is called before init finished? self.char_w = -1 self.soft_scale = 1.0 self.window_ready = False self.data = [] self.sc_activity = None self.original_texts = {} self.tooltips = {} self.event_idx_offset = 0 self._last_log_dir = os.path.expanduser("~/") self.c = None # database connection try: os.makedirs(os.path.expanduser(os.path.join("~", ".config"))) except OSError: pass self.config_file = os.path.expanduser(os.path.join("~", ".config", "context.cfg")) self.threads = [] self.render_start = DoubleVar(master, 0) self.render_len = IntVar(master, 10) self.render_cutoff = IntVar(master, 1) self.coalesce_threshold = IntVar(master, 1) self.render_auto = IntVar(master, 1) self.scale = IntVar(master, 1000) self.load_settings() master.protocol("WM_DELETE_WINDOW", self.save_settings_and_quit) self.render_start.trace_variable("w", lambda *x: conditional(self.render_auto, self.update)) self.render_len.trace_variable("w", lambda *x: conditional(self.render_auto, self.update)) self.render_cutoff.trace_variable("w", lambda *x: conditional(self.render_auto, self.render)) self.coalesce_threshold.trace_variable("w", lambda *x: conditional(self.render_auto, self.update)) self.scale.trace_variable("w", lambda *x: conditional(self.render_auto, self.render)) self.img_start = PhotoImage(data=data.start) self.img_prev = PhotoImage(data=data.prev) self.img_next = PhotoImage(data=data.next) self.img_end = PhotoImage(data=data.end) self.img_logo = PhotoImage(data=data.context_name) menu = self.__menu(master) controls_panel = self.__control_box(master) bookmarks_panel = self.__bookmarks(master) canvas_panel = self.__canvas(master) scrubber = self.__scrubber(master) status = Label(master, text="") if have_ttk: grip = Sizegrip(master) else: grip = Label(master, text="") master.grid_columnconfigure(1, weight=1) master.grid_rowconfigure(1, weight=1) master.config(menu=menu) controls_panel.grid(column=0, row=0, sticky=(W, E), columnspan=2) bookmarks_panel.grid(column=0, row=1, sticky=(N, W, E, S)) canvas_panel.grid(column=1, row=1, sticky=(N, E, S, W)) scrubber.grid(column=0, row=2, sticky=(W, E), columnspan=2) status.grid(column=0, row=3, sticky=(W, E), columnspan=2) grip.grid(column=1, row=3, sticky=(S, E)) self.scrubber = scrubber self.status = status self.master.update() self.window_ready = True if database_file: self.load_file(database_file) def set_status(self, text): if text: print(text) self.status.config(text=text) self.master.update() ######################################################################### # Open file ######################################################################### def open_file(self): filename = askopenfilename( filetypes=[ ("All Supported Types", "*.ctxt *.cbin"), ("Context Text", "*.ctxt"), ("Context Binary", "*.cbin") ], initialdir=self._last_log_dir ) if filename: try: self.load_file(filename) except Exception as e: self.set_status("Error loading file: %s" % str(e)) def load_file(self, given_file): if not os.path.exists(given_file): showerror("Error", "Context dump file '%s' does not exist" % given_file) return self._last_log_dir = os.path.dirname(given_file) path, _ext = os.path.splitext(given_file) log_file = path + ".ctxt" database_file = path + ".cbin" # if the user picked a log file, compile it (unless an # up-to-date version already exists) if given_file == log_file: needs_recompile = False if not os.path.exists(database_file): needs_recompile = True self.set_status("Compiled log not found, compiling") elif os.stat(log_file).st_mtime > os.stat(database_file).st_mtime: needs_recompile = True self.set_status("Compiled log is out of date, recompiling") elif not version_check(database_file): needs_recompile = True self.set_status("Compiled log is from an old version of context, recompiling") if needs_recompile: compiler = subprocess.Popen(["context-compiler", log_file], stdout=subprocess.PIPE) while True: line = compiler.stdout.readline() if line: self.set_status(line.strip()) else: break self.c = sqlite3.connect(database_file) self.data = [] # don't load the bulk of the data yet self.load_bookmarks(self.c) self.load_summary(self.c) self.load_threads(self.c) self.master.title(NAME + ": " + database_file) # render grid + scrubber self.render() self.event_idx_offset = self.get_earliest_bookmark_after(0) self.render_start.set(self.event_idx_offset) def load_bookmarks(self, conn): self.bookmarks_values = [] self.bookmarks_list.delete(0, END) for ts, tx, et in conn.execute(""" SELECT start_time, start_text, end_text FROM events WHERE start_type = 'BMARK' ORDER BY start_time """): tss = datetime.datetime.fromtimestamp(ts).strftime("%Y/%m/%d %H:%M:%S") # .%f self.bookmarks_values.append(ts) self.bookmarks_list.insert(END, "%s: %s" % (tss, tx or et)) def load_threads(self, conn): # fast because the data is split off into a tiny table self.threads = [ "-".join([str(c) for c in r]) for r in conn.execute("SELECT node, process, thread FROM threads ORDER BY id") ] def load_summary(self, conn): self.sc_activity = [row[0] for row in conn.execute("SELECT events FROM summary ORDER BY id")] ######################################################################### # Settings ######################################################################### def load_settings(self): try: cp = ConfigParser.SafeConfigParser() cp.readfp(file(self.config_file)) if cp.has_section("gui"): if cp.has_option("gui", "render_len"): self.render_len.set(cp.getint("gui", "render_len")) if cp.has_option("gui", "scale"): self.scale.set(cp.getint("gui", "scale")) if cp.has_option("gui", "render_cutoff"): self.render_cutoff.set(cp.getint("gui", "render_cutoff")) if cp.has_option("gui", "coalesce_threshold"): self.coalesce_threshold.set(cp.getint("gui", "coalesce_threshold")) if cp.has_option("gui", "render_auto"): self.render_auto.set(cp.getint("gui", "render_auto")) if cp.has_option("gui", "last_log_dir"): self._last_log_dir = cp.get("gui", "last_log_dir") except Exception as e: print("Error loading settings from %s:\n %s" % (self.config_file, e)) def save_settings(self): try: cp = ConfigParser.SafeConfigParser() cp.add_section("gui") cp.set("gui", "render_len", str(self.render_len.get())) cp.set("gui", "scale", str(self.scale.get())) cp.set("gui", "render_cutoff", str(self.render_cutoff.get())) cp.set("gui", "coalesce_threshold", str(self.coalesce_threshold.get())) cp.set("gui", "render_auto", str(self.render_auto.get())) cp.set("gui", "last_log_dir", self._last_log_dir) cp.write(file(self.config_file, "w")) except Exception as e: print("Error writing settings to %s:\n %s" % (self.config_file, e)) def save_settings_and_quit(self): self.save_settings() self.master.destroy() self.master.quit() ######################################################################### # Navigation ######################################################################### def get_earliest_bookmark_after(self, start_hint=0): return list(self.c.execute( "SELECT min(start_time) FROM events WHERE start_time > ? AND start_type = 'BMARK'", [start_hint, ] ))[0][0] def get_latest_bookmark_before(self, end_hint=0): return list(self.c.execute( "SELECT max(start_time) FROM events WHERE start_time < ? AND start_type = 'BMARK'", [end_hint, ] ))[0][0] def end_event(self): next_ts = self.get_latest_bookmark_before(sys.maxint) if next_ts: self.render_start.set(next_ts) self.canvas.xview_moveto(0) def next_event(self): next_ts = self.get_earliest_bookmark_after(self.render_start.get()) if next_ts: self.render_start.set(next_ts) self.canvas.xview_moveto(0) def prev_event(self): prev_ts = self.get_latest_bookmark_before(self.render_start.get()) if prev_ts: self.render_start.set(prev_ts) self.canvas.xview_moveto(0) def start_event(self): next_ts = self.get_earliest_bookmark_after(0) if next_ts: self.render_start.set(next_ts) self.canvas.xview_moveto(0) ######################################################################### # Rendering ######################################################################### def scale_view(self, e=None, n=1.0): # get the old pos if e: _xv = self.canvas.xview() left_edge = _xv[0] width = _xv[1] - _xv[0] width_fraction = float(e.x) / self.canvas.winfo_width() x_pos = left_edge + width * width_fraction # scale if n != 1: self.soft_scale *= n self.canvas.scale("event", 0, 0, n, 1) self.canvas.scale("lock", 0, 0, n, 1) for t in self.canvas.find_withtag("time_label"): val = self.canvas.itemcget(t, 'text')[2:] self.canvas.itemconfigure(t, text=" +%.4f" % (float(val) / n)) for t in self.canvas.find_withtag("event_tip"): self.canvas.itemconfigure(t, width=float(self.canvas.itemcget(t, 'width')) * n) # this seems slow? sure something similar was faster... for t in self.canvas.find_withtag("event_label"): self.canvas.itemconfigure(t, width=float(self.canvas.itemcget(t, 'width')) * n) # this seems slow? sure something similar was faster... w = int(self.canvas.itemcget(t, 'width')) tx = self.truncate_text(" " + self.original_texts[t], w) self.canvas.itemconfigure(t, text=tx) # this seems slow? sure something similar was faster... self.canvas.delete("grid") self.render_base() self.canvas.configure(scrollregion=shrink(self.canvas.bbox("grid"), 2)) # scroll the canvas so that the mouse still points to the same place if e: _xv = self.canvas.xview() new_width = _xv[1] - _xv[0] self.canvas.xview_moveto(x_pos - new_width * width_fraction) def truncate_text(self, text, w): return text.split("\n")[0][:w / self.char_w] def update(self): self.update_events() self.render() def update_events(self): """ Data settings changed, get new data and re-render """ if not self.window_ready: # update() is called a couple of times during init() return try: s = self.render_start.get() e = self.render_start.get() + self.render_len.get() threshold = float(self.coalesce_threshold.get()) / 1000.0 except ValueError: return try: self.n = 0 self.data = [] # free memory # thread_level_starts = [[], ] * len(self.threads) # this bug is subtle and hilarious thread_level_ends = [[] for _ in self.threads] def progress(*args): try: self.n += 1 self.set_status("Loading... (%dk opcodes)" % (self.n * 10)) return 0 except Exception as e: return 1 # non-zero = cancel query self.c.set_progress_handler(progress, 10000) try: for row in self.c.execute( """ SELECT * FROM events WHERE id IN (SELECT id FROM events_index WHERE end_time > ? AND start_time < ?) AND (end_time - start_time) * 1000 >= ? ORDER BY start_time ASC, end_time DESC """, (s - self.event_idx_offset, e - self.event_idx_offset, self.render_cutoff.get()) ): event = Event(row) thread_idx = event.thread_id if event.start_type == "START": prev_event_at_level = None while thread_level_ends[thread_idx] and thread_level_ends[thread_idx][-1].end_time <= event.start_time: prev_event_at_level = thread_level_ends[thread_idx].pop() event.depth = len(thread_level_ends[thread_idx]) if ( threshold and prev_event_at_level and prev_event_at_level.can_merge(event, threshold) ): prev_event_at_level.merge(event) thread_level_ends[thread_idx].append(prev_event_at_level) else: thread_level_ends[thread_idx].append(event) self.data.append(event) else: self.data.append(event) except sqlite3.OperationalError: pass self.c.set_progress_handler(None, 0) finally: self.set_status("") def render(self): """ Render settings changed, re-render with existing data """ if not self.window_ready: return if not MIN_PPS < self.scale.get() < MAX_PPS: return self.soft_scale = 1.0 self.render_clear() self.render_scrubber_activity() self.render_scrubber_arrow() self.render_base() self.render_data() def render_clear(self): """ clear the canvas and any cached variables """ self.canvas.delete(ALL) self.original_texts = {} self.tooltips = {} self.canvas.configure(scrollregion=( 0, 0, self.render_len.get() * self.scale.get(), len(self.threads) * (MAX_DEPTH * BLOCK_HEIGHT) + HEADER_HEIGHT )) if self.char_w == -1: t = self.canvas.create_text(0, 0, font="TkFixedFont", text="_", anchor=NW) bb = self.canvas.bbox(t) # [2]-[0]=10, but trying by hand, 8px looks better on win7 # 7px looks right on linux, not sure what [2]-[0] is there, # hopefully 9px, so "-2" always helps? self.char_w = bb[2] - bb[0] - 2 self.canvas.delete(t) def render_scrubber_activity(self, length=None): sc = self.scrubber if not sc: return if self.sc_activity is not None: sc.delete("activity") activity_peak = max(self.sc_activity) if activity_peak == 0: return for n in range(0, length or len(self.sc_activity)): col = gen_colour(self.sc_activity[n], activity_peak) sc.create_rectangle( int(float(n) / len(self.sc_activity) * sc.winfo_width()), 1, int(float(n + 1) / len(self.sc_activity) * sc.winfo_width()), SCRUBBER_HEIGHT, fill=col, outline=col, tags="activity", ) def render_scrubber_arrow(self): sc = self.scrubber if not self.window_ready: return if not sc: return # events start / end / length ev_s = self.get_earliest_bookmark_after(0) ev_e = self.get_latest_bookmark_before(sys.maxint) ev_l = ev_e - ev_s if ev_l == 0: # only one bookmark return # view start / end / length vi_s = self.render_start.get() vi_e = self.render_start.get() + self.render_len.get() # vi_l = vi_e - vi_s # scrubber width sc_w = sc.winfo_width() sc.delete("arrow") # arrow start_abs = vi_s start_rel = start_abs - ev_s start_fraction = start_rel / ev_l start_scaled = start_fraction * sc_w start = start_scaled end_abs = vi_e end_rel = end_abs - ev_s end_fraction = end_rel / ev_l end_scaled = end_fraction * sc_w end = end_scaled # left edge sc.create_line( start, 1, start, SCRUBBER_HEIGHT, fill="#000", tags="arrow", ) sc.create_line( start, SCRUBBER_HEIGHT/2, start + 5, 15, fill="#000", tags="arrow", ) sc.create_line( start, SCRUBBER_HEIGHT/2, start + 5, 5, fill="#000", tags="arrow", ) # right edge sc.create_line( end, 1, end, SCRUBBER_HEIGHT, fill="#000", tags="arrow", ) sc.create_line( end, SCRUBBER_HEIGHT/2, end - 5, 15, fill="#000", tags="arrow", ) sc.create_line( end, SCRUBBER_HEIGHT/2, end - 5, 5, fill="#000", tags="arrow", ) # join sc.create_line( start, SCRUBBER_HEIGHT/2, end, SCRUBBER_HEIGHT/2, fill="#000", tags="arrow", ) def render_base(self): """ Render grid lines and markers """ _rl = self.render_len.get() _sc = self.scale.get() * self.soft_scale rs_px = int(_rl * _sc) rl_px = int(_rl * _sc) for n in range(rs_px, rs_px + rl_px, 100): label = " +%.4f" % (float(n) / _sc - _rl) self.canvas.create_line(n - rs_px, 0, n - rs_px, HEADER_HEIGHT + len(self.threads) * MAX_DEPTH * BLOCK_HEIGHT, fill="#CCC", tags="grid") self.canvas.create_text(n - rs_px, 5, text=label, anchor=NW, tags="time_label grid") for n in range(0, len(self.threads)): self.canvas.create_line(0, HEADER_HEIGHT + MAX_DEPTH * BLOCK_HEIGHT * n, rl_px, HEADER_HEIGHT + MAX_DEPTH * BLOCK_HEIGHT * n, tags="grid") self.canvas.create_text(0, HEADER_HEIGHT + MAX_DEPTH * BLOCK_HEIGHT * (n + 1) - 5, text=" " + self.threads[n], anchor=SW, tags="grid") self.canvas.tag_lower("grid") def render_data(self): """ add the event rectangles """ if not self.window_ready: # update() is called a couple of times during init() return _rs = self.render_start.get() _rc = self.render_cutoff.get() _sc = self.scale.get() event_count = len(self.data) - 1 shown = 0 for n, event in enumerate(self.data): if n % 1000 == 0 or n == event_count: self.set_status("Rendered %d events (%d%%)" % (n, float(n) * 100 / event_count)) self.master.update() thread_idx = event.thread_id if event.start_type == "START": if (event.end_time - event.start_time) * 1000 < _rc: continue if event.depth >= MAX_DEPTH: continue shown += 1 if shown == 500 and VERSION.endswith("-demo"): showerror("Demo Limit", "The evaluation build is limited to showing 500 events at a time, so rendering has stopped") break self.show_event( event, _rs, _sc, thread_idx, ) elif event.start_type == "BMARK": # note that when loading data, we currently filter for # "start_type=START" for a massive indexed speed boost # so there are no bookmarks. We may want to load bookmarks # into a separate array? pass # render bookmark elif event.start_type == "LOCKW" or event.start_type == "LOCKA": self.show_lock( event, _rs, _sc, thread_idx, ) self.set_status("") def show_event(self, event, offset_time, scale_factor, thread): function = event.start_location ok = event.end_type == "ENDOK" start_px = int((event.start_time - offset_time) * scale_factor) length_px = int(event.length * scale_factor) tip = "%dms @%dms: %s\n%s" % ( (event.end_time - event.start_time) * 1000, (event.start_time - offset_time) * 1000, function, event.text ) fill = "#CFC" if ok else "#FCC" outl = "#484" if ok else "#844" r = self.canvas.create_rectangle( start_px, HEADER_HEIGHT + thread * MAX_DEPTH * BLOCK_HEIGHT + event.depth * BLOCK_HEIGHT, start_px + length_px, HEADER_HEIGHT + thread * MAX_DEPTH * BLOCK_HEIGHT + event.depth * BLOCK_HEIGHT + BLOCK_HEIGHT, fill=fill, outline=outl, tags="event", ) t = self.canvas.create_text( start_px, HEADER_HEIGHT + thread * MAX_DEPTH * BLOCK_HEIGHT + event.depth * BLOCK_HEIGHT + 3, text=self.truncate_text(" " + event.text, length_px), tags="event event_label", anchor=NW, width=length_px, font="TkFixedFont", state="disabled", ) self.canvas.tag_raise(r) self.canvas.tag_raise(t) self.canvas.tag_bind(r, "<1>", lambda e: self._focus(r)) self.original_texts[t] = event.text self.tooltips[r] = tip self.canvas.tag_bind(r, "<Enter>", lambda e: self._ttip_show(r)) self.canvas.tag_bind(r, "<Leave>", lambda e: self._ttip_hide()) def show_lock(self, event, offset_time, scale_factor, thread): start_px = int((event.start_time - offset_time) * scale_factor) length_px = int(event.length * scale_factor) fill = "#FDD" if event.start_type == "LOCKW" else "#DDF" r = self.canvas.create_rectangle( start_px, HEADER_HEIGHT + thread * MAX_DEPTH * BLOCK_HEIGHT, start_px + length_px, HEADER_HEIGHT + (thread + 1) * MAX_DEPTH * BLOCK_HEIGHT, fill=fill, outline=fill, tags="lock", ) t = self.canvas.create_text( start_px + length_px, HEADER_HEIGHT + (thread + 1) * MAX_DEPTH * BLOCK_HEIGHT, text=self.truncate_text(event.text, length_px), tags="lock lock_label", anchor=SE, width=length_px, font="TkFixedFont", state="disabled", fill="#888", ) self.canvas.tag_lower(t) self.canvas.tag_lower(r) def _focus(self, r): # scale the canvas so that the (selected item width + padding == screen width) view_w = self.canvas.winfo_width() rect_w = max(self.canvas.bbox(r)[2] - self.canvas.bbox(r)[0] + HEADER_HEIGHT, 10) self.scale_view(n=float(view_w) / rect_w) # move the view so that the selected (item x1 = left edge of screen + padding) canvas_w = self.canvas.bbox("grid")[2] rect_x = self.canvas.bbox(r)[0] - 5 self.canvas.xview_moveto(float(rect_x) / canvas_w) def _ttip_show(self, r): tip = self.tooltips[r] x0, y0, x1, y1 = self.canvas.bbox(r) if x0 < 0: x1 = x1 - x0 x0 = x0 - x0 t2 = self.canvas.create_text( x0 + 4, y0 + BLOCK_HEIGHT + 4, text=tip.strip(), width=400, tags="tooltip", anchor=NW, justify="left", state="disabled", ) x0, y0, x1, y1 = self.canvas.bbox(t2) r2 = self.canvas.create_rectangle( x0 - 2, y0 - 1, x1 + 2, y1 + 2, state="disabled", fill="#FFA", outline="#AA8", tags="tooltip" ) self.canvas.tag_raise(t2) def _ttip_hide(self): self.canvas.delete("tooltip")
class Wveinterface: """ Create a wave user interface based on Tkinterface to read and modify the waves to play on the DPS """ def __init__(self, prevroot, datawve): """ Create a waveinterface instance. :param prevroot: is the main window :param datawve: is the datapoints to play with :returns: a new instance of wave interface """ self.root = maketoplevel(prevroot, True) self.root.title("Wave editor") self.datawve = datawve self.dataclpbrd = [] self.clipboardtime = 0 row = 0 col = 0 self.tablewve = Table(self.root, self.datawve, ('step', 'time [s]', ('voltage [V]', VCOL), ('current [A]', CCOL)), row, col, TABLEROW, TABLECOL) SCOPEROWSPAN = 15 self.scope = Scope(self.root, self.datawve, TABLEROW + 1 + 1, 0, rowspan=SCOPEROWSPAN, showpower=False, horizontaljoin=True, buttoncallback=self.buttoncallback) row = 1 rowspan = 1 colspan = 1 col = TABLECOL + colspan Button(self.root, text="Pick beg", command=self.btncmdpckbeg).grid(row=row, column=col, sticky=E + W, padx=8) col = TABLECOL + colspan row += rowspan Button(self.root, text="Pick end", command=self.btncmdpckend).grid(row=row, column=col, sticky=E + W, padx=8) Separator(self.root, orient='horizontal').grid(row=TABLEROW + 1, column=0, columnspan=TABLECOL + 2 + 1 + 6, sticky=E + W, pady=8) Separator(self.root, orient='vertical').grid(row=0, column=6, rowspan=1 + TABLEROW + 1 + SCOPEROWSPAN, sticky=N + S, padx=8) row = 0 COL1 = TABLECOL + 2 + 1 col = COL1 colspan = 1 insertlabelrow(self.root, row, col, (None, None, ('voltage [V]', VCOL), ('current [A]', CCOL))) row += rowspan insertlabelrow(self.root, row, col, ('time [s]:', )) self.dvartime = DoubleVar() self.dvarvoltage = DoubleVar() self.dvarcurrent = DoubleVar() insertentryrow( self.root, row, col, (None, self.dvartime, self.dvarvoltage, self.dvarcurrent)) col += TABLECOL Button(self.root, text="Insert", command=self.butcmdinsert).grid(row=row, column=col, sticky=E + W, padx=8) row += rowspan col = COL1 insertlabelrow(self.root, row, col, ('step :', )) self.ivarstep = IntVar() insertentryrow( self.root, row, col, (None, self.ivarstep, self.dvarvoltage, self.dvarcurrent)) col += TABLECOL Button(self.root, text="Modify", command=self.butcmdmodify).grid(row=row, column=col, sticky=E + W, padx=8) col += colspan Button(self.root, text="Delete", command=self.butcmddelete).grid(row=row, column=col, sticky=E + W, padx=8) row += rowspan col = COL1 insertlabelrow(self.root, row, col, ('pause [s]:', )) self.dvarpause = DoubleVar() insertentryrow( self.root, row, col, (None, self.dvarpause, self.dvarvoltage, self.dvarcurrent)) col += TABLECOL Button(self.root, text="Append", command=self.butcmdappend).grid(row=row, column=col, sticky=E + W, padx=8) self.clipboard = Clipboard(self.root, self.datawve, self.updateview, TABLEROW + 2, COL1) col = COL1 + TABLECOL colspan = 1 row = TABLEROW + 1 + SCOPEROWSPAN Button(self.root, text="Help", command=self.btncmdhelp).grid(row=row, column=col, sticky=E + W, padx=8) col += 1 Button(self.root, text="Done", command=self.butcmddone).grid(row=row, column=col, sticky=E + W, padx=8) self.scope.update() self.scope.redraw() def updateview(self): """ Update scope and table views """ self.tablewve.updateview() self.scope.redraw() def butcmdmodify(self): """ Modify and item of the table. Gets the item to modify and new values from the user interface fields. """ i = self.ivarstep.get() if i < len(self.datawve) and i >= 0: self.datawve[i] = [self.datawve[self.ivarstep.get()][0] ] + self.getvc(i) self.tablewve.updateview() self.scope.redraw() else: tkMessageBox.showinfo('Step not found', 'Step index is not in the points interval') def butcmddelete(self): """ Delete a table row. Read the index to delete by the interface field. """ i = self.ivarstep.get() if i < len(self.datawve) and i >= 0: del self.datawve[i] self.tablewve.updateview() self.scope.redraw() else: tkMessageBox.showinfo('Step not found', 'Step index is not in the points interval') def butcmdinsert(self): """ Insert an item on the data table. Gets the item data from the interface fields. """ i = self.tablewve.findtime(self.dvartime.get()) if len(self.datawve) > 0 and i > 0 and abs( self.datawve[i - 1][TPOS] - self.dvartime.get() ) < 0.01: #if the time is the same the insert becomes a modify self.datawve[i - 1] = [self.dvartime.get()] + self.getvc(i - 1) else: self.datawve.insert(i, [self.dvartime.get()] + self.getvc(i - 1)) self.tablewve.updateview() self.scope.redraw() def butcmdappend(self): """ Append an item to the data table. Gets the item to append values from the user interface fields. """ if self.dvarpause.get() <= 0: tkMessageBox.showinfo('Time not monotonic', 'Time pause has to be > 0') return if len(self.datawve) > 0: t0 = self.datawve[-1][TPOS] else: t0 = 0 self.datawve.append([self.dvarpause.get() + t0] + self.getvc(len(self.datawve) - 1)) self.tablewve.updateview() self.scope.redraw() def btncmdpckbeg(self): """ Gets begin data on the clipboard from the first row visible on the data list. """ r = self.tablewve.getfistvisiblerow() self.ivarstep.set(r) self.dvartime.set(self.datawve[r][TPOS]) self.dvarvoltage.set(self.datawve[r][VPOS]) self.dvarcurrent.set(self.datawve[r][CPOS]) self.clipboard.setbegin(r) def btncmdpckend(self): """ Gets end data on the clipboard from the second row visible on the data list. """ r = self.tablewve.getfistvisiblerow() + 1 if r < len(self.datawve): self.ivarstep.set(r) self.dvartime.set(self.datawve[r][TPOS]) self.dvarvoltage.set(self.datawve[r][VPOS]) self.dvarcurrent.set(self.datawve[r][CPOS]) self.clipboard.setend(r) def butcmddone(self): """ Close the window. """ self.root.destroy() def getvc(self, i): """ Gets voltage and current from the interface fields. If they are negative, the voltage/current at the given position are taken. In case of the first point the value 0 is used. :param i: the index from which get parameters if something is < 0 :return: a list containing voltage and current """ v = self.dvarvoltage.get() c = self.dvarcurrent.get() if i >= 0: if v < 0.: v = self.datawve[i][VPOS] if c < 0.: c = self.datawve[i][CPOS] else: if v < 0.: v = 0. if c < 0.: c = 0. return [v, c] def buttoncallback(self, p, action='insert'): """ Insert, modify or delete a point. That interface is used by the scopetube to edit the table. :param p: is a list containing the new value for (t, v, c) if v or c are not updated -1 is returned :param action: describes the type of action required """ self.dvarvoltage.set(p[1]) self.dvarcurrent.set(p[2]) self.dvartime.set(p[0]) self.ivarstep.set(self.tablewve.findtime(p[0])) if action == 'insert': self.butcmdinsert() elif action == 'modify': self.butcmdmodify() elif action == 'delete': self.butcmddelete() else: print( 'Internal error: unexpected button call back in wve interface') def btncmdhelp(self): """ Open a window with basic help on the wave interface. """ Txtinterface( self.root, 'Help', """Wave editor window is designed to create new waveform to play on the DPS supplier. The wave is visible on two different output formats: - top-left is text table showing what voltage and current set at give timing Every line has its step number useful for editing - bottom-left is the wave graphical picture representing the table above The wave data can be entered in three ways: - graphically with mouse clicking on the bottom-left graph - textually with the commands on top-right input section - from clipboard on the bottom-right side The clipboard can copy/cut and paste from the data section. Clipboard data can be modified bebore pasting back: - amplified (or attenuated if the factor is below 1) - translated (on Y for voltage and current and also on time) - transformed in a ramp: the give number of steps are inserted between the first and last data sample On the graphical section it is possible to manage the enabled waveforms with the mouse: - drage with left button pressed to move the waveform(s) - rotate wheel to zoom/unzoom the time (x) - press shift while rotating wheel to zoom/unzoom the amplitude (y) - press ctrl while rotating wheel to change the enabled waveform(s) - press wheel to fit waveform(s) on time and y scales - press right button to insert a point (on the enabled variables) - press shift and right button to modify the amplitude of the point(s) at the right of the mouse arrow with mouse amplitude on the enabled wave(s) - press ctrl and right button to delete the point at the right of the mouse pointer on the enabled wave(s) - press ctrl and shift to replace the point at the right of the mouse pointer with the current mouse arrow place on the enabled wave(s) On the bottom of the screen the scale, translation and enables are available for manual zooming and moving. On the top-right side it is possible to add new points: - insert button adds a new point at given time, use -1 on voltage/current to keep previous value - insert button to insert a new point (with absolute time) if the required time is already present, that point is modified with new values - modify and delete buttons can be used to edit or delete the given step - append is used to add a new point to the tail of current waveform known the delta time between last one On the clipboard the sample time is stored as delta between adiacent points while on the main table it is absolute. On the clipboard are available the following functions: - Copy and cut from begin/end steps of the data into the clipboard - Paste clipboard at the given step inserting or overwriteing the data present there The clipboard can be modified: - Amplified to stretch in x or y depending on the factors - Translated on x and y depending on the factors - Transform the clipboard in a ramp using first and last points as begin and end values with given number of steps The clipboard and the data are showed with following buttons: - Line up/down to move up or down by 1 line - Page up/down to move up or dosn by all row available minus 1 - Top/bottom to go to the first or last element - Goto time/step to move the first line at the given step - Pick begin/end to read the first/second line and put is in begin/end fields That is useful for edit purpose without copying by hand. """)
class Example(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent self.initUI() self.centerUI(w=450,h=340) def initUI(self): self.parent.title("LINEARITY TEST FOR PMT BASES") self.pack(fill=BOTH, expand=True) self.columnconfigure(0, weight=1) #self.rowconfigure(0, weight=1) # weight attibute is used to make them growable # self.graph_cb = BooleanVar() self.init_point = IntVar() self.base_path = StringVar() self.end_point = IntVar() self.step = IntVar() self.n_meas = IntVar() self.inc_point = IntVar() self.coef = DoubleVar() self.noise = DoubleVar() self.thr_sigma = DoubleVar() self.SPE_DAQ = DoubleVar() search = Image.open("next_logo.jpg") search_temp = search.resize((170, 200), Image.ANTIALIAS) search_aux = ImageTk.PhotoImage(search_temp) label1 = Label(self, image=search_aux) label1.image = search_aux label1.grid(row=0, column=0, columnspan=10, rowspan=10, sticky=E+W+S+N) #Text Box self.base_path.set("F:/DATOS_DAC/2052/pmt_0_trace_evt_") e1 = Entry(self, textvariable=self.base_path, width=40) e1.grid(row=1,column=2, sticky=W, columnspan=5, pady=5) e1_label = Label(self, text="DataSet path (including name file)") e1_label.grid(row=0,column=2,sticky=W, columnspan=5, pady=5) #Spin Boxes self.n_meas.set("20") sb1 = Spinbox(self, from_=1, to=1000, width=6, textvariable=self.n_meas) sb1.grid(row=3,column=3, sticky=W) sb1_label = Label(self, text="Measurements") sb1_label.grid(row=2,column=3, padx=0, sticky=W) self.step.set("10") sb2 = Spinbox(self, from_=10, to=200, width=6, textvariable=self.step) sb2.grid(row=3,column=4, sticky=W) sb2_label = Label(self, text="Pulse Width Step") sb2_label.grid(row=2,column=4, padx=0, sticky=W) # INTEGRATION LIMITS Integration_label = Label(self, text="INTEGRATION LIMITS", font = "Verdana 12 bold") Integration_label.grid(row=4,column=3, padx=5, columnspan = 3, pady=10) self.init_point.set("30") sb3 = Spinbox(self, from_=1, to=10000, width=6, textvariable=self.init_point) sb3.grid(row=7,column=3, sticky=W) sb3_label = Label(self, text="Start (usec)") sb3_label.grid(row=6,column=3, padx=0, sticky=W) self.end_point.set("160") sb4 = Spinbox(self, from_=1, to=10000, width=6, textvariable=self.end_point) sb4.grid(row=7,column=4, sticky=W) sb4_label = Label(self, text="End (usec)") sb4_label.grid(row=6,column=4, padx=0, sticky=W) # PARAMETERS Integration_label = Label(self, text="PARAMETERS", font = "Verdana 12 bold") Integration_label.grid(row=8,column=3, padx=5, columnspan = 3, pady=10) self.inc_point.set("3") sb5 = Spinbox(self, from_=1, to=100, width=6, textvariable=self.inc_point) sb5.grid(row=11,column=3, sticky=W) sb5_label = Label(self, text="First point") sb5_label.grid(row=10,column=3, padx=0, sticky=W) self.coef.set("1.636E-3") e6 = Entry(self, width=10, textvariable=self.coef) e6.grid(row=11,column=4, sticky=W) e6_label = Label(self, text="DBLR Coef") e6_label.grid(row=10,column=4, sticky=W) self.noise.set("0.75") e7 = Entry(self, width=10, textvariable=self.noise) e7.grid(row=11,column=5, sticky=W) e7_label = Label(self, text="Noise (LSB)") e7_label.grid(row=10,column=5, sticky=W) self.thr_sigma.set("40") e8 = Entry(self, width=10, textvariable=self.thr_sigma) e8.grid(row=13,column=3, sticky=W) e8_label = Label(self, text="Threshold") e8_label.grid(row=12,column=3, sticky=W) self.SPE_DAQ.set("20.5") e9 = Entry(self, width=10, textvariable=self.SPE_DAQ) e9.grid(row=13,column=4, sticky=W) e9_label = Label(self, text="SPE (LSB)") e9_label.grid(row=12,column=4, sticky=W) # #Check buttons # cb1 = Checkbutton(self, text="MultiGraph Output", variable=self.graph_cb ) # cb1.select() # cb1.grid(row=7,column=6, sticky=W) # Main buttons obtn = Button(self, text="GO!!", command=self.linearity_f) obtn.grid(row=14, column=4, sticky=E, pady=10) cbtn = Button(self, text="Quit", command=self.quit) cbtn.grid(row=14, column=5, sticky=E, pady=10) hbtn = Button(self, text="Help") hbtn.grid(row=14, column=0, sticky=W, pady=10) def linearity_f(self): # global a # # if (self.graph_cb.get()==True): # b=a # a=a+1 # else: # b=0 linearity.linearity_test(base_path=self.base_path.get(), init_point=self.init_point.get(), end_point=self.end_point.get(), step=self.step.get(), n_meas=self.n_meas.get(), inc_point=self.inc_point.get(), coef=self.coef.get(), noise=self.noise.get(), thr_sigma=self.thr_sigma.get(), SPE_DAQ=self.SPE_DAQ.get(), graph_sw=0 ) def centerUI(self,w,h): sw = self.parent.winfo_screenwidth() sh = self.parent.winfo_screenheight() x = (sw-w)/2 y = (sh-h)/2 self.parent.geometry('%dx%d+%d+%d' % (w,h,x,y))
class Application(Frame): def __init__(self, master=None): Frame.__init__(self, master) self.DEFAULT_SECTION = 'DEFAULT' self.grid() self.createWidgets() def createWidgets(self): self.__config = ConfigParser.ConfigParser() self.__config.set(self.DEFAULT_SECTION, 'input', '~/input.jpg') self.__config.set(self.DEFAULT_SECTION, 'inverted', '0') self.__config.set(self.DEFAULT_SECTION, 'output', '~/output.svg') self.__config.set(self.DEFAULT_SECTION, 'preamble', 'G17 G21 G90 G64 P0.1 S4500 M3 M8') self.__config.set(self.DEFAULT_SECTION, 'size', '256') self.__config.set(self.DEFAULT_SECTION, 'scale', '1') self.__config.set(self.DEFAULT_SECTION, 'width', '152.4') self.__config.set(self.DEFAULT_SECTION, 'height', '101.6') self.__config.set(self.DEFAULT_SECTION, 'columns', '3') self.__config.set(self.DEFAULT_SECTION, 'rows', '2') self.__config.set(self.DEFAULT_SECTION, 'margin', '10.0') self.__config.set(self.DEFAULT_SECTION, 'thickness', '6.35') self.__config.set(self.DEFAULT_SECTION, 'tool_diameter', '3.175') self.__config.read(os.path.expanduser('~/.py-art.cfg')) self.EntryFrame = Frame(self, bd=5) self.EntryFrame.grid(row=0, column=1) i = 0 Label(self.EntryFrame, text='Engrave an image\n').grid(row=i, column=0, columnspan=2) i += 1 Label(self.EntryFrame, text='Input file').grid(row=i, column=0, sticky=E) self.InputVar = StringVar() self.InputVar.set(self.__config.get(self.DEFAULT_SECTION, 'input')) Entry(self.EntryFrame, textvariable=self.InputVar, width=50).grid(row=i, column=1) i += 1 Label(self.EntryFrame, text='Size').grid(row=i, column=0, sticky=E) self.SizeVar = IntVar() self.SizeVar.set(self.__config.get(self.DEFAULT_SECTION, 'size')) Entry(self.EntryFrame, textvariable=self.SizeVar, width=50).grid(row=i, column=1) i += 1 Label(self.EntryFrame, text='Scale').grid(row=i, column=0, sticky=E) self.ScaleVar = IntVar() self.ScaleVar.set(self.__config.get(self.DEFAULT_SECTION, 'scale')) Entry(self.EntryFrame, textvariable=self.ScaleVar, width=50).grid(row=i, column=1) i += 1 Label(self.EntryFrame, text='Rows').grid(row=i, column=0, sticky=E) self.RowsVar = IntVar() self.RowsVar.set(self.__config.get(self.DEFAULT_SECTION, 'rows')) Entry(self.EntryFrame, textvariable=self.RowsVar, width=50).grid(row=i, column=1) i += 1 Label(self.EntryFrame, text='Columns').grid(row=i, column=0, sticky=E) self.ColumnsVar = IntVar() self.ColumnsVar.set(self.__config.get(self.DEFAULT_SECTION, 'columns')) Entry(self.EntryFrame, textvariable=self.ColumnsVar, width=50).grid(row=i, column=1) i += 1 Label(self.EntryFrame, text='Image effects').grid(row=i, column=0, sticky=E) self.InvertedVar = IntVar() self.InvertedVar.set( self.__config.getint(self.DEFAULT_SECTION, 'inverted')) Checkbutton(self.EntryFrame, text='Inverted', variable=self.InvertedVar).grid(row=i, column=1, sticky=W) if IN_AXIS: i += 1 Label(self.EntryFrame, text='Preamble').grid(row=i, column=0, sticky=E) self.PreambleVar = StringVar() self.PreambleVar.set( self.__config.get(self.DEFAULT_SECTION, 'preamble')) Entry(self.EntryFrame, textvariable=self.PreambleVar, width=50).grid(row=i, column=1) i += 1 Label(self.EntryFrame, text='Width').grid(row=i, column=0, sticky=E) self.WidthVar = DoubleVar() self.WidthVar.set(self.__config.get(self.DEFAULT_SECTION, 'width')) Entry(self.EntryFrame, textvariable=self.WidthVar, width=50).grid(row=i, column=1) i += 1 Label(self.EntryFrame, text='Height').grid(row=i, column=0, sticky=E) self.HeightVar = DoubleVar() self.HeightVar.set( self.__config.get(self.DEFAULT_SECTION, 'height')) Entry(self.EntryFrame, textvariable=self.HeightVar, width=50).grid(row=i, column=1) i += 1 Label(self.EntryFrame, text='Margin').grid(row=i, column=0, sticky=E) self.MarginVar = DoubleVar() self.MarginVar.set( self.__config.get(self.DEFAULT_SECTION, 'margin')) Entry(self.EntryFrame, textvariable=self.MarginVar, width=50).grid(row=i, column=1) i += 1 Label(self.EntryFrame, text='Tool diameter').grid(row=i, column=0, sticky=E) self.ToolDiameterVar = DoubleVar() self.ToolDiameterVar.set( self.__config.get(self.DEFAULT_SECTION, 'tool_diameter')) Entry(self.EntryFrame, textvariable=self.ToolDiameterVar, width=50).grid(row=i, column=1) i += 1 Label(self.EntryFrame, text='Thickness').grid(row=i, column=0, sticky=E) self.ThicknessVar = DoubleVar() self.ThicknessVar.set( self.__config.get(self.DEFAULT_SECTION, 'thickness')) Entry(self.EntryFrame, textvariable=self.ThicknessVar, width=50).grid(row=i, column=1) i += 1 Button(self.EntryFrame, text='Trace boundary in AXIS and Quit', command=self.WriteBoundaryTraceToAxis).grid(row=i, column=1, sticky=E) i += 1 Button(self.EntryFrame, text='Engrave in AXIS and Quit', command=self.WriteEngravingToAxis).grid(row=i, column=1, sticky=E) i += 1 Button(self.EntryFrame, text='Cut boundary in AXIS and Quit', command=self.WriteBoundaryCutToAxis).grid(row=i, column=1, sticky=E) else: i += 1 Label(self.EntryFrame, text='Output file').grid(row=i, column=0, sticky=E) self.OutputVar = StringVar() self.OutputVar.set( self.__config.get(self.DEFAULT_SECTION, 'output')) Entry(self.EntryFrame, textvariable=self.OutputVar, width=50).grid(row=i, column=1) i += 1 Button(self.EntryFrame, text='Write to SVG and Quit', command=self.WriteToSvg).grid(row=i, column=1, sticky=E) def WriteConfig(self): with open(os.path.expanduser('~/.py-art.cfg'), 'wb') as configfile: self.__config.set(self.DEFAULT_SECTION, 'input', self.InputVar.get()) self.__config.set(self.DEFAULT_SECTION, 'inverted', self.InvertedVar.get()) self.__config.set(self.DEFAULT_SECTION, 'size', self.SizeVar.get()) self.__config.set(self.DEFAULT_SECTION, 'scale', self.ScaleVar.get()) self.__config.set(self.DEFAULT_SECTION, 'rows', self.RowsVar.get()) self.__config.set(self.DEFAULT_SECTION, 'columns', self.ColumnsVar.get()) if IN_AXIS: self.__config.set(self.DEFAULT_SECTION, 'height', self.ToolDiameterVar.get()) self.__config.set(self.DEFAULT_SECTION, 'margin', self.ToolDiameterVar.get()) self.__config.set(self.DEFAULT_SECTION, 'preamble', self.PreambleVar.get()) self.__config.set(self.DEFAULT_SECTION, 'tool_diameter', self.ToolDiameterVar.get()) self.__config.set(self.DEFAULT_SECTION, 'thickness', self.ThicknessVar.get()) self.__config.set(self.DEFAULT_SECTION, 'width', self.ToolDiameterVar.get()) else: self.__config.set(self.DEFAULT_SECTION, 'output', self.OutputVar.get()) self.__config.write(configfile) def DisplayAndQuit(self, display, size): image = Image.open(os.path.expanduser(self.InputVar.get())) rows = self.RowsVar.get() columns = self.ColumnsVar.get() curve = Curve(display, image) curve.scale = (self.ScaleVar.get(), self.ScaleVar.get()) curve.is_inverted = self.InvertedVar.get() curve.calculate_levels(5, 0, 0, columns * size, rows * size) self.display_nxm_with_border(rows, columns, size, display, curve) display.close() self.WriteConfig() self.quit() def WriteToSvg(self): size = int(self.SizeVar.get()) display = SvgDisplay(os.path.expanduser(self.OutputVar.get()), self.ColumnsVar.get() * size + 22, self.RowsVar.get() * size + 22) # display = TurtleDisplay() display.offset = (11, 11) self.DisplayAndQuit(display, size) def WriteBoundaryMoves(self, display, cut_depth): width = self.WidthVar.get() height = self.HeightVar.get() tool_radius = self.ToolDiameterVar.get() / 2 corner_radius = 1.0 display.add_point((-tool_radius, -corner_radius)) print "g1 y%f z%f" % (-height + corner_radius, -cut_depth) print "g3 x%f y%f i%f" % (corner_radius, -height - tool_radius, tool_radius + corner_radius) print "g1 x%f" % (width - corner_radius) print "g3 x%f y%f j%f" % (width + tool_radius, -height + corner_radius, tool_radius + corner_radius) print "g1 y%f" % (-corner_radius) print "g3 x%f y%f i%f" % (width - corner_radius, tool_radius, -tool_radius - corner_radius) print "g1 x%f" % (corner_radius) print "g3 x%f y%f j%f" % (-tool_radius, -corner_radius, -tool_radius - corner_radius) def WriteBoundaryTraceToAxis(self): display = self.CreateGCodeDisplay() self.WriteBoundaryMoves(display, cut_depth=0) display.close_curve() display.close() self.WriteConfig() self.quit() def WriteBoundaryCutToAxis(self): display = self.CreateGCodeDisplay() tool_radius = self.ToolDiameterVar.get() / 2 thickness = self.ThicknessVar.get() zstart = 0.05 zstep = -tool_radius / 2 zstop = -thickness - 0.5 display.depth = -zstart for cut_depth in range(zstart, zstop, zstep): self.WriteBoundaryMoves(display, cut_depth) display.close_curve() display.close() self.WriteConfig() self.quit() def CreateGCodeDisplay(self): display = GCodeDisplay() display.preamble = self.PreambleVar.get() display.feed_rate = 1200 return display def WriteEngravingToAxis(self): display = self.CreateGCodeDisplay() width = self.WidthVar.get() height = self.HeightVar.get() margin = self.MarginVar.get() size = self.SizeVar.get() xscale = (width - 2 * margin) / (3 * size) yscale = (height - 2 * margin) / (2 * size) scale = min(xscale, yscale) xoff = width / 2 + 1.5 * size * scale yoff = -height / 2 + size * scale display.scale = (-scale, -scale) display.offset = (xoff, yoff) self.DisplayAndQuit(display, size) def display_rectangle(self, size, display, curve): display.add_point((-1, -1)) display.add_point((-1, size)) display.add_point((size * 2, size)) display.add_point((size * 2, -1)) display.close_curve() curve.draw_cell((size - 1, 0), (size - 1, size - 1), -1) display.add_point((size, size - 1)) curve.draw_cell((size, size - 1), (size, 0), -1) display.add_point((size - 1, 0)) display.close_curve() def display_square(self, size, display, curve): display.add_point((-1, -1)) display.add_point((-1, size)) display.add_point((size, size)) display.add_point((size, -1)) display.close_curve() curve.draw_cell((size / 2 - 1, 0), (size / 2 - 1, size / 2 - 1), -1) display.add_point((size / 2 - 1, size / 2)) curve.draw_cell((size / 2 - 1, size / 2), (size / 2 - 1, size - 1), -1) display.add_point((size / 2, size - 1)) curve.draw_cell((size / 2, size - 1), (size / 2, size / 2), -1) display.add_point((size / 2, size / 2 - 1)) curve.draw_cell((size / 2, size / 2 - 1), (size / 2, 0), -1) display.add_point((size / 2 - 1, 0)) display.close_curve() def display_nxm_with_border(self, n, m, size, display, curve): """ Draw the curve using n rows and m columns. n - the number of rows must be even. m - the number of columns. size - the size of each row and column. display - the place to draw the curve. curve - the curve to draw. """ display.add_point((-1, n / 2 * size)) display.add_point((-1, n * size)) display.add_point((m * size, n * size)) display.add_point((m * size, -1)) display.add_point((-1, -1)) display.add_point((-1, n / 2 * size - 1)) self.display_nxm(n, m, size, display, curve) def display_nxm(self, n, m, size, display, curve): for i in range(n / 2 - 1): display.add_point((0, (n / 2 - i) * size - 1)) curve.draw_cell((0, (n / 2 - i) * size - 1), (0, (n / 2 - i - 1) * size), -1) for i in range(m): display.add_point((i * size, size - 1)) curve.draw_cell((i * size, size - 1), ((i + 1) * size - 1, size - 1), 1) for i in range(n / 2 - 1): for j in range(m - 2): display.add_point(((m - j) * size - 1, (2 * i + 1) * size)) curve.draw_cell(((m - j) * size - 1, (2 * i + 1) * size), ((m - j - 1) * size, (2 * i + 1) * size), 1) for j in range(2): display.add_point((2 * size - 1, (2 * i + j + 1) * size)) curve.draw_cell((2 * size - 1, (2 * i + j + 1) * size), (2 * size - 1, (2 * i + j + 2) * size - 1), -1) for j in range(m - 2): display.add_point(((2 + j) * size, (2 * i + 3) * size)) curve.draw_cell(((2 + j) * size, (2 * i + 3) * size - 1), ((3 + j) * size - 1, (2 * i + 3) * size - 1), 1) for i in range(m): display.add_point(((m - i) * size - 1, (n - 1) * size)) curve.draw_cell(((m - i) * size - 1, (n - 1) * size), ((m - i - 1) * size, (n - 1) * size), 1) for i in range(n / 2 - 1): display.add_point((0, (n - i - 1) * size - 1)) curve.draw_cell((0, (n - i - 1) * size - 1), (0, (n - i - 2) * size), -1) display.close_curve()
class SolidDatabaseEditor: """Gets the contaminant properties.""" def __init__(self, master, system, solid, solid_database, editflag): """Constructor method. Defines the parameters to be obtained in this window.""" self.master = master self.fonttype = system.fonttype self.version = system.version self.superfont = get_superfont(self.fonttype) #superscript font self.tframe = Frame(master.tframe) self.frame = Frame(master.frame) self.bframe = Frame(master.bframe) self.top = None #flag for existence of toplevel# self.solid = solid self.solid_database = solid_database self.torts = ['Millington & Quirk', 'Boudreau', 'None'] self.sorps = [ 'Linear--Kd specified', 'Linear--Kocfoc', 'Freundlich', 'Langmuir' ] self.name = StringVar( value='Solid ' + str(solid_database[-1].number)) #stores the chemical name self.e = DoubleVar(value=0.5) #stores the porosity self.rho = DoubleVar(value=1.0) #stores the bulk density self.foc = DoubleVar(value=0.01) #stores the organic carbon fraction self.tort = StringVar( value=self.torts[0]) #stores the default tortuosity correction self.sorp = StringVar( value=self.sorps[0]) #stores the default sorption correction self.Ref = StringVar(value='') #stores the density self.editflag = editflag self.cancelflag = 0 if editflag == 1: #Detemine whether the chemical is added or edited self.name.set(solid.name) self.e.set(solid.e) self.rho.set(solid.rho) self.foc.set(solid.foc) self.tort.set(solid.tort) self.sorp.set(solid.sorp) self.Ref.set(solid.Ref) def make_widgets(self): """Make the widgets for the window.""" self.bgcolor = self.frame.cget('bg') self.instructions = Label( self.frame, text= ' Please provide the following properties for the solid/mixture: ' ) self.blankcolumn = Label(self.frame, text=' ', width=1) self.namecolumn = Label(self.frame, text=' ', width=18) self.ecolumn = Label(self.frame, text=' ', width=10) self.rhocolumn = Label(self.frame, text=' ', width=10) self.foccolumn = Label(self.frame, text=' ', width=10) self.tortcolumn = Label(self.frame, text=' ', width=18) self.sorpcolumn = Label(self.frame, text=' ', width=20) self.refcolumn = Label(self.frame, text=' ', width=18) self.endcolumn = Label(self.frame, text=' ', width=2) self.namelabel = Label(self.frame, text='Material') self.elabel = Label(self.frame, text='Porosity') self.rholabel = Label(self.frame, text='Bulk density') self.foclabel = Label(self.frame, text='Organic carbon fraction') self.tortlabel = Label(self.frame, text='Tortruosity correction') self.sorplabel = Label(self.frame, text='Sorption isotherms') self.reflabel = Label(self.frame, text='Reference') self.rhounitlabel = Label(self.frame, text=u'g/cm\u00B3') self.namewidget = Entry(self.frame, width=16, justify='center', textvariable=self.name) self.ewidget = Entry(self.frame, width=8, justify='center', textvariable=self.e) self.rhowidget = Entry(self.frame, width=8, justify='center', textvariable=self.rho) self.focwidget = Entry(self.frame, width=8, justify='center', textvariable=self.foc) self.tortwidget = OptionMenu(self.frame, self.tort, *self.torts) self.sorpwidget = OptionMenu(self.frame, self.sorp, *self.sorps) self.refwidget = Entry(self.frame, width=15, justify='center', textvariable=self.Ref) self.okbutton = Button(self.frame, text='OK', width=20, command=self.OK) self.cancelbutton = Button(self.frame, text='Cancel', width=20, command=self.Cancel) self.blank1 = Label(self.frame, text=' ') self.blank2 = Label(self.frame, text=' ') #show the widgets on the grid self.instructions.grid(row=0, column=0, columnspan=7, padx=8, sticky='W') self.blankcolumn.grid(row=1, column=0, sticky='WE', padx=1, pady=1) self.namecolumn.grid(row=1, column=1, sticky='WE', padx=1, pady=1) self.ecolumn.grid(row=1, column=2, sticky='WE', padx=1, pady=1) self.rhocolumn.grid(row=1, column=3, sticky='WE', padx=1, pady=1) self.foccolumn.grid(row=1, column=4, sticky='WE', padx=1, pady=1) self.tortcolumn.grid(row=1, column=5, sticky='WE', padx=1, pady=1) self.sorpcolumn.grid(row=1, column=6, sticky='WE', padx=1, pady=1) self.refcolumn.grid(row=1, column=7, sticky='WE', padx=1, pady=1) self.endcolumn.grid(row=1, column=8, sticky='WE', padx=1, pady=1) self.namelabel.grid(row=2, column=1, sticky='WE', padx=1, pady=1) self.elabel.grid(row=2, column=2, sticky='WE', padx=1, pady=1) self.rholabel.grid(row=2, column=3, sticky='WE', padx=1, pady=1) self.foclabel.grid(row=2, column=4, sticky='WE', padx=1, pady=1) self.tortlabel.grid(row=2, column=5, sticky='WE', padx=1, pady=1) self.sorplabel.grid(row=2, column=6, sticky='WE', padx=1, pady=1) self.reflabel.grid(row=2, column=7, sticky='WE', padx=1, pady=1) self.rhounitlabel.grid(row=3, column=3, sticky='WE', padx=1, pady=1) self.namewidget.grid(row=4, column=1, padx=1, pady=1) self.ewidget.grid(row=4, column=2, padx=1, pady=1) self.rhowidget.grid(row=4, column=3, padx=1, pady=1) self.focwidget.grid(row=4, column=4, padx=1, pady=1) self.tortwidget.grid(row=4, column=5, padx=1, pady=1, sticky='WE') self.sorpwidget.grid(row=4, column=6, padx=1, pady=1, sticky='WE') self.refwidget.grid(row=4, column=7, padx=1, pady=1) self.blank1.grid(row=5) self.okbutton.grid(row=6, columnspan=11) self.cancelbutton.grid(row=7, columnspan=11) self.blank2.grid(row=8) self.okbutton.bind('<Return>', self.OK) self.focusbutton = self.okbutton def OK(self, event=None): """Finish and move on. Checks that the number chemicals are less than the total number of chemicals in database.""" if self.editflag == 0: check = [(solid.name == self.name.get()) for solid in self.solid_database[0:-1]] if self.editflag == 1: check = [(solid.name == self.name.get() and self.solid.name != self.name.get()) for solid in self.solid_database[0:-1]] if self.master.window.top is not None: self.master.open_toplevel() elif self.e.get() > 1 or self.e.get() < 0: tkmb.showinfo( self.version, 'The porosity of a solid can not be larger than 1 or smaller than 0' ) self.e.set(0.5) elif self.rho.get() < 0: tkmb.showinfo(self.version, 'The bulk density of a solid can not be negative') self.e.set(1.0) elif self.foc.get() > 1 or self.foc.get() < 0: tkmb.showinfo( self.version, 'The organic carbon fraction of a solid can not be larger than 1 or smaller than 0' ) self.e.set(1.0) elif sum(check) >= 1 or self.name.get() == '': self.solids_error() else: self.master.tk.quit() def solids_error(self): tkmb.showerror( title=self.version, message= 'This solid material has already been added to the database!') self.focusbutton = self.okbutton self.master.tk.lift() def Cancel(self): try: self.name.set(self.solid.name) self.e.set(self.solid.e) self.rho.set(self.solid.rho) self.foc.set(self.solid.foc) self.tort.set(self.solid.tort) self.sorp.set(self.solid.sorp) self.Ref.set(self.solid.Ref) except: self.cancelflag = 1 if self.master.window.top is not None: self.master.open_toplevel() else: self.master.tk.quit()
class MatrixEditor: """Gets the contaminant properties.""" def __init__(self, master, system, matrix, matrices, materials, editflag, newflag): """Constructor method. Defines the parameters to be obtained in this window.""" self.master = master self.fonttype = system.fonttype self.version = system.version self.superfont = get_superfont(self.fonttype) #superscript font self.tframe = Frame(master.tframe) self.frame = Frame(master.frame) self.bframe = Frame(master.bframe) self.top = None #flag for existence of toplevel# self.matrix = matrix self.matrices = matrices self.materials = materials self.matrices_list = self.materials.keys() self.matrices_list.sort() for matrix in (self.matrices): if matrix.number <> self.matrix.number and len( matrix.components) == 1 and self.matrices_list.count( matrix.name) > 0: self.matrices_list.remove(matrix.name) self.model = StringVar( value='Linear') #Define the imaginary model for the components self.name = StringVar(value=self.matrices_list[0]) #matrix name self.e = DoubleVar(value=0.5) #stores the porosity self.rho = DoubleVar(value=1.0) #stores the bulk density self.foc = DoubleVar(value=0.01) #stores the organic carbon fraction self.editflag = editflag self.newflag = newflag self.cancelflag = 0 if editflag == 0: self.components = [MatrixComponent(1)] #Define components if editflag == 1: #Detemine whether the chemical is added or edited self.components = self.matrix.components self.name.set(self.matrix.name) self.model.set(self.matrix.model) self.e.set(self.matrix.e) self.rho.set(self.matrix.rho) self.foc.set(self.matrix.foc) def make_widgets(self): """Make the widgets for the window.""" self.bgcolor = self.frame.cget('bg') self.instructions = Label( self.frame, text= ' Please provide the following properties for the matrix: ' ) self.blankcolumn = Label(self.frame, text=' ', width=1) self.namecolumn = Label(self.frame, text=' ', width=20) self.ecolumn = Label(self.frame, text=' ', width=14) self.rhocolumn = Label(self.frame, text=' ', width=15) self.foccolumn = Label(self.frame, text=' ', width=15) self.namelabel = Label(self.frame, text='Material') self.elabel = Label(self.frame, text='Porosity') self.rholabel = Label(self.frame, text='Bulk density (' + u'g/cm\u00B3' + ')') self.foclabel = Label(self.frame, text='Organic carbon fraction') if self.editflag == 1: self.namewidget = Label(self.frame, width=16, justify='center', textvariable=self.name) else: if self.newflag == 0: self.namewidget = OptionMenu(self.frame, self.name, *self.matrices_list, command=self.click_matrix) else: self.name.set('Matrix') self.namewidget = Entry(self.frame, width=16, justify='center', textvariable=self.name) self.ewidget = Entry(self.frame, width=10, justify='center', textvariable=self.e) self.rhowidget = Entry(self.frame, width=10, justify='center', textvariable=self.rho) self.focwidget = Entry(self.frame, width=10, justify='center', textvariable=self.foc) self.okbutton = Button(self.frame, text='OK', width=20, command=self.OK) self.cancelbutton = Button(self.frame, text='Cancel', width=20, command=self.Cancel) self.blank1 = Label(self.frame, text=' ') self.blank2 = Label(self.frame, text=' ') #show the widgets on the grid self.instructions.grid(row=0, column=0, columnspan=7, padx=8, sticky='W') self.blankcolumn.grid(row=1, column=0, sticky='WE', padx=1, pady=1) self.namecolumn.grid(row=1, column=1, sticky='WE', padx=1, pady=1) self.ecolumn.grid(row=1, column=2, sticky='WE', padx=1, pady=1) self.rhocolumn.grid(row=1, column=3, sticky='WE', padx=1, pady=1) self.foccolumn.grid(row=1, column=4, sticky='WE', padx=1, pady=1) self.namelabel.grid(row=2, column=1, sticky='WE', padx=4, pady=1) self.elabel.grid(row=2, column=2, sticky='WE', padx=1, pady=1) self.rholabel.grid(row=2, column=3, sticky='WE', padx=1, pady=1) self.foclabel.grid(row=2, column=4, sticky='WE', padx=1, pady=1) if self.newflag == 0: self.namewidget.grid(row=4, column=1, sticky='WE', padx=6, pady=1) else: self.namewidget.grid(row=4, column=1, padx=6, pady=1) self.ewidget.grid(row=4, column=2, padx=6, pady=1) self.rhowidget.grid(row=4, column=3, padx=6, pady=1) self.focwidget.grid(row=4, column=4, padx=6, pady=1) self.blank1.grid(row=5) self.okbutton.grid(row=6, columnspan=11) self.cancelbutton.grid(row=7, columnspan=11) self.blank2.grid(row=8) self.okbutton.bind('<Return>', self.OK) self.focusbutton = self.okbutton if self.editflag == 0 and self.newflag == 0: self.click_matrix() def click_matrix(self, event=None): """Pulls up the contaminant properties from the database after selecting a compound.""" self.tort = self.materials[self.name.get()].tort self.sorp = self.materials[self.name.get()].sorp self.e.set(self.materials[self.name.get()].e) self.rho.set(self.materials[self.name.get()].rho) self.foc.set(self.materials[self.name.get()].foc) self.frame.update() self.master.geometry() self.master.center() def OK(self, event=None): """Finish and move on. Checks that the number chemicals are less than the total number of chemicals in database.""" if self.editflag == 0: check = [(matrix.name == self.name.get()) for matrix in self.matrices[0:-1]] if self.editflag == 1: check = [0] if self.master.window.top is not None: self.master.open_toplevel() elif self.e.get() > 1 or self.e.get() < 0: tkmb.showinfo( self.version, 'The porosity of a solid can not be larger than 1 or smaller than 0' ) self.e.set(0.5) elif self.rho.get() < 0: tkmb.showinfo(self.version, 'The bulk density of a solid can not be negative') self.e.set(1.0) elif self.foc.get() > 1 or self.foc.get() < 0: tkmb.showinfo( self.version, 'The organic carbon fraction of a solid can not be larger than 1 or smaller than 0' ) self.e.set(1.0) elif sum(check) >= 1 or self.name.get() == '': self.matrix_error() else: self.components[0].name = self.name.get() self.components[0].mfraction = 1. self.components[0].fraction = 1. self.components[0].e = self.e.get() self.components[0].rho = self.rho.get() self.components[0].foc = self.foc.get() if self.editflag == 0: if self.newflag == 0: self.components[0].tort = self.materials[ self.name.get()].tort self.components[0].sorp = self.materials[ self.name.get()].sorp else: self.components[0].tort = 'Millington & Quirk' self.components[0].sorp = 'Linear--Kd specified' self.master.tk.quit() def matrix_error(self): tkmb.showerror( title=self.version, message= 'This solid material has already been added to the database!') self.focusbutton = self.okbutton self.master.tk.lift() def Cancel(self): try: self.name.set(self.matrix.name) self.model.set(self.matrix.model) self.e.set(self.matrix.e) self.rho.set(self.matrix.rho) self.foc.set(self.matrix.foc) self.components = self.matrix.components except: self.cancelflag = 1 if self.master.window.top is not None: self.master.open_toplevel() else: self.master.tk.quit()
class NumberEntry(BaseWiget): def __init__(self, parent, def_dict=None, tracker_path=None, to_game_callback=None, **kw): BaseWiget.__init__(self,parent, def_dict=def_dict, tracker_path=tracker_path, to_game_callback=to_game_callback, **kw) self.old_value = 0 outType = def_dict.get("outType", float) if outType == int: integer = True elif outType == float: integer = False else: raise TypeError("outType = %s"%repr(outType)) minVal = def_dict.get("minVal", 0) maxVal = def_dict.get("maxVal", 100) step = 1 if integer: self.var = IntVar() else: self.var = DoubleVar() step = 1.0 if (maxVal-minVal) < 5: step = 0.01 if "step" in def_dict: step = def_dict["step"] self.entry = Control(self, label=self.caption, integer=integer, variable=self.var, min=minVal, max=maxVal, step = step, options='entry.width 20 label.width 1 label.anchor w entry.anchor w') if not integer: number_zero = len(str(step).split(".")[1]) foramter = "%.{0}f".format(number_zero) def foo(num): num = float(num) if num>maxVal:num = maxVal if num<minVal:num = minVal return foramter%num self.entry['validatecmd'] = foo self.entry.grid(row=1, column=1) self.var.trace("w", self._onChangeVariable) self.old_value = self.getValue() self.onEndSetupContent() #------------- интерфейс -------------# def setValue(self, value): if self.old_value == value: return self.old_value = value self.var.set(value) def getValue(self): return self.var.get() def getDictValue(self): raise NotImplementedError def forceSave(self): """принудительное сохранение""" self._onEndInput() #------------- внутренние методы -------------# def _onEndInput(self): value = self.getValue() if self.old_value != value: self.onValueChangeEndByUser(self.old_value, value) self.old_value = value def _onChangeVariable(self, *event): value = self.getValue() if self.old_value == value: return self._onEndInput()
class FontPanel(StylePropertyPanel): title = _("Fonts") def __init__(self, master, main_window, doc): self.family_to_fonts = font.make_family_to_fonts() self.families = self.family_to_fonts.keys() self.families.sort() StylePropertyPanel.__init__(self, master, main_window, doc, name = 'fontdlg') self.family_list.SetList(self.families) index = self.families.index(self.font_family) self.family_list.select_set(index) self.family_list.yview(index) def build_dlg(self): top = self.top buttons = self.create_std_buttons(top) buttons.grid(row = 3, column = 4, columnspan = 2, sticky = "news") self.sample_text = StringVar(top) self.sample_text.set(config.preferences.sample_text) self.sample = Entry(top, textvariable = self.sample_text, relief = FLAT, bg = top['bg'], width = len(config.preferences.sample_text)) self.sample.grid(column = 0, row = 3, columnspan = 4, sticky = "news") # XXX: the background color of the sample text should be # configurable label = Label(top, text = _("Font Family:"), anchor = W) label.grid(column = 0, row = 0, columnspan = 2, sticky = "ew") sb_vert = Scrollbar(top, takefocus = 0) sb_vert.grid(column = 1, row = 1, rowspan = 2, sticky = "news") family_list = UpdatedListbox(top, name = 'families', height = 8) family_list.grid(column = 0, row = 1, rowspan = 2, sticky = "news") family_list.Subscribe(SELECTION, self.family_selected) sb_vert['command'] = (family_list, 'yview') family_list['yscrollcommand'] = (sb_vert, 'set') self.family_list = family_list label = Label(top, text = _("Font Style:"), anchor = W) label.grid(column = 2, row = 0, sticky = "ew") sb_vert = Scrollbar(top, takefocus = 0) sb_vert.grid(column = 3, row = 1, rowspan = 2, sticky = "news") self.font_attr_list = UpdatedListbox(top, name = 'weights', height = 4, width = 15) self.font_attr_list.grid(column = 2, row = 1, rowspan = 2, sticky = "news") self.font_attr_list.Subscribe(SELECTION, self.attr_selected) sb_vert['command'] = (self.font_attr_list, 'yview') self.font_attr_list['yscrollcommand'] = (sb_vert, 'set') label = Label(top, text = _("Size:"), anchor = W) label.grid(column = 4, row = 0, columnspan = 2, sticky = "ew") frame = Frame(top) frame.grid(column = 4, row = 1, columnspan = 2, sticky = 'ew') self.var_size = DoubleVar(top) scroll = MiniScroller(frame, variable = self.var_size, min = 0.0, max = None, step = 1) scroll.pack(side = RIGHT, fill = Y) self.size_entry = MyEntry(frame, textvariable = self.var_size, width = 4, command = self.apply_size, justify = RIGHT) self.size_entry.pack(side = LEFT, expand = 1, fill = BOTH) sb_vert = Scrollbar(top, takefocus = 0) sb_vert.grid(column = 5, row = 2, sticky = "news") self.size_list = UpdatedListbox(top, name = 'sizes', width = 4, height = 5) self.size_list.grid(column = 4, row = 2, sticky = "news") self.size_list.Subscribe(SELECTION, self.size_selected) self.size_list.SetList(std_sizes) sb_vert['command'] = (self.size_list, 'yview') self.size_list['yscrollcommand'] = (sb_vert, 'set') top.columnconfigure(0, weight = 1000) top.columnconfigure(4, weight = 1) top.rowconfigure(2, weight = 1) def init_from_doc(self): object = self.document.CurrentObject() if object is not None and object.is_Text: self.update_from_object_cb(object) else: default = font.GetFont(config.preferences.default_font) self.font_family = default.family self.font_attr = default.font_attrs self.update_from_family() self.update_size(properties.default_text_style.font_size) def Update(self): self.update_from_object_cb(self.document.CurrentObject()) def update_from_object_cb(self, obj): if obj is not None and obj.is_Text: font = obj.Font() self.font_family = font.family self.font_attr = font.font_attrs self.update_size(obj.FontSize()) self.update_from_family() def do_apply(self): name = self.current_font_ps() if not name: if __debug__: pdebug(None, 'FontPanel.do_apply: no ps name!') return kw = {'font': font.GetFont(name), 'font_size': self.var_size.get(), # set if_type_present to one to make sure that font # properties are only set on objects that can have font # properties. This is not ideal, but it works and needed # only simple changes to base.py 'if_type_present': 1} self.set_properties(_("Set Font `%s'") % name, 'font', kw) def update_from_family(self, set_view = 1): index = self.families.index(self.font_family) self.family_list.Select(index, set_view) fonts = self.family_to_fonts[self.font_family] attrs = [] for name in fonts: attrs.append(font.fontmap[name][1]) attrs.sort() self.set_font_attrs(attrs) self.update_sample() def update_size(self, size): self.var_size.set(size) if size in std_sizes: self.size_list.Select(list(std_sizes).index(size), 1) else: self.size_list.SelectNone() def update_sample(self): xlfd = self.current_font_xlfd() if not xlfd: xlfd = 'fixed' self.sample['font'] = xlfd def set_font_attrs(self, attrs): self.font_attrs = attrs self.font_attr_list.SetList(attrs) self.font_attr = get_from_list(self.font_attr, attrs) self.font_attr_list.Select(attrs.index(self.font_attr), 1) def current_font_xlfd(self): fonts = self.family_to_fonts[self.font_family] for name in fonts: family, attrs, xlfd_start, encoding = font.fontmap[name] if attrs == self.font_attr: return font.xlfd_template % (xlfd_start, 24, encoding) return '' def current_font_ps(self): fonts = self.family_to_fonts[self.font_family] for name in fonts: family, attrs, xlfd_start, encoding = font.fontmap[name] if attrs == self.font_attr: return name return '' def family_selected(self): sel = self.family_list.curselection() if sel: index = string.atoi(sel[0]) self.font_family = self.families[index] self.update_from_family(set_view = 0) def attr_selected(self): sel = self.font_attr_list.curselection() if sel: index = string.atoi(sel[0]) self.font_attr = self.font_attrs[index] self.update_sample() def size_selected(self): sel = self.size_list.curselection() if sel: self.var_size.set(self.size_list.get(sel[0])) def apply_size(self, *args): if self.can_apply(): size = self.var_size.get() self.document.CallObjectMethod(text.CommonText, _("Set Font Size %.1f") % size, 'SetFontSize', size) def save_prefs(self): StylePropertyPanel.save_prefs(self) config.preferences.sample_text = self.sample_text.get()
class FakeDeviceApp(Frame): MIN_X = 0 MAX_X = 50 MIN_Y = 0 MAX_Y = 100 MIN_Z = 0 MAX_Z = 200 def __init__(self, parent): Frame.__init__(self, parent, background='white') self.parent = parent self.init_ui() def init_ui(self): self.parent.title('Fake Device') self.style = Style() self.style.theme_use('default') self.pack(fill=BOTH, expand=1) x_scale = Scale(self, from_=self.MIN_X, to=self.MAX_X, command=self.on_scale_x) x_scale.place(x=0, y=0) y_scale = Scale(self, from_=self.MIN_Y, to=self.MAX_Y, command=self.on_scale_y) y_scale.place(x=0, y=20) z_scale = Scale(self, from_=self.MIN_Z, to=self.MAX_Z, command=self.on_scale_z) z_scale.place(x=0, y=40) angle_scale = Scale(self, from_=0, to=math.pi/2, command=self.on_scale_angle) angle_scale.place(x=0, y=80) self.x_var = IntVar() self.x_label = Label(self, text=0, textvariable=self.x_var) self.x_label.place(x=100, y=0) self.y_var = IntVar() self.y_label = Label(self, text=0, textvariable=self.y_var) self.y_label.place(x=100, y=20) self.z_var = IntVar() self.z_label = Label(self, text=0, textvariable=self.z_var) self.z_label.place(x=100, y=40) self.angle_var = DoubleVar() self.angle_label = Label(self, text=0, textvariable=self.angle_var) self.angle_label.place(x=100, y=80) self.button = Button(self, text='test', command=self.on_button) self.button.place(x=0, y=100) def on_button(self): print('hello') def on_scale_angle(self, val): v = float(val) self.angle_var.set(v) self.update() def on_scale_x(self, val): v = int(float(val)) self.x_var.set(v) self.update() def on_scale_y(self, val): v = int(float(val)) self.y_var.set(v) self.update() def on_scale_z(self, val): v = int(float(val)) self.z_var.set(v) self.update() def update(self): x = self.x_var.get() y = self.y_var.get() z = self.z_var.get() angle = self.angle_var.get() sensor = events.sensor_storage sensor.reset() if not (x == 0 and y == 0 and z == 0): index_pos = [x, y, z] sensor.index_finger_pos = index_pos sensor.cmd_angle = angle
class RotatePanel(PluginPanel): name = 'Rotate' title = _("Rotate") def init(self, master): PluginPanel.init(self, master) root = self.mw.root self.var_angle = DoubleVar(root) self.var_angle.set(0) self.var_width_number = DoubleVar(root) self.var_height_number = DoubleVar(root) self.var_width_base = DoubleVar(root) self.var_height_base = DoubleVar(root) self.cnt_x_absolute = None self.cnt_y_absolute = None var_width_unit = StringVar(root) var_height_unit = StringVar(root) unit = config.preferences.default_unit self.var_width = LengthVar(10, unit, self.var_width_number, var_width_unit) self.var_height = LengthVar(10, unit, self.var_height_number, var_height_unit) jump = config.preferences.default_unit_jump self.var_width.set(0) self.var_height.set(0) self.var_width_base.set(0) self.var_height_base.set(0) self.var_position = StringVar(root) self.var_position.set(ABSOLUTE) self.var_basepoint = StringVar(root) self.var_basepoint.set('C') #--------------------------------------------------------- top = TFrame(self.panel, style='FlatFrame') top.pack(side=TOP, fill=BOTH) #--------------------------------------------------------- angle_frame = TFrame(top, style='FlatFrame', borderwidth=3) angle_frame.pack(side=TOP, fill=BOTH) label = TLabel(angle_frame, style='FlatLabel', text=" " + _("Angle:") + " ") label.pack(side=LEFT, padx=5) self.entry_angle = TSpinbox(angle_frame, var=0, vartype=1, textvariable=self.var_angle, min=-360, max=360, step=5, width=6, command=self.apply_rotate) self.entry_angle.pack(side=LEFT, anchor=E) label = TLabel(angle_frame, style='FlatLabel', text=_("deg")) label.pack(side=LEFT, padx=5) #--------------------------------------------------------- label = TLabel(top, style='FlatLabel', text=_("Center:")) label.pack(side=TOP, fill=BOTH, padx=5) #--------------------------------------------------------- # Horisontal size_frameH = TFrame(top, style='FlatFrame', borderwidth=3) size_frameH.pack(side=TOP, fill=BOTH) label = TLabel(size_frameH, style='FlatLabel', image='center_h') label.pack(side=LEFT, padx=5) self.entry_width = TSpinbox(size_frameH, var=0, vartype=1, textvariable=self.var_width_number, min=-50000, max=50000, step=jump, width=10, command=self.apply_rotate) self.entry_width.pack(side=LEFT) self.labelwunit = TLabel(size_frameH, style='FlatLabel', text=self.var_width.unit) self.labelwunit.pack(side=LEFT, padx=5) #--------------------------------------------------------- # Vertical size_frameV = TFrame(top, style='FlatFrame', borderwidth=3) size_frameV.pack(side=TOP, fill=BOTH) label = TLabel(size_frameV, style='FlatLabel', image='center_v') label.pack(side=LEFT, padx=5) self.entry_height = TSpinbox(size_frameV, var=0, vartype=1, textvariable=self.var_height_number, min=-50000, max=50000, step=jump, width=10, command=self.apply_rotate) self.entry_height.pack(side=LEFT) self.labelhunit = TLabel(size_frameV, style='FlatLabel', text=self.var_height.unit) self.labelhunit.pack(side=LEFT, padx=5) #--------------------------------------------------------- # position chek self.position_check = TCheckbutton(top, text=_("Absolute Center"), variable=self.var_position, onvalue=ABSOLUTE, offvalue=RELATIVE, command=self.position) self.position_check.pack(side=TOP, anchor=W, padx=5, pady=5) #--------------------------------------------------------- # Basepoint check label = TLabel(top, style='FlatLabel', text=_("Basepoint:")) label.pack(side=TOP, fill=BOTH, padx=5) basepoint_frame = TLabelframe(top, labelwidget=label, style='Labelframe', borderwidth=4) basepoint_frame.pack(side=TOP, fill=X, padx=5, pady=2) self.Basepoint = BasePointSelector(basepoint_frame, anchor=self.var_basepoint, command=self.apply_basepoint) self.Basepoint.pack(side=LEFT, fill=BOTH, padx=5) label = TLabel(basepoint_frame, style='FlatLabel', image='coordinate_deg') label.pack(side=LEFT, fill=BOTH, padx=10) self.position_check.pack(side=TOP, anchor=W, padx=5, pady=5) #--------------------------------------------------------- # Button frame button_frame = TFrame(top, style='FlatFrame', borderwidth=5) button_frame.pack(side=BOTTOM, fill=BOTH) self.update_buttons = [] self.button = UpdatedButton(top, text=_("Apply"), command=self.apply_rotate) self.button.pack(in_=button_frame, side=BOTTOM, expand=1, fill=X, pady=3) self.button_copy = UpdatedButton(top, text=_("Apply to Copy"), command=self.apply_to_copy) self.button_copy.pack(in_=button_frame, side=BOTTOM, expand=1, fill=X) self.init_from_doc() self.subscribe_receivers() ############################################################################### def subscribe_receivers(self): self.document.Subscribe(SELECTION, self.Update) self.document.Subscribe(EDITED, self.update_var) config.preferences.Subscribe(CHANGED, self.update_pref) def unsubscribe_receivers(self): self.document.Unsubscribe(SELECTION, self.Update) self.document.Unsubscribe(EDITED, self.update_var) config.preferences.Unsubscribe(CHANGED, self.update_pref) def init_from_doc(self, *arg): self.Update() def Update(self, *arg): if self.is_selection(): self.entry_angle.set_state(NORMAL) self.entry_width.set_state(NORMAL) self.entry_height.set_state(NORMAL) self.position_check['state'] = NORMAL self.button['state'] = NORMAL self.button_copy['state'] = NORMAL self.TestBasepoint() else: self.entry_angle.set_state(DISABLED) self.entry_width.set_state(DISABLED) self.entry_height.set_state(DISABLED) self.position_check['state'] = DISABLED self.button['state'] = DISABLED self.button_copy['state'] = DISABLED self.update_pref() def apply_basepoint(self): self.update_var() def position(self): self.update_var() def RotateSelected(self, angle, cnt=None): text = _("Rotation") if self.document.selection: self.document.begin_transaction(text) try: try: if cnt is None: cnt = self.document.selection.coord_rect.center() angle = angle * degrees trafo = Rotation(angle, cnt) self.document.TransformSelected(trafo, text) except: self.document.abort_transaction() finally: self.document.end_transaction() def RotateAndCopy(self, angle, cnt=None): text = _("Rotation&Copy") if self.document.selection: self.document.begin_transaction(text) try: try: if cnt is None: cnt = self.document.selection.coord_rect.center() angle = angle * degrees trafo = Rotation(angle, cnt) self.document.ApplyToDuplicate() self.document.TransformSelected(trafo, text) except: self.document.abort_transaction() finally: self.document.end_transaction() def apply_rotate(self, *arg): if self.button["state"] == DISABLED: return try: var_x = self.var_width.get() var_y = self.var_height.get() var_a = self.var_angle.get() except: return if var_a < 0: if var_a < -360: var_a += int(var_a / 360) * 360 var_a += 360 if self.var_basepoint.get() != 'USER': self.cnt_x_absolute, self.cnt_y_absolute = self.coordinates( ABSOLUTE) self.var_basepoint.set('USER') if self.var_width_base != var_x or self.var_height_base != var_y: if self.var_position.get() == ABSOLUTE: self.cnt_x_absolute = var_x self.cnt_y_absolute = var_y else: x, y = self.coordinates(ABSOLUTE, 'C') self.cnt_x_absolute = var_x + x self.cnt_y_absolute = var_y + y self.var_basepoint.set('USER') if arg and arg[0] == 'Duplicate': self.RotateAndCopy(var_a, Point(self.cnt_x_absolute, self.cnt_y_absolute)) else: self.RotateSelected( var_a, Point(self.cnt_x_absolute, self.cnt_y_absolute)) def apply_to_copy(self): self.apply_rotate('Duplicate') def coordinates(self, position, anchor=None): br = self.document.selection.coord_rect hor_sel = br.right - br.left ver_sel = br.top - br.bottom if position == RELATIVE: left, bottom = -hor_sel / 2.0, -ver_sel / 2.0 else: left, bottom = br.left, br.bottom cnt_x, cnt_y = self.Basepoint.get_basepoint(hor_sel, ver_sel, left, bottom, anchor) return cnt_x, cnt_y def TestBasepoint(self): if self.cnt_x_absolute is None: return base = ['C', 'NW', 'N', 'NE', 'W', 'E', 'SW', 'S', 'SE'] for b in xrange(len(base)): cnt_x, cnt_y = self.coordinates(ABSOLUTE, base[b]) if round(cnt_x,2) == round(self.cnt_x_absolute,2) and \ round(cnt_y,2) == round(self.cnt_y_absolute,2): self.var_basepoint.set(base[b]) return self.var_basepoint.set('USER') def update_pref(self, *arg): self.labelwunit['text'] = config.preferences.default_unit self.labelhunit['text'] = config.preferences.default_unit self.entry_width.step = config.preferences.default_unit_jump self.entry_height.step = config.preferences.default_unit_jump self.update_var() def update_var(self, *arg): if len(self.document.selection.GetInfo()): self.var_width.unit = config.preferences.default_unit self.var_height.unit = config.preferences.default_unit if self.var_basepoint.get() == 'USER': if self.var_position.get() == ABSOLUTE: self.var_width.set(self.cnt_x_absolute) self.var_height.set(self.cnt_y_absolute) else: x, y = self.coordinates(ABSOLUTE, 'C') self.var_width.set(self.cnt_x_absolute - x) self.var_height.set(self.cnt_y_absolute - y) else: x, y = self.coordinates(self.var_position.get()) self.var_width.set(x) self.var_height.set(y) self.var_width_base = self.var_width.get() self.var_height_base = self.var_height.get() def is_selection(self): return (len(self.document.selection) > 0)
def test_invalid_value(self): v = DoubleVar(self.root, name="name") self.root.globalsetvar("name", "value") with self.assertRaises(ValueError): v.get()
class wm_seg: """ Simple GUI application If the application inside a container, automatic updates are removed. The application uses two frames (tabs): - training - testing """ def __init__(self, master, container): self.master = master master.title("nicMSlesions") # running on a container self.container = container # gui attributes self.path = os.getcwd() self.default_config = None self.user_config = None self.current_folder = os.getcwd() self.list_train_pretrained_nets = [] self.list_test_nets = [] self.version = __version__ if self.container is False: # version_number self.commit_version = subprocess.check_output( ['git', 'rev-parse', 'HEAD']) # queue and thread parameters. All processes are embedded # inside threads to avoid freezing the application self.train_task = None self.test_task = None self.test_queue = Queue.Queue() self.train_queue = Queue.Queue() # -------------------------------------------------- # parameters. Mostly from the config/*.cfg files # -------------------------------------------------- # data parameters self.param_training_folder = StringVar() self.param_test_folder = StringVar() self.param_FLAIR_tag = StringVar() self.param_T1_tag = StringVar() self.param_MOD3_tag = StringVar() self.param_MOD4_tag = StringVar() self.param_mask_tag = StringVar() self.param_model_tag = StringVar() self.param_register_modalities = BooleanVar() self.param_skull_stripping = BooleanVar() self.param_denoise = BooleanVar() self.param_denoise_iter = IntVar() self.param_save_tmp = BooleanVar() self.param_debug = BooleanVar() # train parameters self.param_net_folder = os.path.join(self.current_folder, 'nets') self.param_use_pretrained_model = BooleanVar() self.param_pretrained_model = StringVar() self.param_inference_model = StringVar() self.param_num_layers = IntVar() self.param_net_name = StringVar() self.param_net_name.set('None') self.param_balanced_dataset = StringVar() self.param_fract_negatives = DoubleVar() # model parameters self.param_pretrained = None self.param_min_th = DoubleVar() self.param_patch_size = IntVar() self.param_weight_paths = StringVar() self.param_load_weights = BooleanVar() self.param_train_split = DoubleVar() self.param_max_epochs = IntVar() self.param_patience = IntVar() self.param_batch_size = IntVar() self.param_net_verbose = IntVar() self.param_t_bin = DoubleVar() self.param_l_min = IntVar() self.param_min_error = DoubleVar() self.param_mode = BooleanVar() self.param_gpu_number = IntVar() # load the default configuration from the conf file self.load_default_configuration() # self frame (tabbed notebook) self.note = Notebook(self.master) self.note.pack() os.system('cls' if platform.system() == 'Windows' else 'clear') print "##################################################" print "# ------------ #" print "# nicMSlesions #" print "# ------------ #" print "# MS WM lesion segmentation #" print "# #" print "# ------------------------------- #" print "# (c) Sergi Valverde 2018 #" print "# Neuroimage Computing Group #" print "# ------------------------------- #" print "##################################################\n" print "Please select options for training or inference in the menu..." # -------------------------------------------------- # training tab # -------------------------------------------------- self.train_frame = Frame() self.note.add(self.train_frame, text="Training") self.test_frame = Frame() self.note.add(self.test_frame, text="Inference") # label frames cl_s = 5 self.tr_frame = LabelFrame(self.train_frame, text="Training images:") self.tr_frame.grid(row=0, columnspan=cl_s, sticky='WE', padx=5, pady=5, ipadx=5, ipady=5) self.model_frame = LabelFrame(self.train_frame, text="CNN model:") self.model_frame.grid(row=5, columnspan=cl_s, sticky='WE', padx=5, pady=5, ipadx=5, ipady=5) # training options self.inFolderLbl = Label(self.tr_frame, text="Training folder:") self.inFolderLbl.grid(row=0, column=0, sticky='E', padx=5, pady=2) self.inFolderTxt = Entry(self.tr_frame) self.inFolderTxt.grid(row=0, column=1, columnspan=5, sticky="W", pady=3) self.inFileBtn = Button(self.tr_frame, text="Browse ...", command=self.load_training_path) self.inFileBtn.grid(row=0, column=5, columnspan=1, sticky='W', padx=5, pady=1) self.optionsBtn = Button(self.tr_frame, text="Other options", command=self.parameter_window) self.optionsBtn.grid(row=0, column=10, columnspan=1, sticky="W", padx=(100, 1), pady=1) # setting input modalities: FLAIR + T1 are mandatory # Mod 3 / 4 are optional self.flairTagLbl = Label(self.tr_frame, text="FLAIR tag:") self.flairTagLbl.grid(row=1, column=0, sticky='E', padx=5, pady=2) self.flairTxt = Entry(self.tr_frame, textvariable=self.param_FLAIR_tag) self.flairTxt.grid(row=1, column=1, columnspan=1, sticky="W", pady=1) self.t1TagLbl = Label(self.tr_frame, text="T1 tag:") self.t1TagLbl.grid(row=2, column=0, sticky='E', padx=5, pady=2) self.t1Txt = Entry(self.tr_frame, textvariable=self.param_T1_tag) self.t1Txt.grid(row=2, column=1, columnspan=1, sticky="W", pady=1) self.mod3TagLbl = Label(self.tr_frame, text="mod 3 tag:") self.mod3TagLbl.grid(row=3, column=0, sticky='E', padx=5, pady=2) self.mod3Txt = Entry(self.tr_frame, textvariable=self.param_MOD3_tag) self.mod3Txt.grid(row=3, column=1, columnspan=1, sticky="W", pady=1) self.mod4TagLbl = Label(self.tr_frame, text="mod 4 tag:") self.mod4TagLbl.grid(row=4, column=0, sticky='E', padx=5, pady=2) self.mod4Txt = Entry(self.tr_frame, textvariable=self.param_MOD4_tag) self.mod4Txt.grid(row=4, column=1, columnspan=1, sticky="W", pady=1) self.maskTagLbl = Label(self.tr_frame, text="MASK tag:") self.maskTagLbl.grid(row=5, column=0, sticky='E', padx=5, pady=2) self.maskTxt = Entry(self.tr_frame, textvariable=self.param_mask_tag) self.maskTxt.grid(row=5, column=1, columnspan=1, sticky="W", pady=1) # model options self.modelTagLbl = Label(self.model_frame, text="Model name:") self.modelTagLbl.grid(row=6, column=0, sticky='E', padx=5, pady=2) self.modelTxt = Entry(self.model_frame, textvariable=self.param_net_name) self.modelTxt.grid(row=6, column=1, columnspan=1, sticky="W", pady=1) self.checkPretrain = Checkbutton(self.model_frame, text="use pretrained", var=self.param_use_pretrained_model) self.checkPretrain.grid(row=6, column=3, padx=5, pady=5) self.update_pretrained_nets() self.pretrainTxt = OptionMenu(self.model_frame, self.param_pretrained_model, *self.list_train_pretrained_nets) self.pretrainTxt.grid(row=6, column=5, sticky='E', padx=5, pady=5) # START button links self.trainingBtn = Button(self.train_frame, state='disabled', text="Start training", command=self.train_net) self.trainingBtn.grid(row=7, column=0, sticky='W', padx=1, pady=1) # -------------------------------------------------- # inference tab # -------------------------------------------------- self.tt_frame = LabelFrame(self.test_frame, text="Inference images:") self.tt_frame.grid(row=0, columnspan=cl_s, sticky='WE', padx=5, pady=5, ipadx=5, ipady=5) self.test_model_frame = LabelFrame(self.test_frame, text="CNN model:") self.test_model_frame.grid(row=5, columnspan=cl_s, sticky='WE', padx=5, pady=5, ipadx=5, ipady=5) # testing options self.test_inFolderLbl = Label(self.tt_frame, text="Testing folder:") self.test_inFolderLbl.grid(row=0, column=0, sticky='E', padx=5, pady=2) self.test_inFolderTxt = Entry(self.tt_frame) self.test_inFolderTxt.grid(row=0, column=1, columnspan=5, sticky="W", pady=3) self.test_inFileBtn = Button(self.tt_frame, text="Browse ...", command=self.load_testing_path) self.test_inFileBtn.grid(row=0, column=5, columnspan=1, sticky='W', padx=5, pady=1) self.test_optionsBtn = Button(self.tt_frame, text="Other options", command=self.parameter_window) self.test_optionsBtn.grid(row=0, column=10, columnspan=1, sticky="W", padx=(100, 1), pady=1) self.test_flairTagLbl = Label(self.tt_frame, text="FLAIR tag:") self.test_flairTagLbl.grid(row=1, column=0, sticky='E', padx=5, pady=2) self.test_flairTxt = Entry(self.tt_frame, textvariable=self.param_FLAIR_tag) self.test_flairTxt.grid(row=1, column=1, columnspan=1, sticky="W", pady=1) self.test_t1TagLbl = Label(self.tt_frame, text="T1 tag:") self.test_t1TagLbl.grid(row=2, column=0, sticky='E', padx=5, pady=2) self.test_t1Txt = Entry(self.tt_frame, textvariable=self.param_T1_tag) self.test_t1Txt.grid(row=2, column=1, columnspan=1, sticky="W", pady=1) self.test_mod3TagLbl = Label(self.tt_frame, text="mod 3 tag:") self.test_mod3TagLbl.grid(row=3, column=0, sticky='E', padx=5, pady=2) self.test_mod3Txt = Entry(self.tt_frame, textvariable=self.param_MOD3_tag) self.test_mod3Txt.grid(row=3, column=1, columnspan=1, sticky="W", pady=1) self.test_mod4TagLbl = Label(self.tt_frame, text="mod 4 tag:") self.test_mod4TagLbl.grid(row=4, column=0, sticky='E', padx=5, pady=2) self.test_mod4Txt = Entry(self.tt_frame, textvariable=self.param_MOD4_tag) self.test_mod4Txt.grid(row=4, column=1, columnspan=1, sticky="W", pady=1) self.test_pretrainTxt = OptionMenu(self.test_model_frame, self.param_inference_model, *self.list_test_nets) self.param_inference_model.set('None') self.test_pretrainTxt.grid(row=5, column=0, sticky='E', padx=5, pady=5) # START button links cto docker task self.inferenceBtn = Button(self.test_frame, state='disabled', text="Start inference", command=self.infer_segmentation) self.inferenceBtn.grid(row=7, column=0, sticky='W', padx=1, pady=1) # train / test ABOUT button self.train_aboutBtn = Button(self.train_frame, text="about", command=self.about_window) self.train_aboutBtn.grid(row=7, column=4, sticky='E', padx=(1, 1), pady=1) self.test_aboutBtn = Button(self.test_frame, text="about", command=self.about_window) self.test_aboutBtn.grid(row=7, column=4, sticky='E', padx=(1, 1), pady=1) # Processing state self.process_indicator = StringVar() self.process_indicator.set(' ') self.label_indicator = Label(master, textvariable=self.process_indicator) self.label_indicator.pack(side="left") # Closing processing events is implemented via # a master protocol self.master.protocol("WM_DELETE_WINDOW", self.close_event) def parameter_window(self): """ Setting other parameters using an emerging window CNN parameters, CUDA device, post-processing.... """ t = Toplevel(self.master) t.wm_title("Other parameters") # data parameters t_data = LabelFrame(t, text="data options:") t_data.grid(row=0, sticky="WE") checkPretrain = Checkbutton(t_data, text="Register modalities", var=self.param_register_modalities) checkPretrain.grid(row=0, sticky='W') checkSkull = Checkbutton(t_data, text="Skull-strip modalities", var=self.param_skull_stripping) checkSkull.grid(row=1, sticky="W") checkDenoise = Checkbutton(t_data, text="Denoise masks", var=self.param_denoise) checkDenoise.grid(row=2, sticky="W") denoise_iter_label = Label(t_data, text=" Denoise iter: ") denoise_iter_label.grid(row=3, sticky="W") denoise_iter_entry = Entry(t_data, textvariable=self.param_denoise_iter) denoise_iter_entry.grid(row=3, column=1, sticky="E") check_tmp = Checkbutton(t_data, text="Save tmp files", var=self.param_save_tmp) check_tmp.grid(row=4, sticky="W") checkdebug = Checkbutton(t_data, text="Debug mode", var=self.param_debug) checkdebug.grid(row=5, sticky="W") # model parameters t_model = LabelFrame(t, text="Model:") t_model.grid(row=5, sticky="EW") maxepochs_label = Label(t_model, text="Max epochs: ") maxepochs_label.grid(row=6, sticky="W") maxepochs_entry = Entry(t_model, textvariable=self.param_max_epochs) maxepochs_entry.grid(row=6, column=1, sticky="E") trainsplit_label = Label(t_model, text="Validation %: ") trainsplit_label.grid(row=7, sticky="W") trainsplit_entry = Entry(t_model, textvariable=self.param_train_split) trainsplit_entry.grid(row=7, column=1, sticky="E") batchsize_label = Label(t_model, text="Test batch size:") batchsize_label.grid(row=8, sticky="W") batchsize_entry = Entry(t_model, textvariable=self.param_batch_size) batchsize_entry.grid(row=8, column=1, sticky="E") mode_label = Label(t_model, text="Verbosity:") mode_label.grid(row=9, sticky="W") mode_entry = Entry(t_model, textvariable=self.param_net_verbose) mode_entry.grid(row=9, column=1, sticky="E") #gpu_mode = Checkbutton(t_model, # text="GPU:", # var=self.param_mode) #gpu_mode.grid(row=10, sticky="W") gpu_number = Label(t_model, text="GPU number:") gpu_number.grid(row=10, sticky="W") gpu_entry = Entry(t_model, textvariable=self.param_gpu_number) gpu_entry.grid(row=10, column=1, sticky="W") # training parameters tr_model = LabelFrame(t, text="Training:") tr_model.grid(row=12, sticky="EW") balanced_label = Label(tr_model, text="Balanced dataset: ") balanced_label.grid(row=13, sticky="W") balanced_entry = Entry(tr_model, textvariable=self.param_balanced_dataset) balanced_entry.grid(row=13, column=1, sticky="E") fraction_label = Label(tr_model, text="Fraction negative/positives: ") fraction_label.grid(row=14, sticky="W") fraction_entry = Entry(tr_model, textvariable=self.param_fract_negatives) fraction_entry.grid(row=14, column=1, sticky="E") # postprocessing parameters t_post = LabelFrame(t, text="Post-processing: ") t_post.grid(row=15, sticky="EW") t_bin_label = Label(t_post, text="Out probability th: ") t_bin_label.grid(row=16, sticky="W") t_bin_entry = Entry(t_post, textvariable=self.param_t_bin) t_bin_entry.grid(row=16, column=1, sticky="E") l_min_label = Label(t_post, text="Min out region size: ") l_min_label.grid(row=17, sticky="W") l_min_entry = Entry(t_post, textvariable=self.param_l_min) l_min_entry.grid(row=17, column=1, sticky="E") vol_min_label = Label(t_post, text="Min vol error (ml): ") vol_min_label.grid(row=18, sticky="W") vol_min_entry = Entry(t_post, textvariable=self.param_min_error) vol_min_entry.grid(row=18, column=1, sticky="E") def load_default_configuration(self): """ load the default configuration from /config/default.cfg This method assign each of the configuration parameters to class attributes """ default_config = ConfigParser.SafeConfigParser() default_config.read(os.path.join(self.path, 'config', 'default.cfg')) # dastaset parameters self.param_training_folder.set( default_config.get('database', 'train_folder')) self.param_test_folder.set( default_config.get('database', 'inference_folder')) self.param_FLAIR_tag.set(default_config.get('database', 'flair_tags')) self.param_T1_tag.set(default_config.get('database', 't1_tags')) self.param_MOD3_tag.set(default_config.get('database', 'mod3_tags')) self.param_MOD4_tag.set(default_config.get('database', 'mod4_tags')) self.param_mask_tag.set(default_config.get('database', 'roi_tags')) self.param_register_modalities.set( default_config.get('database', 'register_modalities')) self.param_denoise.set(default_config.get('database', 'denoise')) self.param_denoise_iter.set( default_config.getint('database', 'denoise_iter')) self.param_skull_stripping.set( default_config.get('database', 'skull_stripping')) self.param_save_tmp.set(default_config.get('database', 'save_tmp')) self.param_debug.set(default_config.get('database', 'debug')) # train parameters self.param_use_pretrained_model.set( default_config.get('train', 'full_train')) self.param_pretrained_model.set( default_config.get('train', 'pretrained_model')) self.param_inference_model.set(" ") self.param_balanced_dataset.set( default_config.get('train', 'balanced_training')) self.param_fract_negatives.set( default_config.getfloat('train', 'fraction_negatives')) # model parameters self.param_net_folder = os.path.join(self.current_folder, 'nets') self.param_net_name.set(default_config.get('model', 'name')) self.param_train_split.set( default_config.getfloat('model', 'train_split')) self.param_max_epochs.set(default_config.getint('model', 'max_epochs')) self.param_patience.set(default_config.getint('model', 'patience')) self.param_batch_size.set(default_config.getint('model', 'batch_size')) self.param_net_verbose.set(default_config.get('model', 'net_verbose')) self.param_gpu_number.set(default_config.getint('model', 'gpu_number')) # self.param_mode.set(default_config.get('model', 'gpu_mode')) # post-processing self.param_l_min.set(default_config.getint('postprocessing', 'l_min')) self.param_t_bin.set(default_config.getfloat('postprocessing', 't_bin')) self.param_min_error.set( default_config.getfloat('postprocessing', 'min_error')) def write_user_configuration(self): """ write the configuration into config/configuration.cfg """ user_config = ConfigParser.RawConfigParser() # dataset parameters user_config.add_section('database') user_config.set('database', 'train_folder', self.param_training_folder.get()) user_config.set('database', 'inference_folder', self.param_test_folder.get()) user_config.set('database', 'flair_tags', self.param_FLAIR_tag.get()) user_config.set('database', 't1_tags', self.param_T1_tag.get()) user_config.set('database', 'mod3_tags', self.param_MOD3_tag.get()) user_config.set('database', 'mod4_tags', self.param_MOD4_tag.get()) user_config.set('database', 'roi_tags', self.param_mask_tag.get()) user_config.set('database', 'register_modalities', self.param_register_modalities.get()) user_config.set('database', 'denoise', self.param_denoise.get()) user_config.set('database', 'denoise_iter', self.param_denoise_iter.get()) user_config.set('database', 'skull_stripping', self.param_skull_stripping.get()) user_config.set('database', 'save_tmp', self.param_save_tmp.get()) user_config.set('database', 'debug', self.param_debug.get()) # train parameters user_config.add_section('train') user_config.set('train', 'full_train', not (self.param_use_pretrained_model.get())) user_config.set('train', 'pretrained_model', self.param_pretrained_model.get()) user_config.set('train', 'balanced_training', self.param_balanced_dataset.get()) user_config.set('train', 'fraction_negatives', self.param_fract_negatives.get()) # model parameters user_config.add_section('model') user_config.set('model', 'name', self.param_net_name.get()) user_config.set('model', 'pretrained', self.param_pretrained) user_config.set('model', 'train_split', self.param_train_split.get()) user_config.set('model', 'max_epochs', self.param_max_epochs.get()) user_config.set('model', 'patience', self.param_patience.get()) user_config.set('model', 'batch_size', self.param_batch_size.get()) user_config.set('model', 'net_verbose', self.param_net_verbose.get()) # user_config.set('model', 'gpu_mode', self.param_mode.get()) user_config.set('model', 'gpu_number', self.param_gpu_number.get()) # postprocessing parameters user_config.add_section('postprocessing') user_config.set('postprocessing', 't_bin', self.param_t_bin.get()) user_config.set('postprocessing', 'l_min', self.param_l_min.get()) user_config.set('postprocessing', 'min_error', self.param_min_error.get()) # Writing our configuration file to 'example.cfg' with open(os.path.join(self.path, 'config', 'configuration.cfg'), 'wb') as configfile: user_config.write(configfile) def load_training_path(self): """ Select training path from disk and write it. If the app is run inside a container, link the iniitaldir with /data """ initialdir = '/data' if self.container else os.getcwd() fname = askdirectory(initialdir=initialdir) if fname: try: self.param_training_folder.set(fname) self.inFolderTxt.delete(0, END) self.inFolderTxt.insert(0, self.param_training_folder.get()) self.trainingBtn['state'] = 'normal' except: pass def load_testing_path(self): """ Selecet the inference path from disk and write it If the app is run inside a container, link the iniitaldir with /data """ initialdir = '/data' if self.container else os.getcwd() fname = askdirectory(initialdir=initialdir) if fname: try: self.param_test_folder.set(fname) self.test_inFolderTxt.delete(0, END) self.test_inFolderTxt.insert(0, self.param_test_folder.get()) self.inferenceBtn['state'] = 'normal' except: pass def update_pretrained_nets(self): """ get a list of the different net configuration present in the system. Each model configuration is represented by a folder containing the network weights for each of the networks. The baseline net config is always included by default """ folders = os.listdir(self.param_net_folder) self.list_train_pretrained_nets = folders self.list_test_nets = folders def write_to_console(self, txt): """ to doc: important method """ self.command_out.insert(END, str(txt)) def write_to_test_console(self, txt): """ to doc: important method """ self.test_command_out.insert(END, str(txt)) def infer_segmentation(self): """ Method implementing the inference process: - Check network selection - write the configuration to disk - Run the process on a new thread """ if self.param_inference_model.get() == 'None': print "ERROR: Please, select a network model before starting...\n" return if self.test_task is None: self.inferenceBtn.config(state='disabled') self.param_net_name.set(self.param_inference_model.get()) self.param_use_pretrained_model.set(False) self.write_user_configuration() print "\n-----------------------" print "Running configuration:" print "-----------------------" print "Inference model:", self.param_model_tag.get() print "Inference folder:", self.param_test_folder.get(), "\n" print "Method info:" print "------------" self.test_task = ThreadedTask(self.write_to_test_console, self.test_queue, mode='testing') self.test_task.start() self.master.after(100, self.process_container_queue) def train_net(self): """ Method implementing the training process: - write the configuration to disk - Run the process on a new thread """ if self.param_net_name.get() == 'None': print "ERROR: Please, define network name before starting...\n" return self.trainingBtn['state'] = 'disable' if self.train_task is None: self.trainingBtn.update() self.write_user_configuration() print "\n-----------------------" print "Running configuration:" print "-----------------------" print "Train model:", self.param_net_name.get() print "Training folder:", self.param_training_folder.get(), "\n" print "Method info:" print "------------" self.train_task = ThreadedTask(self.write_to_console, self.test_queue, mode='training') self.train_task.start() self.master.after(100, self.process_container_queue) def check_update(self): """ check update version and propose to download it if differnt So far, a rudimentary mode is used to check the last version. """ # I have to discard possible local changes :( print "---------------------------------------" print "Updating software" print "current version:", self.commit_version remote_commit = subprocess.check_output(['git', 'stash']) remote_commit = subprocess.check_output(['git', 'fetch']) remote_commit = subprocess.check_output( ['git', 'rev-parse', 'origin/master']) if remote_commit != self.commit_version: proc = subprocess.check_output(['git', 'pull', 'origin', 'master']) self.check_link.config(text="Updated") self.commit_version = remote_commit print "updated version:", self.commit_version else: print "This software is already in the latest version" print "---------------------------------------" def about_window(self): """ Window showing information about the software and version number, including auto-update. If the application is run from a container, then auto-update is disabled """ def callback(event): """ open webbrowser when clicking links """ webbrowser.open_new(event.widget.cget("text")) # main window t = Toplevel(self.master, width=500, height=500) t.wm_title("About") # NIC logo + name title = Label(t, text="nicMSlesions v" + self.version + "\n" "Multiple Sclerosis White Matter Lesion Segmentation") title.grid(row=2, column=1, padx=20, pady=10) img = ImageTk.PhotoImage(Image.open('./logonic.png')) imglabel = Label(t, image=img) imglabel.image = img imglabel.grid(row=1, column=1, padx=10, pady=10) group_name = Label(t, text="Copyright Sergi Valverde (2018-) \n " + "NeuroImage Computing Group") group_name.grid(row=3, column=1) group_link = Label(t, text=r"http://atc.udg.edu/nic", fg="blue", cursor="hand2") group_link.grid(row=4, column=1) group_link.bind("<Button-1>", callback) license_content = "Licensed under the BSD 2-Clause license. \n" + \ "A copy of the license is present in the root directory." license_label = Label(t, text=license_content) license_label.grid(row=5, column=1, padx=20, pady=20) # if self.container is False: # # check version and updates # version_number = Label(t, text="commit: " + self.commit_version) # version_number.grid(row=6, column=1, padx=20, pady=(1, 1)) # # self.check_link = Button(t, # text="Check for updates", # command=self.check_update) # self.check_link.grid(row=7, column=1) def process_container_queue(self): """ Process the threading queue. When the threaded processes are finished, buttons are reset and a message is shown in the app. """ self.process_indicator.set('Running... please wait') try: msg = self.test_queue.get(0) self.process_indicator.set('Done. See log for more details.') self.inferenceBtn['state'] = 'normal' self.trainingBtn['state'] = 'normal' except Queue.Empty: self.master.after(100, self.process_container_queue) def close_event(self): """ Stop the thread processes using OS related calls. """ if self.train_task is not None: self.train_task.stop_process() if self.test_task is not None: self.test_task.stop_process() os.system('cls' if platform.system == "Windows" else 'clear') root.destroy()
class Radio_monitor(object): def __init__(self,the_dic): self.value = DoubleVar() self.title, self.dic,self.func = the_dic def show_info(self): the_value = self.value.get() for each in self.dic: if each.values()[0]==the_value: select = each.keys()[0] text = "{0}\t{1}\t{2}".format(self.title,select,the_value) self.label['text'] = text self.func(text) def add_gui(self,form): self.form = form self.form.row() self.form.col() self.label = self.form.la(text=self.title,bg='SkyBlue',padx=2) self.form.gr(3) for info in self.dic: self.form.rb(text=info.keys()[0], variable=self.value, value=info.values()[0],\ command=self.show_info,indicatoron=1) self.form.endrow() #FFB6C1 LightPink 浅粉红 #FFC0CB Pink 粉红 #DC143C Crimson 深红/猩红 #FFF0F5 LavenderBlush 淡紫红 #DB7093 PaleVioletRed 弱紫罗兰红 #FF69B4 HotPink 热情的粉红 #FF1493 DeepPink 深粉红 #C71585 MediumVioletRed 中紫罗兰红 #DA70D6 Orchid 暗紫色/兰花紫 #D8BFD8 Thistle 蓟色 #DDA0DD Plum 洋李色/李子紫 #EE82EE Violet 紫罗兰 #FF00FF Magenta 洋红/玫瑰红 #FF00FF Fuchsia 紫红/灯笼海棠 #8B008B DarkMagenta 深洋红 #800080 Purple 紫色 #BA55D3 MediumOrchid 中兰花紫 #9400D3 DarkViolet 暗紫罗兰 #9932CC DarkOrchid 暗兰花紫 #4B0082 Indigo 靛青/紫兰色 #8A2BE2 BlueViolet 蓝紫罗兰 #9370DB MediumPurple 中紫色 #7B68EE MediumSlateBlue 中暗蓝色/中板岩蓝 #6A5ACD SlateBlue 石蓝色/板岩蓝 #483D8B DarkSlateBlue 暗灰蓝色/暗板岩蓝 #E6E6FA Lavender 淡紫色/熏衣草淡紫 #F8F8FF GhostWhite 幽灵白 #0000FF Blue 纯蓝 #0000CD MediumBlue 中蓝色 #191970 MidnightBlue 午夜蓝 #00008B DarkBlue 暗蓝色 #000080 Navy 海军蓝 #4169E1 RoyalBlue 皇家蓝/宝蓝 #6495ED CornflowerBlue 矢车菊蓝 #B0C4DE LightSteelBlue 亮钢蓝 #778899 LightSlateGray 亮蓝灰/亮石板灰 #708090 SlateGray 灰石色/石板灰 #1E90FF DodgerBlue 闪兰色/道奇蓝 #F0F8FF AliceBlue 爱丽丝蓝 #4682B4 SteelBlue 钢蓝/铁青 #87CEFA LightSkyBlue 亮天蓝色 #87CEEB SkyBlue 天蓝色 #00BFFF DeepSkyBlue 深天蓝 #ADD8E6 LightBlue 亮蓝 #B0E0E6 PowderBlue 粉蓝色/火药青 #5F9EA0 CadetBlue 军兰色/军服蓝 #F0FFFF Azure 蔚蓝色 #E0FFFF LightCyan 淡青色 #AFEEEE PaleTurquoise 弱绿宝石 #00FFFF Cyan 青色 #00FFFF Aqua 浅绿色/水色 #00CED1 DarkTurquoise 暗绿宝石 #2F4F4F DarkSlateGray 暗瓦灰色/暗石板灰 #008B8B DarkCyan 暗青色 #008080 Teal 水鸭色 #48D1CC MediumTurquoise 中绿宝石 #20B2AA LightSeaGreen 浅海洋绿 #40E0D0 Turquoise 绿宝石 #7FFFD4 Aquamarine 宝石碧绿 #66CDAA MediumAquamarine 中宝石碧绿 #00FA9A MediumSpringGreen 中春绿色 #F5FFFA MintCream 薄荷奶油 #00FF7F SpringGreen 春绿色 #3CB371 MediumSeaGreen 中海洋绿 #2E8B57 SeaGreen 海洋绿 #F0FFF0 Honeydew 蜜色/蜜瓜色 #90EE90 LightGreen 淡绿色 #98FB98 PaleGreen 弱绿色 #8FBC8F DarkSeaGreen 暗海洋绿 #32CD32 LimeGreen 闪光深绿 #00FF00 Lime 闪光绿 #228B22 ForestGreen 森林绿 #008000 Green 纯绿 #006400 DarkGreen 暗绿色 #7FFF00 Chartreuse 黄绿色/查特酒绿 #7CFC00 LawnGreen 草绿色/草坪绿 #ADFF2F GreenYellow 绿黄色 #556B2F DarkOliveGreen 暗橄榄绿 #9ACD32 YellowGreen 黄绿色 #6B8E23 OliveDrab 橄榄褐色 #F5F5DC Beige 米色/灰棕色 #FAFAD2 LightGoldenrodYellow 亮菊黄 #FFFFF0 Ivory 象牙色 #FFFFE0 LightYellow 浅黄色 #FFFF00 Yellow 纯黄 #808000 Olive 橄榄 #BDB76B DarkKhaki 暗黄褐色/深卡叽布 #FFFACD LemonChiffon 柠檬绸 #EEE8AA PaleGoldenrod 灰菊黄/苍麒麟色 #F0E68C Khaki 黄褐色/卡叽布 #FFD700 Gold 金色 #FFF8DC Cornsilk 玉米丝色 #DAA520 Goldenrod 金菊黄 #B8860B DarkGoldenrod 暗金菊黄 #FFFAF0 FloralWhite 花的白色 #FDF5E6 OldLace 老花色/旧蕾丝 #F5DEB3 Wheat 浅黄色/小麦色 #FFE4B5 Moccasin 鹿皮色/鹿皮靴 #FFA500 Orange 橙色 #FFEFD5 PapayaWhip 番木色/番木瓜 #FFEBCD BlanchedAlmond 白杏色 #FFDEAD NavajoWhite 纳瓦白/土著白 #FAEBD7 AntiqueWhite 古董白 #D2B48C Tan 茶色 #DEB887 BurlyWood 硬木色 #FFE4C4 Bisque 陶坯黄 #FF8C00 DarkOrange 深橙色 #FAF0E6 Linen 亚麻布 #CD853F Peru 秘鲁色 #FFDAB9 PeachPuff 桃肉色 #F4A460 SandyBrown 沙棕色 #D2691E Chocolate 巧克力色 #8B4513 SaddleBrown 重褐色/马鞍棕色 #FFF5EE Seashell 海贝壳 #A0522D Sienna 黄土赭色 #FFA07A LightSalmon 浅鲑鱼肉色 #FF7F50 Coral 珊瑚 #FF4500 OrangeRed 橙红色 #E9967A DarkSalmon 深鲜肉/鲑鱼色 #FF6347 Tomato 番茄红 #FFE4E1 MistyRose 浅玫瑰色/薄雾玫瑰 #FA8072 Salmon 鲜肉/鲑鱼色 #FFFAFA Snow 雪白色 #F08080 LightCoral 淡珊瑚色 #BC8F8F RosyBrown 玫瑰棕色 #CD5C5C IndianRed 印度红 #FF0000 Red 纯红 #A52A2A Brown 棕色 #B22222 FireBrick 火砖色/耐火砖 #8B0000 DarkRed 深红色 #800000 Maroon 栗色 #FFFFFF White 纯白 #F5F5F5 WhiteSmoke 白烟 #DCDCDC Gainsboro 淡灰色 #D3D3D3 LightGrey 浅灰色 #C0C0C0 Silver 银灰色 #A9A9A9 DarkGray 深灰色 #808080 Gray 灰色 #696969 DimGray 暗淡灰 #000000 Black 纯黑'''
def test_invalid_value(self): v = DoubleVar(self.root, name='name') self.root.globalsetvar('name', 'value') with self.assertRaises(ValueError): v.get()
def test_default(self): v = DoubleVar(self.root) self.assertEqual(0.0, v.get())
class Example(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent self.initUI() self.centerUI(w=560,h=235) def initUI(self): self.parent.title("DBLR for Dummies") self.pack(fill=BOTH, expand=True) #self.columnconfigure(0, weight=1) #self.rowconfigure(0, weight=1) # weight attibute is used to make them growable self.meas = IntVar() self.point = IntVar() self.base_path = StringVar() self.coef = DoubleVar() self.noise = DoubleVar() self.n_sigma = DoubleVar() self.thr1 = DoubleVar() self.thr2 = DoubleVar() self.thr3 = DoubleVar() self.graph_sw = BooleanVar() #Image factor=0.65 search = Image.open("NEXT_official_logo.jpg") width_org, height_org = search.size search_temp = search.resize((int(width_org*factor), int(height_org*factor)), Image.ANTIALIAS) search_aux = ImageTk.PhotoImage(search_temp) label1 = Label(self, image=search_aux) label1.image = search_aux label1.grid(row=0, column=4, columnspan=2, rowspan=3, padx=5) #self.base_path.set("F:/DATOS_DAC/2052/pmt_0_trace_evt_") self.base_path.set("Argon.h5.z") e1 = Entry(self, textvariable=self.base_path, width=40) e1.grid(row=0,column=1, sticky=W, columnspan=3, pady=5, padx=5) e1_label = Label(self, text="Path & Name") e1_label.grid(row=0,column=0, columnspan=1, sticky=E, pady=5, padx=5) self.point.set("0") sb1 = Spinbox(self, from_=0, to=100, width=4, textvariable=self.point) sb1.grid(row=2,column=1, sticky=W, pady=5, padx=5) sb1_label = Label(self, text="PMT") sb1_label.grid(row=2,column=0, padx=5, sticky=E) self.meas.set("0") sb1 = Spinbox(self, from_=0, to=100, width=4, textvariable=self.meas) sb1.grid(row=2,column=3, sticky=W, pady=5, padx=5) sb1_label = Label(self, text="Event") sb1_label.grid(row=2,column=2, padx=5, sticky=E) #Check buttons # cb1 = Checkbutton(self, text="New Graph", variable=self.graph_sw) # cb1.select() # cb1.grid(row=2,column=2, sticky=W) #PARAMETERS Integration_label = Label(self, text="PARAMETERS", font = "Verdana 12 bold") Integration_label.grid(row=3,column=1, padx=5, columnspan = 2, pady=10, sticky=E) self.coef.set("1.65E-3") e2 = Entry(self, width=12, textvariable=self.coef) e2.grid(row=4,column=1, sticky=W, pady=5, padx=5) e2_label = Label(self, text="DBLR Coef") e2_label.grid(row=4,column=0, sticky=E, pady=5, padx=5) self.noise.set("0.75") e3 = Entry(self, width=12, textvariable=self.noise) e3.grid(row=4,column=3, sticky=W, pady=5, padx=5) e3_label = Label(self, text="Noise (LSB)") e3_label.grid(row=4,column=2, sticky=E, pady=5, padx=5) self.n_sigma.set("4") e4 = Entry(self, width=12, textvariable=self.n_sigma) e4.grid(row=4,column=5, sticky=W, pady=5, padx=5) e4_label = Label(self, text="Noise Threshold") e4_label.grid(row=4,column=4, sticky=E, pady=5, padx=5) self.thr1.set("0") e5 = Entry(self, width=12, textvariable=self.thr1) e5.grid(row=5,column=1, sticky=W, pady=5, padx=5) e5_label = Label(self, text="Threshold 1") e5_label.grid(row=5,column=0, sticky=E, pady=5, padx=5) self.thr2.set("0") e6 = Entry(self, width=12, textvariable=self.thr2) e6.grid(row=5,column=3, sticky=W, pady=5, padx=5) e6_label = Label(self, text="Threshold 2") e6_label.grid(row=5,column=2, sticky=E, pady=5, padx=5) self.thr3.set("0") e7 = Entry(self, width=12, textvariable=self.thr3) e7.grid(row=5,column=5, sticky=W, pady=5, padx=5) e7_label = Label(self, text="Threshold 3") e7_label.grid(row=5,column=4, sticky=E, pady=5, padx=5) # Main buttons obtn = Button(self, text="GO!!", command=self.DBLR_f) obtn.grid(row=6, column=4, sticky=E, pady=10) cbtn = Button(self, text="Quit", command=self.quit) cbtn.grid(row=6, column=5, sticky=E, pady=10) hbtn = Button(self, text="Help", command=self.help_f) hbtn.grid(row=6, column=0, sticky=W, pady=10) def help_f(self): top = Toplevel() top.title("HELP") msg = Message(top, width= 500, text="Noise Threshold (NT) - Noise Based Main Threshold \ (Sigmas)\n Threshold 1 - Main Threshold (LSBs) \n Threshold 2 - End of Pulse Error \n \ Threshold 3 - End of Tail Error \n When Thr1 = Thr3 = 0 their values are defined as: \n \ (THR1 = NT (LSBs) / THR3 = NT*NOISE_ADC / 5)") msg.pack() button = Button(top, text="Close", command=top.destroy) button.pack() def DBLR_f(self): global a #if (self.graph_sw.get()==True): b=a a=a+1 #else: # b=0 aux=self.base_path.get() # path=''.join([aux,str(self.meas.get()),'.txt']) # g=pd.read_csv(path) f=read_panel_hdf5(aux, self.point.get(), self.meas.get()) f=4096-f recons,energia = DB.BLR( signal_daq=f.flatten().astype(float), coef=self.coef.get(), n_sigma=self.n_sigma.get(), NOISE_ADC=self.noise.get(), thr1=self.thr1.get(), thr2=self.thr2.get(), thr3=self.thr3.get(), plot=False) plt.figure(a) plt.plot(recons) plt.figtext(0.2,0.75, ('ENERGY = %0.2f ' % (energia))) plt.show() def centerUI(self,w,h): sw = self.parent.winfo_screenwidth() sh = self.parent.winfo_screenheight() x = (sw-w)/2 y = (sh-h)/2 self.parent.geometry('%dx%d+%d+%d' % (w,h,x,y))
def test_invalid_value(self): v = DoubleVar(self.root, name='name') self.root.globalsetvar('name', 'value') with self.assertRaises(ValueError): v.get()
class Controller(Observer): def __init__(self,parent,view,lissajou,subjectSig,subjects): self.cursorFrame = Frame(parent) self.selectionFrame = Frame(self.cursorFrame) self.view = view self.lissajou = lissajou self.subjects = subjects self.subjectSig=subjectSig self.amp=IntVar() self.scale_amp=Scale(self.cursorFrame,variable=self.amp, label="Amplitude", orient="horizontal",length=250,from_=0,to=10, sliderlength=50,tickinterval=1,showvalue=0, command=self.update) self.freq=IntVar() self.scale_freq=Scale(self.cursorFrame,variable=self.freq, label="Frequence", orient="horizontal",length=250,from_=0,to=10, sliderlength=50,tickinterval=0,showvalue=0, command=self.update) self.offset=DoubleVar() self.scale_offset=Scale(self.cursorFrame,variable=self.offset, label="Offset", orient="horizontal",length=250,from_=-10.0,to=10.0, sliderlength=50,tickinterval=5,showvalue=0, command=self.update) self.phase=IntVar() self.scale_phase=Scale(self.cursorFrame,variable=self.phase, label="Phase", orient="horizontal",length=250,from_=-90,to=90, sliderlength=10,tickinterval=45,showvalue=0, command=self.update) self.voltVar = DoubleVar() self.voltVar.set(1) self.button1 = Radiobutton(self.selectionFrame, text="1V", variable=self.voltVar, value=1.0*5.0,command =lambda:self.update(None)) self.button1.select() self.button2 = Radiobutton(self.selectionFrame, text="2V", variable=self.voltVar, value=2.0*5.0, command =lambda:self.update(None)) self.button5 = Radiobutton(self.selectionFrame, text="5V", variable=self.voltVar, value=5.0*5.0, command =lambda:self.update(None)) self.isOffsetVar= IntVar() self.isOffset = Checkbutton(self.selectionFrame,text = "Offset",variable = self.isOffsetVar, command =lambda:self.update(None)) def update(self,event): self.update_amplitude(event) self.update_offset(event) self.update_frequency(event) self.update_phase(event) self.view.update() if self.lissajou!=None: self.lissajou.update() def update_amplitude(self,event): print("update_amplitude(self,event)",self.amp.get()) self.subjectSig.set_magnitude(self.amp.get()/self.voltVar.get()) self.subjects.generate_XYCurve() def update_frequency(self,event): print("update_frequency(self,event)",self.freq.get()) self.subjectSig.set_frequency(self.freq.get()) self.subjects.generate_XYCurve() def update_phase(self,event): print("update_phase(self,event)",self.phase.get()) self.subjectSig.set_phase(self.phase.get()) self.subjects.generate_XYCurve() def update_offset(self,event): if self.isOffsetVar.get(): print("update_offset(self,event)",self.isOffsetVar.get()) self.subjectSig.set_offset(self.offset.get()/self.voltVar.get()) self.subjects.generate_XYCurve() else: self.subjectSig.set_offset(0.0) self.subjects.generate_XYCurve() def setLissajou(self,lissajou): self.lissajou = lissajou def packing(self) : self.selectionFrame.pack(side='top') self.button1.pack(side='left') self.button2.pack(side='left') self.button5.pack(side='left') self.isOffset.pack(side='left') self.cursorFrame.pack(side='left',expand=1, fill='both') self.scale_amp.pack() self.scale_freq.pack() self.scale_offset.pack() self.scale_phase.pack()
class DPSinterface: """ DSPinterface is a Tk graphical interface to drive a DPS power supplier. """ def __init__(self, root): """ Create a DSP interface instance. :param root: is the Tk() interface where the DPS will be drawedstring with the prot name i.e. /dev/ttyUSB0 or COM5 for Windows :returns: a new instance of DPS graphical interface """ self.root = root root.title("DPS power supplier interface") root.protocol("WM_DELETE_WINDOW", self.wnwcmdclose) self.dps = None self.poller = None self.waver = None self.strtme = time() self.dpsfwave = None self.maxoutv = 5 self.maxoutc = 5 menubar = Menu(root) filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label="Exit", command=self.wnwcmdclose) menubar.add_cascade(label="File", menu=filemenu) scopemenu = Menu(menubar, tearoff=0) scopemenu.add_command(label="Load sampled points...", command=self.mnucmdloadsmppts) scopemenu.add_command(label="Save sampled points as...", command=self.mnucmdsavesmppts) menubar.add_cascade(label="Scope", menu=scopemenu) wavemenu = Menu(menubar, tearoff=0) wavemenu.add_command(label="New wave", command=self.mnucmdnewwve) wavemenu.add_command(label="Load wave...", command=self.mnucmdloadwve) wavemenu.add_command(label="Edit wave...", command=self.mnucmdedtwve) wavemenu.add_command(label="Save wave as...", command=self.mnucmdsavewve) menubar.add_cascade(label="Wave", menu=wavemenu) memmenu = Menu(menubar, tearoff=0) memmenu.add_command(label="Edit memories...", command=self.mnucmdedtmem) menubar.add_cascade(label="Memory", menu=memmenu) helpmenu = Menu(menubar, tearoff=0) helpmenu.add_command(label="Help...", command=self.mnucmdhelp) helpmenu.add_command(label="About...", command=self.mnucmdabout) menubar.add_cascade(label="Help", menu=helpmenu) root.config(menu=menubar) row = 0 col = 0 rowspan = 1 colspan = 1 insertlabelrow(root, row, col, ("Serial: ", None, "Addr,Baud: "), E) col += colspan self.svardpsport = StringVar() self.svardpsport.set('/dev/ttyUSB0') self.entryserport = Entry(root, textvariable=self.svardpsport, width=ENTRYWIDTH, justify='right') self.entryserport.grid(row=row, column=col, sticky=W) col += colspan col += colspan self.svardpsaddbrt = StringVar() self.svardpsaddbrt.set('1, 9600') self.entrydpsadd = Entry(root, textvariable=self.svardpsaddbrt, width=ENTRYWIDTH, justify='right') self.entrydpsadd.grid(row=row, column=col, sticky=W) col += colspan colspan = 2 self.ivarconctd = IntVar() self.ivarconctd.set(0) Checkbutton(root, variable=self.ivarconctd, text='Connect', command=self.butcmdconnect).grid(row=row, column=col, columnspan=colspan, sticky=E + W) row += rowspan col = 0 colspan = 1 Separator(root, orient='horizontal').grid(row=row, columnspan=8, sticky=E + W, pady=8) row += rowspan rowspan = 1 colspan = 2 col = 0 self.ivarbrghtnes = IntVar() s = Scale(root, label='Brightness', variable=self.ivarbrghtnes, from_=0, to=5, resolution=1, orient="horizontal") s.bind("<ButtonRelease-1>", self.sclbndbrghtnss) s.grid(row=row, column=col, columnspan=colspan, sticky=E + W) col += colspan colspan = 1 Label(root, text="Model: ").grid(row=row, column=col, sticky=E) col += colspan self.ivarmodel = IntVar() Entry(root, textvariable=self.ivarmodel, state="readonly", width=ENTRYWIDTH, justify='right').grid(row=row, column=col, sticky=W) col += colspan colspan = 2 self.ivarsetmem = IntVar() s = Scale(root, label='Mem Recall', variable=self.ivarsetmem, from_=1, to=9, resolution=1, orient="horizontal") s.bind("<ButtonRelease-1>", self.sclbndmemory) s.grid(row=row, column=col, columnspan=colspan, sticky=E + W) row += rowspan colspan = 1 col = 0 insertlabelrow( root, row, col, (("Vinp [V]: ", VCOL), None, "Out Mode: ", None, "Protection: "), E) self.dvarvinp = DoubleVar() self.svarwrmde = StringVar() self.setworkmode(0) self.svarprot = StringVar() self.setprotection(0) insertentryrow( root, row, col, (None, self.dvarvinp, None, self.svarwrmde, None, self.svarprot), 'right', W, 'readonly') colspan = 1 row += rowspan col = 0 insertlabelrow(root, row, col, (("Vmax [V]: ", VCOL), None, ("Cmax [A]: ", CCOL), None, ("Pmax [W]: ", PCOL)), E) self.dvarvmaxm0 = DoubleVar() self.dvarcmaxm0 = DoubleVar() self.dvarpmaxm0 = DoubleVar() entries = insertentryrow(root, row, col, (None, self.dvarvmaxm0, None, self.dvarcmaxm0, None, self.dvarpmaxm0), 'right', W) for e, f in zip(entries, (self.entbndvmax, self.entbndcmax, self.entbndpmax)): e.bind('<FocusOut>', f) e.bind('<Return>', f) row += rowspan col = 0 insertlabelrow(root, row, col, (("Vout [V]: ", VCOL), None, ("Cout [A]: ", CCOL), None, ("Pout [W]: ", PCOL)), E) self.dvarvout = DoubleVar() self.dvarcout = DoubleVar() self.dvarpout = DoubleVar() insertentryrow( root, row, col, (None, self.dvarvout, None, self.dvarcout, None, self.dvarpout), 'right', W, 'readonly') row += rowspan col = 0 self.scope = Scope(root, [], row, col) row += 9 col = 4 Label(root, text="Rte[s/Sa]: ").grid(row=row, column=col, sticky=E) col += colspan self.dvarsecsmp = DoubleVar() self.dvarsecsmp.set(self.scope.sampletime()) e = Entry(root, textvariable=self.dvarsecsmp, width=ENTRYWIDTH, justify='right').grid(row=row, column=col, sticky=W) row += rowspan col = 0 colspan = 2 self.ivaracquire = IntVar() self.ivaracquire.set(0) Checkbutton(root, variable=self.ivaracquire, text='Run Acquisition', command=self.butcmdacquire).grid(row=row, column=col, columnspan=2, sticky=E + W) col += colspan self.ivarkeylock = IntVar() self.ivarkeylock.set(0) Checkbutton(root, variable=self.ivarkeylock, text="Key Lock", command=self.butcmdkeylock).grid(row=row, column=col, sticky=E + W, columnspan=colspan) col += colspan self.ivaroutenab = IntVar() self.ivaroutenab.set(0) Checkbutton(root, variable=self.ivaroutenab, text="Output Enable", command=self.butcmdoutenable).grid(row=row, column=col, sticky=E + W, columnspan=colspan) row += rowspan col = 0 rowspan = 1 colspan = 3 self.dvarvscale = DoubleVar() self.voltscale = Scale(root, label='Vset [V]', foreground=VCOL, variable=self.dvarvscale, from_=0, to=self.maxoutv, resolution=1, orient="horizontal") #, label='Vset[V]' self.voltscale.bind("<ButtonRelease-1>", self.sclbndvolt) self.voltscale.grid(row=row, column=col, columnspan=colspan, sticky=E + W) col += colspan self.dvarcscale = DoubleVar() self.curntscale = Scale(root, label='Cset[A]', foreground=CCOL, variable=self.dvarcscale, from_=0, to=self.maxoutc, resolution=1, orient="horizontal") #,label='Cset[A]' self.curntscale.bind("<ButtonRelease-1>", self.sclbndcrnt) self.curntscale.grid(row=row, column=col, columnspan=colspan, sticky=E + W) row += rowspan col = 0 self.dvarvscalef = DoubleVar() sc = Scale(root, foreground=VCOL, variable=self.dvarvscalef, from_=0, to=0.99, resolution=0.01, orient="horizontal") sc.bind("<ButtonRelease-1>", self.sclbndvolt) sc.grid(row=row, column=col, columnspan=colspan, sticky=E + W) col += colspan self.dvarcscalef = DoubleVar() sc = Scale(root, foreground=CCOL, variable=self.dvarcscalef, from_=0, to=0.99, resolution=0.01, orient="horizontal") sc.bind("<ButtonRelease-1>", self.sclbndcrnt) sc.grid(row=row, column=col, columnspan=colspan, sticky=E + W) row += rowspan col = 0 colspan = 1 Separator(root, orient='horizontal').grid(row=row, columnspan=6, sticky=E + W, pady=8) row += rowspan colspan = 1 col = 0 Label(root, text="Waveform: ").grid(row=row, column=col, sticky=E) col += colspan colspan = 2 self.svarwave = StringVar() Entry(root, textvariable=self.svarwave, width=ENTRYWIDTH, justify='right', state='readonly').grid(row=row, column=col, columnspan=colspan, sticky=E + W) col += colspan colspan = 1 self.ivarplaywv = IntVar() self.ivarplaywv.set(0) Checkbutton(root, variable=self.ivarplaywv, text='Play', command=self.butcmdplaywave).grid(row=row, column=col, sticky=E + W) col += colspan self.ivarpausewv = IntVar() self.ivarpausewv.set(0) Checkbutton(root, variable=self.ivarpausewv, text='Pause', command=self.butcmdpausewave).grid(row=row, column=col, sticky=E + W) col += colspan self.ivarloopwv = IntVar() self.ivarloopwv.set(0) Checkbutton(root, variable=self.ivarloopwv, text='Loop').grid(row=row, column=col, sticky=E + W) self.scope.update() self.scope.redraw() def sclbndvolt(self, event): """ Voltage scale bind command to set the voltage on the DSP. :param event: the event describing what changed """ if self.isconnected(): self.dps.set(['vset'], [self.getvscale()]) def sclbndcrnt(self, event): """ Current scale bind command to set the current on the DSP. :param event: the event describing what changed """ if self.isconnected(): self.dps.set(['cset'], [self.getcscale()]) def sclbndmemory(self, event): """ Memory-set bind command to set the memory on the DSP. :param event: the event describing what changed """ if self.isconnected(): m = self.ivarsetmem.get() self.dps.set(['mset'], [m]) self.updatefields(True) def sclbndbrghtnss(self, event): """ Brightness bind command to set the brightness on the DSP. :param event: the event describing what changed """ if self.isconnected(): b = self.ivarbrghtnes.get() self.dps.set(['brght'], [b]) def mnucmdnewwve(self): """ New wave menu command to initialize a new wave. """ self.dpsfwave = Dpsfile() self.svarwave.set('unnamed') def mnucmdloadwve(self): """ Load wave menu command to load a wave file. """ fname = tkFileDialog.askopenfilename(initialdir=".", title="Select wave file to load", filetypes=(("dps files", "*.dps"), ("all files", "*.*"))) if fname: self.svarwave.set(os.path.basename(fname)) self.dpsfwave = Dpsfile() self.dpsfwave.load(fname) def mnucmdedtwve(self): """ Edit wave menu command to open the edit wave window. """ if self.dpsfwave is not None: Wveinterface(self.root, self.dpsfwave.getpoints()) else: tkMessageBox.showinfo('No wave loaded', 'Load or create a new wave file to modify') def mnucmdsavewve(self): """ Save wave menu command to save the current wave in memory. """ if self.dpsfwave is not None: fname = tkFileDialog.asksaveasfilename( initialdir=".", title="Select wave file to save", filetypes=(("dps files", "*.dps"), ("all files", "*.*"))) if fname: self.dpsfwave.save(fname) self.svarwave.set(os.path.basename(fname)) else: tkMessageBox.showinfo('No wave in memory', 'Load or create a wave file to modify') def mnucmdloadsmppts(self): """ Load sampled points menu command to load in the graphical view sampled before. """ fname = tkFileDialog.askopenfilename(initialdir=".", title="Select data file to load", filetypes=(("dps files", "*.dps"), ("all files", "*.*"))) if fname: self.scope.load(fname) def mnucmdsavesmppts(self): """ Save sampled points menu command to save the last points sampled showed in the graphical view. """ fname = tkFileDialog.asksaveasfilename( initialdir=".", title="Select data file to save", filetypes=(("dps files", "*.dps"), ("all files", "*.*"))) if fname: self.scope.save(fname) def mnucmdedtmem(self): """ Memory menu command to edit the values of preset memories on DSP. """ if self.isconnected(): Meminterface(self.root, self.dps, self.updatefields) def mnucmdabout(self): """ About menu command to show the window with program information. """ Txtinterface( self.root, 'About', """DPS interface is designed by Simone Pernice That project was born as a textual driver to interface any DPS device. After the driver I made also a graphical interface to manage DPS devices. This project was born because I was not able to find any Linux application to manage DPS devices via USB. For question email to me: [email protected] Version {} relesed on {} First release on 3rd February 2019 Turin Italy DPS interface is under licence {} If you like this program please make a donation with PayPal to [email protected]""" .format(__version__, __date__, __license__)) def mnucmdhelp(self): """ Help menu command to show basic help on usage. """ Txtinterface( self.root, 'Help', """This is an interface to remote controll a power supplier of DPS series. The white fields can be edited, the gray are read only. To connect to DPS power supplier first link it to the PC through an USB cable. The data required to connect is on the first row of the graphical interface. Write the serial address on the first field (COMxx for Windows or /dev/ttyUSBx for Linux). Address and baudrate do not require update because they are the default for DPS power supplier. Turn on DPS with up key pressed to change those values. Press 'Connect' check button and if the device is present it is linked. Press again the same check button to disconnect the DPS. Once the link to DPS is in place all the data on the interface are updated and on the DPS the keylock is set. The second block of graphical interface contains all data about DPS. The brightness set which can be changed through the scale regulation. The model number. The memory from which recall the preset parameters. The input voltage, the output mode cv (constant voltage) or cc (constant current). The protection mode: none (no protection triggered), ovp (over voltage protection), ocp (over current protection), opp (over power protection). The maximum voltage, current and power to provide before triggering the self protection. The next row contains output voltage, current and power in textual form. A time diagram of the DPS output voltage, current and power is avaiable. It is possible to play with the mouse on that screen: - wheel press to fit in the screen all the enabled drawings - wheel to zoom in time - shift+wheel to zoom on Y for the highlighted curves - ctrl+wheel to change the enabled curves - left button drag to move the highlighted curve The same mouse functions are available in the fields below the diagram: - voltage per division, current per division and watt per division - zero position for voltage, current and power - check button to view voltage, current and power - time: second per divisions and zero position for time The sample time is used for the acquisition. DPS is quite slot, the minimum read time is around 1 second. The suggested rate is to have a sample for displayed pixel. The next buttons are: - Run acquisition: starts a thread that read the DPS status, update the interface fields as well as the time diagram. The acquisition points can be saved and loaded to be showed lated with menu commands on DPS scope load/save. They can be also edited through the wave edit window and played. - Key lock: set or reset the DPS key lock. It should be on in order to have faster communication. If key lock is on less fields of DPS are read since user can change them only through the PC interface. - Output enable to enable the DPS output Eventually there are the voltage and current scale. Thery are split in two: - the first is for coarse (1 unit/step) adjustment the unit of voltage/current - the second is for fine (0.01 unit/step) adjustament of voltage/current On the last block of interface there is a waveform field showing the wave loaded. Wave is a set of required output voltage and current at give timings. It is possible play and pause it through the respective commands of the interface. If loop is set when the wave play is completed it restarts. The acquisition may slow the wave player, use low acquisition sample time to avoid delays.""") def butcmdconnect(self): """ Connect check button command to connect to the DSP. It reads: serial port address, DPS address and serial speed from other interface fields. If it is capable to link to the DPS: - the maximum voltage and current are read and scale maximums set accordingly - the DPS current data are read and set accordingly in the interface - the localDPS interface is locked so that the user cannot change them but has to go through the graphical interface if the DPS is locked the polling is faster because less data needs to be read from DPS - the input fields are disabled """ if self.ivarconctd.get(): try: flds = self.svardpsaddbrt.get().split(',') if len(flds) > 0: ch = int(flds[0]) else: ch = 1 if len(flds) > 1: br = int(flds[1]) else: br = 9600 self.dps = DPSdriver(self.svardpsport.get(), ch, br) except Exception as e: tkMessageBox.showerror('Error', 'Cannot connect: ' + str(e)) self.ivarconctd.set(0) self.dps = None return m = self.dps.get(['model']) m = m[0] self.ivarmodel.set(m) to = m / 100 self.voltscale.config(to=to) self.maxoutv = to to = m % 100 self.curntscale.config(to=to) self.maxoutv = to self.scope.resetpoints() self.ivarkeylock.set(1) self.butcmdkeylock() self.updatefields(True) self.entryserport.config(state='readonly') self.entrydpsadd.config(state='readonly') else: # Stop polling self.ivaracquire.set(0) if self.poller: self.poller.wake() time.sleep(1.) # Wait to be sure the thread exits # Stop waveform generation self.ivarplaywv.set(0) if self.waver: self.waver.wake() time.sleep(1.) # Wait to be sure the thread exits self.dps = None self.entryserport.config(state=NORMAL) self.entrydpsadd.config(state=NORMAL) def butcmdacquire(self): """ Acquire check button command to manage the acquisition thread to read the DSP data. If the button is not selected the thread is lunched. If the button is selected the thread is stopped. """ if self.ivaracquire.get(): if not self.isconnected(): self.ivaracquire.set(0) return self.scope.resetpoints() self.strtme = time() self.poller = Poller(self.ivaracquire, self.dvarsecsmp, self.updatefields) else: self.poller.wake() def butcmdkeylock(self): """ Key lock button command to enable or disable the key lock on DPS remote interface. """ if self.isconnected(): self.dps.set(['lock'], [self.ivarkeylock.get()]) else: self.ivarkeylock.set(0) def butcmdoutenable(self): """ DPS output button command to enable or disable the DPS output power. """ if self.isconnected(): self.dps.set(['onoff'], [self.ivaroutenab.get()]) else: self.ivaroutenab.set(0) def butcmdplaywave(self): """ Wave generator check button command to manage the wave generation thread to make a waveform on the DSP. If the button is not selected the thread is lunched. If the button is selected the thread is stopped. """ if self.ivarplaywv.get(): if not self.isconnected(): self.ivarplaywv.set(0) return if not self.dpsfwave: tkMessageBox.showinfo('No wave in memory', 'Load or create a wave file to modify') self.ivarplaywv.set(0) return if not self.ivaroutenab.get(): self.ivaroutenab.set(1) self.butcmdoutenable() self.waver = Waver(self.setvcdps, self.ivarplaywv, self.ivarpausewv, self.ivarloopwv, self.dpsfwave.getpoints()) else: self.waver.wake() def butcmdpausewave(self): """ Wave generator pause check button command to temporary pause the wave generations. """ self.waver.wake() def wnwcmdclose(self): """ DPS main window close. Before exiting the supplier is disconnected the external supplier. """ if self.ivarconctd.get(): self.ivarconctd.set(0) self.butcmdconnect() self.root.destroy() def entbndvmax(self, event): """ Maximum voltage entry bind to set the protection maximum ouput voltage of the DSP. :param event: the event describing what changed """ if self.isconnected(): if self.dvarvmaxm0.get() > self.maxoutv * PROTEXCEED: self.dvarvmaxm0.set(self.maxoutv * PROTEXCEED) elif self.dvarvmaxm0.get() < 0.: self.dvarvmaxm0.set(0.) self.dps.set(['m0ovp'], [self.dvarvmaxm0.get()]) def entbndcmax(self, event): """ Maximum current entry bind to set the protection maximum output curret of the DSP. :param event: the event describing what changed """ if self.isconnected(): if self.dvarcmaxm0.get() > self.maxoutc * PROTEXCEED: self.dvarcmaxm0.set(self.maxoutc * PROTEXCEED) elif self.dvarcmaxm0.get() < 0.: self.dvarcmaxm0.set(0.) self.dps.set(['m0ocp'], [self.dvarcmaxm0.get()]) def entbndpmax(self, event): """ Maximum power entry bind to set the protection maximum output power of the DSP. :param event: the event describing what changed """ if self.isconnected(): if self.dvarpmaxm0.get( ) > self.maxoutv * self.maxoutc * PROTEXCEED * PROTEXCEED: self.dvarpmaxm0.set(self.maxoutv * self.maxoutc * PROTEXCEED * PROTEXCEED) elif self.dvarpmaxm0.get() < 0.: self.dvarcmaxm0.set(0.) self.dps.set(['m0opp'], [self.dvarpmaxm0.get()]) def setvcdps(self, v, c): """ Set the DPS output voltage and current moving their scales accordingly. :param v: the required voltage, if negative it is not changed :param c: the required current, if negative it is not changed """ if v >= 0: if c >= 0: self.setvscale(v) self.setcscale(c) self.dps.set(['vset', 'cset'], [v, c]) else: self.setvscale(v) self.dps.set(['vset'], [v]) elif c >= 0: self.setcscale(c) self.dps.set(['cset'], [c]) def isconnected(self): """ Check if the DPS is connected, if not display a message. :returns: True if connected, False if not """ if self.dps is None: tkMessageBox.showinfo('Not connected', 'Enstablish a connection before') return False return True def setvscale(self, v): """ Set the voltage scale, nothing is changed on the DPS. :param v: the voltage to set """ if v > self.maxoutv: v = self.maxoutv elif v < 0: v = 0 self.dvarvscale.set(int(v)) self.dvarvscalef.set(round(v - int(v), 2)) def getvscale(self): """ Get the voltage scale set value. :returns: the voltage set """ return self.dvarvscale.get() + self.dvarvscalef.get() def setcscale(self, c): """ Set the current scale, nothing is changed on the DPS. :param c: the current to set """ if c > self.maxoutc: c = self.maxoutc elif c < 0: c = 0 self.dvarcscale.set(int(c)) self.dvarcscalef.set(round(c - int(c), 2)) def getcscale(self): """ Get the current scale set value. :returns: the current set """ return self.dvarcscale.get() + self.dvarcscalef.get() def updatefields(self, forcereadall=False): """ Reads data stored in DPS and updates the interface fields accordingly. In order to be as fast as possible, if keylock is enabled, reads only the fields that can change without uses access. If keylock is disabled all the fields are read because user may have changed something from the interface. :param forcereadall: if True read and update all the DPS fields regardless of the keylock status :returns: the point read. A point is made by (time, voltage, current, power) """ if not forcereadall and self.ivarkeylock.get( ): # If user keep locked fewer data are read, otherwise all data = self.dps.get( ['vout', 'cout', 'pout', 'vinp', 'lock', 'prot', 'cvcc']) self.dvarvout.set(data[0]) self.dvarcout.set(data[1]) self.dvarpout.set(data[2]) self.dvarvinp.set(data[3]) self.ivarkeylock.set(data[4]) self.setprotection(data[5]) self.setworkmode(data[6]) vcp = data[0:3] else: # All data is read data = self.dps.get([ 'vset', 'cset', 'vout', 'cout', 'pout', 'vinp', 'lock', 'prot', 'cvcc', 'onoff', 'brght', 'mset', 'm0ovp', 'm0ocp', 'm0opp' ]) self.setvscale(data[0]) self.setcscale(data[1]) self.dvarvout.set(data[2]) self.dvarcout.set(data[3]) self.dvarpout.set(data[4]) self.dvarvinp.set(data[5]) self.ivarkeylock.set(data[6]) self.setprotection(data[7]) self.setworkmode(data[8]) self.ivaroutenab.set(data[9]) self.ivarbrghtnes.set(data[10]) self.ivarsetmem.set(data[11]) self.dvarvmaxm0.set(data[12]) self.dvarcmaxm0.set(data[13]) self.dvarpmaxm0.set(data[14]) vcp = data[2:5] vcp.insert(TPOS, time() - self.strtme) self.scope.addpoint(vcp) return vcp def setprotection(self, p): """ Set the protection field with an user readable string explaining the DPS protection status. :param p: the protection statu returned by the DPS """ self.svarprot.set({0: 'none', 1: 'ovp', 2: 'ocp', 3: 'opp'}[p]) def setworkmode(self, wm): """ Set the workmode field with an user readable string explaining the DPS work mode. :param wm: the working mode returned by the DPS """ self.svarwrmde.set({0: 'cv', 1: 'cc'}[wm])
class Example(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent self.initUI() self.centerUI(w=560, h=235) def initUI(self): self.parent.title("DBLR for Dummies") self.pack(fill=BOTH, expand=True) #self.columnconfigure(0, weight=1) #self.rowconfigure(0, weight=1) # weight attibute is used to make them growable self.meas = IntVar() self.point = IntVar() self.base_path = StringVar() self.coef = DoubleVar() self.noise = DoubleVar() self.n_sigma = DoubleVar() self.thr1 = DoubleVar() self.thr2 = DoubleVar() self.thr3 = DoubleVar() self.graph_sw = BooleanVar() #Image factor = 0.65 search = Image.open("NEXT_official_logo.jpg") width_org, height_org = search.size search_temp = search.resize( (int(width_org * factor), int(height_org * factor)), Image.ANTIALIAS) search_aux = ImageTk.PhotoImage(search_temp) label1 = Label(self, image=search_aux) label1.image = search_aux label1.grid(row=0, column=4, columnspan=2, rowspan=3, padx=5) #self.base_path.set("F:/DATOS_DAC/2052/pmt_0_trace_evt_") self.base_path.set("Argon.h5.z") e1 = Entry(self, textvariable=self.base_path, width=40) e1.grid(row=0, column=1, sticky=W, columnspan=3, pady=5, padx=5) e1_label = Label(self, text="Path & Name") e1_label.grid(row=0, column=0, columnspan=1, sticky=E, pady=5, padx=5) self.point.set("0") sb1 = Spinbox(self, from_=0, to=100, width=4, textvariable=self.point) sb1.grid(row=2, column=1, sticky=W, pady=5, padx=5) sb1_label = Label(self, text="PMT") sb1_label.grid(row=2, column=0, padx=5, sticky=E) self.meas.set("0") sb1 = Spinbox(self, from_=0, to=100, width=4, textvariable=self.meas) sb1.grid(row=2, column=3, sticky=W, pady=5, padx=5) sb1_label = Label(self, text="Event") sb1_label.grid(row=2, column=2, padx=5, sticky=E) #Check buttons # cb1 = Checkbutton(self, text="New Graph", variable=self.graph_sw) # cb1.select() # cb1.grid(row=2,column=2, sticky=W) #PARAMETERS Integration_label = Label(self, text="PARAMETERS", font="Verdana 12 bold") Integration_label.grid(row=3, column=1, padx=5, columnspan=2, pady=10, sticky=E) self.coef.set("1.65E-3") e2 = Entry(self, width=12, textvariable=self.coef) e2.grid(row=4, column=1, sticky=W, pady=5, padx=5) e2_label = Label(self, text="DBLR Coef") e2_label.grid(row=4, column=0, sticky=E, pady=5, padx=5) self.noise.set("0.75") e3 = Entry(self, width=12, textvariable=self.noise) e3.grid(row=4, column=3, sticky=W, pady=5, padx=5) e3_label = Label(self, text="Noise (LSB)") e3_label.grid(row=4, column=2, sticky=E, pady=5, padx=5) self.n_sigma.set("4") e4 = Entry(self, width=12, textvariable=self.n_sigma) e4.grid(row=4, column=5, sticky=W, pady=5, padx=5) e4_label = Label(self, text="Noise Threshold") e4_label.grid(row=4, column=4, sticky=E, pady=5, padx=5) self.thr1.set("0") e5 = Entry(self, width=12, textvariable=self.thr1) e5.grid(row=5, column=1, sticky=W, pady=5, padx=5) e5_label = Label(self, text="Threshold 1") e5_label.grid(row=5, column=0, sticky=E, pady=5, padx=5) self.thr2.set("0") e6 = Entry(self, width=12, textvariable=self.thr2) e6.grid(row=5, column=3, sticky=W, pady=5, padx=5) e6_label = Label(self, text="Threshold 2") e6_label.grid(row=5, column=2, sticky=E, pady=5, padx=5) self.thr3.set("0") e7 = Entry(self, width=12, textvariable=self.thr3) e7.grid(row=5, column=5, sticky=W, pady=5, padx=5) e7_label = Label(self, text="Threshold 3") e7_label.grid(row=5, column=4, sticky=E, pady=5, padx=5) # Main buttons obtn = Button(self, text="GO!!", command=self.DBLR_f) obtn.grid(row=6, column=4, sticky=E, pady=10) cbtn = Button(self, text="Quit", command=self.quit) cbtn.grid(row=6, column=5, sticky=E, pady=10) hbtn = Button(self, text="Help", command=self.help_f) hbtn.grid(row=6, column=0, sticky=W, pady=10) def help_f(self): top = Toplevel() top.title("HELP") msg = Message(top, width=500, text="Noise Threshold (NT) - Noise Based Main Threshold \ (Sigmas)\n Threshold 1 - Main Threshold (LSBs) \n Threshold 2 - End of Pulse Error \n \ Threshold 3 - End of Tail Error \n When Thr1 = Thr3 = 0 their values are defined as: \n \ (THR1 = NT (LSBs) / THR3 = NT*NOISE_ADC / 5)") msg.pack() button = Button(top, text="Close", command=top.destroy) button.pack() def DBLR_f(self): global a #if (self.graph_sw.get()==True): b = a a = a + 1 #else: # b=0 aux = self.base_path.get() # path=''.join([aux,str(self.meas.get()),'.txt']) # g=pd.read_csv(path) f = read_panel_hdf5(aux, self.point.get(), self.meas.get()) f = 4096 - f recons, energia = DB.BLR(signal_daq=f.flatten().astype(float), coef=self.coef.get(), n_sigma=self.n_sigma.get(), NOISE_ADC=self.noise.get(), thr1=self.thr1.get(), thr2=self.thr2.get(), thr3=self.thr3.get(), plot=False) plt.figure(a) plt.plot(recons) plt.figtext(0.2, 0.75, ('ENERGY = %0.2f ' % (energia))) plt.show() def centerUI(self, w, h): sw = self.parent.winfo_screenwidth() sh = self.parent.winfo_screenheight() x = (sw - w) / 2 y = (sh - h) / 2 self.parent.geometry('%dx%d+%d+%d' % (w, h, x, y))
class SkewPanel(PluginPanel): name = "Skew" title = _("Skew") def init(self, master): PluginPanel.init(self, master) self.width_priority = 1 root = self.mw.root self.var_angleX = DoubleVar(root) self.var_angleY = DoubleVar(root) jump = 5 self.var_angleX.set(0) self.var_angleY.set(0) self.var_proportional = IntVar(root) self.var_proportional.set(0) self.var_basepoint = StringVar(root) self.var_basepoint.set("C") # --------------------------------------------------------- top = TFrame(self.panel, style="FlatFrame") top.pack(side=TOP, fill=BOTH) # --------------------------------------------------------- # Horisontal size_frameH = TFrame(top, style="FlatFrame", borderwidth=3) size_frameH.pack(side=TOP, fill=BOTH) label = TLabel(size_frameH, style="FlatLabel", image="skew_h") label.pack(side=LEFT, padx=5) self.entry_angleX = TSpinbox( size_frameH, var=0, vartype=1, textvariable=self.var_angleX, min=-75, max=75, step=jump, width=10, command=self.apply_skew, ) self.entry_angleX.pack(side=LEFT) self.labelwunit = TLabel(size_frameH, style="FlatLabel", text=_("deg")) self.labelwunit.pack(side=LEFT, padx=5) # --------------------------------------------------------- # Vertical size_frameV = TFrame(top, style="FlatFrame", borderwidth=3) size_frameV.pack(side=TOP, fill=BOTH) label = TLabel(size_frameV, style="FlatLabel", image="skew_v") label.pack(side=LEFT, padx=5) self.entry_angleY = TSpinbox( size_frameV, var=0, vartype=1, textvariable=self.var_angleY, min=-75, max=75, step=jump, width=10, command=self.apply_skew, ) self.entry_angleY.pack(side=LEFT) self.labelhunit = TLabel(size_frameV, style="FlatLabel", text=_("deg")) self.labelhunit.pack(side=LEFT, padx=5) # --------------------------------------------------------- # Basepoint check label = TLabel(top, style="FlatLabel", text=_("Basepoint:")) label.pack(side=TOP, fill=BOTH, padx=5) basepoint_frame = TLabelframe(top, labelwidget=label, style="Labelframe", borderwidth=4) basepoint_frame.pack(side=TOP, fill=X, padx=5, pady=2) self.Basepoint = BasePointSelector(basepoint_frame, anchor=self.var_basepoint) self.Basepoint.pack(side=LEFT, fill=BOTH, padx=5) label = TLabel(basepoint_frame, style="FlatLabel", image="coordinate_deg") label.pack(side=LEFT, fill=BOTH, padx=10) # --------------------------------------------------------- # Button frame button_frame = TFrame(top, style="FlatFrame", borderwidth=5) button_frame.pack(side=BOTTOM, fill=BOTH) self.update_buttons = [] self.button = UpdatedButton(top, text=_("Apply"), command=self.apply_skew) self.button.pack(in_=button_frame, side=BOTTOM, expand=1, fill=X, pady=3) self.button_copy = UpdatedButton(top, text=_("Apply to Copy"), command=self.apply_to_copy) self.button_copy.pack(in_=button_frame, side=BOTTOM, expand=1, fill=X) self.init_from_doc() self.subscribe_receivers() ############################################################################### def subscribe_receivers(self): self.document.Subscribe(SELECTION, self.Update) def unsubscribe_receivers(self): self.document.Unsubscribe(SELECTION, self.Update) def init_from_doc(self): self.Update() def Update(self, *arg): if self.is_selection(): self.entry_angleX.set_state(NORMAL) self.entry_angleY.set_state(NORMAL) self.button["state"] = NORMAL self.button_copy["state"] = NORMAL else: self.entry_angleX.set_state(DISABLED) self.entry_angleY.set_state(DISABLED) self.button["state"] = DISABLED self.button_copy["state"] = DISABLED def SkewSelected(self, axisX=0, axisY=0): if self.document.selection: self.document.begin_transaction() try: try: br = self.document.selection.coord_rect hor_sel = br.right - br.left ver_sel = br.top - br.bottom cnt_x, cnt_y = self.Basepoint.get_basepoint(hor_sel, ver_sel, br.left, br.bottom) text = _("Skew") ax, ay = tan(axisX), tan(axisY) sx = 1.0 sy = 1.0 - (ax * ay) tx = cnt_x * ax ty = cnt_y * ax * ay - cnt_y * ay # Move the selection in the coordinates x0 y0 trafo = Trafo(1, 0, 0, 1, -cnt_x, -cnt_y) # Skew and Scaling trafo = Trafo(sx, ay, -ax, sy, 0, 0)(trafo) # Move the selection in the coordinates basepoint trafo = Trafo(1, 0, 0, 1, cnt_x, cnt_y)(trafo) self.document.TransformSelected(trafo, text) except: self.document.abort_transaction() finally: self.document.end_transaction() def apply_skew(self, *arg): if self.button["state"] == DISABLED: return try: angleX = self.var_angleX.get() * degrees angleY = self.var_angleY.get() * degrees self.SkewSelected(angleX, angleY) except: return def apply_to_copy(self): if self.button["state"] == DISABLED: return self.document.begin_transaction(_("Skew&Copy")) try: try: self.document.ApplyToDuplicate() self.apply_skew() except: self.document.abort_transaction() finally: self.document.end_transaction() def is_selection(self): return len(self.document.selection) > 0
class SkewPanel(PluginPanel): name = 'Skew' title = _("Skew") def init(self, master): PluginPanel.init(self, master) self.width_priority = 1 root = self.mw.root self.var_angleX = DoubleVar(root) self.var_angleY = DoubleVar(root) jump = 5 self.var_angleX.set(0) self.var_angleY.set(0) self.var_proportional = IntVar(root) self.var_proportional.set(0) self.var_basepoint = StringVar(root) self.var_basepoint.set('C') #--------------------------------------------------------- top = TFrame(self.panel, style='FlatFrame') top.pack(side=TOP, fill=BOTH) #--------------------------------------------------------- # Horisontal size_frameH = TFrame(top, style='FlatFrame', borderwidth=3) size_frameH.pack(side=TOP, fill=BOTH) label = TLabel(size_frameH, style='FlatLabel', image='skew_h') label.pack(side=LEFT, padx=5) self.entry_angleX = TSpinbox(size_frameH, var=0, vartype=1, textvariable=self.var_angleX, min=-75, max=75, step=jump, width=10, command=self.apply_skew) self.entry_angleX.pack(side=LEFT) self.labelwunit = TLabel(size_frameH, style='FlatLabel', text=_("deg")) self.labelwunit.pack(side=LEFT, padx=5) #--------------------------------------------------------- # Vertical size_frameV = TFrame(top, style='FlatFrame', borderwidth=3) size_frameV.pack(side=TOP, fill=BOTH) label = TLabel(size_frameV, style='FlatLabel', image='skew_v') label.pack(side=LEFT, padx=5) self.entry_angleY = TSpinbox(size_frameV, var=0, vartype=1, textvariable=self.var_angleY, min=-75, max=75, step=jump, width=10, command=self.apply_skew) self.entry_angleY.pack(side=LEFT) self.labelhunit = TLabel(size_frameV, style='FlatLabel', text=_("deg")) self.labelhunit.pack(side=LEFT, padx=5) #--------------------------------------------------------- # Basepoint check label = TLabel(top, style='FlatLabel', text=_("Basepoint:")) label.pack(side=TOP, fill=BOTH, padx=5) basepoint_frame = TLabelframe(top, labelwidget=label, style='Labelframe', borderwidth=4) basepoint_frame.pack(side=TOP, fill=X, padx=5, pady=2) self.Basepoint = BasePointSelector(basepoint_frame, anchor=self.var_basepoint) self.Basepoint.pack(side=LEFT, fill=BOTH, padx=5) label = TLabel(basepoint_frame, style='FlatLabel', image='coordinate_deg') label.pack(side=LEFT, fill=BOTH, padx=10) #--------------------------------------------------------- # Button frame button_frame = TFrame(top, style='FlatFrame', borderwidth=5) button_frame.pack(side=BOTTOM, fill=BOTH) self.update_buttons = [] self.button = UpdatedButton(top, text=_("Apply"), command=self.apply_skew) self.button.pack(in_=button_frame, side=BOTTOM, expand=1, fill=X, pady=3) self.button_copy = UpdatedButton(top, text=_("Apply to Copy"), command=self.apply_to_copy) self.button_copy.pack(in_=button_frame, side=BOTTOM, expand=1, fill=X) self.init_from_doc() self.subscribe_receivers() ############################################################################### def subscribe_receivers(self): self.document.Subscribe(SELECTION, self.Update) def unsubscribe_receivers(self): self.document.Unsubscribe(SELECTION, self.Update) def init_from_doc(self): self.Update() def Update(self, *arg): if self.is_selection(): self.entry_angleX.set_state(NORMAL) self.entry_angleY.set_state(NORMAL) self.button['state'] = NORMAL self.button_copy['state'] = NORMAL else: self.entry_angleX.set_state(DISABLED) self.entry_angleY.set_state(DISABLED) self.button['state'] = DISABLED self.button_copy['state'] = DISABLED def SkewSelected(self, axisX=0, axisY=0): if self.document.selection: self.document.begin_transaction() try: try: br = self.document.selection.coord_rect hor_sel = br.right - br.left ver_sel = br.top - br.bottom cnt_x, cnt_y = self.Basepoint.get_basepoint( hor_sel, ver_sel, br.left, br.bottom) text = _("Skew") ax, ay = tan(axisX), tan(axisY) sx = 1.0 sy = 1.0 - (ax * ay) tx = cnt_x * ax ty = cnt_y * ax * ay - cnt_y * ay # Move the selection in the coordinates x0 y0 trafo = Trafo(1, 0, 0, 1, -cnt_x, -cnt_y) # Skew and Scaling trafo = Trafo(sx, ay, -ax, sy, 0, 0)(trafo) # Move the selection in the coordinates basepoint trafo = Trafo(1, 0, 0, 1, cnt_x, cnt_y)(trafo) self.document.TransformSelected(trafo, text) except: self.document.abort_transaction() finally: self.document.end_transaction() def apply_skew(self, *arg): if self.button["state"] == DISABLED: return try: angleX = self.var_angleX.get() * degrees angleY = self.var_angleY.get() * degrees self.SkewSelected(angleX, angleY) except: return def apply_to_copy(self): if self.button["state"] == DISABLED: return self.document.begin_transaction(_("Skew&Copy")) try: try: self.document.ApplyToDuplicate() self.apply_skew() except: self.document.abort_transaction() finally: self.document.end_transaction() def is_selection(self): return (len(self.document.selection) > 0)
class GradientPatternFrame(PatternFrame): def __init__(self, master=None, **kw): apply(PatternFrame.__init__, (self, master), kw) gradient = CreateSimpleGradient(StandardColors.white, StandardColors.black) frame = Frame(self) frame.pack(side = TOP, fill = X) self.var_gradient_type = IntVar(self) for value, bitmap in [(0, 'linear'), (1, 'conical'), (2, 'radial')]: bitmap = getattr(pixmaps, 'gradient_' + bitmap) button = make_button(frame, bitmap = bitmap, value = value, variable = self.var_gradient_type, command = self.choose_type) button.pack(side = LEFT, fill = X, expand = 1) frame = Frame(self) frame.pack(side = TOP, expand = 1, fill = X) self.colors = [None, None] self.colors[0] = ColorButton(frame, height = 1, color = gradient.StartColor(), command = self.set_color, args = 0) self.colors[0].pack(side = LEFT, fill = X, expand = 1) self.colors[1] = ColorButton(frame, height = 1, color = gradient.EndColor(), command = self.set_color, args = 1) self.colors[1].pack(side = LEFT, fill = X, expand = 1) self.var_border = DoubleVar(self) self.var_border.set(0.0) frame = Frame(self) frame.pack(side = TOP, fill = X, expand = 1) label = Label(frame, text = _("Border")) label.pack(side = LEFT, expand = 1, anchor = E) entry = MyEntry(frame, textvariable = self.var_border, width = 4, justify = RIGHT, command = self.set_border) entry.pack(side = LEFT, expand = 1, fill = X) scroll = MiniScroller(frame, variable = self.var_border, min = 0.0, max = 100.0, step = 1.0, command = self.set_border) scroll.pack(side = LEFT, fill = Y) button = UpdatedButton(self, text = _("Edit Gradient"), command = self.edit_gradient) button.pack(side = TOP, fill = X) pattern = LinearGradient(gradient) self.SetPattern(pattern) def set_color(self, idx): self.gradient = self.gradient.Duplicate() self.gradient.SetStartColor(self.__get_color(0)) self.gradient.SetEndColor(self.__get_color(1)) self.pattern = self.pattern.Duplicate() self.pattern.SetGradient(self.gradient) self.issue(CHANGED) def __get_color(self, idx): return self.colors[idx].Color() def choose_type(self): type = gradient_types[self.var_gradient_type.get()] self.pattern = type(duplicate = self.pattern) self.issue(CHANGED) def set_border(self, *rest): border = self.var_border.get() / 100.0 if hasattr(self.pattern, 'SetBorder'): self.pattern = self.pattern.Duplicate() self.pattern.SetBorder(border) self.issue(CHANGED) def SetPattern(self, pattern): PatternFrame.SetPattern(self, pattern) self.gradient = gradient = pattern.Gradient().Duplicate() self.var_gradient_type.set(gradient_types.index(pattern.__class__)) self.colors[0].SetColor(gradient.StartColor()) self.colors[1].SetColor(gradient.EndColor()) if hasattr(pattern, 'Border'): self.var_border.set(pattern.Border() * 100.0) def Center(self): if self.pattern.__class__ == LinearGradient: return (0.5, 0.5) return tuple(self.pattern.Center()) def SetCenter(self, center): if self.pattern.__class__ == LinearGradient: return p = apply(Point, center) self.pattern = self.pattern.Duplicate() self.pattern.SetCenter(p) self.issue(CHANGED) def SetDirection(self, dir): if self.pattern.__class__ == RadialGradient: return dir = apply(Point, dir) self.pattern = self.pattern.Duplicate() self.pattern.SetDirection(dir) self.issue(CHANGED) def EditModes(self): if self.pattern.__class__ == LinearGradient: return (0, 1) elif self.pattern.__class__ == RadialGradient: return (1, 0) else: return (1, 1) def edit_gradient(self): gradient = gradientedit.EditGradient(self, self.gradient) if gradient is not None: pattern = self.pattern.Duplicate() pattern.SetGradient(gradient) self.SetPattern(pattern) self.issue(CHANGED)
class Clipboard: """ Clipboard is a standard clipboar with copy, cut and past functions. It is showed as table that can be scrolled and several buttons to operate. Compared to a standard clipboard it has the function paste-overwrite. It has also the function ramp to transform two levels in a ramp. """ def __init__(self, root, datawve, updateview, row0, col0): """ Create a Clipboard. :param root: is the top level Tkinterface where the clipboard sits. :param datawve: is the list of poins from which the data is copied and pasted :param updateview: is the function called when the main data is changed (paste/cut action) :param row0: is th first row of the grid where the clipborad sits :param col0: is th first column of the grid where the clipborad sits """ self.root = root self.datawve = datawve self.updateview = updateview self.dataclpbrd = [] self.clipboardtime = 0 row = row0 col = col0 rowspan = 1 colspan = 1 self.tableclipboard = Table(root, self.dataclpbrd, ('step', 'dt [s]', ('voltage [V]', VCOL), ('current [A]', CCOL)), row, col, CLIPROW, TABLECOL) row += CLIPROW+1 col = col0 colspan = 1 insertlabelrow(root, row, col, ('beg step', None, 'end step')) self.ivarstepbeg = IntVar() self.ivarstepend = IntVar() insertentryrow(root, row, col, (None, self.ivarstepbeg, None, self.ivarstepend)) col = col0+TABLECOL Button(root, text="Copy", command=self.butcmdcopy).grid(row=row, column=col, sticky=E+W, padx=8) col += colspan Button(root, text="Cut", command=self.butcmdcut).grid(row=row, column=col, sticky=E+W, padx=8) row += rowspan col = col0 insertlabelrow(root, row, col, ('paste step', None, 'paste times')) self.ivarpastestep = IntVar() self.ivarpastetimes = IntVar() self.ivarpastetimes.set(1) insertentryrow(root, row, col, (None, self.ivarpastestep, None, self.ivarpastetimes)) col = col0+TABLECOL Button(root, text="Paste Ins", command=self.butcmdpasteins).grid(row=row, column=col, sticky=E+W, padx=8) col += colspan Button(root, text="Paste Ovw", command=self.butcmdpasteovw).grid(row=row, column=col, sticky=E+W, padx=8) row += rowspan col = col0 insertlabelrow(root, row, col, ('coef (t,v,c)', )) self.dvartcoeff = DoubleVar() self.dvarvcoeff = DoubleVar() self.dvarccoeff = DoubleVar() insertentryrow(root, row, col, (None, self.dvartcoeff, self.dvarvcoeff, self.dvarccoeff)) col = col0+TABLECOL Button(root, text="Amp Clipb", command=self.butcmdampliclip).grid(row=row, column=col, sticky=E+W, padx=8) col += colspan Button(root, text="Trn Clipb", command=self.butcmdtransclip).grid(row=row, column=col, sticky=E+W, padx=8) row += rowspan col = col0 insertlabelrow(root, row, col, ('rmp steps', )) self.ivarrampsteps = IntVar() self.ivarrampsteps.set(10) insertentryrow(root, row, col, (None, self.ivarrampsteps, None, None)) col = col0+TABLECOL Button(root, text="Rmp Clipb", command=self.butcmdramp).grid(row=row, column=col, sticky=E+W, padx=8) def setbegin(self, r): """ Set begin row from which operate. :param r: is the begin row (index) of the data from which copy/paste/cut will operate """ if r < len(self.datawve): self.ivarstepbeg.set(r) self.ivarpastestep.set(r) def setend(self, r): """ Set end row from which operate. :param r: is the end row (index) of the data from which copy/cut will operate """ if r < len(self.datawve): self.ivarstepend.set(r) def butcmdcopy(self): """ Copy from data (from begin to end) to clipboard. Timings in the clipboard are stored as delta. :returns: True if the operation was succseful """ sb = self.ivarstepbeg.get() se = self.ivarstepend.get() if sb < 0 or sb >= len(self.datawve) or se < 0 or se >= len(self.datawve) or se < sb: return False del self.dataclpbrd[:] self.clipboardtime = 0 if sb > 0: t0 = self.datawve[sb-1][0] else: t0 = 0 t00 = t0 for i in range(sb, se+1): lne = self.datawve[i] t1 = lne[0] self.dataclpbrd.append([t1-t0]+lne[1:]) t0 = t1 self.clipboardtime = t0-t00 self.tableclipboard.updateview() return True def butcmdcut(self): """ Cut from clipboard (begin to help) to data. Timings in the clipboard are stored as delta. :returns: True if the operation was succseful. """ if not self.butcmdcopy(): return False for i in range(self.ivarstepend.get()+1, len(self.datawve)): self.datawve[i][TPOS] -= self.clipboardtime sb = self.ivarstepbeg.get() for i in range(self.ivarstepend.get()-sb+1): del self.datawve[sb] self.tableclipboard.updateview() self.updateview() return True def paste(self): """ Paste from clipboard to data (paste step). Timings in the data are restored as absolute timings. :returns: True if the operation was succseful """ i = self.ivarpastestep.get() if i > 0: t0 = self.datawve[i-1][0] else: t0 = 0 for t in range(self.ivarpastetimes.get()): for lne in self.dataclpbrd: t1 = lne[0]+t0 self.datawve.insert(i, [t1]+lne[1:]) i += 1 t0 = t1 return i def butcmdpasteins(self): """ Paste from clipboard inserting into data (paste step). Timings in the data are restored as absolute timings. :returns: True if the operation was succseful """ i = self.paste() dt = self.clipboardtime*self.ivarpastetimes.get() for i in range(i, len(self.datawve)): self.datawve[i][0] += dt self.updateview() def butcmdpasteovw(self): """ Paste from clipboard overwriting data (paste step) with timings lower the clipboard data. Timings in the data are restored as absolute timings. :returns: True if the operation was succseful """ i = self.paste() if i > 0: t0 = self.datawve[i-1][0] else: t0 = 0 while i < len(self.datawve) and self.datawve[i][0] <= t0: del self.datawve[i] self.updateview() def butcmdampliclip(self): """ Clipboard data is amplified (attenuated if factor is <1). Also timing can be alterated. """ coeff = (self.dvartcoeff.get(), self.dvarvcoeff.get(), self.dvarccoeff.get()) acc = 0 for l in self.dataclpbrd: for i in range(3): l[i] *= coeff[i] acc += l[0] self.clipboardtime = acc self.tableclipboard.updateview() def butcmdtransclip(self): """ Clipboard data is translated. Also timing can be translated since the timing is stored as relative only the first occurence is alered. :returns: True if the operation was succseful """ if len(self.dataclpbrd) <= 0: return False self.dataclpbrd[0][TPOS] += self.dvartcoeff.get() self.clipboardtime += self.dvartcoeff.get() # only the first occurency of time is updated coeff = (0, self.dvarvcoeff.get(), self.dvarccoeff.get()) # time is not traslated because stored as delta on the clipboard for l in self.dataclpbrd: for i in range(1, 3): l[i] += coeff[i] self.tableclipboard.updateview() return True def butcmdramp(self): """ Clipboard first and last rows are used to make a ramp of given number of steps. :returns: True if the operation was succseful """ if len(self.dataclpbrd) <= 0: return False beg = self.dataclpbrd[0][1:] end = self.dataclpbrd[-1][1:] steps = self.ivarrampsteps.get()-1 deltastep = [(e-b)/steps for e, b in zip(end, beg)] tstep = (self.clipboardtime-self.dataclpbrd[0][0])/steps del self.dataclpbrd[1:] for s in range(steps): beg = [a+b for a, b in zip(beg, deltastep)] self.dataclpbrd.append([tstep]+beg) self.tableclipboard.updateview() return True
def test_default(self): v = DoubleVar(self.root) self.assertEqual(0.0, v.get())
class ScalePanel(PluginPanel): name = 'ScaleAndMirror' title = _("Scale and Mirror") def init(self, master): PluginPanel.init(self, master) self.width_priority = 1 root = self.mw.root self.var_width = DoubleVar(root) self.var_height = DoubleVar(root) unit = '%' jump = 5 self.var_proportional = IntVar(root) self.var_proportional.set(0) self.var_basepoint = StringVar(root) self.var_basepoint.set('C') #--------------------------------------------------------- top = TFrame(self.panel, style='FlatFrame') top.pack(side=TOP, fill=BOTH) #--------------------------------------------------------- # Horisontal size size_frameH = TFrame(top, style='FlatFrame', borderwidth=3) size_frameH.pack(side=TOP, fill=BOTH) label = TLabel(size_frameH, style='FlatLabel', image='size_h') label.pack(side=LEFT, padx=5) self.entry_width = TSpinbox(size_frameH, var=100, vartype=1, textvariable=self.var_width, min=-30000, max=30000, step=jump, width=6, command=self.apply_scale) self.entry_width.pack(side=LEFT) self.entry_width.down_button.bind('<ButtonRelease>', self.entry_width_chang) self.entry_width.down_button.bind('<KeyRelease>', self.entry_width_chang) self.entry_width.up_button.bind('<ButtonRelease>', self.entry_width_chang) self.entry_width.up_button.bind('<KeyRelease>', self.entry_width_chang) self.entry_width.entry.bind('<ButtonRelease>', self.entry_width_chang) self.entry_width.entry.bind('<KeyRelease>', self.entry_width_chang) self.entry_width.entry.bind('<FocusOut>', self.entry_width_chang) self.entry_width.entry.bind('<FocusIn>', self.entry_width_FocusIn) self.labelwunit = TLabel(size_frameH, style='FlatLabel', text=unit) self.labelwunit.pack(side=LEFT, padx=5) self.hflip = BooleanVar(root) self.hflip.set(0) button = TCheckbutton(size_frameH, image="pstrip_hflip", style='ToolBarCheckButton', variable=self.hflip, command=None) button.pack(side=LEFT) #--------------------------------------------------------- # Vertical size_frameV = TFrame(top, style='FlatFrame', borderwidth=3) size_frameV.pack(side=TOP, fill=BOTH) label = TLabel(size_frameV, style='FlatLabel', image='size_v') label.pack(side=LEFT, padx=5) self.entry_height = TSpinbox(size_frameV, var=100, vartype=1, textvariable=self.var_height, min=-30000, max=30000, step=jump, width=6, command=self.apply_scale) self.entry_height.pack(side=LEFT) self.entry_height.down_button.bind('<ButtonRelease>', self.entry_height_chang) self.entry_height.down_button.bind('<KeyRelease>', self.entry_height_chang) self.entry_height.up_button.bind('<ButtonRelease>', self.entry_height_chang) self.entry_height.up_button.bind('<KeyRelease>', self.entry_height_chang) self.entry_height.entry.bind('<ButtonRelease>', self.entry_height_chang) self.entry_height.entry.bind('<KeyRelease>', self.entry_height_chang) self.entry_height.entry.bind('<FocusOut>', self.entry_height_chang) self.entry_height.entry.bind('<FocusIn>', self.entry_height_FocusIn) self.labelhunit = TLabel(size_frameV, style='FlatLabel', text=unit) self.labelhunit.pack(side=LEFT, padx=5) self.vflip = BooleanVar(root) self.vflip.set(0) button = TCheckbutton(size_frameV, image="pstrip_vflip", style='ToolBarCheckButton', variable=self.vflip, command=None) button.pack(side=LEFT) #--------------------------------------------------------- # Proportional chek self.proportional_check = TCheckbutton(top, text=_("Proportional"), variable=self.var_proportional, command=self.proportional) self.proportional_check.pack(side=TOP, anchor=W, padx=5, pady=5) #--------------------------------------------------------- # Basepoint check label = TLabel(top, style='FlatLabel', text=_("Basepoint:")) label.pack(side=TOP, fill=BOTH, padx=5) basepoint_frame = TLabelframe(top, labelwidget=label, style='Labelframe', borderwidth=4) basepoint_frame.pack(side=TOP, fill=X, padx=5, pady=2) self.Basepoint = BasePointSelector(basepoint_frame, anchor=self.var_basepoint) self.Basepoint.pack(side=LEFT, fill=BOTH, padx=5) label = TLabel(basepoint_frame, style='FlatLabel', image='coordinate_sys') label.pack(side=LEFT, fill=BOTH, padx=10) #--------------------------------------------------------- # Button frame button_frame = TFrame(top, style='FlatFrame', borderwidth=5) button_frame.pack(side=BOTTOM, fill=BOTH) self.update_buttons = [] self.button = UpdatedButton(top, text=_("Apply"), command=self.apply_scale) self.button.pack(in_=button_frame, side=BOTTOM, expand=1, fill=X, pady=3) self.button_copy = UpdatedButton(top, text=_("Apply to Copy"), command=self.apply_to_copy) self.button_copy.pack(in_=button_frame, side=BOTTOM, expand=1, fill=X) self.init_from_doc() self.subscribe_receivers() ############################################################################### def subscribe_receivers(self): self.document.Subscribe(SELECTION, self.Update) def unsubscribe_receivers(self): self.document.Unsubscribe(SELECTION, self.Update) def init_from_doc(self, *arg): self.Update() def Update(self, *arg): if self.is_selection(): self.entry_width.set_state(NORMAL) self.entry_height.set_state(NORMAL) self.proportional_check['state'] = NORMAL self.button['state'] = NORMAL self.button_copy['state'] = NORMAL else: self.entry_width.set_state(DISABLED) self.entry_height.set_state(DISABLED) self.proportional_check['state'] = DISABLED self.button['state'] = DISABLED self.button_copy['state'] = DISABLED def entry_width_FocusIn(self, *arg): self.width_priority = 1 def entry_height_FocusIn(self, *arg): self.width_priority = 0 def ScaleSelected(self, h, v, cnt_x=None, cnt_y=None): text = _("Scale") if self.document.selection: self.document.begin_transaction(text) try: try: br = self.document.selection.coord_rect hor_sel = br.right - br.left ver_sel = br.top - br.bottom if cnt_x is None: cnt_x = hor_sel / 2 + br.left if cnt_y is None: cnt_y = ver_sel / 2 + br.bottom trafo = Trafo(h, 0, 0, v, cnt_x - cnt_x * h, cnt_y - cnt_y * v) self.document.TransformSelected(trafo, text) except: self.document.abort_transaction() finally: self.document.end_transaction() def ScaleAndCopy(self, h, v, cnt_x=None, cnt_y=None): text = _("Scale&Copy") if self.document.selection: self.document.begin_transaction(text) try: try: br = self.document.selection.coord_rect hor_sel = br.right - br.left ver_sel = br.top - br.bottom if cnt_x is None: cnt_x = hor_sel / 2 + br.left if cnt_y is None: cnt_y = ver_sel / 2 + br.bottom trafo = Trafo(h, 0, 0, v, cnt_x - cnt_x * h, cnt_y - cnt_y * v) self.document.ApplyToDuplicate() self.document.TransformSelected(trafo, text) except: self.document.abort_transaction() finally: self.document.end_transaction() def entry_height_chang(self, *arg): if self.var_proportional.get(): self.var_width.set(self.var_height.get()) def entry_width_chang(self, *arg): if self.var_proportional.get(): self.var_height.set(self.var_width.get()) def proportional(self): if self.width_priority: self.entry_width_chang() else: self.entry_height_chang() def apply_scale(self, *arg): if self.button["state"] == DISABLED: return self.proportional() width = self.var_width.get() height = self.var_height.get() br = self.document.selection.coord_rect hor_sel = br.right - br.left ver_sel = br.top - br.bottom cnt_x, cnt_y = self.Basepoint.get_basepoint(hor_sel, ver_sel, br.left, br.bottom) h = width / 100 if h == 0: h = 1 if self.hflip.get(): h = -1 * h v = height / 100 if v == 0: v = 1 if self.vflip.get(): v = -1 * v if arg and arg[0] == 'Duplicate': self.ScaleAndCopy(h, v, cnt_x, cnt_y) else: self.ScaleSelected(h, v, cnt_x, cnt_y) def apply_to_copy(self): self.apply_scale('Duplicate') def is_selection(self): return (len(self.document.selection) > 0)
def test_invalid_value(self): v = DoubleVar(self.root, name="name") self.root.globalsetvar("name", "value") with self.assertRaises(ValueError): v.get()
class gui(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent self.initUI() self.centerUI(w=600, h=250) def initUI(self): self.parent.title("FIND BLR COEFFICIENT VALUE") self.pack(fill=BOTH, expand=True) self.columnconfigure(0, weight=1) # self.rowconfigure(0, weight=1) # weight attibute is used to make them growable ###### GUI Control Variables ###### self.LIMIT_L = IntVar() self.LIMIT_H = IntVar() self.PULSE_R = IntVar() self.PULSE_L = IntVar() self.pulse_height = DoubleVar() self.hdf5_file = StringVar() self.PMT = IntVar() self.EVENT = IntVar() self.amplitude_range = DoubleVar() self.delta = DoubleVar() self.noise_sigma = DoubleVar() self.coeff = DoubleVar() #self.DRAW = BooleanVar() search = Image.open("next_logo.jpg") search_temp = search.resize((170, 200), Image.ANTIALIAS) search_aux = ImageTk.PhotoImage(search_temp) label1 = Label(self, image=search_aux) label1.image = search_aux label1.grid(row=0, column=0, columnspan=10, rowspan=10, sticky=E + W + S + N) self.hdf5_file.set("2052.h5.z") e1 = Entry(self, textvariable=self.hdf5_file, width=30) e1.grid(row=1, column=1, sticky=W, columnspan=5, pady=5) e1_label = Label(self, text="HDF5 file") e1_label.grid(row=0, column=1, sticky=W, columnspan=5, pady=5) self.PMT.set("0") sb1 = Spinbox(self, from_=0, to=12, width=3, textvariable=self.PMT) sb1.grid(row=3, column=2, sticky=W) sb1_label = Label(self, text="PMT") sb1_label.grid(row=2, column=2, padx=0, sticky=W) self.EVENT.set("0") sb1 = Spinbox(self, from_=0, to=1000, width=5, textvariable=self.EVENT) sb1.grid(row=3, column=3, sticky=W) sb1_label = Label(self, text="EVENT") sb1_label.grid(row=2, column=3, padx=0, sticky=W) self.LIMIT_L.set("19000") sb1 = Spinbox(self, from_=0, to=100000, width=5, textvariable=self.LIMIT_L) sb1.grid(row=5, column=2, sticky=W) sb1_label = Label(self, text="ROI Start ") sb1_label.grid(row=4, column=2, padx=0, sticky=W) self.LIMIT_H.set("22500") sb1 = Spinbox(self, from_=0, to=100000, width=5, textvariable=self.LIMIT_H) sb1.grid(row=5, column=3, sticky=W) sb1_label = Label(self, text="ROI End ") sb1_label.grid(row=4, column=3, padx=0, sticky=W) self.PULSE_R.set("20142") sb1 = Spinbox(self, from_=0, to=100000, width=8, textvariable=self.PULSE_R) sb1.grid(row=5, column=4, sticky=E) sb1_label = Label(self, text=" Pulse Rise") sb1_label.grid(row=4, column=4, padx=0, sticky=E) self.PULSE_L.set("1200") sb1 = Spinbox(self, from_=0, to=5000, width=8, textvariable=self.PULSE_L) sb1.grid(row=5, column=5, sticky=E) sb1_label = Label(self, text=" Pulse Length") sb1_label.grid(row=4, column=5, padx=0, sticky=E) sb1_label = Label(self, text=" ") sb1_label.grid(row=2, column=7, padx=0, sticky=W) sb1_label = Label(self, text=" ") sb1_label.grid(row=6, column=7, padx=0, sticky=W) self.pulse_height.set("545.5") sb1 = Entry(self, width=8, textvariable=self.pulse_height) sb1.grid(row=7, column=3, sticky=E) sb1_label = Label(self, text=" Amplitude") sb1_label.grid(row=6, column=3, padx=0, sticky=E) self.amplitude_range.set("2") sb1 = Entry(self, width=8, textvariable=self.amplitude_range) sb1.grid(row=7, column=4, sticky=E) sb1_label = Label(self, text=" Loop Range") sb1_label.grid(row=6, column=4, padx=0, sticky=E) self.delta.set("0.1") sb1 = Entry(self, width=8, textvariable=self.delta) sb1.grid(row=7, column=5, sticky=E) sb1_label = Label(self, text=" Loop Delta") sb1_label.grid(row=6, column=5, padx=0, sticky=E) self.noise_sigma.set("4") sb1 = Entry(self, width=3, textvariable=self.noise_sigma) sb1.grid(row=5, column=6, sticky=E) sb1_label = Label(self, text=" Noise Threshold") sb1_label.grid(row=4, column=6, padx=0, sticky=E) sb_coeff_label = Label(self, text="Coefficient ") sb_coeff_label.grid(row=0, column=6, padx=0, sticky=E) self.sb_coeff = Label(self) self.sb_coeff.grid(row=1, column=6, padx=0, sticky=E) # MAIN BUTTONS obtn = Button(self, text="GO!!", command=self.find_C) obtn.grid(row=14, column=4, sticky=E, pady=10) cbtn = Button(self, text="Quit", command=self.quit) cbtn.grid(row=14, column=5, sticky=E, pady=10) hbtn = Button(self, text="Help", command=self.help_f) hbtn.grid(row=14, column=0, sticky=W, pady=10) def help_f(self): top = Toplevel() top.title("HELP") msg = Message(top, width=500, text="COEFF Calibration Procedure: \n \ Input Start Point and Length of the pulse \n \ Input an initial guess of the pulse amplitude \n \ Use a ROI with at least 1000 samples of baseline \n \ and 1000 samples after pulse end \n \ Adjust loop range and step until a graph error \n \ with a minimum is observed \n \ Refine the search to increase precision") msg.pack() button = Button(top, text="Close", command=top.destroy) button.pack() def find_C(self): draw = False LIMIT_L = self.LIMIT_L.get() #19000 LIMIT_H = self.LIMIT_H.get() #22500 PULSE_R = self.PULSE_R.get() #20142 PULSE_L = self.PULSE_L.get() #1200 pulse_height = self.pulse_height.get() #545 hdf5_file = self.hdf5_file.get() #'2052.h5.z' PMT = self.PMT.get() event = self.EVENT.get() amplitude_range = self.amplitude_range.get() #2 delta = self.delta.get() #0.1 noise_sigma = self.noise_sigma.get() #4 coeff_aux = fc.find_coeff(LIMIT_L, LIMIT_H, PULSE_R, PULSE_L, pulse_height, hdf5_file, PMT, event, amplitude_range, delta, noise_sigma, draw) plt.show() self.sb_coeff.configure(text=str(coeff_aux)) def centerUI(self, w, h): sw = self.parent.winfo_screenwidth() sh = self.parent.winfo_screenheight() x = (sw - w) / 2 y = (sh - h) / 2 self.parent.geometry('%dx%d+%d+%d' % (w, h, x, y))
class ChemicalEditor: """Gets the contaminant properties.""" def __init__(self, master, system, chemical, chemicals, database, editflag): """Constructor method. Defines the parameters to be obtained in this window.""" self.master = master self.fonttype = system.fonttype self.version = system.version self.superfont = get_superfont(self.fonttype) #superscript font self.frame = Frame(master.frame) self.tframe = Frame(master.tframe) self.bframe = Frame(master.bframe) self.system = system self.database = database self.top = None #flag for existence of toplevel# self.tkfont = tkFont.Font(font=system.fonttype) self.soluableflag = chemical.soluable self.editflag = editflag self.cancelflag = 0 self.chemicals = chemicals self.diffunit = system.diffunit self.diffunits = system.diffunits if self.soluableflag == 1: self.database = database self.chemical = chemical self.name = StringVar(value='') self.formula = StringVar(value='') self.MW = DoubleVar(value=0) self.temp = DoubleVar(value=0) self.Dw = DoubleVar(value=0) self.Ref = StringVar(value='') self.Koc = DoubleVar(value=0) self.Kdoc = DoubleVar(value=0) self.Kf = DoubleVar(value=0) self.N = DoubleVar(value=0) if editflag == 1: #Detemine whether the chemical is added or edited self.name.set(self.chemical.name) self.formula.set(self.chemical.formula) self.MW.set(self.chemical.MW) self.temp.set(self.chemical.temp) self.Dw.set(self.chemical.Dw) self.Koc.set(self.chemical.Koc) self.Kdoc.set(self.chemical.Kdoc) self.Ref.set(self.chemical.Ref) self.Kf.set(self.chemical.Kf) self.N.set(self.chemical.N) else: self.name = StringVar(value=' ') self.formula = StringVar(value=' ') self.MW = DoubleVar(value=100) self.temp = DoubleVar(value=0) self.Dw = DoubleVar(value=0) self.Koc = DoubleVar(value=0) self.Kdoc = DoubleVar(value=0) self.Kf = DoubleVar(value=0) self.N = DoubleVar(value=0) if editflag == 1: #Detemine whether the chemical is added or edited self.name.set(chemical.name) def make_widgets(self): """Make the widgets for the window.""" self.bgcolor = self.frame.cget('bg') self.instructions = Label( self.tframe, text= ' Please provide the following chemical properties: ' ) self.blankcolumn = Label(self.frame, text=' ', width=2) self.namecolumn = Label(self.frame, text=' ', width=20) self.MWcolumn = Label(self.frame, text=' ', width=12) self.tempcolumn = Label(self.frame, text=' ', width=10) self.Dwcolumn = Label(self.frame, text=' ', width=18) self.Koccolumn = Label(self.frame, text=' ', width=18) self.Kdoccolumn = Label(self.frame, text=' ', width=18) self.Refcolumn = Label(self.frame, text=' ', width=20) self.Rightcolumn = Label(self.frame, text=' ', width=2) self.namelabel = Label(self.frame, text='Chemical name') self.MWlabel = Label(self.frame, text='Molecular\n weight') self.templabel = Label(self.frame, text='Temperature') self.Dwlabel = Label(self.frame, text='Molecular diffusivity\n in water') self.Koclabel = Label(self.frame, text='Organic carbon\n partition coefficient') self.Kdoclabel = Label( self.frame, text='Dissolved organic carbon\n partition coefficient') self.Reflabel = Label(self.frame, text='Reference') self.tempunits = Label(self.frame, text=unichr(176) + 'C') self.Dwunits = Label(self.frame, text=self.diffunit) self.Kocunits = Label(self.frame, text='log(L/kg)') self.Kdocunits = Label(self.frame, text='log(L/kg)') self.importbutton = Button(self.frame, text='From Database', width=20, command=self.importchemical) self.okbutton = Button(self.frame, text='OK', width=20, command=self.OK) self.cancelbutton = Button(self.frame, text='Cancel', width=20, command=self.Cancel) self.blank1 = Label(self.frame, text=' ') self.blank2 = Label(self.frame, text=' ') #show the widgets on the grid self.instructions.grid(row=0, column=0, columnspan=6, padx=8, sticky='W') self.blankcolumn.grid(row=1, column=0, sticky='WE', padx=1, pady=1) self.namecolumn.grid(row=1, column=1, sticky='WE', padx=1, pady=1) self.MWcolumn.grid(row=1, column=2, sticky='WE', padx=1, pady=1) self.tempcolumn.grid(row=1, column=3, sticky='WE', padx=1, pady=1) self.Dwcolumn.grid(row=1, column=4, sticky='WE', padx=1, pady=1) self.Koccolumn.grid(row=1, column=5, sticky='WE', padx=1, pady=1) self.Kdoccolumn.grid(row=1, column=6, sticky='WE', padx=1, pady=1) self.Refcolumn.grid(row=1, column=7, sticky='WE', padx=1, pady=1) self.Rightcolumn.grid(row=1, column=8, sticky='WE', padx=1, pady=1) self.namelabel.grid(row=2, column=1, sticky='WE', padx=1, pady=1) self.MWlabel.grid(row=2, column=2, sticky='WE', padx=1, pady=1) self.templabel.grid(row=2, column=3, sticky='WE', padx=1, pady=1) self.Dwlabel.grid(row=2, column=4, sticky='WE', padx=1, pady=1) self.Koclabel.grid(row=2, column=5, sticky='WE', padx=1, pady=1) self.Kdoclabel.grid(row=2, column=6, sticky='WE', padx=1, pady=1) self.Reflabel.grid(row=2, column=7, sticky='WE', padx=1, pady=1) self.tempunits.grid(row=3, column=3, sticky='WE', padx=1, pady=1) self.Dwunits.grid(row=3, column=4, sticky='WE', padx=1, pady=1) self.Kocunits.grid(row=3, column=5, sticky='WE', padx=1, pady=1) self.Kdocunits.grid(row=3, column=6, sticky='WE', padx=1, pady=1) if self.soluableflag == 1: if self.editflag == 0: self.namewidget = Entry(self.frame, width=18, justify='center', textvariable=self.name) self.tempwidget = Entry(self.frame, width=10, justify='center', textvariable=self.temp) else: self.namewidget = Label(self.frame, width=18, justify='center', textvariable=self.name) self.tempwidget = Label(self.frame, width=10, justify='center', textvariable=self.temp) self.Dwwidget = Entry(self.frame, width=16, justify='center', textvariable=self.Dw) self.MWwidget = Entry(self.frame, width=10, justify='center', textvariable=self.MW) self.Kocwidget = Entry(self.frame, width=16, justify='center', textvariable=self.Koc) self.Kdocwidget = Entry(self.frame, width=16, justify='center', textvariable=self.Kdoc) self.Refwidget = Entry(self.frame, width=18, justify='center', textvariable=self.Ref) self.namewidget.grid(row=4, column=1, padx=2, pady=1) self.MWwidget.grid(row=4, column=2, padx=2, pady=1) self.tempwidget.grid(row=4, column=3, padx=2, pady=1) self.Dwwidget.grid(row=4, column=4, padx=2, pady=1) self.Kocwidget.grid(row=4, column=5, padx=2, pady=1) self.Kdocwidget.grid(row=4, column=6, padx=2, pady=1) self.Refwidget.grid(row=4, column=7, padx=2, pady=1) else: self.namewidget = Entry(self.frame, width=18, justify='center', textvariable=self.name) self.Dwwidget = Label(self.frame, width=16, justify='center', text='Not applicable') self.Kocwidget = Label(self.frame, width=16, justify='center', text='Not applicable') self.Kdocwidget = Label(self.frame, width=16, justify='center', text='Not applicable') self.namewidget.grid(row=4, column=1, padx=2, pady=1) self.Dwwidget.grid(row=4, column=3, padx=2, pady=1) self.Kocwidget.grid(row=4, column=4, padx=2, pady=1) self.Kdocwidget.grid(row=4, column=5, padx=2, pady=1) self.blank1.grid(row=5) if self.editflag == 0: self.importbutton.grid(row=6, columnspan=11) self.okbutton.grid(row=7, columnspan=11) self.cancelbutton.grid(row=8, columnspan=11) self.blank2.grid(row=9) self.okbutton.bind('<Return>', self.OK) self.focusbutton = self.okbutton if int((self.tkfont.measure(self.Ref.get()) + 10) * 1.1424219345 / 8) + 1 > 18: self.Refwidget.config( width=int((self.tkfont.measure(self.Ref.get()) + 10) * 1.1424219345 / 8) + 3) if int((self.tkfont.measure(self.name.get()) + 10) * 1.1424219345 / 8) + 1 > 18: self.namewidget.config( width=int((self.tkfont.measure(self.name.get()) + 10) * 1.1424219345 / 8) + 3) self.master.geometry() self.master.center() def importchemical(self): if self.top is None: self.top = CapSimWindow(master=self.master, buttons=2) self.top.make_window( ChemicalImporter(self.top, self.system, self.database)) self.top.tk.mainloop() if self.top.window.cancelflag == 0: self.updatechemical(self.top.window) if self.top is not None: self.top.destroy() self.top = None elif self.top is not None: tkmb.showerror( title=self.system.version, message= 'Please close the existing parameter input window first.') self.top.tk.focus() def updatechemical(self, window): self.name.set(window.name.get()) self.formula.set(window.formula.get()) self.MW.set(window.MW.get()) self.temp.set(window.temp.get()) self.Koc.set(window.Koc.get()) self.Kdoc.set(window.Kdoc.get()) self.Ref.set(window.Ref.get()) self.Kf.set(window.Kf.get()) self.N.set(window.N.get()) if self.diffunit == self.diffunits[0]: self.Dw.set(window.Dw.get()) elif self.diffunit == self.diffunits[1]: Dw = window.Dw.get() * 86400 * 365 if Dw > 1: self.Dw.set(round(Dw, 2)) else: i = 2 while Dw / 100 < 0.1**i: i = i + 1 self.Dw.set(round(Dw, i)) self.frame.update() if int((self.tkfont.measure(self.Ref.get()) + 10) * 1.1424219345 / 8) + 1 > 20: self.Refwidget.config( width=int((self.tkfont.measure(self.Ref.get()) + 10) * 1.1424219345 / 8) + 3) if int((self.tkfont.measure(self.name.get()) + 10) * 1.1424219345 / 8) + 1 > 20: self.namewidget.config( width=int((self.tkfont.measure(self.name.get()) + 10) * 1.1424219345 / 8) + 3) self.master.geometry() self.master.center() def OK(self, event=None): """Finish and move on. Checks that the number chemicals are less than the total number of chemicals in database.""" if self.editflag == 0: check = [(chemical.name == self.name.get()) for chemical in self.chemicals[0:-1]] else: check = [0] if self.master.window.top is not None: self.master.open_toplevel() elif sum(check) >= 1: self.chemicals_error() elif self.name.get() == '' or self.name.get().count(' ') == len( self.name.get()): self.name_error() elif self.Dw.get() == 0: self.Dw_error() else: self.master.tk.quit() def chemicals_error(self): tkmb.showerror(title=self.version, message='This chemical has already been selected!') self.focusbutton = self.okbutton self.master.tk.lift() def name_error(self): tkmb.showerror(title=self.version, message='Please input the name for the chemical!') self.focusbutton = self.okbutton self.master.tk.lift() def Dw_error(self): tkmb.showerror( title=self.version, message= 'The diffusivity of the chemical can not be zero, please correct!') self.focusbutton = self.okbutton self.master.tk.lift() def Cancel(self): try: self.name.set(self.chemical.name) self.MW.set(self.chemical.MW.get()) self.formula.set(self.chemical.formula.get()) self.temp.set(self.chemical.temp.get()) self.Dw.set(self.chemical.Dw.get()) self.Koc.set(self.chemical.Koc.get()) self.Kdoc.set(self.chemical.Kdoc.get()) self.Ref.set(self.chemical.Ref.get()) self.Kf.set(self.chemical.Kf.get()) self.N.set(self.chemical.N.get()) except: self.cancelflag = 1 if self.master.window.top is not None: self.master.open_toplevel() else: self.master.tk.quit()
class OdeIntGui(object): def __init__(self, master): self.frame = Frame(master) self.frame.grid() #--- Subframes self.frame_menus = Frame(self.frame) self.frame_entries = Frame(self.frame) self.frame_canvas = Frame(self.frame) self.frame_buttons = Frame(self.frame) self.frame_menus.grid(row=0) self.frame_entries.grid(row=1) self.frame_canvas.grid(row=2) self.frame_buttons.grid(row=3) #--- #--- String variables self.method = StringVar(self.frame_menus) self.system = StringVar(self.frame_menus) # SET DEFAULTS HERE self.method.set("4th-order Runge-Kutta") self.system.set("Lorenz system") self.prev_system = self.system.get() #--- #--- Double variables self.dt = DoubleVar(self.frame_entries) self.t0 = DoubleVar(self.frame_entries) self.X0a = DoubleVar(self.frame_entries) self.X0b = DoubleVar(self.frame_entries) self.X0c = DoubleVar(self.frame_entries) self.X0d = DoubleVar(self.frame_entries) self.X0e = DoubleVar(self.frame_entries) self.X0f = DoubleVar(self.frame_entries) #--- #--- Integer variables self.n = IntVar(self.frame_entries) #--- #--- Menu subframe self.label_methods = Label(self.frame_menus, text="Method:") self.menu_methods = OptionMenu(self.frame_menus, self.method, *methods.keys(), command=self.menu_onclick) self.label_systems = Label(self.frame_menus, text="System:") self.menu_systems = OptionMenu(self.frame_menus, self.system, *systems.keys(), command=self.menu_onclick) # Put the "number of steps" entry here too self.label_n = Label(self.frame_menus, text="Number of steps:") self.entry_n = Entry(self.frame_menus, textvariable=self.n, width=5) self.label_methods.grid(row=0, column=0) self.menu_methods.grid(row=0, column=1) self.label_systems.grid(row=0, column=2) self.menu_systems.grid(row=0, column=3) self.label_n.grid(row=0, column=4) self.entry_n.grid(row=0, column=5) #--- #--- Entry subframe self.label_dt = Label(self.frame_entries, text="Step size:") self.entry_dt = Entry(self.frame_entries, textvariable=self.dt, width=5) self.label_t0 = Label(self.frame_entries, text="Initial time:") self.entry_t0 = Entry(self.frame_entries, textvariable=self.t0, width=5) self.label_X0 = Label(self.frame_entries, text="Initial state:") self.entry_X0 = [ Entry(self.frame_entries, textvariable=self.X0a, width=5), Entry(self.frame_entries, textvariable=self.X0b, width=5), Entry(self.frame_entries, textvariable=self.X0c, width=5), Entry(self.frame_entries, textvariable=self.X0d, width=5), Entry(self.frame_entries, textvariable=self.X0e, width=5), Entry(self.frame_entries, textvariable=self.X0f, width=5), ] self.label_dt.grid(row=0, column=0) self.entry_dt.grid(row=0, column=1) self.label_t0.grid(row=0, column=2) self.entry_t0.grid(row=0, column=3) self.label_X0.grid(row=0, column=4) self.entry_X0[0].grid(row=0, column=6) self.entry_X0[1].grid(row=0, column=8) if dims[self.system.get()] >= 3: self.entry_X0[2].grid(row=0, column=10) if dims[self.system.get()] >= 4: self.entry_X0[3].grid(row=0, column=12) if dims[self.system.get()] >= 5: self.entry_X0[4].grid(row=0, column=14) if dims[self.system.get()] >= 6: self.entry_X0[5].grid(row=0, column=16) self.label_X0a = Label(self.frame_entries, text="") self.label_X0b = Label(self.frame_entries, text="") self.label_X0c = Label(self.frame_entries, text="") self.label_X0d = Label(self.frame_entries, text="") self.label_X0e = Label(self.frame_entries, text="") self.label_X0f = Label(self.frame_entries, text="") self.label_X0a.grid(row=0, column=5) self.label_X0b.grid(row=0, column=7) self.label_X0c.grid(row=0, column=9) self.label_X0d.grid(row=0, column=11) self.label_X0e.grid(row=0, column=13) self.label_X0f.grid(row=0, column=15) self.label_X0a.config(text=state_vars[self.system.get()][0]) self.label_X0b.config(text=state_vars[self.system.get()][1]) if dims[self.system.get()] >= 3: self.label_X0c.config(text=state_vars[self.system.get()][2]) if dims[self.system.get()] >= 4: self.label_X0d.config(text=state_vars[self.system.get()][3]) if dims[self.system.get()] >= 5: self.label_X0e.config(text=state_vars[self.system.get()][4]) if dims[self.system.get()] >= 6: self.label_X0f.config(text=state_vars[self.system.get()][5]) #--- #--- Canvas subframe self.figure = Figure(figsize=(7.8, 4.9)) self.canvas = FigureCanvasTkAgg(self.figure, master=self.frame_canvas) self.canvas.get_tk_widget().grid(row=2, column=0) #--- #--- Button subframe self.button_plot = Button(self.frame_buttons, text="Plot", command=self.plot) self.button_clear = Button(self.frame_buttons, text="Clear", command=self.clear_figure) self.button_quit = Button(self.frame_buttons, text="Quit", command=self.frame.quit) self.button_plot.grid(row=3, column=0) self.button_clear.grid(row=3, column=1) self.button_quit.grid(row=3, column=2) #--- def menu_onclick(self, event): print "%s with %s" % (self.system.get(), self.method.get()) # Adjust number of state variables self.entry_X0[0].grid_forget() self.entry_X0[1].grid_forget() if dims[self.prev_system] >= 3: self.entry_X0[2].grid_forget() if dims[self.prev_system] >= 4: self.entry_X0[3].grid_forget() if dims[self.prev_system] >= 5: self.entry_X0[4].grid_forget() if dims[self.prev_system] >= 6: self.entry_X0[5].grid_forget() self.entry_X0[0].grid(row=0, column=6) self.entry_X0[1].grid(row=0, column=8) if dims[self.system.get()] >= 3: self.entry_X0[2].grid(row=0, column=10) if dims[self.system.get()] >= 4: self.entry_X0[3].grid(row=0, column=12) if dims[self.system.get()] >= 5: self.entry_X0[4].grid(row=0, column=14) if dims[self.system.get()] >= 6: self.entry_X0[5].grid(row=0, column=16) # Update labels for state variables self.label_X0a.config(text="") self.label_X0b.config(text="") if dims[self.prev_system] >= 3: self.label_X0c.config(text="") if dims[self.prev_system] >= 4: self.label_X0f.config(text="") if dims[self.prev_system] >= 5: self.label_X0e.config(text="") if dims[self.prev_system] >= 6: self.label_X0f.config(text="") self.label_X0a.config(text=state_vars[self.system.get()][0]) self.label_X0b.config(text=state_vars[self.system.get()][1]) if dims[self.system.get()] >= 3: self.label_X0c.config(text=state_vars[self.system.get()][2]) if dims[self.system.get()] >= 4: self.label_X0d.config(text=state_vars[self.system.get()][3]) if dims[self.system.get()] >= 5: self.label_X0e.config(text=state_vars[self.system.get()][4]) if dims[self.system.get()] >= 6: self.label_X0f.config(text=state_vars[self.system.get()][5]) self.clear_figure() prev_system = self.system.get() def plot(self): cmd = ("../src/integrate %s %s -d %s -t %s " % (methods[self.method.get()], systems[self.system.get()], self.dt.get(), self.t0.get())) if dims[self.system.get()] >= 2: cmd += "-x %s -x %s " % (self.X0a.get(), self.X0b.get()) if dims[self.system.get()] >= 3: cmd += "-x %s " % self.X0c.get() if dims[self.system.get()] >= 4: cmd += "-x %s " % self.X0d.get() if dims[self.system.get()] >= 5: cmd += "-x %s " % self.X0e.get() if dims[self.system.get()] >= 6: cmd += "-x %s " % self.X0f.get() cmd += "-n %s -v " % self.n.get() print cmd print "Computing..." t0 = time.clock() # heard "shell=True" might not be safe? integration = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True) t1 = time.clock() print "Finished in %.9f s" % (t1 - t0) print "Processing data..." integration_stdout = integration.communicate()[0] print "Plotting..." data = [] for line in integration_stdout.split("\n"): if line != "": data.append(map(float, line.split(" "))) arrays = zip(*data) t = arrays[0] # TODO: fix this # ===== HACK ALERT ===== if len(arrays[1:]) == 2: self.graph = self.figure.add_subplot(111, projection='3d') self.graph.plot(arrays[1], arrays[2]) elif len(arrays[1:]) == 3: self.graph = self.figure.add_subplot(111, projection='3d') self.graph.plot(arrays[1], arrays[2], arrays[3]) #--- Especially need to fix these elif len(arrays[1:]) == 4: self.graph = self.figure.add_subplot(111, projection='3d') self.graph.plot(arrays[1], arrays[2], arrays[3]) elif len(arrays[1:]) == 6: self.graph = self.figure.add_subplot(111, projection='3d') self.graph.plot(arrays[1], arrays[2], arrays[3]) #--- self.canvas.draw() def clear_figure(self): self.figure.clear() self.canvas.draw()
class CreateStarDlg(SKModal): title = _("Create Star") def __init__(self, master, **kw): # This constructor is here just for illustration purposes; it's # not really needed here, as it simply passes all parameters on # to the base class' constructor. # # The parameter master is the window this dialog belongs to. It # should normally be the top-level application window. apply(SKModal.__init__, (self, master), kw) def build_dlg(self): # The SKModal constructor automatically calls this method to # create the widgets in the dialog. # # self.top is the top-level window of the dialog. All widgets of # the dialog must contained in it. top = self.top # The rest is normal Tkinter code. self.var_corners = IntVar(top) self.var_corners.set(5) label = Label(top, text = _("Corners"), anchor = 'e') label.grid(column = 0, row = 0, sticky = 'ew') entry = Entry(top, textvariable = self.var_corners, width = 15) entry.grid(column = 1, row = 0, sticky = 'ew') self.var_steps = IntVar(top) self.var_steps.set(2) label = Label(top, text = _("Steps"), anchor = 'e') label.grid(column = 0, row = 1, sticky = 'ew') entry = Entry(top, textvariable = self.var_steps, width = 15) entry.grid(column = 1, row = 1, sticky = 'ew') self.var_radius = DoubleVar(top) self.var_radius.set(100) label = Label(top, text = _("Radius"), anchor = 'e') label.grid(column = 0, row = 2, sticky = 'ew') entry = Entry(top, textvariable = self.var_radius, width = 15) entry.grid(column = 1, row = 2, sticky = 'ew') but_frame = Frame(top) but_frame.grid(column = 0, row = 3, columnspan = 2) button = Button(but_frame, text = _("OK"), command = self.ok) button.pack(side = 'left', expand = 1) # The self.cancel method is provided by the base class and # cancels the dialog. button = Button(but_frame, text = _("Cancel"), command = self.cancel) button.pack(side = 'right', expand = 1) def ok(self, *args): # This method is bound to the OK-button. Its purpose is to # collect the values of the various edit fields and pass them as # one parameter to the close_dlg method. # # close_dlg() saves its parameter and closes the dialog. corners = self.var_corners.get() steps = self.var_steps.get() radius = self.var_radius.get() self.close_dlg((corners, steps, radius))
class CMYKDigitizer(TFrame): def __init__(self, parent, callback, **kw): self.callback = callback TFrame.__init__(self, parent, style='FlatFrame', **kw) self.C_value = DoubleVar(0) self.M_value = DoubleVar(0) self.Y_value = DoubleVar(0) self.K_value = DoubleVar(0) self.A_value = DoubleVar(0) b = TLabel(self, style='HLine') b.pack(side=BOTTOM, fill=X) frame = TFrame(self, borderwidth=0, style='FlatFrame') frame.pack(side=BOTTOM) label = TLabel(frame, text=_("Opacity: ")) label.pack(side=LEFT) self.A_spin = TSpinbox(frame, min=0, max=255, step=1, vartype=0, width=7, textvariable=self.A_value, command=self.cmyk_component_changed) self.A_spin.pack(side=RIGHT) b = TLabel(self, style='HLine') b.pack(side=BOTTOM, fill=X) cmyk_frame = TFrame(self, borderwidth=2, style='FlatFrame') cmyk_frame.pack(side=LEFT, padx=10) frame = TFrame(cmyk_frame, borderwidth=2, style='FlatFrame') frame.pack(side=TOP) label = TLabel(frame, text="C: ") label.pack(side=LEFT) self.C_spin = TSpinbox(frame, min=0, max=100, step=1, vartype=1, width=7, textvariable=self.C_value, command=self.cmyk_component_changed) self.C_spin.pack(side=RIGHT) frame = TFrame(cmyk_frame, borderwidth=2, style='FlatFrame') frame.pack(side=TOP) label = TLabel(frame, text="M: ") label.pack(side=LEFT) self.M_spin = TSpinbox(frame, min=0, max=100, step=1, vartype=1, width=7, textvariable=self.M_value, command=self.cmyk_component_changed) self.M_spin.pack(side=RIGHT) frame = TFrame(cmyk_frame, borderwidth=2, style='FlatFrame') frame.pack(side=TOP) label = TLabel(frame, text="Y: ") label.pack(side=LEFT) self.Y_spin = TSpinbox(frame, min=0, max=100, step=1, vartype=1, width=7, textvariable=self.Y_value, command=self.cmyk_component_changed) self.Y_spin.pack(side=RIGHT) frame = TFrame(cmyk_frame, borderwidth=2, style='FlatFrame') frame.pack(side=TOP) label = TLabel(frame, text="K: ") label.pack(side=LEFT) self.K_spin = TSpinbox(frame, min=0, max=100, step=1, vartype=1, width=7, textvariable=self.K_value, command=self.cmyk_component_changed) self.K_spin.pack(side=RIGHT) rgb_frame = TFrame(self, borderwidth=2, style='FlatFrame') rgb_frame.pack(side=LEFT) self.RGB_label = TLabel(rgb_frame, text='R:\nG:\nB:', justify=LEFT) self.RGB_label.pack(side=LEFT) def set_color(self, color): self.color = color c, m, y, k = color.getCMYK() self.C_value.set(round(c * 100, 2)) self.M_value.set(round(m * 100, 2)) self.Y_value.set(round(y * 100, 2)) self.K_value.set(round(k * 100, 2)) self.A_value.set(int(round(color.alpha * 100))) r, g, b = color.getRGB() text = 'R: %d\nG: %d\nB: %d' % (round(r * 255, 2), round( g * 255, 2), round(b * 255, 2)) int_color = (round(r * 255), round(g * 255), round(b * 255)) text += '\n\n#%02X%02X%02X' % int_color self.RGB_label['text'] = text def cmyk_component_changed(self, *arg): c = self.C_value.get() / 100.0 m = self.M_value.get() / 100.0 y = self.Y_value.get() / 100.0 k = self.K_value.get() / 100.0 a = self.A_value.get() / 100.0 self.callback(CreateCMYKAColor(c, m, y, k, a))
class RotatePanel(PluginPanel): name = "Rotate" title = _("Rotate") def init(self, master): PluginPanel.init(self, master) root = self.mw.root self.var_angle = DoubleVar(root) self.var_angle.set(0) self.var_width_number = DoubleVar(root) self.var_height_number = DoubleVar(root) self.var_width_base = DoubleVar(root) self.var_height_base = DoubleVar(root) self.cnt_x_absolute = None self.cnt_y_absolute = None var_width_unit = StringVar(root) var_height_unit = StringVar(root) unit = config.preferences.default_unit self.var_width = LengthVar(10, unit, self.var_width_number, var_width_unit) self.var_height = LengthVar(10, unit, self.var_height_number, var_height_unit) jump = config.preferences.default_unit_jump self.var_width.set(0) self.var_height.set(0) self.var_width_base.set(0) self.var_height_base.set(0) self.var_position = StringVar(root) self.var_position.set(ABSOLUTE) self.var_basepoint = StringVar(root) self.var_basepoint.set("C") # --------------------------------------------------------- top = TFrame(self.panel, style="FlatFrame") top.pack(side=TOP, fill=BOTH) # --------------------------------------------------------- angle_frame = TFrame(top, style="FlatFrame", borderwidth=3) angle_frame.pack(side=TOP, fill=BOTH) label = TLabel(angle_frame, style="FlatLabel", text=" " + _("Angle:") + " ") label.pack(side=LEFT, padx=5) self.entry_angle = TSpinbox( angle_frame, var=0, vartype=1, textvariable=self.var_angle, min=-360, max=360, step=5, width=6, command=self.apply_rotate, ) self.entry_angle.pack(side=LEFT, anchor=E) label = TLabel(angle_frame, style="FlatLabel", text=_("deg")) label.pack(side=LEFT, padx=5) # --------------------------------------------------------- label = TLabel(top, style="FlatLabel", text=_("Center:")) label.pack(side=TOP, fill=BOTH, padx=5) # --------------------------------------------------------- # Horisontal size_frameH = TFrame(top, style="FlatFrame", borderwidth=3) size_frameH.pack(side=TOP, fill=BOTH) label = TLabel(size_frameH, style="FlatLabel", image="center_h") label.pack(side=LEFT, padx=5) self.entry_width = TSpinbox( size_frameH, var=0, vartype=1, textvariable=self.var_width_number, min=-50000, max=50000, step=jump, width=10, command=self.apply_rotate, ) self.entry_width.pack(side=LEFT) self.labelwunit = TLabel(size_frameH, style="FlatLabel", text=self.var_width.unit) self.labelwunit.pack(side=LEFT, padx=5) # --------------------------------------------------------- # Vertical size_frameV = TFrame(top, style="FlatFrame", borderwidth=3) size_frameV.pack(side=TOP, fill=BOTH) label = TLabel(size_frameV, style="FlatLabel", image="center_v") label.pack(side=LEFT, padx=5) self.entry_height = TSpinbox( size_frameV, var=0, vartype=1, textvariable=self.var_height_number, min=-50000, max=50000, step=jump, width=10, command=self.apply_rotate, ) self.entry_height.pack(side=LEFT) self.labelhunit = TLabel(size_frameV, style="FlatLabel", text=self.var_height.unit) self.labelhunit.pack(side=LEFT, padx=5) # --------------------------------------------------------- # position chek self.position_check = TCheckbutton( top, text=_("Absolute Center"), variable=self.var_position, onvalue=ABSOLUTE, offvalue=RELATIVE, command=self.position, ) self.position_check.pack(side=TOP, anchor=W, padx=5, pady=5) # --------------------------------------------------------- # Basepoint check label = TLabel(top, style="FlatLabel", text=_("Basepoint:")) label.pack(side=TOP, fill=BOTH, padx=5) basepoint_frame = TLabelframe(top, labelwidget=label, style="Labelframe", borderwidth=4) basepoint_frame.pack(side=TOP, fill=X, padx=5, pady=2) self.Basepoint = BasePointSelector(basepoint_frame, anchor=self.var_basepoint, command=self.apply_basepoint) self.Basepoint.pack(side=LEFT, fill=BOTH, padx=5) label = TLabel(basepoint_frame, style="FlatLabel", image="coordinate_deg") label.pack(side=LEFT, fill=BOTH, padx=10) self.position_check.pack(side=TOP, anchor=W, padx=5, pady=5) # --------------------------------------------------------- # Button frame button_frame = TFrame(top, style="FlatFrame", borderwidth=5) button_frame.pack(side=BOTTOM, fill=BOTH) self.update_buttons = [] self.button = UpdatedButton(top, text=_("Apply"), command=self.apply_rotate) self.button.pack(in_=button_frame, side=BOTTOM, expand=1, fill=X, pady=3) self.button_copy = UpdatedButton(top, text=_("Apply to Copy"), command=self.apply_to_copy) self.button_copy.pack(in_=button_frame, side=BOTTOM, expand=1, fill=X) self.init_from_doc() self.subscribe_receivers() ############################################################################### def subscribe_receivers(self): self.document.Subscribe(SELECTION, self.Update) self.document.Subscribe(EDITED, self.update_var) config.preferences.Subscribe(CHANGED, self.update_pref) def unsubscribe_receivers(self): self.document.Unsubscribe(SELECTION, self.Update) self.document.Unsubscribe(EDITED, self.update_var) config.preferences.Unsubscribe(CHANGED, self.update_pref) def init_from_doc(self, *arg): self.Update() def Update(self, *arg): if self.is_selection(): self.entry_angle.set_state(NORMAL) self.entry_width.set_state(NORMAL) self.entry_height.set_state(NORMAL) self.position_check["state"] = NORMAL self.button["state"] = NORMAL self.button_copy["state"] = NORMAL self.TestBasepoint() else: self.entry_angle.set_state(DISABLED) self.entry_width.set_state(DISABLED) self.entry_height.set_state(DISABLED) self.position_check["state"] = DISABLED self.button["state"] = DISABLED self.button_copy["state"] = DISABLED self.update_pref() def apply_basepoint(self): self.update_var() def position(self): self.update_var() def RotateSelected(self, angle, cnt=None): text = _("Rotation") if self.document.selection: self.document.begin_transaction(text) try: try: if cnt is None: cnt = self.document.selection.coord_rect.center() angle = angle * degrees trafo = Rotation(angle, cnt) self.document.TransformSelected(trafo, text) except: self.document.abort_transaction() finally: self.document.end_transaction() def RotateAndCopy(self, angle, cnt=None): text = _("Rotation&Copy") if self.document.selection: self.document.begin_transaction(text) try: try: if cnt is None: cnt = self.document.selection.coord_rect.center() angle = angle * degrees trafo = Rotation(angle, cnt) self.document.ApplyToDuplicate() self.document.TransformSelected(trafo, text) except: self.document.abort_transaction() finally: self.document.end_transaction() def apply_rotate(self, *arg): if self.button["state"] == DISABLED: return try: var_x = self.var_width.get() var_y = self.var_height.get() var_a = self.var_angle.get() except: return if var_a < 0: if var_a < -360: var_a += int(var_a / 360) * 360 var_a += 360 if self.var_basepoint.get() != "USER": self.cnt_x_absolute, self.cnt_y_absolute = self.coordinates(ABSOLUTE) self.var_basepoint.set("USER") if self.var_width_base != var_x or self.var_height_base != var_y: if self.var_position.get() == ABSOLUTE: self.cnt_x_absolute = var_x self.cnt_y_absolute = var_y else: x, y = self.coordinates(ABSOLUTE, "C") self.cnt_x_absolute = var_x + x self.cnt_y_absolute = var_y + y self.var_basepoint.set("USER") if arg and arg[0] == "Duplicate": self.RotateAndCopy(var_a, Point(self.cnt_x_absolute, self.cnt_y_absolute)) else: self.RotateSelected(var_a, Point(self.cnt_x_absolute, self.cnt_y_absolute)) def apply_to_copy(self): self.apply_rotate("Duplicate") def coordinates(self, position, anchor=None): br = self.document.selection.coord_rect hor_sel = br.right - br.left ver_sel = br.top - br.bottom if position == RELATIVE: left, bottom = -hor_sel / 2.0, -ver_sel / 2.0 else: left, bottom = br.left, br.bottom cnt_x, cnt_y = self.Basepoint.get_basepoint(hor_sel, ver_sel, left, bottom, anchor) return cnt_x, cnt_y def TestBasepoint(self): if self.cnt_x_absolute is None: return base = ["C", "NW", "N", "NE", "W", "E", "SW", "S", "SE"] for b in xrange(len(base)): cnt_x, cnt_y = self.coordinates(ABSOLUTE, base[b]) if round(cnt_x, 2) == round(self.cnt_x_absolute, 2) and round(cnt_y, 2) == round(self.cnt_y_absolute, 2): self.var_basepoint.set(base[b]) return self.var_basepoint.set("USER") def update_pref(self, *arg): self.labelwunit["text"] = config.preferences.default_unit self.labelhunit["text"] = config.preferences.default_unit self.entry_width.step = config.preferences.default_unit_jump self.entry_height.step = config.preferences.default_unit_jump self.update_var() def update_var(self, *arg): if len(self.document.selection.GetInfo()): self.var_width.unit = config.preferences.default_unit self.var_height.unit = config.preferences.default_unit if self.var_basepoint.get() == "USER": if self.var_position.get() == ABSOLUTE: self.var_width.set(self.cnt_x_absolute) self.var_height.set(self.cnt_y_absolute) else: x, y = self.coordinates(ABSOLUTE, "C") self.var_width.set(self.cnt_x_absolute - x) self.var_height.set(self.cnt_y_absolute - y) else: x, y = self.coordinates(self.var_position.get()) self.var_width.set(x) self.var_height.set(y) self.var_width_base = self.var_width.get() self.var_height_base = self.var_height.get() def is_selection(self): return len(self.document.selection) > 0
class CMYKDigitizer(TFrame): def __init__(self, parent, callback, **kw): self.callback = callback TFrame.__init__(self, parent, style='FlatFrame', **kw) self.C_value = DoubleVar(0) self.M_value = DoubleVar(0) self.Y_value = DoubleVar(0) self.K_value = DoubleVar(0) self.A_value = DoubleVar(0) b = TLabel(self, style='HLine') b.pack(side=BOTTOM, fill=X) frame = TFrame(self, borderwidth=0, style='FlatFrame') frame.pack(side=BOTTOM) label = TLabel(frame, text=_("Opacity: ")) label.pack(side=LEFT) self.A_spin = TSpinbox(frame, min=0, max=255, step=1, vartype=0, width=7, textvariable=self.A_value, command=self.cmyk_component_changed) self.A_spin.pack(side=RIGHT) b = TLabel(self, style='HLine') b.pack(side=BOTTOM, fill=X) cmyk_frame = TFrame(self, borderwidth=2, style='FlatFrame') cmyk_frame.pack(side=LEFT, padx=10) frame = TFrame(cmyk_frame, borderwidth=2, style='FlatFrame') frame.pack(side=TOP) label = TLabel(frame, text="C: ") label.pack(side=LEFT) self.C_spin = TSpinbox(frame, min=0, max=100, step=1, vartype=1, width=7, textvariable=self.C_value, command=self.cmyk_component_changed) self.C_spin.pack(side=RIGHT) frame = TFrame(cmyk_frame, borderwidth=2, style='FlatFrame') frame.pack(side=TOP) label = TLabel(frame, text="M: ") label.pack(side=LEFT) self.M_spin = TSpinbox(frame, min=0, max=100, step=1, vartype=1, width=7, textvariable=self.M_value, command=self.cmyk_component_changed) self.M_spin.pack(side=RIGHT) frame = TFrame(cmyk_frame, borderwidth=2, style='FlatFrame') frame.pack(side=TOP) label = TLabel(frame, text="Y: ") label.pack(side=LEFT) self.Y_spin = TSpinbox(frame, min=0, max=100, step=1, vartype=1, width=7, textvariable=self.Y_value, command=self.cmyk_component_changed) self.Y_spin.pack(side=RIGHT) frame = TFrame(cmyk_frame, borderwidth=2, style='FlatFrame') frame.pack(side=TOP) label = TLabel(frame, text="K: ") label.pack(side=LEFT) self.K_spin = TSpinbox(frame, min=0, max=100, step=1, vartype=1, width=7, textvariable=self.K_value, command=self.cmyk_component_changed) self.K_spin.pack(side=RIGHT) rgb_frame = TFrame(self, borderwidth=2, style='FlatFrame') rgb_frame.pack(side=LEFT) self.RGB_label = TLabel(rgb_frame, text='R:\nG:\nB:', justify=LEFT) self.RGB_label.pack(side=LEFT) def set_color(self, color): self.color = color c, m, y, k = color.getCMYK() self.C_value.set(round(c * 100, 2)) self.M_value.set(round(m * 100, 2)) self.Y_value.set(round(y * 100, 2)) self.K_value.set(round(k * 100, 2)) self.A_value.set(int(round(color.alpha * 100))) r, g, b = color.getRGB() text = 'R: %d\nG: %d\nB: %d' % (round(r * 255, 2), round(g * 255, 2), round(b * 255, 2)) int_color = (round(r * 255), round(g * 255), round(b * 255)) text += '\n\n#%02X%02X%02X' % int_color self.RGB_label['text'] = text def cmyk_component_changed(self, *arg): c = self.C_value.get() / 100.0 m = self.M_value.get() / 100.0 y = self.Y_value.get() / 100.0 k = self.K_value.get() / 100.0 a = self.A_value.get() / 100.0 self.callback(CreateCMYKAColor(c, m, y, k, a))
class TopoConsole(tk.AppWindow,tk.TkParameterized): """ Main window for the Tk-based GUI. """ def _getmenubar(self): return self.master.menubar menubar = property(_getmenubar) def __getitem__(self,menu_name): """Allow dictionary-style access to the menu bar.""" return self.menubar[menu_name] def __init__(self, root,exit_on_quit=True, **params): tk.AppWindow.__init__(self,root,status=True) tk.TkParameterized.__init__(self,root,**params) # Instead of displaying tracebacks on the commandline, try to display # them on the originating window. # CEBALERT: on destroy(), ought to revert this Tkinter.Misc._report_exception=_tkinter_report_exception self.exit_on_quit = exit_on_quit self.auto_refresh_panels = [] self._init_widgets() self.title(topo.sim.name) # If -g passed *before* scripts on commandline, this is useless. # So topo.misc.commandline sets the title as its last action (if -g) # catch click on the 'x': offers choice to quit or not self.protocol("WM_DELETE_WINDOW",self.quit_topographica) ########## ### Make cascade menus open automatically on linux when the mouse ### is over the menu title. ### [Tkinter-discuss] Cascade menu issue ### http://mail.python.org/pipermail/tkinter-discuss/2006-August/000864.html if topo.tkgui.system_platform is 'linux': activate_cascade = """\ if {[%W cget -type] != {menubar} && [%W type active] == {cascade}} { %W postcascade active } """ self.bind_class("Menu", "<<MenuSelect>>", activate_cascade) ########## # Install warning and message handling from param.parameterized import Parameterized self.__orig_P_warning = Parameterized.warning #self.__orig_P_message = Parameterized.message type.__setattr__(Parameterized,'warning',self.gui_warning) #type.__setattr__(Parameterized,'message',self.gui_message) def gui_warning(self,msg,*args,**kw): stat = self.__get_status_bar() stat.warn(msg%args) self.__orig_P_warning(self,msg,*args,**kw) def gui_message(self,msg,*args,**kw): stat = self.__get_status_bar() stat.message(msg%args) self.__orig_P_message(self,*args) def title(self,t=None): newtitle = "Topographica" if t: newtitle+=": %s" % t tk.AppWindow.title(self,newtitle) def _init_widgets(self): ## CEBALERT: now we can have multiple operations at the same time, ## status bar could be improved to show all tasks? # CEBALERT self.messageBar = self.status self.some_area = DockManager(self) self.some_area.pack(fill="both", expand=1) ### Balloon, for pop-up help self.balloon = tk.Balloon(self.content) ### Top-level (native) menu bar #self.menubar = tk.ControllableMenu(self.content) self.configure(menu=self.menubar) #self.menu_balloon = Balloon(topo.tkgui.root) # no menubar in tile yet # http://news.hping.org/comp.lang.tcl.archive/4679.html self.__simulation_menu() self.__create_plots_menu() self.refresh_plots_menu() self.__help_menu() ### Running the simulation run_frame = Frame(self.content) run_frame.pack(side='top',fill='x',padx=4,pady=8) self.run_frame = run_frame Label(run_frame,text='Run for: ').pack(side=LEFT) self.run_for_var=DoubleVar() self.run_for_var.set(1.0) run_for = tk.TaggedSlider(run_frame, variable=self.run_for_var, tag_width=11, slider_length=150, bounds=(0,20000)) self.balloon.bind(run_for,"Duration to run the simulation, e.g. 0.0500, 1.0, or 20000.") run_for.pack(side=LEFT,fill='x',expand=YES) run_for.tag.bind("<Return>",self.run_simulation) # When return is pressed, the TaggedSlider updates itself...but we also want to run # the simulation in this case. run_frame.optional_action=self.run_simulation go_button = Button(run_frame,text="Go", command=self.run_simulation) go_button.pack(side=LEFT) self.balloon.bind(go_button,"Run the simulation for the specified duration.") self.step_button = Button(run_frame,text="Step",command=self.run_step) self.balloon.bind(self.step_button,"Run the simulation through the time at which the next events are processed.") self.step_button.pack(side=LEFT) self.sizeright() def __simulation_menu(self): """Add the simulation menu options to the menubar.""" simulation_menu = ControllableMenu(self.menubar,tearoff=0) self.menubar.add_cascade(label='Simulation',menu=simulation_menu) simulation_menu.add_command(label='Run script',command=self.run_script) simulation_menu.add_command(label='Save script',command=self.save_script_repr) simulation_menu.add_command(label='Load snapshot',command=self.load_snapshot) simulation_menu.add_command(label='Save snapshot',command=self.save_snapshot) #simulation_menu.add_command(label='Reset',command=self.reset_network) simulation_menu.add_command(label='Test Pattern',command=self.open_test_pattern) simulation_menu.add_command(label='Model Editor',command=self.open_model_editor) simulation_menu.add_command(label='Quit',command=self.quit_topographica) def open_test_pattern(self): return open_plotgroup_panel(TestPattern) def __create_plots_menu(self): """ Add the plot menu to the menubar, with Basic plots on the menu itself and others in cascades by category (the plots come from plotgroup_templates). """ plots_menu = ControllableMenu(self.menubar,tearoff=0) self.menubar.add_cascade(label='Plots',menu=plots_menu) # CEBALERT: should split other menus in same way as plots (create/refresh) def refresh_plots_menu(self): plots_menu = self['Plots'] plots_menu.delete(0,'end') # create menu entries, and get list of categories entries=OrderedDict() # keep the order of plotgroup_templates (which is also KL) categories = [] for label,plotgroup in plotgroups.items(): entries[label] = PlotsMenuEntry(plotgroup) categories.append(plotgroup.category) categories = sorted(set(categories)) # The Basic category items appear on the menu itself. assert 'Basic' in categories, "'Basic' is the category for the standard Plots menu entries." for label,entry in entries.items(): if entry.plotgroup.category=='Basic': plots_menu.add_command(label=label,command=entry.__call__) categories.remove('Basic') plots_menu.add_separator() # Add the other categories to the menu as cascades, and the plots of each category to # their cascades. for category in categories: category_menu = ControllableMenu(plots_menu,tearoff=0) plots_menu.add_cascade(label=category,menu=category_menu) # could probably search more efficiently than this for label,entry in entries.items(): if entry.plotgroup.category==category: category_menu.add_command(label=label,command=entry.__call__) plots_menu.add_separator() plots_menu.add_command(label="Help",command=(lambda x=plotting_help_locations: self.open_location(x))) def __help_menu(self): """Add the help menu options.""" help_menu = ControllableMenu(self.menubar,tearoff=0,name='help') self.menubar.add_cascade(label='Help',menu=help_menu) help_menu.add_command(label='About',command=self.new_about_window) help_menu.add_command(label="User Manual", command=(lambda x=user_manual_locations: self.open_location(x))) help_menu.add_command(label="Tutorials", command=(lambda x=tutorials_locations: self.open_location(x))) help_menu.add_command(label="Examples", command=self.run_example_script) help_menu.add_command(label="Reference Manual", command=(lambda x=reference_manual_locations: self.open_location(x))) help_menu.add_command(label="Topographica.org", command=(lambda x=topo_www_locations: self.open_location(x))) help_menu.add_command(label="Python documentation", command=(lambda x=python_doc_locations: self.open_location(x))) def quit_topographica(self,check=True,exit_status=0): """Quit topographica.""" if not check or (check and tk.askyesno("Quit Topographica","Really quit?")): self.destroy() # matplotlib's tk backend starts its own Tk instances; we # need to close these ourselves (at least to avoid error # message about 'unusual termination' in Windows). try: # not that there should be an error, but just in case... import matplotlib._pylab_helpers for figman in matplotlib._pylab_helpers.Gcf.get_all_fig_managers(): figman.destroy() except: pass self.message("Quit selected%s" % ("; exiting" if self.exit_on_quit else "")) # Workaround for obscure problem on some UNIX systems # as of 4/2007, probably including Fedora Core 5. # On these systems, if Topographica is started from a # bash prompt and then quit from the Tkinter GUI (as # opposed to using Ctrl-D in the terminal), the # terminal would suppress echoing of all future user # input. stty sane restores the terminal to sanity, # but it is not clear why this is necessary. # For more info: # http://groups.google.com/group/comp.lang.python/browse_thread/thread/68d0f33c8eb2e02d if topo.tkgui.system_platform=="linux" and os.getenv('EMACS')!='t': try: os.system("stty sane") except: pass # CEBALERT: re. above. Shouldn't we be able to store the # output of "stty --save" before starting the gui, then # ensure that when the gui exits (however badly it # happens) run "stty saved_settings"? # CEBALERT: there was no call to self.master.destroy() if self.exit_on_quit: sys.exit(exit_status) def run_script(self): """ Dialog to run a user-selected script The script is exec'd in __main__.__dict__ (i.e. as if it were specified on the commandline.) """ script = askopenfilename(initialdir=normalize_path(),filetypes=SCRIPT_FILETYPES) if script in ('',(),None): # (representing the various ways no script was selected in the dialog) self.messageBar.response('Run canceled') else: execfile(script,__main__.__dict__) self.messageBar.response('Ran ' + script) sim_name_from_filename(script) self.title(topo.sim.name) # CEBALERT: duplicates most of run_script() def run_example_script(self): script = askopenfilename(initialdir=topo.misc.genexamples.find_examples(), filetypes=SCRIPT_FILETYPES) if script in ('',(),None): # (representing the various ways no script was selected in the dialog) self.messageBar.response('No example opened') else: execfile(script,__main__.__dict__) self.messageBar.response('Ran ' + script) sim_name_from_filename(script) self.title(topo.sim.name) def save_script_repr(self): script_name = asksaveasfilename(filetypes=SCRIPT_FILETYPES, initialdir=normalize_path(), initialfile=topo.sim.basename()+"_script_repr.ty") if script_name: topo.command.save_script_repr(script_name) self.messageBar.response('Script saved to ' + script_name) def load_snapshot(self): """ Dialog to load a user-selected snapshot (see topo.command.load_snapshot() ). """ snapshot_name = askopenfilename(initialdir=normalize_path(),filetypes=SAVED_FILETYPES) if snapshot_name in ('',(),None): self.messageBar.response('No snapshot loaded.') else: self.messageBar.dynamicinfo('Loading snapshot (may take some time)...') self.update_idletasks() topo.command.load_snapshot(snapshot_name) self.messageBar.response('Loaded snapshot ' + snapshot_name) self.title(topo.sim.name) self.auto_refresh() def save_snapshot(self): """ Dialog to save a snapshot (see topo.command.save_snapshot() ). Adds the file extension .typ if not already present. """ snapshot_name = asksaveasfilename(filetypes=SAVED_FILETYPES, initialdir=normalize_path(), initialfile=topo.sim.basename()+".typ") if snapshot_name in ('',(),None): self.messageBar.response('No snapshot saved.') else: if not snapshot_name.endswith('.typ'): snapshot_name = snapshot_name + SAVED_FILE_EXTENSION self.messageBar.dynamicinfo('Saving snapshot (may take some time)...') self.update_idletasks() topo.command.save_snapshot(snapshot_name) self.messageBar.response('Snapshot saved to ' + snapshot_name) def auto_refresh(self, update=True): """ Refresh all windows in auto_refresh_panels. Panels can add and remove themselves to the list; those in the list will have their refresh() method called whenever this console's autorefresh() is called. """ for win in self.auto_refresh_panels: win.refresh(update) self.set_step_button_state() self.update_idletasks() ### CEBERRORALERT: why doesn't updatecommand("display=True") for an ### orientation preference map measurement work with the ### hierarchical example? I guess this is the reason I thought the ### updating never worked properly (or I really did break it ### recently - or I'm confused)... def refresh_activity_windows(self): """ Update any windows with a plotgroup_key ending in 'Activity'. Used primarily for debugging long scripts that present a lot of activity patterns. """ for win in self.auto_refresh_panels: if re.match('.*Activity$',win.plotgroup.name): win.refresh() self.update_idletasks() def open_model_editor(self): """Start the Model editor.""" return ModelEditor(self) def new_about_window(self): win = tk.AppWindow(self) win.withdraw() win.title("About Topographica") text = Label(win,text=topo.about(display=False),justify=LEFT) text.pack(side=LEFT) win.deiconify() #self.messageBar.message('state', 'OK') def open_location(self, locations): """ Try to open one of the specified locations in a new window of the default browser. See webbrowser module for more information. locations should be a tuple. """ # CB: could have been a list. This is only here because if locations is set # to a string, it will loop over the characters of the string. assert isinstance(locations,tuple),"locations must be a tuple." for location in locations: try: existing_location = resolve_path(location) webbrowser.open(existing_location,new=2,autoraise=True) self.messageBar.response('Opened local file '+existing_location+' in browser.') return ### except: pass for location in locations: if location.startswith('http'): try: webbrowser.open(location,new=2,autoraise=True) self.messageBar.response('Opened remote location '+location+' in browser.') return ### except: pass self.messageBar.response("Could not open any of %s in a browser."%locations) # CEBALERT: need to take care of removing old messages automatically? # (Otherwise callers might always have to pass 'ok'.) def status_message(self,m): self.messageBar.response(m) def run_simulation(self,event=None): # event=None allows use as callback """ Run the simulation for the duration specified in the 'run for' taggedslider. """ fduration = self.run_for_var.get() self.open_progress_window(timer=topo.sim.timer) topo.sim.run_and_time(fduration) self.auto_refresh() # CEBERRORALERT: Step button does strange things at time==0. # E.g. for lissom_oo_or, nothing appears to happen. For # hierarchical, runs to time==10. def run_step(self): if not topo.sim.events: # JP: step button should be disabled if there are no events, # but just in case... return # JPALERT: This should really use .run_and_time() but it doesn't support # run(until=...) topo.sim.run(until=topo.sim.events[0].time) self.auto_refresh() def set_step_button_state(self): if topo.sim.events: self.step_button.config(state=NORMAL) else: self.step_button.config(state=DISABLED) def __get_status_bar(self,i=2): # Hack to find appropriate status bar: Go back through frames # until a widget with a status bar is found, and return it. try: while True: f = sys._getframe(i) if hasattr(f,'f_locals'): if 'self' in f.f_locals: o = f.f_locals['self'] # (temporary hack til ScrolledFrame cleaned up) if o.__class__.__name__!='ScrolledFrame': if hasattr(o,'messageBar'): return o.messageBar elif hasattr(o,'status'): return o.status i+=1 except: pass #print "GUI INTERNAL WARNING: failed to determine window on which to display message." return self.messageBar def open_progress_window(self,timer,title=None): """ Provide a convenient link to progress bars. """ stat = self.__get_status_bar() return stat.open_progress_window(timer=timer,sim=topo.sim)
class Cockpit(ttkFrame): ''' Remote controller GUI ''' KEY_ANG_SPEED = "ang-speed" KEY_ANGLES = "angles" KEY_ACCEL = "accel" PID_KEYS = ["P", "I", "D"] DEFAULT_DRONE_IP = "192.168.1.130" DEFAULT_DRONE_PORT = 2121 DIR_NONE = 0 DIR_VERTICAL = 1 DIR_HORIZONTAL = 2 MAX_ACCEL = 10.0 #TODO angles. Replace by m/s² MAX_ACCEL_Z = 0.1 #m/s² MAX_ANGLE_SPEED = 50.0 #º/s def __init__(self, parent, isDummy = False, droneIp = DEFAULT_DRONE_IP, dronePort = DEFAULT_DRONE_PORT): ''' Constructor ''' ttkFrame.__init__(self, parent) self._started = IntVar() self._integralsEnabled = IntVar() self._target = [0.0] * 4 self._selectedPidConstats = "--" self._pidConstants = { Cockpit.KEY_ANG_SPEED:{ "X":{ "P": 0.0, "I": 0.0, "D": 0.0 }, "Y":{ "P": 0.0, "I": 0.0, "D": 0.0 }, "Z":{ "P": 0.0, "I": 0.0, "D": 0.0 } }, Cockpit.KEY_ANGLES: { "X":{ "P": 0.0, "I": 0.0, "D": 0.0 }, "Y":{ "P": 0.0, "I": 0.0, "D": 0.0 } }, Cockpit.KEY_ACCEL:{ "X":{ "P": 0.0, "I": 0.0, "D": 0.0 }, "Y":{ "P": 0.0, "I": 0.0, "D": 0.0 }, "Z":{ "P": 0.0, "I": 0.0, "D": 0.0 } } } self.parent = parent self.initUI() self._controlKeysLocked = False if not isDummy: self._link = INetLink(droneIp, dronePort) else: self._link = ConsoleLink() self._link.open() self._updateInfoThread = Thread(target=self._updateInfo) self._updateInfoThreadRunning = False self._readingState = False self._start() def initUI(self): self.parent.title("Drone control") self.style = Style() self.style.theme_use("default") self.pack(fill=BOTH, expand=1) self.parent.bind_all("<Key>", self._keyDown) self.parent.bind_all("<KeyRelease>", self._keyUp) if system() == "Linux": self.parent.bind_all("<Button-4>", self._onMouseWheelUp) self.parent.bind_all("<Button-5>", self._onMouseWheelDown) else: #case of Windows self.parent.bind_all("<MouseWheel>", self._onMouseWheel) #Commands commandsFrame = tkFrame(self) commandsFrame.grid(column=0, row=0, sticky="WE") self._startedCB = Checkbutton(commandsFrame, text="On", variable=self._started, command=self._startedCBChanged) self._startedCB.pack(side=LEFT, padx=4) self._integralsCB = Checkbutton(commandsFrame, text="Int.", variable=self._integralsEnabled, \ command=self._integralsCBChanged, state=DISABLED) self._integralsCB.pack(side=LEFT, padx=4) self._quitButton = Button(commandsFrame, text="Quit", command=self.exit) self._quitButton.pack(side=LEFT, padx=2, pady=2) # self._angleLbl = Label(commandsFrame, text="Angle") # self._angleLbl.pack(side=LEFT, padx=4) # # self._angleEntry = Entry(commandsFrame, state=DISABLED) # self._angleEntry.pack(side=LEFT) #Info infoFrame = tkFrame(self) infoFrame.grid(column=1, row=1, sticky="E", padx=4) #Throttle Label(infoFrame, text="Throttle").grid(column=0, row=0, sticky="WE") self._throttleTexts = [StringVar(),StringVar(),StringVar(),StringVar()] Entry(infoFrame, textvariable=self._throttleTexts[3], state=DISABLED, width=5).grid(column=0, row=1) Entry(infoFrame, textvariable=self._throttleTexts[0], state=DISABLED, width=5).grid(column=1, row=1) Entry(infoFrame, textvariable=self._throttleTexts[2], state=DISABLED, width=5).grid(column=0, row=2) Entry(infoFrame, textvariable=self._throttleTexts[1], state=DISABLED, width=5).grid(column=1, row=2) #Angles Label(infoFrame, text="Angles").grid(column=0, row=3, sticky="WE") self._angleTexts = [StringVar(),StringVar(),StringVar()] for index in range(3): Entry(infoFrame, textvariable=self._angleTexts[index], state=DISABLED, width=5).grid(column=index, row=4) #Accels Label(infoFrame, text="Accels").grid(column=0, row=5, sticky="WE") self._accelTexts = [StringVar(),StringVar(),StringVar()] for index in range(3): Entry(infoFrame, textvariable=self._accelTexts[index], state=DISABLED, width=5).grid(column=index, row=6) #Speeds Label(infoFrame, text="Speeds").grid(column=0, row=7, sticky="WE") self._speedTexts = [StringVar(),StringVar(),StringVar()] for index in range(3): Entry(infoFrame, textvariable=self._speedTexts[index], state=DISABLED, width=5).grid(column=index, row=8) #Height Label(infoFrame, text="Height").grid(column=0, row=9, sticky="W") self._heightText = StringVar() Entry(infoFrame, state=DISABLED, width=5).grid(column=1, row=9) #control controlFrame = tkFrame(self) controlFrame.grid(column=0, row=1, sticky="W") self._throttle = DoubleVar() self._thrustScale = Scale(controlFrame, orient=VERTICAL, from_=100.0, to=-100.0, \ tickinterval=0, variable=self._throttle, \ length=200, showvalue=1, \ state=DISABLED, command=self._onThrustScaleChanged) self._thrustScale.bind("<Double-Button-1>", self._onThrustScaleDoubleButton1, "+") self._thrustScale.grid(column=0) self._shiftCanvas = Canvas(controlFrame, bg="white", height=400, width=400, \ relief=SUNKEN) self._shiftCanvas.bind("<Button-1>", self._onMouseButton1) #self._shiftCanvas.bind("<ButtonRelease-1>", self._onMouseButtonRelease1) self._shiftCanvas.bind("<B1-Motion>", self._onMouseButton1Motion) self._shiftCanvas.bind("<Double-Button-1>", self._onMouseDoubleButton1) self._shiftCanvas.bind("<Button-3>", self._onMouseButton3) #self._shiftCanvas.bind("<ButtonRelease-3>", self._onMouseButtonRelease3) self._shiftCanvas.bind("<B3-Motion>", self._onMouseButton3Motion) self._shiftCanvas.grid(row=0,column=1, padx=2, pady=2) self._shiftCanvas.create_oval(2, 2, 400, 400, outline="#ff0000") self._shiftCanvas.create_line(201, 2, 201, 400, fill="#ff0000") self._shiftCanvas.create_line(2, 201, 400, 201, fill="#ff0000") self._shiftMarker = self._shiftCanvas.create_oval(197, 197, 205, 205, outline="#0000ff", fill="#0000ff") self._yaw = DoubleVar() self._yawScale = Scale(controlFrame, orient=HORIZONTAL, from_=-100.0, to=100.0, \ tickinterval=0, variable=self._yaw, \ length=200, showvalue=1, \ command=self._onYawScaleChanged) self._yawScale.bind("<Double-Button-1>", self._onYawScaleDoubleButton1, "+") self._yawScale.grid(row=1, column=1) self._controlKeyActive = False #PID calibration pidCalibrationFrame = tkFrame(self) pidCalibrationFrame.grid(column=0, row=2, sticky="WE"); self._pidSelected = StringVar() self._pidSelected.set("--") self._pidListBox = OptionMenu(pidCalibrationFrame, self._pidSelected, "--", \ Cockpit.KEY_ANG_SPEED, Cockpit.KEY_ANGLES, Cockpit.KEY_ACCEL, \ command=self._onPidListBoxChanged) self._pidListBox.pack(side=LEFT, padx=2) self._pidListBox.config(width=10) self._axisSelected = StringVar() self._axisSelected.set("--") self._axisListBox = OptionMenu(pidCalibrationFrame, self._axisSelected, "--", "X", "Y", "Z", \ command=self._onAxisListBoxChanged) self._axisListBox.pack(side=LEFT, padx=2) self._axisListBox.config(state=DISABLED) Label(pidCalibrationFrame, text="P").pack(side=LEFT, padx=(14, 2)) self._pidPString = StringVar() self._pidPString.set("0.00") self._pidPSpinbox = Spinbox(pidCalibrationFrame, width=5, from_=0.0, to=100.0, increment=0.01, state=DISABLED, \ textvariable=self._pidPString, command=self._onPidSpinboxChanged) self._pidPSpinbox.pack(side=LEFT, padx=2) Label(pidCalibrationFrame, text="I").pack(side=LEFT, padx=(14, 2)) self._pidIString = StringVar() self._pidIString.set("0.00") self._pidISpinbox = Spinbox(pidCalibrationFrame, width=5, from_=0.0, to=100.0, increment=0.01, state=DISABLED, \ textvariable=self._pidIString, command=self._onPidSpinboxChanged) self._pidISpinbox.pack(side=LEFT, padx=2) Label(pidCalibrationFrame, text="D").pack(side=LEFT, padx=(14, 2)) self._pidDString = StringVar() self._pidDString.set("0.00") self._pidDSpinbox = Spinbox(pidCalibrationFrame, width=5, from_=0.0, to=100.0, increment=0.01, state=DISABLED, \ textvariable=self._pidDString, command=self._onPidSpinboxChanged) self._pidDSpinbox.pack(side=LEFT, padx=2) #debug debugFrame = tkFrame(self) debugFrame.grid(column=0, row=3, sticky="WE") self._debugMsg = Message(debugFrame, anchor="nw", justify=LEFT, relief=SUNKEN, width=300) self._debugMsg.pack(fill=BOTH, expand=1) def _start(self): self._readDroneConfig() def exit(self): self._link.send({"key": "close", "data": None}) self._stopUpdateInfoThread() self._link.close() self.quit() def _updateTarget(self): markerCoords = self._shiftCanvas.coords(self._shiftMarker) coords = ((markerCoords[0] + markerCoords[2]) / 2, (markerCoords[1] + markerCoords[3]) / 2) self._target[1] = float(coords[0] - 201) * Cockpit.MAX_ACCEL / 200.0 self._target[0] = float(coords[1] - 201) * Cockpit.MAX_ACCEL / 200.0 #Remote control uses clockwise angle, but the drone's referece system uses counter-clockwise angle self._target[2] = -self._yaw.get() * Cockpit.MAX_ANGLE_SPEED / 100.0 self._target[3] = self._throttle.get() * Cockpit.MAX_ACCEL_Z / 100.0 self._sendTarget() def _keyDown(self, event): if event.keysym == "Escape": self._throttle.set(0) self._started.set(0) self._thrustScale.config(state=DISABLED) self._stopUpdateInfoThread() self._sendIsStarted() elif event.keysym.startswith("Control"): self._controlKeyActive = True elif not self._controlKeysLocked and self._controlKeyActive: if event.keysym == "Up": self._thrustScaleUp() elif event.keysym == "Down": self._thrustScaleDown() elif event.keysym == "Left": self._yawLeft() elif event.keysym == "Right": self._yawRight() elif event.keysym == "space": self._yawReset() self._thrustReset() elif not self._controlKeysLocked and not self._controlKeyActive: if event.keysym == "Up": self._moveShiftCanvasMarker((0,-5)) elif event.keysym == "Down": self._moveShiftCanvasMarker((0,5)) elif event.keysym == "Left": self._moveShiftCanvasMarker((-5,0)) elif event.keysym == "Right": self._moveShiftCanvasMarker((5,0)) elif event.keysym == "space": self._resetShiftCanvasMarker() def _keyUp(self, eventArgs): if eventArgs.keysym.startswith("Control"): self._controlKeyActive = False def _onMouseButton1(self, eventArgs): self._lastMouseCoords = (eventArgs.x, eventArgs.y) def _onMouseButtonRelease1(self, eventArgs): self._shiftCanvas.coords(self._shiftMarker, 197, 197, 205, 205) def _limitCoordsToSize(self, coords, size): if coords[0] > size: x = size elif coords[0] < 0: x = 0 else: x = coords[0] if coords[1] > size: y = size elif coords[1] < 0: y = 0 else: y = coords[1] return (x,y) def _moveShiftCanvasMarker(self, shift): lastCoords = self._shiftCanvas.coords(self._shiftMarker) newCoords = (lastCoords[0] + shift[0], lastCoords[1] + shift[1]) newCoords = self._limitCoordsToSize(newCoords, 400) self._shiftCanvas.coords(self._shiftMarker, newCoords[0], newCoords[1], newCoords[0] + 8, newCoords[1] + 8) self._updateTarget() def _resetShiftCanvasMarker(self): self._shiftCanvas.coords(self._shiftMarker, 197, 197, 205, 205) self._updateTarget() def _onMouseButton1Motion(self, eventArgs): deltaCoords = (eventArgs.x - self._lastMouseCoords[0], eventArgs.y - self._lastMouseCoords[1]) self._moveShiftCanvasMarker(deltaCoords) self._lastMouseCoords = (eventArgs.x, eventArgs.y) def _onMouseDoubleButton1(self, eventArgs): self._resetShiftCanvasMarker() def _onMouseButton3(self, eventArgs): self._lastMouseCoords = (eventArgs.x, eventArgs.y) self._mouseDirection = Cockpit.DIR_NONE def _onMouseButtonRelease3(self, eventArgs): self._shiftCanvas.coords(self._shiftMarker, 197, 197, 205, 205) def _onMouseButton3Motion(self, eventArgs): deltaCoords = (eventArgs.x - self._lastMouseCoords[0], eventArgs.y - self._lastMouseCoords[1]) if self._mouseDirection == Cockpit.DIR_NONE: if abs(deltaCoords[0]) > abs(deltaCoords[1]): self._mouseDirection = Cockpit.DIR_HORIZONTAL else: self._mouseDirection = Cockpit.DIR_VERTICAL if self._mouseDirection == Cockpit.DIR_HORIZONTAL: deltaCoords = (deltaCoords[0], 0) else: deltaCoords = (0, deltaCoords[1]) self._moveShiftCanvasMarker(deltaCoords) self._lastMouseCoords = (eventArgs.x, eventArgs.y) def _thrustScaleUp(self): if self._started.get(): newValue = self._thrustScale.get() + 1 self._thrustScale.set(newValue) self._updateTarget() def _thrustScaleDown(self): if self._started.get(): newValue = self._thrustScale.get() - 1 self._thrustScale.set(newValue) self._updateTarget() def _thrustReset(self): if self._started.get(): self._thrustScale.set(0.0) self._updateTarget() def _onThrustScaleDoubleButton1(self, eventArgs): self._thrustReset() return "break" def _yawRight(self): newValue = self._yaw.get() + 1 self._yaw.set(newValue) self._updateTarget() def _yawLeft(self): newValue = self._yaw.get() - 1 self._yaw.set(newValue) self._updateTarget() def _yawReset(self): self._yaw.set(0) self._updateTarget() def _onMouseWheelUp(self, eventArgs): if not self._controlKeyActive: self._thrustScaleUp() else: self._yawRight() def _onMouseWheelDown(self, eventArgs): if not self._controlKeyActive: self._thrustScaleDown() else: self._yawLeft() def _onMouseWheel(self, eventArgs): factor = int(eventArgs.delta/120) if not self._controlKeyActive: if self._started.get(): newValue = self._thrustScale.get() + factor self._thrustScale.set(newValue) self._updateTarget() else: newValue = self._yaw.get() + factor self._yaw.set(newValue) self._updateTarget() def _onYawScaleChanged(self, eventArgs): self._updateTarget() def _onYawScaleDoubleButton1(self, eventArgs): self._yawReset() return "break" def _startedCBChanged(self): if not self._started.get(): self._throttle.set(0) self._thrustScale.config(state=DISABLED) self._integralsCB.config(state=DISABLED) self._stopUpdateInfoThread() else: self._thrustScale.config(state="normal") self._integralsCB.config(state="normal") self._startUpdateInfoThread() self._sendIsStarted() def _integralsCBChanged(self): self._link.send({"key": "integrals", "data":self._integralsEnabled.get() != 0}) def _onThrustScaleChanged(self, eventArgs): self._updateTarget() def _sendTarget(self): self._link.send({"key": "target", "data": self._target}) def _sendIsStarted(self): isStarted = self._started.get() != 0 self._link.send({"key": "is-started", "data": isStarted}) def _sendPidCalibrationData(self): if self._pidSelected.get() != "--" and self._axisSelected.get() != "--": pidData = { "pid": self._pidSelected.get(), "axis": self._axisSelected.get(), "p": float(self._pidPSpinbox.get()), "i": float(self._pidISpinbox.get()), "d": float(self._pidDSpinbox.get())} self._link.send({"key": "pid-calibration", "data": pidData}) def _updatePidCalibrationData(self): pid = self._pidSelected.get() axis = self._axisSelected.get() if pid != "--" and axis != "--": self._pidConstants[pid][axis]["P"] = float(self._pidPSpinbox.get()) self._pidConstants[pid][axis]["I"] = float(self._pidISpinbox.get()) self._pidConstants[pid][axis]["D"] = float(self._pidDSpinbox.get()) def _readDroneConfig(self): self._link.send({"key": "read-drone-config", "data": None}, self._onDroneConfigRead) def _readDroneState(self): if not self._readingState: self._readingState = True self._link.send({"key": "read-drone-state", "data": None}, self._onDroneStateRead) def _readPidConfigItem(self, message, cockpitKey, axises, configKeys): for i in range(len(axises)): for j in range(len(Cockpit.PID_KEYS)): self._pidConstants[cockpitKey][axises[i]][Cockpit.PID_KEYS[j]] = message[configKeys[j]][i] def _onDroneConfigRead(self, message): #TODO Show current configuration within the GUI (at least relevant settings) if message: #Angle-speeds self._readPidConfigItem(message, Cockpit.KEY_ANG_SPEED, ["X", "Y", "Z"], \ [Configuration.PID_ANGLES_SPEED_KP, \ Configuration.PID_ANGLES_SPEED_KI, \ Configuration.PID_ANGLES_SPEED_KD]) #Angles self._readPidConfigItem(message, Cockpit.KEY_ANGLES, ["X", "Y"], \ [Configuration.PID_ANGLES_KP, \ Configuration.PID_ANGLES_KI, \ Configuration.PID_ANGLES_KD]) #Accels self._readPidConfigItem(message, Cockpit.KEY_ACCEL, ["X", "Y", "Z"], \ [Configuration.PID_ACCEL_KP, \ Configuration.PID_ACCEL_KI, \ Configuration.PID_ACCEL_KD]) def _onDroneStateRead(self, state): if state: for index in range(4): self._throttleTexts[index].set("{0:.3f}".format(state["_throttles"][index])) for index in range(3): self._accelTexts[index].set("{0:.3f}".format(state["_accels"][index])) self._angleTexts[index].set("{0:.3f}".format(state["_angles"][index])) else: self._stopUpdateInfoThread() self._readingState = False def _onPidSpinboxChanged(self): self._updatePidCalibrationData() self._sendPidCalibrationData() def _onPidListBoxChanged(self, pid): self._axisSelected.set("--") self._pidPString.set("--") self._pidIString.set("--") self._pidDString.set("--") self._pidPSpinbox.config(state=DISABLED) self._pidISpinbox.config(state=DISABLED) self._pidDSpinbox.config(state=DISABLED) self._selectedPidConstats = pid if pid == "--": self._axisListBox.config(state=DISABLED) self._controlKeysLocked = False else: self._axisListBox.config(state="normal") self._controlKeysLocked = True def _onAxisListBoxChanged(self, axis): if axis == "--" or (self._selectedPidConstats == Cockpit.KEY_ANGLES and axis == "Z"): self._pidPString.set("--") self._pidIString.set("--") self._pidDString.set("--") self._pidPSpinbox.config(state=DISABLED) self._pidISpinbox.config(state=DISABLED) self._pidDSpinbox.config(state=DISABLED) self._controlKeysLocked = axis != "--" else: self._pidPString.set("{:.2f}".format(self._pidConstants[self._selectedPidConstats][axis]["P"])) self._pidIString.set("{:.2f}".format(self._pidConstants[self._selectedPidConstats][axis]["I"])) self._pidDString.set("{:.2f}".format(self._pidConstants[self._selectedPidConstats][axis]["D"])) self._pidPSpinbox.config(state="normal") self._pidISpinbox.config(state="normal") self._pidDSpinbox.config(state="normal") self._controlKeysLocked = True def _updateInfo(self): while self._updateInfoThreadRunning: self._readDroneState() time.sleep(1.0) def _startUpdateInfoThread(self): self._updateInfoThreadRunning = True if not self._updateInfoThread.isAlive(): self._updateInfoThread.start() def _stopUpdateInfoThread(self): self._updateInfoThreadRunning = False if self._updateInfoThread.isAlive(): self._updateInfoThread.join()