def test_enum(): """Test manipulating an Enum member. """ e = Enum('a', 'b') assert e.items == ('a', 'b') assert e.default_value_mode[1] == 'a' e_def = e('b') assert e_def is not e assert e_def.default_value_mode[1] == 'b' with pytest.raises(TypeError): e('c') e_add = e.added('c', 'd') assert e_add is not e assert e_add.items == ('a', 'b', 'c', 'd') e_rem = e.removed('a') assert e_rem is not e assert e_rem.items == ('b',) assert e_rem.default_value_mode[1] == 'b' with pytest.raises(ValueError): e.removed('a', 'b') with pytest.raises(ValueError): Enum()
class Ol(Tag): type = d_(Enum("", "1", "A", "a", "I", "i")) @observe('type') def _update_proxy(self, change): super(Ol, self)._update_proxy(change)
class SlopeShape(AbstractShape): """Shape whose amplitude varies linearly with time. """ #: Interpretation of the input values. #: Note that the slope is interpreted with respect to the context time #: unit. mode = Enum('Start/Stop', 'Start/Slope', 'Slope/Stop').tag(pref=True) #: First input parameter, will be interpreted based on the selected mode. def1 = Unicode('0.5').tag(pref=True, feval=Feval(types=Real)) #: Second input parameter, will be interpreted based on the selected mode. def2 = Unicode('1.0').tag(pref=True, feval=Feval(types=Real)) def eval_entries(self, root_vars, sequence_locals, missing, errors): """ Evaluate the parameters of the pulse shape. Parameters ---------- root_vars : dict Global variables. As shapes and modulation cannot update them an empty dict is passed. sequence_locals : dict Known locals variables for the pulse sequence. missing : set Set of variables missing to evaluate some entries in the sequence. errors : dict Errors which occurred when trying to compile the pulse sequence. Returns ------- result : bool Flag indicating whether or not the evaluation succeeded. """ res = super(SlopeShape, self).eval_entries(root_vars, sequence_locals, missing, errors) if res: if self.mode in ('Start/Stop', 'Start/Slope'): start = self._cache['def1'] if not -1.0 <= start <= 1.0: msg = 'Shape start must be between -1 and 1 (got %s).' errors[self.format_error_id('start')] = msg % start res = False if self.mode in ('Start/Stop', 'Slope/Stop'): stop = self._cache['def2'] if not -1.0 <= stop <= 1.0: msg = 'Shape stop must be between -1 and 1 (got %s).' errors[self.format_error_id('stop')] = msg % stop res = False if self.mode == 'Start/Slope': duration = sequence_locals['{}_duration'.format(self.index)] stop = self._cache['def1'] + self._cache['def2'] * duration if not -1.0 <= stop <= 1.0: msg = ('For the given slope and pulse duration, the stop ' 'is not between -1 and 1 (got %s).') errors[self.format_error_id('slope')] = msg % stop res = False elif self.mode == 'Slope/Stop': duration = sequence_locals['{}_duration'.format(self.index)] start = self._cache['def2'] - self._cache['def1'] * duration if not -1.0 <= start <= 1.0: msg = ('For the given slope and pulse duration, the start ' 'is not between -1 and 1 (got %s).') errors[self.format_error_id('slope')] = msg % start res = False return res def compute(self, time, unit): """ Computes the shape of the pulse at a given time. Parameters ---------- time : ndarray Times at which to compute the modulation. unit : str Unit in which the time is expressed. Returns ------- shape : ndarray Amplitude of the pulse. """ if self.mode == 'Start/Stop': start = self._cache['def1'] stop = self._cache['def2'] elif self.mode == 'Start/Slope': start = self._cache['def1'] stop = start + self._cache['def2'] * time[-1] else: stop = self._cache['def2'] start = stop - self._cache['def1'] * time[-1] return np.linspace(start, stop, len(time))
class Field(Control): """ A single line editable text widget. """ #: The unicode text to display in the field. text = d_(Str()) #: The mask to use for text input #: http://qt-project.org/doc/qt-4.8/qlineedit.html#inputMask-prop #: #: The summary of the mask grammar is as follows: #: A ASCII alphabetic character required. A-Z, a-z. #: a ASCII alphabetic character permitted but not required. #: N ASCII alphanumeric character required. A-Z, a-z, 0-9. #: n ASCII alphanumeric character permitted but not required. #: X Any character required. #: x Any character permitted but not required. #: 9 ASCII digit required. 0-9. #: 0 ASCII digit permitted but not required. #: D ASCII digit required. 1-9. #: d ASCII digit permitted but not required (1-9). #: # ASCII digit or plus/minus sign permitted but not required. #: H Hexadecimal character required. A-F, a-f, 0-9. #: h Hexadecimal character permitted but not required. #: B Binary character required. 0-1. #: b Binary character permitted but not required. #: > All following alphabetic characters are uppercased. #: < All following alphabetic characters are lowercased. #: ! Switch off case conversion. #: \ Use \ to escape the special characters listed above to use them as separators. #: #: The mask consists of a string of mask characters and separators, optionally #: followed by a semicolon and the character used for blanks #: Eg: 9 digit phone number: (999) 999-9999;_ mask = d_(Str()) #: The validator to use for this field. If the validator provides #: a client side validator, then text will only be submitted if it #: passes that validator. validator = d_(Typed(Validator)) #: The list of actions which should cause the client to submit its #: text to the server for validation and update. The currently #: supported values are 'lost_focus', 'return_pressed', and 'auto_sync'. #: The 'auto_sync' mode will attempt to validate and synchronize the #: text when the user stops typing. submit_triggers = d_( List(Enum('lost_focus', 'return_pressed', 'auto_sync'), ['lost_focus', 'return_pressed'])) #: Time in ms after which the client submit its text to the server for #: validation and update when the user stop typing. This is used only when #: the 'auto_sync' mode is part of the submit_triggers. sync_time = d_(Int(300)) #: The grayed-out text to display if the field is empty and the #: widget doesn't have focus. Defaults to the empty string. placeholder = d_(Str()) #: How to display the text in the field. Valid values are 'normal' #: which displays the text as normal, 'password' which displays the #: text with an obscured character, and 'silent' which displays no #: text at all but still allows input. echo_mode = d_(Enum('normal', 'password', 'silent')) #: The maximum length of the field in characters. The default value #: is Zero and indicates there is no maximum length. max_length = d_(Int(0)) #: Whether or not the field is read only. Defaults to False. read_only = d_(Bool(False)) #: Alignment for the text inside the field. Defaults to 'left'. text_align = d_(Enum('left', 'right', 'center')) #: How strongly a component hugs it's contents' width. Fields ignore #: the width hug by default, so they expand freely in width. hug_width = set_default('ignore') #: A reference to the ProxyField object. proxy = Typed(ProxyField) #-------------------------------------------------------------------------- # Observers #-------------------------------------------------------------------------- @observe('text', 'mask', 'submit_triggers', 'placeholder', 'echo_mode', 'max_length', 'read_only', 'text_align', 'sync_time') def _update_proxy(self, change): """ An observer which sends state change to the proxy. """ # The superclass implementation is sufficient. super(Field, self)._update_proxy(change) #-------------------------------------------------------------------------- # Public API #-------------------------------------------------------------------------- def field_text(self): """ Get the text stored in the field control. Depending on the state of the field, this text may be different than that stored in the 'text' attribute. Returns ------- result : unicode The unicode text stored in the field. """ if self.proxy_is_active: return self.proxy.field_text() return u''
""" __slots__ = () def __init__(self): super(ConstraintMember, self).__init__() mode = DefaultValue.MemberMethod_Object self.set_default_value_mode(mode, 'default') def default(self, owner): return kiwi.Variable(self.name) #: An atom enum which defines the allowable constraints strengths. #: Clones will be made by selecting a new default via 'select'. PolicyEnum = Enum('ignore', 'weak', 'medium', 'strong', 'required') class ConstrainableMixin(Atom): """ An atom mixin class which defines constraint members. This class implements the Constrainable interface. """ #: The symbolic left boundary of the constrainable. left = ConstraintMember() #: The symbolic top boundary of the constrainable. top = ConstraintMember() #: The symbolic width of the constrainable.
class DeviceConfig(Model): """ The default device configuration. Custom devices may want to subclass this. """ #: Time between each path command #: Time to wait between each step so we don't get #: way ahead of the cutter and fill up it's buffer step_time = Float(strict=False).tag(config=True) custom_rate = Float(-1, strict=False).tag(config=True) #: Distance between each command in user units #: this is effectively the resolution the software supplies step_size = Float(parse_unit('1mm'), strict=False).tag(config=True) #: Interpolate paths breaking them into small sections that #: can be sent. This allows pausing mid plot as many devices do not have #: a cancel command. interpolate = Bool(False).tag(config=True) #: How often the position will be updated in ms. Low power devices should #: set this to a high number like 2000 or 3000 sample_rate = Int(100).tag(config=True) #: Final output rotation rotation = Enum(0, 90, -90).tag(config=True) #: Swap x and y axis swap_xy = Bool().tag(config=True) mirror_y = Bool().tag(config=True) mirror_x = Bool().tag(config=True) #: Final out scaling scale = ContainerList(Float(strict=False), default=[1, 1]).tag(config=True) #: Defines prescaling before conversion to a polygon quality_factor = Float(1, strict=False).tag(config=True) #: In cm/s speed = Float(4, strict=False).tag(config=True) speed_units = Enum('in/s', 'cm/s').tag(config=True) speed_enabled = Bool().tag(config=True) #: Force in g force = Float(40, strict=False).tag(config=True) force_units = Enum('g').tag(config=True) force_enabled = Bool().tag(config=True) #: Use absolute coordinates absolute = Bool().tag(config=True) #: Device output is spooled by an external service #: this will cause the job to run with no delays between commands spooled = Bool().tag(config=True) #: Use a virtual connection test_mode = Bool().tag(config=True) #: Init commands commands_before = Str().tag(config=True) commands_after = Str().tag(config=True) commands_connect = Str().tag(config=True) commands_disconnect = Str().tag(config=True) def _default_step_time(self): """ Determine the step time based on the device speed setting """ #: Convert speed to px/s then to mm/s units = self.speed_units.split("/")[0] speed = parse_unit('%s%s' % (self.speed, units)) speed = to_unit(speed, 'mm') if speed == 0: return 0 #: No determine the time and convert to ms return max(0, round(1000*self.step_size/speed)) @observe('speed', 'speed_units', 'step_size') def _update_step_time(self, change): if change['type'] == 'update': self.step_time = self._default_step_time()
class Plotter(Atom): title = Unicode() xlabel = Unicode() ylabel = Unicode() xyfs = Dict() pd = Typed(ArrayPlotData, ()) plot = Typed(Plot) color_index = Int() figures = Dict(default=figures) plottables = Dict() overall_plot_type = Enum("XY plot", "img plot") value_scale = Enum('linear', 'log') index_scale = Enum('linear', 'log') def _observe_value_scale(self, change): if self.overall_plot_type == "XY plot": self.plot.value_scale = self.value_scale self.plot.request_redraw() def _observe_index_scale(self, change): if self.overall_plot_type == "XY plot": self.plot.index_scale = self.index_scale self.plot.request_redraw() def _default_plottables(self): return dict(plotted=[None]) #tempdict=dict() #for instr in self.instruments: #tempdict[instr.name]=[] # tempdict[instr.name]=instr.get_all_tags('plot', True, instr.plot_all, instr.all_params) #for key in instr.members().keys(): # if instr.get_tag(key, 'plot', instr.plot_all): # tempdict[instr.name].append(key) # if tempdict[instr.name]==[]: # tempdict[instr.name]=instr.members().keys() #return tempdict def _observe_title(self, change): self.plot.title = self.title self.plot.request_redraw() def _observe_xlabel(self, change): self.plot.x_axis.title = self.xlabel self.plot.request_redraw() def _observe_ylabel(self, change): self.plot.y_axis.title = self.ylabel self.plot.request_redraw() def _default_xyfs(self): xyf = AllXYFormat() xyf.plotter = self return {"All": xyf} def delete_all_plots(self): for key in self.plot.plots.keys(): self.plot.delplot(key) self.color_index = 0 def _save(self): win_size = self.plot.outer_bounds plot_gc = PlotGraphicsContext(win_size) #, dpi=300) plot_gc.render_component(self.plot) plot_gc.save("image_test.png") def set_data(self, zname, zdata, coord='z'): if zname not in self.pd.list_data(): self.plottables['plotted'].append(zname) self.pd.set_data(zname, zdata) def add_poly_plot(self, n, verts, cn="green", polyname=""): nxarray, nyarray = transpose(verts) xname = polyname + "x" + str(n) yname = polyname + "y" + str(n) self.pd.set_data(xname, nxarray, coord='x') self.pd.set_data(yname, nyarray, coord='y') self.plot.plot( (xname, yname), type="polygon", face_color=cn, #colors[nsides], hittest_type="poly")[0] def add_img_plot(self, zname, zdata, xname=None, yname=None, xdata=None, ydata=None): self.set_data(zname, zdata) if xname != None and yname != None: if xdata != None and ydata != None: self.set_data(xname, xdata, coord='x') self.set_data(yname, ydata, coord='y') xyf = XYFormat() xyf.plotter = self xyf.draw_img_plot(name=zname, zname=zname, xname=xname, yname=yname) self.xyfs.update(**{xyf.name: xyf}) self.overall_plot_type = "img plot" def add_line_plot(self, name, zname, zdata, xname=None, xdata=None): xyf = XYFormat(plotter=self) if zdata.ndim > 1: for i, arr in enumerate(self.splitMultiD(zdata, 0)): self.add_line_plot(name + str(i), zname + str(i), squeeze(arr), xname, xdata) else: self.set_data(zname, zdata) if xname != None and xdata != None: self.set_data(xname, xdata, coord='x') xyf.draw_plot(name=name, zname=zname, xname=xname) self.xyfs.update(**{xyf.name: xyf}) self.overall_plot_type = "XY plot" def append_data(self, name, zpoint, xpoint=None): xyf = self.xyfs[name] zdata = self.pd.get_data(xyf.zname) zdata = append(zdata, zpoint) self.pd.set_data(xyf.zname, zdata) xdata = self.pd.get_data(xyf.xname) if xpoint == None: xpoint = max(xdata) + range(len(zpoint)) + 1 xdata = append(xdata, xpoint) self.pd.set_data(xyf.xname, xdata) def _default_plot(self): plot = Plot(self.pd, padding=50, fill_padding=True, bgcolor="white", use_backbuffer=True, unified_draw=True) plot.tools.append(PanTool(plot, constrain_key="shift")) plot.overlays.append( ZoomTool(component=plot, tool_mode="box", always_on=False)) plot.legend.tools.append(LegendTool(plot.legend, drag_button="right")) return plot def splitMultiD(self, arr, axis=1): if arr.ndim < 2: return atleast_2d(arr) else: return split(arr, arr.shape[axis], axis=axis) def gatherMultiD(self, arrs, axis=1): print arrs[0].ndim # print "yo" return concatenate(arrs, axis) def show(self): with traits_enaml.imports(): from enaml_Plotter import PlotMain app = QtApplication() view = PlotMain(plotr=self) view.show() app.start()
class OccViewer(Control): """ A widget to view OpenCascade shapes. """ #: A reference to the ProxySpinBox object. proxy = Typed(ProxyOccViewer) #: Bounding box of displayed shapes. A tuple of the following values #: (xmin, ymin, zmin, xmax, ymax, zmax). bbox = d_(Typed(BBox), writable=False) #: Display mode display_mode = d_(Enum('shaded', 'wireframe')) #: Selection mode selection_mode = d_(Enum( 'any', 'shape', 'shell', 'face', 'edge', 'wire', 'vertex')) #: Selected items selection = d_(Typed(ViewerSelection), writable=False) #: View direction view_mode = d_(Enum('iso', 'top', 'bottom', 'left', 'right', 'front', 'rear')) # ------------------------------------------------------------------------- # Grid # ------------------------------------------------------------------------- grid_mode = d_(Enum('', 'rectangular-lines', 'rectangular-points', 'circular-lines', 'circular-points')) grid_colors = d_(Coerced(tuple, coercer=color_pair_coercer)) def _default_grid_colors(self): return (parse_color('#888'), parse_color('#444')) #: Selection event #reset_view = d_(Event(),writable=False) #: Show tahedron trihedron_mode = d_(Enum('right-lower', 'right-upper', 'left-lower', 'left-upper')) #: Background gradient this is corecred from a of strings background_gradient = d_(Coerced(tuple, coercer=color_pair_coercer)) def _default_background_gradient(self): return (parse_color('white'), parse_color('silver')) #: Default shape rendering color if none is defined shape_color = d_(ColorMember('steelblue')) #: Display shadows shadows = d_(Bool(True)) #: Display reflections reflections = d_(Bool(True)) #: Enable antialiasing antialiasing = d_(Bool(True)) #: Enable raytracing raytracing = d_(Bool(True)) #: Raytracing depth raytracing_depth = d_(Int(3)) #: Enable hidden line removal hidden_line_removal = d_(Bool(False)) #: Draw face boundaries draw_boundaries = d_(Bool(False)) #: View expands freely in width by default. hug_width = set_default('ignore') #: View expands freely in height by default. hug_height = set_default('ignore') #: Lock rotation so the mouse cannot not rotate lock_rotation = d_(Bool()) #: Lock zoom so the mouse wheel cannot not zoom lock_zoom = d_(Bool()) #: Lights lights = d_(List(ViewerLight)) def _default_lights(self): headlight = ViewerLight( type="directional", color="white", headlight=True) ambient = ViewerLight(type="ambient", color="white", intensity=0.95) return [headlight, ambient] #: Chordial Deviation. This is the "smoothness" of curves chordial_deviation = d_(Float(0.001, strict=False)) #: Events #: Raise StopIteration to indicate handling should stop key_pressed = d_(Event(), writable=False) mouse_pressed = d_(Event(), writable=False) mouse_released = d_(Event(), writable=False) mouse_wheeled = d_(Event(), writable=False) mouse_moved = d_(Event(), writable=False) #: Loading status loading = d_(Bool(), writable=False) progress = d_(Float(strict=False), writable=False) # ------------------------------------------------------------------------- # Observers # ------------------------------------------------------------------------- @observe('position', 'display_mode', 'view_mode', 'trihedron_mode', 'selection_mode', 'background_gradient', 'double_buffer', 'shadows', 'reflections', 'antialiasing', 'lock_rotation', 'lock_zoom', 'draw_boundaries', 'hidden_line_removal', 'shape_color', 'raytracing_depth', 'lights', 'grid_mode', 'grid_colors') def _update_proxy(self, change): """ An observer which sends state change to the proxy. """ # The superclass handler implementation is sufficient. super(OccViewer, self)._update_proxy(change) # ------------------------------------------------------------------------- # Viewer API # ------------------------------------------------------------------------- def fit_all(self): """ Zoom in and center on all item(s) """ self.proxy.fit_all() def fit_selection(self): """ Zoom in and center on the selected item(s) """ self.proxy.fit_selection() def take_screenshot(self, filename): """ Take a screenshot and save it with the given filename """ self.proxy.take_screenshot(filename) def zoom_factor(self, factor): """ Zoom in by a given factor """ self.proxy.zoom_factor(factor) def rotate_view(self, *args, **kwargs): """ Rotate by the given number of degrees about the current axis""" self.proxy.rotate_view(*args, **kwargs) def turn_view(self, *args, **kwargs): """ Rotate by the given number of degrees about the current axis""" self.proxy.turn_view(*args, **kwargs) def reset_view(self): """ Reset zoom to defaults """ self.proxy.reset_view() def clear_display(self): """ Clear the display, all children should be removed before calling this or they'll be rerendered. """ self.proxy.clear_display()
class VNA_Two_Tone_Lyzer(VNA_Pwr_Lyzer): base_name = "vna_two_tone_lyzer" frq2 = Array().tag(unit="GHz", label="2nd frequency", sub=True) pwr2 = Array().tag(unit="dBm", label="2nd power", sub=True) frq2_ind = Int() swp_type = Enum("pwr_first", "yoko_first") def _default_read_data(self): return read_data #def _observe_pwr_ind(self, change): # reset_property(self, "Magcom") @tag_property(sub=True) def Magcom(self): if self.filter_type == "None": Magcom = self.MagcomData elif self.filter_type == "Fit": return self.MagAbsFit else: Magcom = self.MagcomFilt[self.indices, :, :, :] if self.bgsub_type == "Complex": return self.bgsub(Magcom) return Magcom[:, :, self.frq2_ind] #, self.pwr_ind] #array([[self.fft_filter_full(m, n, Magcom) for n in range(len(self.yoko))] for m in range(len(self.pwr))]).transpose() @private_property def MagcomFilt(self): if self.filt.filter_type == "FIR": return array([[ self.filt.fir_filter(self.MagcomData[:, n, o, m]) for n in self.flat_flux_indices ] for m in range(len(self.pwr))]).transpose() return array([[ self.filt.fft_filter(self.MagcomData[:, n, o]) for n in self.flat_flux_indices ] for o in range(len(self.frq2))]).transpose() @tag_property(sub=True) def MagAbsFilt_sq(self): return absolute(self.MagcomFilt[:, :, self.frq2_ind])**2 @private_property def fit_params(self): if self.fitter.fit_params is None: self.fitter.full_fit(x=self.flux_axis[self.flat_flux_indices], y=self.MagAbsFilt_sq, indices=self.flat_indices, gamma=self.fitter.gamma) if self.calc_p_guess: self.fitter.make_p_guess( self.flux_axis[self.flat_flux_indices], y=self.MagAbsFilt_sq, indices=self.flat_indices, gamma=self.fitter.gamma) return self.fitter.fit_params @private_property def MagAbsFit(self): return sqrt( self.fitter.reconstruct_fit(self.flux_axis[self.flat_flux_indices], self.fit_params))
class Block(Declarative): """ An object which dynamically insert's its children into another block's parent object. The 'Block' object is used to cleanly and easily insert it's children into the children of another object. The 'Object' instance assigned to the 'block' property of the 'Block' will be parented with the parent of the 'Block'. Creating a 'Block' with no parent is a programming error. """ #: The Block to which this blocks children should be inserted into block = d_(ForwardInstance(lambda: Block)) #: If replace, replace all parent's children (except the block of course) mode = d_(Enum('replace', 'append')) def initialize(self): """ A reimplemented initializer. This method will add the include objects to the parent of the include and ensure that they are initialized. """ super(Block, self).initialize() block = self.block if block: #: This block is setting the content of another block #: Remove the existing blocks children if self.mode == 'replace': #: Clear the blocks children for c in block.children: c.destroy() #: Add this blocks children to the other block block.insert_children(None, self.children) else: #: This block is inserting it's children into it's parent self.parent.insert_children(self, self.children) def _observe_block(self, change): """ A change handler for the 'objects' list of the Include. If the object is initialized objects which are removed will be unparented and objects which are added will be reparented. Old objects will be destroyed if the 'destroy_old' flag is True. """ if self.is_initialized: if change['type'] == 'update': old_block = change['oldvalue'] old_parent = old_block.parent for c in self.children: old_parent.child_removed(c) new_block = change['value'] new_block.parent.insert_children(new_block, self.children) def _observe__children(self, change): if not self.is_initialized: return block = self.block if change['type'] == 'update': if block: if self.mode == 'replace': block.children = change['value'] else: for c in change['oldvalue']: block.children.remove(c) c.destroy() before = block.children[-1] if block.children else None block.insert_children(before, change['value']) else: for c in change['oldvalue']: if c not in change['value']: c.destroy() self.parent.insert_children(self, change['value'])
class FileDialogEx(ToolkitDialog): """ A toolkit dialog for getting file and directory names. This dialog supercedes the FileDialog class. New code you should use this dialog in lieu of the older version. """ #: The accept mode of the dialog. accept_mode = d_(Enum('open', 'save')) #: The file mode of the dialog. file_mode = d_(Enum( 'any_file', 'existing_file', 'existing_files', 'directory')) #: Whether or not to only show directories. This is only valid when #: the file_mode is set to 'directory'. show_dirs_only = d_(Bool(False)) #: The currently selected path in the dialog. current_path = d_(Str()) #: The paths selected by the user when the dialog is accepted. #: This value is output only. selected_paths = List(Str()) #: The name filters used to restrict the available files. name_filters = d_(List(Str())) #: The selected name filter from the list of name filters. selected_name_filter = d_(Str()) #: A reference to the ProxyFileDialog object. proxy = Typed(ProxyFileDialogEx) @staticmethod def get_existing_directory(parent=None, **kwargs): """ Get an existing directory on the filesystem. Parameters ---------- parent : ToolkitObject or None The parent toolkit object for this dialog. **kwargs Additional data to pass to the dialog constructor. Returns ------- result : unicode The user selected directory path. This will be an empty string if no directory was selected. """ kwargs['accept_mode'] = 'open' kwargs['file_mode'] = 'directory' kwargs['show_dirs_only'] = True dialog = FileDialogEx(parent, **kwargs) if dialog.exec_native(): if dialog.selected_paths: return dialog.selected_paths[0] return u'' @staticmethod def get_open_file_name(parent=None, **kwargs): """ Get the file name for an open file dialog. Parameters ---------- parent : ToolkitObject or None The parent toolkit object for this dialog. **kwargs Additional data to pass to the dialog constructor. Returns ------- result : unicode The user selected file name. This will be an empty string if no file name was selected. """ kwargs['accept_mode'] = 'open' kwargs['file_mode'] = 'existing_file' dialog = FileDialogEx(parent, **kwargs) if dialog.exec_native(): if dialog.selected_paths: return dialog.selected_paths[0] return u'' @staticmethod def get_open_file_names(parent=None, **kwargs): """ Get the file names for an open files dialog. Parameters ---------- parent : ToolkitObject or None The parent toolkit object for this dialog. **kwargs Additional data to pass to the dialog constructor. Returns ------- result : list The user selected file names. This will be an empty list if no file names were selected. """ kwargs['accept_mode'] = 'open' kwargs['file_mode'] = 'existing_files' dialog = FileDialogEx(parent, **kwargs) if dialog.exec_native(): return dialog.selected_paths return [] @staticmethod def get_save_file_name(parent=None, **kwargs): """ Get the file name for a save file dialog. Parameters ---------- parent : ToolkitObject or None The parent toolkit object for this dialog. **kwargs Additional data to pass to the dialog constructor. Returns ------- result : unicode The user selected file name. This will be an empty string if no file name was selected. """ kwargs['accept_mode'] = 'save' kwargs['file_mode'] = 'any_file' dialog = FileDialogEx(parent, **kwargs) if dialog.exec_native(): if dialog.selected_paths: return dialog.selected_paths[0] return u'' def exec_native(self): """ Open the dialog using a native OS dialog if available. Returns ------- result : bool Whether or not the dialog was accepted. """ if not self.is_initialized: self.initialize() if not self.proxy_is_active: self.activate_proxy() self._prepare() self.proxy.exec_native() return self.result #-------------------------------------------------------------------------- # Observers #-------------------------------------------------------------------------- @observe('accept_mode', 'file_mode', 'show_dirs_only', 'current_path', 'name_filters', 'selected_name_filter') def _update_proxy(self, change): """ An observer which updates the proxy when the data changes. """ # The superclass implementation is sufficient. super(FileDialogEx, self)._update_proxy(change) #-------------------------------------------------------------------------- # Utility Methods #-------------------------------------------------------------------------- def _prepare(self): """ A reimplemented preparation method. This method resets the selected paths and filters. """ super(FileDialogEx, self)._prepare() self.selected_paths = [] self.selected_name_filter = u''
class Lyzer(TA88_Fund): #def _default_main_params(self): # return ["rt_atten", "fridge_atten", "fridge_gain", "rt_gain", "comment", "flux_factor", "offset", "fit_type", # "on_res_ind", "start_ind", "stop_ind", "filt_start_ind", "filt_end_ind"] rd_hdf=Typed(TA88_Read) rt_atten=Float(40) rt_gain=Float(23*2) comment=Unicode().tag(read_only=True, spec="multiline") frequency=Array().tag(unit="GHz", plot=True, label="Frequency", sub=True) yoko=Array().tag(unit="V", plot=True, label="Yoko", sub=True) pwr=Array().tag(unit="V", plot=True, label="Yoko", sub=True) frq2=Array().tag(unit="V", plot=True, label="Yoko", sub=True) Magcom=Array().tag(sub=True) offset=Float(-0.035) flux_factor=Float(0.2925) on_res_ind=Int() start_ind=Int() stop_ind=Int() filt_end_ind=Int(58) filt_start_ind=Int(5) fit_func=Callable(fano).tag(private=True) #resid_func=Callable(fano_residuals).tag(private=True) def resid_func(self, p, y, x): return y-self.fit_func(x, p) fit_type=Enum("Transmission", "Reflection") @tag_Property(plot=True, sub=True) def flux_par(self): flux_over_flux0=qdt.call_func("flux_over_flux0", voltage=self.yoko, offset=self.offset, flux_factor=self.flux_factor) Ej=qdt.call_func("Ej", flux_over_flux0=flux_over_flux0) return qdt._get_fq(Ej, qdt.Ec) @tag_Property(sub=True) def flux_over_flux0(self): return (self.yoko-self.offset)*self.flux_factor @tag_Property() def p_guess(self): #return [200e6,4.5e9, 0.002, 0.022, 0.1] return [200e6,4.5e9, 0.002, 0.022] @tag_Property(sub=True) def indices(self): return range(len(self.frequency)) #return [range(81, 120+1), range(137, 260+1), range(269, 320+1), range(411, 449+1)]#, [490]]#, [186]] def fft_filter(self, n): myifft=fft.ifft(self.Magcom[:,n]) myifft[self.filt_end_ind:-self.filt_end_ind]=0.0 if self.filt_start_ind!=0: myifft[:self.filt_start_ind]=0.0 myifft[-self.filt_start_ind:]=0.0 return fft.fft(myifft) @tag_Property(plot=True, sub=True) def MagdB(self): return 10.0*log10(self.MagAbs) @tag_Property(plot=True, sub=True) def MagAbs(self): return absolute(self.Magcom) @tag_Property(plot=True, sub=True) def MagAbsFilt(self): return absolute(self.MagcomFilt) @tag_Property(plot=True, sub=True) def MagdBFilt(self): return 10.0*log10(self.MagAbsFilt) @tag_Property(plot=True, sub=True) def MagdBFiltbgsub(self): #return self.MagAbsFilt/mean(self.MagAbsFilt[:, 0:5], axis=1, keepdims=True) return self.MagdBFilt-10.0*log10(mean(self.MagAbsFilt[:, 0:5], axis=1, keepdims=True)) @tag_Property(plot=True, sub=True) def MagAbsFilt_sq(self): return self.MagAbsFilt**2 @tag_Property(plot=True, sub=True) def MagcomFilt(self): return array([self.fft_filter(n) for n in range(len(self.yoko))]).transpose() @plots def magabs_colormesh(self, plotter): plotter.colormesh("magabs_{}".format(self.name), self.yoko, self.frequency, self.MagAbs) plotter.set_ylim(min(self.frequency), max(self.frequency)) plotter.set_xlim(min(self.yoko), max(self.yoko)) plotter.mpl_axes.xlabel="Yoko (V)" plotter.mpl_axes.ylabel="Frequency (Hz)" plotter.mpl_axes.title="Magabs fluxmap {}".format(self.name) @plots def ifft_plot(self, plotter): plotter.line_plot("ifft_{}".format(self.name), absolute(fft.ifft(self.Magcom[:,self.on_res_ind]))) plotter.line_plot("ifft_{}".format(self.name), absolute(fft.ifft(self.Magcom[:,self.start_ind]))) plotter.line_plot("ifft_{}".format(self.name), absolute(fft.ifft(self.Magcom[:,self.stop_ind]))) @plots def ifft_dif_plot(self, plotter): plotter.line_plot("ifft_dif1_{}".format(self.name), absolute(absolute(fft.ifft(self.Magcom[:,self.start_ind]))-absolute(fft.ifft(self.Magcom[:,self.on_res_ind])))) plotter.line_plot("ifft_dif2_{}".format(self.name), absolute(absolute(fft.ifft(self.Magcom[:,self.stop_ind]))-absolute(fft.ifft(self.Magcom[:,self.on_res_ind])))) plotter.line_plot("ifft_dif3_{}".format(self.name), absolute(absolute(fft.ifft(self.Magcom[:,self.stop_ind]))-absolute(fft.ifft(self.Magcom[:,self.start_ind])))) @plots def filt_compare(self, ind, plotter=None): plotter.line_plot("magabs_{}".format(self.name), self.frequency, self.MagdB[:, ind], label="MagAbs (unfiltered)") plotter.line_plot("magabs_{}".format(self.name), self.frequency, self.MagdBFilt[:, ind], label="MagAbs (filtered)") @plots def magabsfilt_colormesh(self, plotter): plotter.colormesh("magabsfilt_{}".format(self.name), self.yoko, self.frequency, self.MagAbsFilt) plotter.set_ylim(min(self.frequency), max(self.frequency)) plotter.set_xlim(min(self.yoko), max(self.yoko)) plotter.mpl_axes.xlabel="Yoko (V)" plotter.mpl_axes.ylabel="Frequency (Hz)" plotter.mpl_axes.title="Magabs fluxmap {}".format(self.name) @plots def magdBfilt_colormesh(self, plotter): plotter.colormesh("magdBfilt_{}".format(self.name), self.yoko, self.frequency, self.MagdBFilt) plotter.set_ylim(min(self.frequency), max(self.frequency)) plotter.set_xlim(min(self.yoko), max(self.yoko)) plotter.mpl_axes.xlabel="Yoko (V)" plotter.mpl_axes.ylabel="Frequency (Hz)" plotter.mpl_axes.title="MagdB fluxmap {}".format(self.name) @plots def magdBfiltbgsub_colormesh(self, plotter): plotter.colormesh("magdBfiltbgsub_{}".format(self.name), self.yoko, self.frequency, self.MagdBFiltbgsub) plotter.set_ylim(min(self.frequency), max(self.frequency)) plotter.set_xlim(min(self.yoko), max(self.yoko)) plotter.mpl_axes.xlabel="Yoko (V)" plotter.mpl_axes.ylabel="Frequency (Hz)" plotter.mpl_axes.title="MagdB bg sub fluxmap {}".format(self.name) def read_data(self): with File(self.rd_hdf.file_path, 'r') as f: Magvec=f["Traces"]["RS VNA - S21"] data=f["Data"]["Data"] self.comment=f.attrs["comment"] self.yoko=data[:,0,0].astype(float64) fstart=f["Traces"]['RS VNA - S21_t0dt'][0][0] fstep=f["Traces"]['RS VNA - S21_t0dt'][0][1] sm=shape(Magvec)[0] sy=shape(data) print sy s=(sm, sy[0], 1)#sy[2]) Magcom=Magvec[:,0, :]+1j*Magvec[:,1, :] Magcom=reshape(Magcom, s, order="F") self.frequency=linspace(fstart, fstart+fstep*(sm-1), sm) self.Magcom=squeeze(Magcom) self.stop_ind=len(self.yoko)-1 def full_fano_fit(self): log_debug("started fano fitting") fit_params=[self.fano_fit(n) for n in self.indices] fit_params=array(zip(*fit_params)) log_debug("ended fano fitting") return fit_params @plots def plot_widths(self, plotter): fit_params=self.full_fano_fit() plotter.scatter_plot("widths_{}".format(self.name), fit_params[0, :], absolute(fit_params[1, :]), color="red", label=self.name) def fano_fit(self, n): pbest= leastsq(self.resid_func, self.p_guess, args=(self.MagAbsFilt_sq[n, :], self.flux_par), full_output=1) best_parameters = pbest[0] #log_debug(best_parameters) #if 0:#n==539 or n==554:#n % 10: #b.line_plot("magabs_flux", self.flux_par*1e-9, (self.MagAbsFilt_sq[n, :], label="{}".format(n), linewidth=0.2) #b.line_plot("lorentzian", self.flux_par*1e-9, self.fit_func(self.flux_par,best_parameters), label="fit {}".format(n), linewidth=0.5) return (self.frequency[n], best_parameters[0], best_parameters[1], best_parameters[2], best_parameters[3])
class ContoursCollector(Atom): blur_kernel_size = Int(3) area_filter_lo = Int(-1) area_filter_hi = Int(40000) canny_thr_1 = Int(0) canny_thr_2 = Int(255) image_rgb = Typed(np.ndarray) image_edges = Typed(np.ndarray) contoursImage = Typed(np.ndarray) contoursList = ContoursList() base_image_kind = Enum('edges', 'original', 'empty') @classmethod def from_file(cls, image_file): image_rgb = cv2.cvtColor(cv2.imread(image_file), cv2.COLOR_BGR2RGB) return cls(image_rgb) def __init__(self, image_rgb): self.image_rgb = image_rgb self.contoursList.observe('selected_items', self._draw_selected_contours) @observe('blur_kernel_size') def make_contours(self, change=None): contours, image_edges = self.find_contours() self.image_edges = cv2.cvtColor(image_edges, cv2.COLOR_GRAY2RGB) self.contoursList.items = contours self.contoursList.toggle_all(True) @observe('base_image_kind') def _draw_selected_contours(self, change): if self.image_edges is None: return # self.contoursImage = self.image_edges if self.base_image_kind == 'edges': base_image = self.image_edges.copy() elif self.base_image_kind == 'original': base_image = self.image_rgb.copy() else: base_image = np.zeros_like(self.image_rgb) self.contoursImage = draw_contours(self.contoursList.selected_items, base_image) def find_contours(self, method=cv2.CHAIN_APPROX_NONE): image_rgb = self._blur_original_image() channels = self._get_single_channel_images(image_rgb) edges = self._combined_edges(channels) _, contours, hierarchy = cv2.findContours(edges, mode=cv2.RETR_EXTERNAL, method=method) contours = [Contour(points) for points in contours] contours = [cont for cont in contours if self.area_filter_accept(cont)] return sorted(contours, key=lambda c: c.measurements().area, reverse=True), edges # def _find_contours_in_channels(self, channels): # edges = self._combined_edges(channels) # _, contours, hierarchy = cv2.findContours(edges, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_NONE) # r = [Contour(points) for points in contours] # return sorted(r, key=lambda c: c.area(), reverse=True), edges def area_filter_accept(self, cont): return self.area_filter_lo <= cont.measurements( ).area <= self.area_filter_hi def _blur_original_image(self): if self.blur_kernel_size == 1: return self.image_rgb # return cv2.GaussianBlur(self.image_rgb, ksize=(self.blur_kernel_size, self.blur_kernel_size), sigmaX=2) return cv2.GaussianBlur(self.image_rgb, (self.blur_kernel_size, self.blur_kernel_size), 0) # return cv2.blur(self.image_rgb, ksize=(self.blur_kernel_size, self.blur_kernel_size)) # return cv2.medianBlur(self.image_rgb, ksize=self.blur_kernel_size) # return cv2.bilateralFilter(self.image_rgb, d=0, sigmaColor=7, sigmaSpace=7) def _get_single_channel_images(self, rgb): # gray, R G B, A B gray = cv2.cvtColor(rgb, cv2.COLOR_RGB2GRAY) # lab = cv2.cvtColor(rgb, cv2.COLOR_RGB2LAB) # hsv = cv2.cvtColor(rgb, cv2.COLOR_RGB2HSV) return [ gray, # rgb[..., 0], # rgb[..., 1], # rgb[..., 2], # lab[..., 0], # lab[..., 1], # lab[..., 2], # hsv[..., 0], # hsv[..., 1], # hsv[..., 2], ] def _edges(self, image): # return cv2.Canny(im_gray, 255 * 0.55, 255 * 0.8, edges=None, apertureSize=3, L2gradient=True) return cv2.Canny(image, self.canny_thr_1, self.canny_thr_2, edges=None, apertureSize=3, L2gradient=False) def _combined_edges(self, channels): if not len(channels): return None accum = np.zeros_like(channels[0]) for ch in channels: edges = self._edges(ch) accum = cv2.bitwise_or(accum, edges) return accum def select_contours_at_point(self, x, y): contours_under_mouse = self.contoursList.items_at_point(x, y) self.contoursList.selected_items = contours_under_mouse
class LinearBoxHelper(BoxHelper): """ A box helper for creating traditional linear box layouts. """ #: The layout orientation of the items in the box. orientation = Enum('vertical', 'horizontal') #: The tuple of items which will be used to generate the constraints. items = Tuple() #: The spacing to use between items if not explicitly provided. spacing = Range(low=0) #: The margins to use around the edges of the box. margins = Coerced(Box) def __init__(self, orientation, items, spacing=10, margins=0): """ Initialize a LinearBoxHelper. Parameters ---------- orientation : str The orientation of the layout box, either 'horizontal' or 'vertical'. items : iterable The iterable of items which should be constrained. spacing : int, optional The spacing to use between items if not specifically given in the sequence of items. The default value is 10 pixels. margins : int, tuple, or Box, optional The margins to use around the edges of the box. The default value is 0 pixels on all sides. """ self.orientation = orientation self.items = self.validate(items) self.spacing = spacing self.margins = margins @staticmethod def validate(items): """ Validate an iterable of constrainable box items. This method asserts that a sequence of items is appropriate for generating box constraints. The following conditions are verified of the sequence of items after they are filtered for None: * All of the items in the sequence are instances of Spacer, int, LinearSymbolic, Constrainable. * There are never two adjacent ints or spacers. Parameters ---------- items : iterable The iterable of constrainable items to validate. Returns ------- result : tuple A tuple of validated items, with any None values removed. """ items = tuple(item for item in items if item is not None) if len(items) == 0: return items was_spacer = False spacers = (int, Spacer) types = (LinearSymbolic, Constrainable, Spacer, int) for item in items: if not isinstance(item, types): msg = 'The allowed item types for a constraint sequence are ' msg += 'LinearSymbolic, Constrainable, Spacer, and int. ' msg += 'Got %s instead.' raise TypeError(msg % type(item).__name__) is_spacer = isinstance(item, spacers) if is_spacer and was_spacer: msg = 'Expected LinearSymbolic or Constrainable after a ' msg += 'spacer. Got %s instead.' raise TypeError(msg % type(item).__name__) was_spacer = is_spacer return items def constraints(self, component): """ Generate the box constraints for the given component. Parameters ---------- component : Constrainable or None The constrainable object which represents the conceptual owner of the generated constraints. Returns ------- result : list The list of Constraint objects for the given component. """ items = self.items if len(items) == 0: return [] # Create the outer boundary box constraints. cns = self.box_constraints(component) first, last = ORIENT_MAP[self.orientation] first_ortho, last_ortho = ORIENT_MAP[ORTHO_MAP[self.orientation]] first_boundary = getattr(self, first) last_boundary = getattr(self, last) first_ortho_boundary = getattr(self, first_ortho) last_ortho_boundary = getattr(self, last_ortho) # Create the margin spacers that will be used. margins = self.margins if self.orientation == 'vertical': first_spacer = EqSpacer(margins.top) last_spacer = EqSpacer(margins.bottom) first_ortho_spacer = FlexSpacer(margins.left) last_ortho_spacer = FlexSpacer(margins.right) else: first_spacer = EqSpacer(margins.left) last_spacer = EqSpacer(margins.right) first_ortho_spacer = FlexSpacer(margins.top) last_ortho_spacer = FlexSpacer(margins.bottom) # Add a pre and post padding spacer if the user hasn't specified # their own spacer as the first/last element of the box items. spacer_types = (Spacer, int) if not isinstance(items[0], spacer_types): pre_items = (first_boundary, first_spacer) else: pre_items = (first_boundary, ) if not isinstance(items[-1], spacer_types): post_items = (last_spacer, last_boundary) else: post_items = (last_boundary, ) # Create the helper for the primary orientation. The helper # validation is bypassed since the sequence is known-valid. spacing = self.spacing helper = SequenceHelper(last, first, (), spacing) helper.items = pre_items + items + post_items helpers = [helper] # Add the ortho orientation and nested helpers. The helper # validation is bypassed since the sequence is known-valid. for item in items: if isinstance(item, Constrainable): helper = SequenceHelper(last_ortho, first_ortho, (), spacing) helper.items = (first_ortho_boundary, first_ortho_spacer, item, last_ortho_spacer, last_ortho_boundary) helpers.append(helper) if isinstance(item, ConstraintHelper): helpers.append(item) # Add in the helper constraints. for helper in helpers: cns.extend(helper.create_constraints(None)) return cns
[sys.maxsize, sys.maxsize + 2], [sys.maxsize - 1, sys.maxsize + 3], ), (Float(), [1, int(1), 1.1], [1.0, 1.0, 1.1], [""]), (Float(strict=True), [1.1], [1.1], [1]), (FloatRange(0.0, 0.5), [0.0, 0.5], [0.0, 0.5], [-0.1, 0.6]), (FloatRange(0.5, 0.0), [0.0, 0.5], [0.0, 0.5], [-0.1, 0.6]), (FloatRange(0.0), [0.0, 0.6], [0.0, 0.6], [-0.1, ""]), (FloatRange(high=0.5), [-0.3, 0.5], [-0.3, 0.5], [0.6]), (FloatRange(1.0, 10.0, strict=True), [1.0, 3.7], [1.0, 3.7 ], [2, 4, 0, -11]), (Bytes(strict=False), [b"a", "a"], [b"a"] * 2, [1]), (Bytes(), [b"a"], [b"a"], ["a"]), (Str(strict=False), [b"a", "a"], ["a"] * 2, [1]), (Str(), ["a"], ["a"], [b"a"]), (Enum(1, 2, "a"), [1, 2, "a"], [1, 2, "a"], [3]), (Callable(), [int, None], [int, None], [1]), # 3.9 subs and 3.10 union tests in test_typing_utils are sufficient (Coerced(set), [{1}, [1], (1, )], [{1}] * 3, [1]), (Coerced(int, coercer=c), ["101"], [5], []), (Coerced((int, float), coercer=c), ["101"], [5], []), (Coerced(int, coercer=lambda x: []), [], [], [""]), # type: ignore (Coerced(TSet[int]), [{1}, [1], (1, )], [{1}] * 3, [1]), (Tuple(), [(1, )], [(1, )], [[1]]), (Tuple(Int()), [(1, )], [(1, )], [(1.0, )]), (Tuple(int), [(1, )], [(1, )], [(1.0, ), (None, )]), (Tuple(TSet[int]), [({1}, )], [({1}, )], [(1.0, ), (None, )]), (Tuple(Optional[int]), [(1, None)], [(1, None)], [("", )]), (List(), [[1]], [[1]], [(1, )]), (List(Int()), [[1]], [[1]], [[1.0]]), (List(float), [[1.0]], [[1.0]], [[1], [None]]),
class QtSerialConfig(Model): device_path = Str() #: Available serial ports ports = List() #: Serial port config port = Str().tag(config=True) flowcontrols = [] # Available FlowControls flowcontrols.append( IdNameItem(QSerialPort.NoFlowControl, 'No flow control')) flowcontrols.append( IdNameItem(QSerialPort.HardwareControl, 'Hardware flow control (RTS/CTS)')) flowcontrols.append( IdNameItem(QSerialPort.SoftwareControl, 'Software flow control (XON/XOFF)')) flowcontrols.append( IdNameItem(QSerialPort.UnknownFlowControl, 'Unknown flow control (obsolete value)')) #: FlowControl config flowcontrol = Int(0).tag(config=True) #: Available BaudRates baudrates = Enum(110, 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 38400, 57600, 115200, 128000, 256000) #: BaudRate config baudrate = Int(9600).tag(config=True) parities = [] # Available Parities parities.append(IdNameItem(QSerialPort.NoParity, 'No Parity')) parities.append(IdNameItem(QSerialPort.EvenParity, 'Even')) parities.append(IdNameItem(QSerialPort.OddParity, 'Odd')) parities.append(IdNameItem(QSerialPort.SpaceParity, 'Space')) parities.append(IdNameItem(QSerialPort.MarkParity, 'Mark')) parities.append(IdNameItem(QSerialPort.UnknownParity, 'Unknown')) #: Parity config parity = Int(0).tag(config=True) list_stopbits = [] # Available Stopbits list_stopbits.append(IdNameItem(QSerialPort.OneStop, '1 stop bit')) list_stopbits.append( IdNameItem(QSerialPort.OneAndHalfStop, '1.5 stop bits (Windows only)')) list_stopbits.append(IdNameItem(QSerialPort.TwoStop, '2 stop bits')) #: Stopbits config stopbits = Int(1).tag(config=True) bytesize = Enum(8, 7, 6, 5).tag(config=True) # ------------------------------------------------------------------------- # Defaults # ------------------------------------------------------------------------- def _default_ports(self): return self.get_serial_ports() def _default_port(self): if self.ports: return self.ports[0].portName() return "" def refresh(self): self.ports = self._default_ports() def get_serial_ports(self): info_list = QSerialPortInfo() serial_list = info_list.availablePorts() return serial_list
class EditableTable(RawWidget): # Expand the table by default hug_width = set_default('weak') hug_height = set_default('weak') model = Typed(QEditableTableModel) #: Instance of QEditableTableView view = Typed(QEditableTableView) event_filter = Typed(EventFilter) editable = d_(Bool(False)) autoscroll = d_(Bool(False)) show_column_labels = d_(Bool(True)) show_row_labels = d_(Bool(True)) show_grid = d_(Bool(True)) #: Dictionary mapping column name to a dictionary of settings for that #: column. Valid keys for each setting include: #: * compact_label - Column label (preferred). #: * label - Column label (used if compact_label not provided). #: * default - Value used for adding rows. #: * coerce - Function to coerce text entered in column to correct value. #: * initial_width - Initial width to set column to. column_info = d_(Dict(Unicode(), Typed(object), {})) #: Widths of columns in table column_widths = Property() #: Dictionary mapping column name to a dictionary of column properties: #: * visual_index: Visual position of column in table #: * width: Width of column in table column_config = Property() #: Can columns be rearranged by dragging labels in the header? columns_movable = d_(Bool(True)) data = d_(Typed(object)) update = d_(Bool()) updated = d_(Event()) # List of row, col tuples of selections selected_coords = d_(List(), []) live_edit = Typed(LiveEdit, {}) select_behavior = d_(Enum('items', 'rows', 'columns')) select_mode = d_(Enum('single', 'contiguous', 'extended', 'multi', None)) #: Strectch width of last column so it fills rest of table? stretch_last_section = d_(Bool(True)) #: How can column headers be resized? header_resize_mode = d_(Enum('interactive', 'fixed', 'stretch', 'contents')) def get_column_attribute(self, column_name, attribute, default, raise_error=False): column = self.column_info.get(column_name, {}) try: return column[attribute] except (KeyError, TypeError): try: return getattr(column, attribute) except AttributeError: if raise_error: raise else: return default @d_func def get_cell_color(self, row_index, column_index): ''' Parameters ---------- row_index : int Row index (zero-based) column_index : int Column index (zero-based) Result ------ color : SVG color name or hex color code Color to use for the background cell. Defaults to white. See http://www.december.com/html/spec/colorsvg.html for SVG color names. ''' # Given the row and column # This must return one of the SVG color names (see return 'white' @d_func def get_row_label(self, row_index): ''' Parameters ---------- row_index : int Row index (zero-based) Result ------ label : str Label to use for column header. Defaults to a 1-based row number. ''' return str(row_index + 1) @d_func def get_column_label(self, column_index): ''' Parameters ---------- column_index : int Column index (zero-based) Result ------ label : str Label to use for row header. Defaults to the 'compact_label' key in 'column_info'. If 'compact_label' is not found, checks for the 'label' key. ''' column = self.get_columns()[column_index] try: return self.get_column_attribute(column, 'compact_label', column, raise_error=True) except AttributeError: return self.get_column_attribute(column, 'label', column) @d_func def get_rows(self): if self.data is None: return [] return range(len(self.data)) @d_func def get_columns(self): ''' Result ------ column_labels : list of str List of column labels. ''' raise NotImplementedError @d_func def get_data(self, row_index, column_index): ''' Parameters ---------- row_index : int Row index (zero-based) column_index : int Column index (zero-based) Result ------ data : object Data to be shown in cell. ''' raise NotImplementedError @d_func def set_data(self, row_index, column_index, value): ''' Save value at specified row and column index to data Parameters ---------- row_index : int Row index (zero-based) column_index : int Column index (zero-based) value : object ''' raise NotImplementedError @d_func def remove_row(self, row_index): raise NotImplementedError @d_func def insert_row(self, row=None): raise NotImplementedError def _get_data(self, row_index, column_index): try: value = self.get_data(row_index, column_index) column = self.get_columns()[column_index] formatter = self.column_info.get(column, {}).get('to_string', str) return formatter(value) except Exception as e: log.warning(e) return '' def _set_data(self, *args): self.set_data(*args) self.updated = True def _remove_row(self, *args): self.remove_row(*args) self.updated = True def _insert_row(self, *args): self.insert_row(*args) self.updated = True @d_func def sort_rows(self, column_index, ascending): raise NotImplementedError @d_func def get_default_row(self): values = [] for column in self.get_columns(): default = self.column_info.get(column, {}).get('default', None) values.append(default) return values @d_func def coerce_to_type(self, column_index, value): column = self.get_columns()[column_index] func = self.column_info.get(column, {}).get('coerce', lambda x: x) return func(value) def create_widget(self, parent): self.model = QEditableTableModel(self) self.view = QEditableTableView(self.model, parent=parent) if self.editable: self.event_filter = EventFilter(self.view) self.view.installEventFilter(self.event_filter) return self.view def _observe_data(self, event): # TODO: for lists does not reset if the values are equivalent. We then # lose a reference to the actual list. self._reset_model() def _observe_columns(self, event): self._reset_model() def _observe_column_info(self, event): self._reset_model() def _observe_update(self, event): if self.update: self._reset_model() self.update = False def _reset_model(self, event=None): # Forces a reset of the model and view self.model.beginResetModel() self.model.endResetModel() if self.autoscroll and self.view: self.view.scrollToBottom() def _get_column_widths(self): return self.view.get_column_widths() def _set_column_widths(self, widths): self.view.set_column_widths(widths) self._reset_model() def get_default_column_widths(self): return {c: self.get_column_attribute(c, 'initial_width', 100) \ for c in self.get_columns()} def _get_column_config(self): return self.view.get_column_config() def _set_column_config(self, config): self.view.set_column_config(config) self._reset_model() def get_visual_columns(self): if not self.columns_movable: return self.get_columns() config = self.column_config indices = [(cfg['visual_index'], c) for c, cfg in config.items()] indices.sort() return [i[1] for i in indices] def as_string(self): rows = self.get_rows() visual_cols = self.get_visual_columns() cols = self.get_columns() table_strings = [] for r in range(len(rows)): row_data = [] for v in visual_cols: c = cols.index(v) row_data.append(self.get_data(r, c)) row_string = '\t'.join(str(d) for d in row_data) table_strings.append(row_string) return '\n'.join(table_strings)
class Window(Widget): """ A top-level Window component. A Window component is represents of a top-level visible component with a frame decoration. It may have at most one child widget which is dubbed the 'central widget'. The central widget is an instance of Container and is expanded to fit the size of the window. A Window does not support features like MenuBars or DockPanes, for such functionality, use a MainWindow widget. """ #: A static set of windows being used by the application. A window #: adds itself to this list when it is initialized, and removes #: itself when it is destroyed. This allows toplevel windows with #: no parent to persist without any other strong references. windows = set() #: The titlebar text. title = d_(Unicode()) #: The initial position of the window frame. A value of (-1, -1) #: indicates that the toolkit should choose the initial position. initial_position = d_(Coerced(Pos, (-1, -1))) #: The initial size of the window client area. A value of (-1, -1) #: indicates that the toolkit should choose the initial size. initial_size = d_(Coerced(Size, (-1, -1))) #: An enum which indicates the modality of the window. The default #: value is 'non_modal'. modality = d_(Enum('non_modal', 'application_modal', 'window_modal')) #: If this value is set to True, the window will be destroyed on #: the completion of the `closed` event. destroy_on_close = d_(Bool(True)) #: The title bar icon. icon = d_(Typed(Icon)) #: Whether or not the window remains on top of all others. always_on_top = d_(Bool(False)) #: An event fired when the window is closed. This event is triggered #: by the proxy object when the window is closed. closed = d_(Event(), writable=False) #: Windows are invisible by default. visible = set_default(False) #: A reference to the ProxyWindow object. proxy = Typed(ProxyWindow) def initialize(self): """ An overridden initializer method. This method adds the window to the static set of Windows. """ super(Window, self).initialize() Window.windows.add(self) def destroy(self): """ An overridden destructor method. This method removes the window from the static set of Windows. """ super(Window, self).destroy() Window.windows.discard(self) #-------------------------------------------------------------------------- # Public API #-------------------------------------------------------------------------- def central_widget(self): """ Get the central widget defined on the window. The last `Container` child of the window is the central widget. """ for child in reversed(self.children): if isinstance(child, Container): return child def position(self): """ Get the position of the window frame. Returns ------- result : Pos The current position of the window frame. """ if self.proxy_is_active: return self.proxy.position() return Pos(-1, -1) def set_position(self, pos): """ Set the position of the window frame. Parameters ---------- pos : Pos The desired position of the window the window frame. """ if self.proxy_is_active: self.proxy.set_position(pos) def size(self): """ Get the size of the window client area. Returns ------- result : Size The current size of the window client area. """ if self.proxy_is_active: return self.proxy.size() return Size(-1, -1) def set_size(self, size): """ Set the size of the window client area. Parameters ---------- size : Size The desired size of the window client area. """ if self.proxy_is_active: self.proxy.set_size(size) def geometry(self): """ Get the geometry of the window client area. Returns ------- result : Rect The current geometry of the window client area. """ if self.proxy_is_active: return self.proxy.geometry() return Rect(-1, -1, -1, -1) def set_geometry(self, rect): """ Set the geometry of the window client area. Parameters ---------- rect : Rect The desired geometry of the window client area. """ if self.proxy_is_active: self.proxy.set_geometry(rect) def frame_geometry(self): """ Get the geometry of the window frame. Returns ------- result : Rect The current geometry of the window frame. """ if self.proxy_is_active: return self.proxy.frame_geometry() return Rect(-1, -1, -1, -1) def maximize(self): """ Send the 'maximize' action to the client widget. """ if self.proxy_is_active: self.proxy.maximize() def minimize(self): """ Send the 'minimize' action to the client widget. """ if self.proxy_is_active: self.proxy.minimize() def restore(self): """ Send the 'restore' action to the client widget. """ if self.proxy_is_active: self.proxy.restore() def send_to_front(self): """ Send the window to the top of the Z order. """ if self.proxy_is_active: self.proxy.send_to_front() def send_to_back(self): """ Send the window to the bottom of the Z order. """ if self.proxy_is_active: self.proxy.send_to_back() def center_on_screen(self): """ Center the window on the screen. """ if self.proxy_is_active: self.proxy.center_on_screen() def center_on_widget(self, other): """ Center this window on another widget. Parameters ---------- other : Widget The widget onto which to center this window. """ assert isinstance(other, Widget) if self.proxy_is_active and other.proxy_is_active: self.proxy.center_on_widget(other) def close(self): """ Close the window. This will cause the window to be hidden, the 'closed' event to be fired, and the window subsequently destroyed. """ if self.proxy_is_active: self.proxy.close() def show(self): """ Show the window to the screen. This is a reimplemented parent class method which will init and build the window hierarchy if needed. """ if not self.is_initialized: self.initialize() if not self.proxy_is_active: self.activate_proxy() super(Window, self).show() #-------------------------------------------------------------------------- # Observers #-------------------------------------------------------------------------- @observe(('title', 'modality', 'icon')) def _update_proxy(self, change): """ Update the ProxyWindow when the Window data changes. """ # The superclass handler implementation is sufficient. super(Window, self)._update_proxy(change) #-------------------------------------------------------------------------- # Private API #-------------------------------------------------------------------------- def _handle_close(self): """ Handle the close event from the proxy widget. """ self.visible = False self.closed() if self.destroy_on_close: deferred_call(self.destroy)
class Block(Declarative): """ An object which dynamically insert's its children into another block's parent object. The 'Block' object is used to cleanly and easily insert it's children into the children of another object. The 'Object' instance assigned to the 'block' property of the 'Block' will be parented with the parent of the 'Block'. Creating a 'Block' with no parent is a programming error. """ #: The Block to which this blocks children should be inserted into block = d_(ForwardInstance(lambda: Block)) #: If replace, replace all parent's children (except the block of course) mode = d_(Enum('replace', 'append', 'prepend')) def initialize(self): """ A reimplemented initializer. This method will add the include objects to the parent of the include and ensure that they are initialized. """ super(Block, self).initialize() self.refresh_items() def refresh_items(self): block = self.block if block: # This block is setting the content of another block before = None # Remove the existing blocks children if self.mode == 'replace': # Clear the blocks children for c in block.children: block.children.remove(c) if not c.is_destroyed: c.destroy() # Add this blocks children to the other block elif self.mode == 'prepend' and block.children: before = block.children[0] block.insert_children(before, self.children) else: # This block is inserting it's children into it's parent self.parent.insert_children(self, self.children) def _observe_mode(self, change): """ If the mode changes. Refresh the items. """ block = self.block if block and self.is_initialized and change['type'] == 'update': if change['oldvalue'] == 'replace': raise NotImplementedError for c in self.children: block.children.remove(c) c.set_parent(None) self.refresh_items() def _observe_block(self, change): """ A change handler for the 'objects' list of the Include. If the object is initialized objects which are removed will be unparented and objects which are added will be reparented. Old objects will be destroyed if the 'destroy_old' flag is True. """ if self.is_initialized and change['type'] == 'update': old_block = change['oldvalue'] for c in self.children: old_block.children.remove(c) c.set_parent(None) self.refresh_items() def _observe__children(self, change): """ When the children of the block change. Update the referenced block. """ if not self.is_initialized or change['type'] != 'update': return block = self.block new_children = change['value'] old_children = change['oldvalue'] for c in old_children: if c not in new_children and not c.is_destroyed: c.destroy() else: c.set_parent(None) if block: # This block is inserting into another block before = None if self.mode == 'replace': block.children = [] if self.mode == 'prepend' and block.children: before = block.children[0] block.insert_children(before, new_children) else: # This block is a placeholder self.parent.insert_children(self, new_children)
class XYFormat(Atom): rend_list = List( default=[None, None, None]) #First is line, second is scatter #Typed(BaseXYPlot) name = Unicode() xname = Unicode() yname = Unicode() zname = Unicode() colormap = Enum(jet) line_color = Enum( *mycolors ) #'blue', 'red', 'green', 'purple', 'black', 'darkgray', 'cyan', 'magenta', 'orange') plot_type = Enum('line', 'scatter', 'line+scatter') line_width = Float(1.0) marker = Enum('square', 'circle', 'triangle', 'inverted_triangle', 'plus', 'cross', 'diamond', 'dot', 'pixel') marker_size = Float(3.0) outline_color = Enum(*mycolors) outline_width = Float(1.0) inside_color = Enum(*mycolors) line_style = Enum('solid', 'dot dash', 'dash', 'dot', 'long dash') render_style = Enum('connectedpoints', 'hold', 'connectedhold') plotter = ForwardTyped(lambda: Plotter) def _default_name(self): return self.yname def set_param(self, param, change, index=-1): if change['type'] != 'create': # if self.rend_list[index]!=None: setattr(self.rend_list[index], param, change['value']) print self.rend_list def set_line_param(self, param, change): self.set_param(param, change, index=0) def set_scatter_param(self, param, change): self.set_param(param, change, index=1) def _observe_line_color(self, change): self.set_line_param('color', change) def _observe_marker_size(self, change): self.set_scatter_param('marker_size', change) def _observe_marker(self, change): self.set_scatter_param('marker', change) def _observe_line_width(self, change): self.set_line_param('line_width', change) def _observe_outline_width(self, change): self.set_scatter_param('line_width', change) def _observe_outline_color(self, change): self.set_scatter_param('outline_color', change) def _observe_inside_color(self, change): self.set_scatter_param('color', change) def _observe_line_style(self, change): self.set_line_param('line_style', change) def redraw_plot(self): self.draw_plot(name=self.name, zname=self.zname, xname=self.xname) def draw_img_plot(self, name, zname, xname=None, yname=None): self.plotter.delete_all_plots() self.name = name self.zname = zname img_plot = self.plotter.plot.img_plot(self.zname, name="img_plot", colormap=self.colormap)[0] # z_shape=shape(self.plotter.pd.get_data(self.zname)) if xname != None and yname != None: x = self.plotter.pd.get_data(xname) y = self.plotter.pd.get_data(yname) img_plot.index.set_data(x, y) img_plot.request_redraw() self.rend_list[2] = img_plot def draw_plot(self, name, zname, xname=None, zdata=None, xdata=None): if "img_plot" in self.plotter.plot.plots.keys(): self.plotter.delete_all_plots() if "{0}_line".format(name) in self.plotter.plot.plots.keys(): self.plotter.plot.delplot("{0}_line".format(name)) if "{0}_scatter".format(name) in self.plotter.plot.plots.keys(): self.plotter.plot.delplot("{0}_scatter".format(name)) if xname == None: xname = "{0}x0".format(zname) self.plotter.pd.set_data( xname, arange(len(self.plotter.pd.arrays[zname]))) self.xname = xname self.zname = zname self.name = name if self.plot_type == 'line': self.draw_line_plot() elif self.plot_type == 'scatter': self.draw_scatter_plot() elif self.plot_type == 'line+scatter': self.draw_line_plot() self.draw_scatter_plot() # if data.x_unit: # x_label = "{} [{}]".format(data.x_label, data.x_unit) # else: # x_label = data.x_label # if data.y_unit: # y_label = "{} [{}]".format(data.y_label, data.y_unit) # else: # y_label = data.y_label # plot.x_axis.title = x_label # plot.y_axis.title = y_label # plot.x_axis.tick_label_formatter = lambda x: '%.e'%x # plot.y_axis.tick_label_formatter = lambda x: '%.e'%x def draw_line_plot(self): renderer = self.plotter.plot.plot( (self.xname, self.zname), name="{0}_line".format(self.name), type="line", line_width=self.line_width, color=self.line_color, render_style=self.render_style, value_scale=self.plotter.value_scale, index_scale=self.plotter.index_scale)[0] renderer.request_redraw() self.rend_list[0] = renderer def draw_scatter_plot(self): renderer = self.plotter.plot.plot( (self.xname, self.zname), name="{0}_scatter".format(self.name), #self.zname, type="scatter", #self.xyformat.plot_type, line_width=self.line_width, color=self.inside_color, outline_color=self.outline_color, marker=self.marker, marker_size=self.marker_size, value_scale=self.plotter.value_scale, index_scale=self.plotter.index_scale)[0] renderer.request_redraw() self.rend_list[1] = renderer
class EBL_IDT(EBL_Polygons, IDT): """handles everything related to drawing a IDT. Units are microns (um)""" trconnect_x=Float(9.0e-6).tag(desc="connection length of transmon", unit="um") trconnect_y=Float(2.0e-6).tag(desc="connection length of transmon", unit="um") trconnect_w=Float(0.5e-6).tag(desc="connection length of transmon", unit="um") trc_wbox=Float(14.0e-6).tag(desc="width of transmon box", unit="um") trc_hbox=Float(12.5e-6).tag(desc="height of transmon box", unit="um") o=Float(0.5e-6).tag(unit="um", desc="gap between electrode and end of finger. The vertical offset of the fingers. Setting this to zero produces a shorted reflector") hbox=Float(0.5e-6).tag(desc="height of electrode box", unit="um") wbox=Float(0.0e-6).tag(unit="um", desc="width of electrode box. Setting to 0.0 (default) makes it autoscaling so it matches the width of the IDT") idt_tooth=Float(0.3e-6).tag(unit="um", desc="tooth size on CPW connection to aid contact") idt_type=Enum("basic", "stepped").tag(desc="basic is a regular IDT, stepped uses stepped fingers for harmonic suppression") qdt_type=Enum("IDT", "QDT") conn_h=Float(150.0e-6).tag(unit="um") add_gate=Bool(True) add_gnd=Bool(True) add_teeth=Bool(True) step_num=Int(3) gate_distance=Float(10.0e-6).tag(desc="distance to gate", unit="um") def _default_color(self): return "blue" def _default_main_params(self): return self.all_main_params mp=["idt_type", "qdt_type", "ft", "add_gate", "add_gnd", "add_teeth", "angle_x", "angle_y", "step_num", "Np", "a", "g", "W", "o","f0", "eta", "ef", "wbox", "hbox", "material", "trconnect_x", "trconnect_y", "trconnect_w", "trc_wbox", "trc_hbox", "conn_h", "idt_tooth", "v", "Dvv", "epsinf", "Ct", "p", "x_ref", "y_ref"] return mp def make_name_sug(self): name_sug="" name_sug+=dict(basic="", stepped="stp")[self.idt_type] name_sug+=self.qdt_type name_sug+=dict(single="s", double="d")[self.ft] if self.idt_type=="stepped": name_sug+="{0}s{1}a{2}e{3}".format(self.Np, self.step_num, int(self.a*1e9), int(self.eta*100)) else: name_sug+="{0}e{1}a{2}h{3}".format(self.Np, self.ef, int(self.a*1e9), int(self.hbox)) self.name_sug=name_sug shot_mod="" shot_mod+=dict(basic="", stepped="T")[self.idt_type] shot_mod+=dict(IDT="I", QDT="Q")[self.qdt_type] shot_mod+=dict(single="S", double="D")[self.ft] shot_mod+="{0}".format(len(self.chief.patterns)) #int(self.a*1e9)) #self.Np, self.ef, self.shot_mod_table=shot_mod @property def m(self): return {"basic": 0, "stepped": 1}[self.idt_type] @property def xo(self): return self.a*(1.0-1.0/self.step_num)*self.m @private_property def polylist(self): """draws single or double fingered IDT. If it is for a qubit, it adjusts the bottom box to contain SQUID connections (central fingers connect bottom to top)""" self.verts=[] self._IDTfingers() self._IDTextrafingers() self._IDTtopbottombox() if self.qdt_type=="QDT": self._squid_touch() self._left_transmon_connect() self._right_transmon_connect() if self.add_teeth: self._add_qubit_idt_teeth() if self.add_gate: self._qubitgate() if self.add_gnd: self._qubitgnd() return self.verts def _subfingrect(self, xt, yt, wt, ht, m): """writes part of finger for stepped IDTs""" if self.ft=="double": self.C(xt-(self.a+self.g)/2.0, yt, wt, ht) self.C(xt+(self.a+self.g)/2.0, yt, wt, ht) else: self.C(xt, yt, wt, ht) if m>1: self._subfingrect(xt+self.a/self.step_num, yt+ht, wt, ht, m-1) return def _fingrect(self, xt, yt, wt, ht, m=0): """writes IDT finger width a and length W and two for a double finger""" if m!=0: if m<0: self._fingrect(xt, yt-self.W/2.0, wt, self.o) else: self._fingrect(xt+self.a*(1.0-1.0/self.step_num), yt+self.W/2.0, wt, self.o) self._subfingrect(xt, -self.W/2.0*(1.0-1.0/self.step_num), wt, self.W/self.step_num, self.step_num) else: if self.ft=="double": self.C(xt-(self.a+self.g)/2.0, yt, wt, ht) self.C(xt+(self.a+self.g)/2.0, yt, wt, ht) else: self.C(xt, yt, wt, ht) def _IDTfingers(self): """writes IDT fingers for single finger IDT with extensions for connections if it is qubit type IDT""" for n in range(-(self.Np-1), self.Np, 2): self._fingrect(self.mult*n*(self.a+self.g), self.o/2.0, self.a, self.W+self.o, self.m) self._fingrect(self.mult*(n-1)*(self.a+self.g), -self.o/2.0, self.a, self.W+self.o, -self.m) if n in [-1,0] and self.qdt_type=="QDT": self._fingrect(self.mult*n*(self.a+self.g), -self.W/2.0-(self.o+self.trconnect_y+self.trconnect_w)/2.0, self.a, -(self.o+self.trconnect_y+self.trconnect_w)) self._fingrect(self.mult*n*(self.a+self.g), -self.W/2.0-self.o-self.trc_hbox+self.trconnect_y/2.0, self.a, self.trconnect_y) self._fingrect(self.mult*self.Np*(self.a+self.g), -self.o/2.0, self.a, self.W+self.o, -self.m) def _IDTextrafingers(self): """write extra fingers for a single IDT""" for n in range(0, self.ef): self._fingrect(-self.mult*n*(self.a+self.g)-self.mult*(self.Np+1)*(self.a+self.g), -self.o/2.0, self.a, self.W, -self.m) self._fingrect(self.mult*n*(self.a+self.g)+self.mult*(self.Np+1)*(self.a+self.g), -self.o/2.0, self.a, self.W, -self.m) def _IDTtopbottombox(self): """writes connecting box at top and also bottom for regular IDT""" if self.wbox==0.0: wr=self.mult*2*self.Np*(self.a+self.g) +self.mult*self.a+self.mult*2*self.ef*(self.a+self.g)+(self.mult-1)*self.g else: wr=self.wbox self.C(self.xo, self.o+self.W/2.0+self.hbox/2.0, wr, self.hbox) if self.qdt_type=="QDT": self.R(-self.trc_wbox/2.0, -self.o-self.W/2.0-self.trc_hbox-self.trconnect_w, self.trc_wbox, self.trconnect_w) else: self.C(0, -self.o-self.W/2.0-self.hbox/2.0, wr, self.hbox) def _qubitgnd(self): """writes qubit ground""" self.P([(-self.trc_wbox/2.0, -self.o-self.W/2.0-self.trc_hbox-self.trconnect_w), (self.trc_wbox/2.0, -self.o-self.W/2.0-self.trc_hbox-self.trconnect_w), (self.trc_wbox/2.0, -self.conn_h), (-self.trc_wbox/2.0, -self.conn_h)]) def _qubitgate(self): """writes gate for a qubit IDT""" self.P([(-self.trc_wbox/2.0, self.o+self.W/2.0+self.hbox+self.gate_distance),#-0.25e-6), (self.trc_wbox/2.0, self.o+self.W/2.0+self.hbox+self.gate_distance), #-0.25e-6), (self.trc_wbox/2.0, self.conn_h), (-self.trc_wbox/2.0, self.conn_h)]) def _squid_touch(self): """writes squid connections""" self.R(-self.trconnect_x/2.0, -self.o-self.W/2.0-self.trconnect_y-self.trconnect_w, self.trconnect_x, -self.trconnect_w) self.R(-self.trconnect_x/2.0, -self.o-self.W/2.0-self.trc_hbox+self.trconnect_y, self.trconnect_x, self.trconnect_w) def _left_transmon_connect(self): """write left part of transmon connect""" if mod(self.Np, 2)==0: #needs fixing for evens wr=-(self.mult*self.ef*(self.a+self.g)+self.mult*(self.Np-1)*(self.a+self.g)-self.g) xr=-self.mult*self.a/2.0-2.0*self.g-self.a else: wr=-(self.mult*self.ef*(self.a+self.g)+self.mult*self.Np*(self.a+self.g)-self.g) xr=-self.mult*self.a/2.0-self.g-(self.mult-1)*self.g/2.0 self.R(xr, -self.o-self.W/2.0, wr, -self.trconnect_w) self.R(xr, -self.o-self.W/2.0, -(self.trc_wbox/2.0-self.a/2.0-self.g), -self.trconnect_w) self.R(-self.trc_wbox/2.0, -self.o-self.W/2.0, -self.trconnect_w, -self.trc_hbox-self.trconnect_w) def _right_transmon_connect(self): """write right part of transmon connect""" if mod(self.Np, 2)==0: wr=self.ef*(self.a+self.g)+(self.Np+1)*(self.a+self.g)-self.g xr=-self.a/2.0 else: wr=self.mult*self.ef*(self.a+self.g)+self.mult*self.Np*(self.a+self.g)-self.g xr=self.mult*self.a/2.0+self.g+(self.mult-1)*self.g/2.0 self.R(xr, -self.o-self.W/2.0, wr, -self.trconnect_w) self.R(xr, -self.o-self.W/2.0, self.trc_wbox/2.0-self.a/2.0-self.g, -self.trconnect_w) self.R(self.trc_wbox/2.0, -self.o-self.W/2.0, self.trconnect_w, -self.trc_hbox-self.trconnect_w) def _add_qubit_idt_teeth(self): """adds teeth to qubit squid connection""" idt_numteeth=int(self.trconnect_x/(2*self.idt_tooth)) idt_conn=self.idt_tooth*(2*idt_numteeth-1) sqt_x=-idt_conn/2.0 sqt_y=-self.o-self.W/2.0-self.trc_hbox+self.trconnect_y+self.trconnect_w sqt_y_top=-self.o-self.W/2.0-self.trconnect_y-2*self.trconnect_w for i in range(idt_numteeth): self.R(sqt_x+2*i*self.idt_tooth, sqt_y, self.idt_tooth, self.idt_tooth ) self.R(sqt_x+2*i*self.idt_tooth, sqt_y_top, self.idt_tooth, -self.idt_tooth )
class DeclaracadPlugin(Plugin): #: Project site wiki_page = Unicode("https;//www.codelv.com/projects/declaracad") #: Dock items to add dock_items = List(DockItem) dock_layout = Instance(AreaLayout) dock_style = Enum(*reversed(ALL_STYLES)).tag(config=True) #: Settings pages to add settings_pages = List(extensions.SettingsPage) #: Current settings page settings_page = Instance(extensions.SettingsPage) #: Internal settings models settings_typemap = Dict() settings_model = Instance(Atom) def start(self): """ Load all the plugins declaracad is dependent on """ w = self.workbench super(DeclaracadPlugin, self).start() self._refresh_dock_items() self._refresh_settings_pages() #self.workbench.application.deferred_call(self.start_default_workspace) def start_default_workspace(self): ui = self.workbench.get_plugin('enaml.workbench.ui') ui.select_workspace('declaracad.workspace') def _bind_observers(self): """ Setup the observers for the plugin. """ super(DeclaracadPlugin, self)._bind_observers() workbench = self.workbench point = workbench.get_extension_point(extensions.DOCK_ITEM_POINT) point.observe('extensions', self._refresh_dock_items) point = workbench.get_extension_point(extensions.SETTINGS_PAGE_POINT) point.observe('extensions', self._refresh_settings_pages) def _unbind_observers(self): """ Remove the observers for the plugin. """ super(DeclaracadPlugin, self)._unbind_observers() workbench = self.workbench point = workbench.get_extension_point(extensions.DOCK_ITEM_POINT) point.unobserve('extensions', self._refresh_dock_items) point = workbench.get_extension_point(extensions.SETTINGS_PAGE_POINT) point.unobserve('extensions', self._refresh_settings_pages) # ------------------------------------------------------------------------- # Dock API # ------------------------------------------------------------------------- def create_new_area(self): """ Create the dock area """ with enaml.imports(): from .dock import DockView area = DockView(workbench=self.workbench, plugin=self) return area def get_dock_area(self): """ Get the dock area Returns ------- area: DockArea """ ui = self.workbench.get_plugin('enaml.workbench.ui') if not ui.workspace or not ui.workspace.content: ui.select_workspace('declaracad.workspace') return ui.workspace.content.find('dock_area') def _refresh_dock_items(self, change=None): """ Reload all DockItems registered by any Plugins Any plugin can add to this list by providing a DockItem extension in their PluginManifest. """ workbench = self.workbench point = workbench.get_extension_point(extensions.DOCK_ITEM_POINT) #: Layout spec layout = {'main': [], 'left': [], 'right': [], 'bottom': [], 'top': []} dock_items = [] for extension in sorted(point.extensions, key=lambda ext: ext.rank): for declaration in extension.get_children(extensions.DockItem): #: Create the item DockItem = declaration.factory() item = DockItem(plugin=workbench.get_plugin( declaration.plugin_id), ) #: Add to our layout layout[declaration.layout].append(item.name) #: Save it dock_items.append(item) #: Update items log.debug("Updating dock items: {}".format(dock_items)) self.dock_items = dock_items self._refresh_layout(layout) def _refresh_layout(self, layout): """ Create the layout for all the plugins """ if not self.dock_items: return AreaLayout() items = layout.pop('main') if not items: raise EnvironmentError("At least one main layout item must be " "defined!") main = (HSplitLayout(TabLayout( *items[1:]), items[0]) if len(items) > 1 else items[0]) dockbars = [ DockBarLayout(*items, position=side) for side, items in layout.items() if items ] #: Update layout self.dock_layout = AreaLayout(main, dock_bars=dockbars) # ------------------------------------------------------------------------- # Settings API # ------------------------------------------------------------------------- def _default_settings_page(self): return self.settings_pages[0] def _observe_settings_page(self, change): log.debug("Settings page: {}".format(change)) def _refresh_settings_pages(self, change=None): """ Reload all SettingsPages registered by any Plugins Any plugin can add to this list by providing a SettingsPage extension in their PluginManifest. """ workbench = self.workbench point = workbench.get_extension_point(extensions.SETTINGS_PAGE_POINT) settings_pages = [] typemap = {} for extension in sorted(point.extensions, key=lambda ext: ext.rank): for d in extension.get_children(extensions.SettingsPage): #: Save it settings_pages.append(d) #: Update the type map plugin = self.workbench.get_plugin(d.plugin_id) t = type(getattr(plugin, d.model) if d.model else plugin) typemap[t] = d.factory() #: Update items log.debug("Updating settings pages: {}".format(settings_pages)) self.settings_typemap = typemap self.settings_pages = sorted(settings_pages, key=lambda p: p.name)
class FileDialog(ToolkitObject): """ A dialog widget that allows the user to open and save files and directories. """ #: The title to use for the dialog. title = d_(Unicode()) #: The mode of the dialog. mode = d_(Enum('open_file', 'open_files', 'save_file', 'directory')) #: The selected path in the dialog. This value will be used to set #: the initial working directory and file, as appropriate, when the #: dialog is opened. It will aslo be updated when the dialog is #: closed and accepted. path = d_(Unicode()) #: The list of selected paths in the dialog. It will be updated #: when the dialog is closed and accepted. It is output only and #: is only applicable for the `open_files` mode. paths = List(Unicode()) #: The string filters used to restrict the user's selections. filters = d_(List(Unicode())) #: The selected filter from the list of filters. This value will be #: used as the initial working filter when the dialog is opened. It #: will also be updated when the dialog is closed and accepted. selected_filter = d_(Unicode()) #: Whether to use a platform native dialog, when available. This #: attribute is deprecated and no longer has any effect. Native #: dialogs are always used when available in a given toolkit. native_dialog = d_(Bool(True)) #: An enum indicating if the dialog was accepted or rejected by #: the user. It will be updated when the dialog is closed. This #: value is output only. result = Enum('rejected', 'accepted') #: An optional callback which will be invoked when the dialog is #: closed. This is a convenience to make it easier to handle a #: dialog opened in non-blocking mode. The callback must accept #: a single argument, which will be the dialog instance. callback = d_(Callable()) #: An event fired if the dialog is accepted. The payload will be #: the selected path. accepted = d_(Event(unicode), writable=False) #: An event fired when the dialog is rejected. It has no payload. rejected = d_(Event(), writable=False) #: An event fired when the dialog is closed. It has no payload. closed = d_(Event(), writable=False) #: Whether to destroy the dialog widget on close. The default is #: True since dialogs are typically used in a transitory fashion. destroy_on_close = d_(Bool(True)) #: A reference to the ProxyFileDialog object. proxy = Typed(ProxyFileDialog) def open(self): """ Open the dialog in a non-blocking fashion. This method will always return None. The state of the dialog will be updated when the dialog is closed by the user. """ if not self.is_initialized: self.initialize() self.proxy.open() def exec_(self): """ Open the dialog in a blocking fashion. Returns ------- result : unicode The path selected by the user, or an empty string if the dialog is cancelled. """ if not self.is_initialized: self.initialize() self.proxy.exec_() if self.result == 'accepted': return self.path return u'' #-------------------------------------------------------------------------- # Utility Methods #-------------------------------------------------------------------------- def _handle_close(self, result, paths, selected_filter): """ Called by the proxy object when the dialog is closed. Parameters ---------- result : string The result of the dialog; either 'accepted' or 'rejected'. paths : list The list of user selected paths. If the result is 'rejected' this should be an empty list. selected_filter : unicode The user selected name filter. If the result is 'rejected' this should be an empty string. """ self.result = result if result == 'accepted': self.paths = paths self.path = paths[0] if paths else u'' self.selected_filter = selected_filter self.accepted(self.path) else: self.rejected() if self.callback: self.callback(self) self.closed() if self.destroy_on_close: deferred_call(self.destroy)
class LockInMeasureTask(InstrumentTask): """Ask a lock-in to perform a measure. Wait for any parallel operationbefore execution. """ # Value to retrieve. mode = Enum('X', 'Y', 'X&Y', 'Amp', 'Phase', 'Amp&Phase').tag(pref=True) # Time to wait before performing the measurement. waiting_time = Float().tag(pref=True) driver_list = ['SR7265-LI', 'SR7270-LI', 'SR830'] task_database_entries = set_default({'x': 1.0}) wait = set_default({'activated': True, 'wait': ['instr']}) def perform(self): """ """ if not self.driver: self.start_driver() sleep(self.waiting_time) if self.mode == 'X': value = self.driver.read_x() self.write_in_database('x', value) elif self.mode == 'Y': value = self.driver.read_y() self.write_in_database('y', value) elif self.mode == 'X&Y': value_x, value_y = self.driver.read_xy() self.write_in_database('x', value_x) self.write_in_database('y', value_y) elif self.mode == 'Amp': value = self.driver.read_amplitude() self.write_in_database('amplitude', value) elif self.mode == 'Phase': value = self.driver.read_phase() self.write_in_database('phase', value) elif self.mode == 'Amp&Phase': amplitude, phase = self.driver.read_amp_and_phase() self.write_in_database('amplitude', amplitude) self.write_in_database('phase', phase) def _observe_mode(self, change): """ Update the database entries acording to the mode. """ new = change['value'] if new == 'X': self.task_database_entries = {'x': 1.0} elif new == 'Y': self.task_database_entries = {'y': 1.0} elif new == 'X&Y': self.task_database_entries = {'x': 1.0, 'y': 1.0} elif new == 'Amp': self.task_database_entries = {'amplitude': 1.0} elif new == 'Phase': self.task_database_entries = {'phase': 1.0} elif new == 'Amp&Phase': self.task_database_entries = {'amplitude': 1.0, 'phase': 1.0}
class PNASweepTask(SingleChannelPNATask): """Measure the specified parameters while sweeping either the frequency or the power. Measure are saved in an array with named fields : Frequency or Power and then 'Measure'_'Format' (S21_MLIN, S33 if Raw) Wait for any parallel operation before execution. """ channel = Int(1).tag(pref=True) start = Str().tag(pref=True) stop = Str().tag(pref=True) points = Str().tag(pref=True) sweep_type = Enum('', 'Frequency', 'Power').tag(pref=True) measures = ContainerList(Tuple()).tag(pref=True) if_bandwidth = Int(0).tag(pref=True) window = Int(1).tag(pref=True) wait = set_default({'activated': True, 'wait': ['instr']}) driver_list = ['AgilentPNA'] task_database_entries = set_default({'sweep_data': np.array([0])}) def perform(self): """ """ if not self.driver: self.start_driver() self.channel_driver = self.driver.get_channel(self.channel) if self.driver.owner != self.task_name: self.driver.owner = self.task_name self.driver.set_all_chanel_to_hold() self.driver.trigger_scope = 'CURRent' self.driver.trigger_source = 'MANual' meas_names = [ 'Ch{}:'.format(self.channel) + ':'.join(measure) for measure in self.measures ] if self.channel_driver.owner != self.task_name: self.channel_driver.owner = self.task_name if self.if_bandwidth > 0: self.channel_driver.if_bandwidth = self.if_bandwidth # Check whether or not we are doing the same measures as the ones # already defined (avoid losing display optimisation) measures = self.channel_driver.list_existing_measures() existing_meas = [meas['name'] for meas in measures] if not (all([meas in existing_meas for meas in meas_names]) and all([meas in meas_names for meas in existing_meas])): clear = True self.channel_driver.delete_all_meas() for i, meas_name in enumerate(meas_names): self.channel_driver.prepare_measure( meas_name, self.window, i + 1, clear) clear = False current_Xaxis = self.channel_driver.sweep_x_axis if self.start: start = self.format_and_eval_string(self.start) else: start = current_Xaxis[0] * 1e9 if self.stop: stop = self.format_and_eval_string(self.stop) else: stop = current_Xaxis[-1] * 1e9 if self.points: points = self.format_and_eval_string(self.points) else: points = len(current_Xaxis) if self.sweep_type: self.channel_driver.prepare_sweep(self.sweep_type.upper(), start, stop, points) else: if self.channel_driver.sweep_type.upper() == 'LIN': self.channel_driver.prepare_sweep('FREQUENCY', start, stop, points) elif self.channel_driver.sweep_type.upper() == 'POW': self.channel_driver.prepare_sweep('POWER', start, stop, points) waiting_time = self.channel_driver.sweep_time self.driver.fire_trigger(self.channel) time.sleep(waiting_time) while not self.driver.check_operation_completion(): time.sleep(0.1 * waiting_time) data = [np.linspace(start, stop, points)] for i, meas_name in enumerate(meas_names): if self.measures[i][1]: data.append(self.channel_driver.read_formatted_data(meas_name)) else: data.append(self.channel_driver.read_raw_data(meas_name)) names = [self.sweep_type ] + ['_'.join(measure) for measure in self.measures] final_arr = np.rec.fromarrays(data, names=names) self.write_in_database('sweep_data', final_arr) def check(self, *args, **kwargs): """ """ test, traceback = super(PNASweepTask, self).check(*args, **kwargs) pattern = re.compile('S[1-4][1-4]') for i, meas in enumerate(self.measures): match = pattern.match(meas[0]) if not match: path = self.task_path + '/' + self.task_name path += '_Meas_{}'.format(i) traceback[path] = 'Unvalid parameter : {}'.format(meas[0]) test = False if self.start: try: self.format_and_eval_string(self.start) except: test = False traceback[self.task_path + '/' + self.task_name + '-start'] = \ 'Failed to eval the start formula {}'.format(self.start) if self.stop: try: self.format_and_eval_string(self.stop) except: test = False traceback[self.task_path + '/' + self.task_name + '-stop'] = \ 'Failed to eval the stop formula {}'.format(self.stop) if self.points: try: self.format_and_eval_string(self.points) except: test = False traceback[self.task_path + '/' + self.task_name + '-step'] = \ 'Failed to eval the points formula {}'.format(self.points) data = [np.array([0.0, 1.0])] + \ [np.array([0.0, 1.0]) for meas in self.measures] names = [self.sweep_type] + ['_'.join(meas) for meas in self.measures] final_arr = np.rec.fromarrays(data, names=names) self.write_in_database('sweep_data', final_arr) return test, traceback
class Shape(ToolkitObject): """ Abstract shape component that can be displayed on the screen and represented by the framework. Attributes ---------- position: Tuple A tuple or list of the (x, y, z) position of this shape. This is coerced into a Point. x: Float y: Float z: Float Alias to the position direction: Tuple A tuple or list of the (u, v, w) vector of this shape. This is coerced into a Vector. axis: Tuple A tuple or list of the (u, v, w) axis of this shape. This is coerced into a Vector that defines the x, y, and z orientation of this shape. tolerance: Float The tolerance to use for operations that may require it. color: string A string representing the color of the shape. material: String A string represeting a pre-defined material which defines a color and luminosity of the shape. transparency: Float The opacity of the shape used for display. shape_edges: List A read only property that returns the list of edges this shape has (if any). shape_faces: List A read only property that returns the list of faces this shape has (if any). shape_shells: List A read only property that returns the list of surfaces this shape has (if any). Notes ------ This shape's proxy holds an internal reference to the underlying shape which can be accessed using `self.proxy.shape` if needed. The topology of the shape can be accessed using the `self.proxy.topology` attribute. """ #: Reference to the implementation control proxy = Typed(ProxyShape) #: Tolerance tolerance = d_(Float(10**-6, strict=False)) #: Color color = d_(Str()).tag(view=True, group='Display') #: Texture material material = d_(Enum(None, 'aluminium', 'brass', 'bronze', 'charcoal', 'chrome', 'copper', 'default', 'diamond', 'glass', 'gold', 'jade', 'metalized', 'neon_gnc', 'neon_phc', 'obsidian', 'pewter', 'plaster', 'plastic', 'satin', 'shiny_plastic', 'silver', 'steel', 'stone', 'water') ).tag(view=True, group='Display') #: Transparency transparency = d_(Float(strict=False)).tag(view=True, group='Display') #: x position x = d_(Float(0, strict=False)).tag(view=True, group='Position') #: y position y = d_(Float(0, strict=False)).tag(view=True, group='Position') #: z position z = d_(Float(0, strict=False)).tag(view=True, group='Position') #: Position position = d_(Coerced(gp_Pnt, (0, 0, 0), coercer=lambda args: gp_Pnt(*args))) #: Direction direction = d_(Coerced(gp_Dir, (0, 0, 1), coercer=lambda args: gp_Dir(*args))) #: Axis axis = d_(Coerced(gp_Ax2, ((0, 0, 0), (0, 0, 1)), coercer=coerce_axis)) def _get_edges(self): topo = self.proxy.topology if not topo: return [] return [e for e in topo.edges()] #: Edges of this shape shape_edges = Property(lambda self: self._get_edges(), cached=True) def _get_faces(self): topo = self.proxy.topology if not topo: return [] return [e for e in topo.faces()] #: Faces of this shape shape_faces = Property(lambda self: self._get_faces(), cached=True) def _get_shells(self): topo = self.proxy.topology if not topo: return [] return [e for e in topo.shells()] #: Shells of this shape shape_shells = Property(lambda self: self._get_shells(), cached=True) #: Block change updates to prevent loops when updated synced properties _block_updates = Bool() @contextmanager def suppress_updates(self): self._block_updates = True try: yield finally: self._block_updates = False @observe('x', 'y', 'z') def _update_position(self, change): """ Keep position in sync with x,y,z """ if change['type'] != 'update': return pt = gp_Pnt(self.x, self.y, self.z) if not pt.IsEqual(self.position, self.tolerance): self.position = pt @observe('position') def _update_xyz(self, change): """ Keep x,y,z in sync with position """ self.x, self.y, self.z = (self.position.X(), self.position.Y(), self.position.Z()) @observe('position', 'direction') def _update_axis(self, change): """ Keep axis in sync with position and direction """ if not self._block_updates: self.axis = self._default_axis() @observe('axis') def _update_state(self, change): """ Keep position and direction in sync with axis """ with self.suppress_updates(): self.position = self.axis.Location() self.direction = self.axis.Direction() def _default_axis(self): return gp_Ax2(self.position, self.direction) @observe('axis', 'color', 'transparency') def _update_proxy(self, change): super(Shape, self)._update_proxy(change) if self.proxy: self.proxy.update_display(change) @observe('proxy.shape') def _update_topo(self, change): """ Update the cached topology references when the shape changes. s""" for k in ['shape_edges', 'shape_faces', 'shape_shells']: self.get_member(k).reset(self)
class DMPLConfig(Model): #: Version number mode = Enum(1, 2, 3, 4, 6).tag(config=True)
class PlotItem(Control): #: Title of data series title = d_(Str()) #: Name name = d_(Str()) #: Row in plot area row = d_(Int(0)) #: Column in plot area column = d_(Int(0)) #: Pen type to use for line line_pen = d_(Instance(PEN_ARGTYPES)) #: Pen type to use for shadow shadow_pen = d_(Instance(PEN_ARGTYPES)) #: Fill level fill_level = d_(Float(strict=False)) # ‘c’ one of: r, g, b, c, m, y, k, w # R, G, B, [A] integers 0-255 # (R, G, B, [A]) tuple of integers 0-255 # float greyscale, 0.0-1.0 # int see intColor() # (int, hues) see intColor() # “RGB” hexadecimal strings; may begin with ‘#’ # “RGBA” # “RRGGBB” # “RRGGBBAA” #: Brush fill type fill_brush = d_(Instance(BRUSH_ARGTYPES)) #: Symbol to use for points symbol = d_(Enum(None, 'o', 's', 't', 'd', '+')) #: Symbol sizes for points symbol_size = d_(Float(10, strict=False)) #: Symbol pen to use symbol_pen = d_(Instance(PEN_ARGTYPES)) #: Symbol brush symbol_brush = d_(Instance(BRUSH_ARGTYPES)) #: Show legend show_legend = d_(Bool(False)) label_left = d_(Str()) label_right = d_(Str()) label_top = d_(Str()) label_bottom = d_(Str()) # H, V grid = d_(Tuple(bool, default=(False, False))) grid_alpha = d_(FloatRange(low=0.0, high=1.0, value=0.5)) #: Display a separate axis for each nested plot multi_axis = d_(Bool(True)) axis_left_ticks = d_(Callable()) axis_bottom_ticks = d_(Callable()) #: Display the axis on log scale log_mode = d_(Tuple(bool, default=(False, False))) # x,y #: Enable antialiasing antialias = d_(Bool(False)) #: Set auto range for each axis auto_range = d_( Enum(True, False, (True, True), (True, False), (False, True), (False, False))) # x-range to use if auto_range is disabled range_x = d_(ContainerList(default=[0, 100])) #: y-range to use if auto_range is disabled range_y = d_(ContainerList(default=[0, 100])) #: Automatically downsaple auto_downsample = d_(Bool(False)) #: Clip data points to view clip_to_view = d_(Bool(False)) #: Step mode to use step_mode = d_(Bool(False)) #: Keep aspect ratio locked when resizing aspect_locked = d_(Bool(False)) #: Time between updates refresh_time = d_(Int(100)) @observe('line_pen', 'symbol', 'symbol_size', 'symbol_pen', 'symbol_brush', 'fill_brush', 'fill_level', 'multi_axis', 'title', 'label_left', 'label_right', 'label_top', 'label_bottom', 'grid', 'grid_alpha', 'log_mode', 'antialias', 'auto_range', 'auto_downsample', 'clip_to_view', 'step_mode', 'aspect_locked', 'axis_left_ticks', 'axis_bottom_ticks', 'show_legend', 'row', 'column') def _update_proxy(self, change): """ An observer which sends state change to the proxy. """ # The superclass handler implementation is sufficient. super(PlotItem, self)._update_proxy(change) @observe('range_x', 'range_y') def _update_range(self, change): """ Handle updates and changes """ getattr(self.proxy, 'set_%s' % change['name'])(change['value'])
class EBL_PolyBase(Atom): color = Enum("green").tag( desc="color or datatype of item, could be used for dosing possibly") layer = Enum("Al").tag(desc='layer of item')
(Range(0), [0, 3], [0, 3], [-1]), (Range(high=2), [-1, 2], [-1, 2], [3]), (Float(), [1, int(1), 1.1], [1.0, 1.0, 1.1], ['']), (Float(strict=True), [1.1], [1.1], [1]), (FloatRange(0.0, 0.5), [0.0, 0.5], [0.0, 0.5], [-0.1, 0.6]), (FloatRange(0.5, 0.0), [0.0, 0.5], [0.0, 0.5], [-0.1, 0.6]), (FloatRange(0.0), [0.0, 0.6], [0.0, 0.6], [-0.1]), (FloatRange(high=0.5), [-0.3, 0.5], [-0.3, 0.5], [0.6]), (Bytes(), [b'a', u'a'], [b'a'] * 2, [1]), (Bytes(strict=True), [b'a'], [b'a'], [u'a']), (Str(), [b'a', u'a'], ['a'] * 2, [1]), (Str(strict=True), [b'a'] if sys.version_info < (3, ) else [u'a'], ['a'], [u'a'] if sys.version_info < (3, ) else [b'a']), (Unicode(), [b'a', u'a'], [u'a'] * 2, [1]), (Unicode(strict=True), [u'a'], [u'a'], [b'a']), (Enum(1, 2, 'a'), [1, 2, 'a'], [1, 2, 'a'], [3]), (Callable(), [int], [int], [1]), (Coerced(set), [{1}, [1], (1, )], [{1}] * 3, [1]), (Coerced(int, coercer=lambda x: int(str(x), 2)), ['101'], [5], []), (Tuple(), [(1, )], [(1, )], [[1]]), (Tuple(Int()), [(1, )], [(1, )], [(1.0, )]), (Tuple(int), [(1, )], [(1, )], [(1.0, )]), (List(), [[1]], [[1]], [(1, )]), (List(Int()), [[1]], [[1]], [[1.0]]), (List(float), [[1.0]], [[1.0]], [[1]]), (List((int, float)), [[1, 1.0]], [[1, 1.0]], [['']]), (ContainerList(), [[1]], [[1]], [(1, )]), (ContainerList(Int()), [[1]], [[1]], [[1.0]]), (ContainerList(float), [[1.0]], [[1.0]], [[1]]), (ContainerList((int, float)), [[1, 1.0]], [[1, 1.0]], [['']]), (Dict(), [{
class SequenceSelector(BaseSelector): ''' TODO ''' settings = Typed(list, []).tag(preference=True) order = d_(Enum(*choice.options.keys())).tag(preference=True) def add_setting(self, values=None, index=None): if values is None: values = {} for item in self.context_items: if item.name not in values: values[item.name] = item.default settings = self.settings[:] if index is None: settings.append(values) else: settings.insert(index, values) self.settings = settings self.updated = True def remove_setting(self, setting): settings = self.settings[:] settings.remove(setting) self.settings = settings self.updated = True def append_item(self, item): ''' Add context item to selector Parameters ---------- item : ContextItem Item to add to selector ''' for setting in self.settings: if item not in setting: setting[item.name] = item.default super(SequenceSelector, self).append_item(item) def get_key(self, settings, use='name'): key = [] for item in self.context_items: if use == 'name': setting_value = settings[item.name] elif use == 'item': setting_value = settings[item] else: raise ValueError(f'Unrecognized value for use: "{use}"') try: value = item.coerce_to_type(setting_value) except ValueError: value = item.coerce_to_type(eval(setting_value, self.symbols)) key.append(value) return key def sort_settings(self): settings = self.settings.copy() settings.sort(key=self.get_key) self.settings = settings self.updated = True def _observe_order(self, event): self.updated = True @warn_empty def get_iterator(self, cycles=np.inf): # Some selectors need to sort the settings. To make sure that the # selector sorts the parameters in the order the columns are specified, # we need to convert to a list of tuples. settings = [{i: s[i.name] for i in self.context_items} \ for s in self.settings] selector = choice.options[self.order] return selector(settings, cycles, key=lambda x: self.get_key(x, 'item')) def set_value(self, setting_index, item, value): # TODO: It's weird that some methods take the index of the setting, # while others take the setting object. Need to sanitize this. self.settings[setting_index][item.name] = value self.updated = True def get_value(self, setting_index, item): return self.settings[setting_index][item.name]