class Pipe(Operation): """ An operation that extrudes a profile along a spline, wire, or path. Attributes ---------- spline: Edge or Wire The spline to extrude along. profile: Wire The profile to extrude. fill_mode: String, optional The fill mode to use. Examples -------- See examples/pipes.enaml """ #: Reference to the implementation control proxy = Typed(ProxyPipe) #: Spline to make the pipe along spline = d_(Instance(Shape)) #: Profile to make the pipe from profile = d_(ForwardInstance(WireFactory)) #: Fill mode fill_mode = d_( Enum(None, 'corrected_frenet', 'fixed', 'frenet', 'constant_normal', 'darboux', 'guide_ac', 'guide_plan', 'guide_ac_contact', 'guide_plan_contact', 'discrete_trihedron')).tag(view=True, group='Pipe') @observe('spline', 'profile', 'fill_mode') def _update_proxy(self, change): super(Pipe, self)._update_proxy(change)
class Splitter(ConstraintsWidget): """ A widget which displays its children in separate resizable compartments that are connected with a resizing bar. A Splitter can have an arbitrary number of Container children. """ #: The orientation of the Splitter. 'horizontal' means the children #: are laid out left to right, 'vertical' means top to bottom. orientation = d_(Enum('horizontal', 'vertical')) #: Whether the child widgets resize as a splitter is being dragged #: (True), or if a simple indicator is drawn until the drag handle #: is released (False). The default is True. live_drag = d_(Bool(True)) #: A splitter expands freely in height and width by default. hug_width = set_default('ignore') hug_height = set_default('ignore') #: A reference to the ProxySplitter object. proxy = Typed(ProxySplitter) def split_items(self): """ Get the split item children defined on the splitter. """ return [c for c in self.children if isinstance(c, SplitItem)] #-------------------------------------------------------------------------- # Observers #-------------------------------------------------------------------------- @observe('orientation', 'live_drag') def _update_proxy(self, change): """ An observer which sends state change to the proxy. """ # The superclass handler implementation is sufficient. super(Splitter, self)._update_proxy(change)
class EditText(TextView): """A simple control for displaying read-only text.""" #: Text selection selection = d_(Tuple(int)) #: Make editable by default input_type = set_default("text") #: Placeholder text placeholder = d_(Str()) #: Style (iOS) style = d_(Enum("", "line", "bezel", "rounded_rect")) #: A reference to the ProxyLabel object. proxy = Typed(ProxyEditText) @observe("selection", "placeholder", "style") def _update_proxy(self, change): super()._update_proxy(change)
class InsertTab(DockLayoutOp): """ A layout operation which inserts a tab into a tab group. This operation will remove an item from the current layout and insert it into a tab group in a dock area. If the item does not exist, the operation is a no-op. If the target - - is a normally docked item The target and item will be merged into a new tab group using the default tab position. - is docked in a tab group The item will be inserted into the tab group. - is docked in a dock bar The item will be appended to the dock bar. - is a floating dock item A new dock area will be created and the target and item will be merged into a new tab group. - does not exist The item is inserted into the left border of the primary dock area. """ #: The name of the dock item to insert into the tab group. item = Unicode() #: The name of an existing dock item in the tab group of interest. target = Unicode() #: The index at which to insert the dock item. index = Int(-1) #: The position of the tabs for a newly created tab group. tab_position = Enum('default', 'top', 'bottom', 'left', 'right')
class SplitLayout(LayoutNode): """ A layout object for defining split dock layouts. """ #: The orientation of the split layout. orientation = Enum('horizontal', 'vertical') #: The default sizes to apply to the items in the splitter. If #: provided, the length must be equal to the number of items. sizes = List(Int()) #: This list of split layout items to include in the split layout. items = List(Coerced(_SplitLayoutItem)) def __init__(self, *items, **kwargs): super(SplitLayout, self).__init__(items=list(items), **kwargs) def children(self): """ Get the list of children of the split layout. """ return self.items[:]
class Material_Parameters(Check): c_eta = Float(c_eta).tag( desc="The element factor", check_value=0.8, unit="for 50% metallization (Datta assuming sqrt(2) cancellation)", latex='c_\eta') material = Enum(*sorted(material_dict.keys())) def _default_material(self): return material Dvv = FloatRange(0.00001, 10 / 100.0, Dvv).tag(label="Dvv", unit=None, LiNb=2.4 / 100.0, reference="Morgan pg 9", desc="Piezoelectric coupling constant", aka="K^2/2") epsinf = FloatRange(0.0001 * 1.0e-12, 500 * 8.85e-12, epsinf).tag(label="epsilon_infty", unit="F/m", LiNb=46.0 * 8.85e-12, reference="Morgan pg 9", aka="C_S in Datta (50% metalization)", desc="Capacitance for one finger pair") v = FloatRange(1000.0, 10000.0, v).tag( label="v", unit="m/s", desc="propagation velocity of SAW (free surface)" ) # propagation velocity for YZ lithium niobate --- page 9 Morgan's Book def _observe_material(self, change): self.Dvv = material_dict[self.material]['Dvv'] self.epsinf = material_dict[self.material]['epsinf'] self.v = material_dict[self.material]['v']
class InstrUser(Declarative): """Extension to the 'ecpy.instruments.users' extensions point. """ #: Plugin id associated with this use of instrument. This allow the manager #: to know what part of the application requested the right to use some #: drivers. id = d_(Unicode()) #: Is the plugin susceptible to release the profiles it is currently using #: if the manager asks it to do so. policy = d_(Enum('releasable', 'unreleasable')) @d_func def release_profiles(self, workbench, profiles): """Release the specified profiles or some of them. This call can block until the profiles can be released (if it is likely to happen in a relatively short time). The 'ecpy.instruments.notify_profiles_released' command should not be called (the manager knows what profiles it requested and will handle the tracking of the current user for each profile itself). Parameters ---------- workbench : Application workbench. profiles : list[unicode] List of profiles the manager is requesting the user to release. Returns ------- released_profiles : list[unicode] List of the profiles that have been released. """ raise NotImplementedError()
class RejectEpochs(EpochInput): ''' Rejects epochs whose amplitude exceeds a specified threshold. Attributes ---------- threshold : float Reject threshold mode : {'absolute value', 'amplitude'} If absolute value, rejects epoch if the minimum or maximum exceeds the reject threshold. If amplitude, rejects epoch if the difference between the minimum and maximum exceeds the reject threshold. ''' threshold = d_(Float()).tag(metadata=True) mode = d_(Enum('absolute value', 'amplitude')).tag(metadata=True) total = Int() rejects = Int() reject_ratio = Float() def configure_callback(self): valid_cb = super().configure_callback() return reject_epochs(self.threshold, self.mode, self, valid_cb).send
class Button(TextView): """ A simple control for displaying a button. """ #: Button is clickable by default clickable = set_default(True) #: Styles style = d_(Enum('', 'borderless', 'inset', 'small')) #: A reference to the proxy object. proxy = Typed(ProxyButton) # ------------------------------------------------------------------------- # Observers # ------------------------------------------------------------------------- @observe('style') def _update_proxy(self, change): """ An observer which sends the state change to the proxy. """ # The superclass implementation is sufficient. super(Button, self)._update_proxy(change)
class LorentzianFitter(LeastSqFitter): """Atom wrapper for Lorentzian least square fitting""" fit_type = Enum("lorentzian", "refl_lorentzian") gamma = Float(1.0).tag(desc="width of peak for initial guess") end_indices = Int(10).tag(desc="indices to average for background guess") fit_func_dict = { "lorentzian": lorentzian, "refl_lorentzian": refl_lorentzian } p_guess_dict = { "lorentzian": lorentzian_p_guess, "refl_lorentzian": refl_lorentzian_p_guess } @private_property def fit_func(self): return self.fit_func_dict[self.fit_type] @private_property def p_guess_func(self): return self.p_guess_dict[self.fit_type]
class Markdown(Raw): """ A block for rendering Markdown source. """ #: Extensions to use when rendering extensions = d_( List(default=[ "markdown.extensions.codehilite", "markdown.extensions.fenced_code", ])).tag(attr=False) #: Configuration for them extension_configs = d_( Dict(default={ 'markdown.extensions.codehilite': { 'css_class': 'highlight' }, })).tag(attr=False) #: Disallow raw HTMl safe_mode = d_(Bool()).tag(attr=False) #: Output format output_format = d_( Enum("xhtml1", "xhtml5", "xhtml", "html4", "html5", "html")).tag(attr=False) #: Tab size tab_length = d_(Int(4)).tag(attr=False) #: Reference to the proxy proxy = Typed(ProxyMarkdown) @observe('extensions', 'extension_configs', 'safe_mode', 'output_format', 'tab_length') def _update_proxy(self, change): """ The superclass implementation is sufficient. """ super(Markdown, self)._update_proxy(change)
class Parameter(ContextItem): ''' A context item that can be evaluated dynamically, but cannot be included as part of a selector. This is typically used for settings that must be determined before values are drawn from the selectors (e.g., probability of a go trial). ''' # Default value of the context item when used as part of a selector. default = d_(Value()) expression = d_(Str()).tag(preference=True) # Defines the span over which the item's value does not change: # * experiment - the value cannot change once the experiment begins # * trial - The value cannot change once a trial begins. This is the only # type of item that can be roved using a selector. # * arbitrary - The value can be changd at any time but it does not make # sense for it to be a roving item. scope = d_(Enum('trial', 'experiment', 'arbitrary')) # Is the value of this item managed by a selector? rove = d_(Bool()).tag(preference=True) def _default_expression(self): return str(self.default) def _default_dtype(self): return np.array(self.default).dtype.str def _default_label(self): return self.name def to_expression(self, value): return str(value) def set_value(self, value): self.expression = self.to_expression(value)
class InsertBorderItem(DockLayoutOp): """ A layout operation which inserts an item into an area border. This operation will remove an item from the current layout and insert it into the border of a dock area. If the item does not exist, the operation is a no-op. If the target - - is a normally docked item The item is inserted into the border of the dock area containing the target. - is docked in a tab group The item is inserted into the border of the dock area containing the tab group. - is docked in a dock bar The item is inserted into the border of the dock area containing the dock bar. - is a floating dock item A new dock area will be created and the item will be inserted into the border of the new dock area. - does not exist The item is inserted into the border of the primary dock area. """ #: The name of the dock item to insert into the layout. item = Unicode() #: The name of the dock item to use as the target location. target = Unicode() #: The border position at which to insert the item. position = Enum('left', 'top', 'right', 'bottom')
class StreamInterpolator(Atom): filespec = Typed(StreamFileSpec) is_reference = Bool(False) selector = Enum(*RECORD_SELECTORS) latency = Float(0.0) streamfile = Typed(StreamFile) @property def fieldname(self): return self.filespec.fieldname @property def datatype(self): return self.filespec.datatype @property def is_array(self): return self.filespec.is_array @property def timestamps(self): return self.streamfile.timestamps @property def interval(self): return self.streamfile.interval @property def record_count(self): return self.streamfile.count def _default_streamfile(self): return self.filespec.getStreamFile() def get(self, idx, dts): return self.streamfile.get(idx, dts - self.latency, self.selector)
class RejectEpochs(EpochInput): ''' Rejects epochs whose amplitude exceeds a specified threshold. Attributes ---------- threshold : float Reject threshold mode : {'absolute value', 'amplitude'} If absolute value, rejects epoch if the minimum or maximum exceeds the reject threshold. If amplitude, rejects epoch if the difference between the minimum and maximum exceeds the reject threshold. ''' threshold = d_(Float()).tag(metadata=True) mode = d_(Enum('absolute value', 'amplitude')).tag(metadata=True) total = Int() rejects = Int() reject_percent = Float() def status_cb(self, n_total, n_accepted): def update(): # Update the status. Must be wrapped in a deferred call to ensure # that the update occurs on the GUI thread. nonlocal self nonlocal n_total nonlocal n_accepted self.total += n_total self.rejects += n_total - n_accepted self.reject_percent = self.rejects / self.total * 100 deferred_call(update) def configure_callback(self): valid_cb = super().configure_callback() return pipeline.reject_epochs(self.threshold, self.mode, self.status_cb, valid_cb).send
class Text_Editor(Atom): view = Enum("Text_Editor") name = Unicode("Text_Editor") main_file = Unicode("idt.jdf").tag(private=True) dir_path = Unicode("/Users/thomasaref/Dropbox/Current stuff/TA_software" ).tag(private=True) data = Str().tag(discard=True, log=False, no_spacer=True, label="", spec="multiline") read_file = Typed(Read_TXT).tag(no_spacer=True) save_file = Typed(Save_TXT).tag(no_spacer=True) @observe('read_file.read_event') def obs_read_event(self, change): self.data = "".join(self.read_file.data["data"]) @observe('save_file.save_event') def obs_save_event(self, change): self.save_file.direct_save(self.data, write_mode='w') def _default_read_file(self): return Read_TXT(main_file=self.main_file, dir_path=self.dir_path) def _default_save_file(self): return Save_TXT(main_file=self.read_file.main_file, dir_path=self.read_file.dir_path) def data_list(self): return self.data.split("\n") @property def view_window(self): with imports(): from e_UserTemps import TextEditorWindow return TextEditorWindow(instr=self)
class StorageDefConstruct(ConstructNode): """ A construct node for a storage definition. """ #: The kind of the state definition. kind = Enum('attr', 'event') #: The name of the state object being defined. name = Str() #: The typename of the allowed values for the state object. typename = Str() #: The resolved type class for using with the state def. This is #: updated during the resolution passes over the tree. typeclass = Typed(type) @classmethod def from_dict(cls, dct): self = super(StorageDefConstruct, cls).from_dict(dct) self.kind = dct['kind'] self.name = dct['name'] self.typename = dct['typename'] return self
class Table(Control): """ Enaml declarative control for giving a Table grid widget. """ rows = d_(List()) columns = d_(List()) selected_rows = d_(List()) alternate_row_colors = d_(Bool(default=True)) stretch_last_column = d_(Bool()) select_mode = d_( Enum("single_row", "multi_rows", "single_cell", "multi_cells", "none")) row_style_callback = d_(Value()) double_click_action = d_(Value()) #: A reference to the ProxyTable implementation. proxy = Typed(ProxyTable) hug_height = "weak" hug_width = "weak" # Observers --------------------------------------------------------------- @observe( "rows", "columns", "alternate_row_colors", "select_mode", "stretch_last_column", "selected_rows", "row_style_callback", ) def _update_proxy(self, change): """ An observer which sends the state change to the proxy. """ # The superclass implementation is sufficient. super(Table, self)._update_proxy(change)
class ActivityIndicator(View): """ A simple control for displaying an ActivityIndicator. """ #: Style for indeterminate size = d_(Enum('normal', 'small', 'large')) #: Sets the color of the indicator. color = d_(Unicode()) #: A reference to the ProxyActivityIndicator object. proxy = Typed(ProxyActivityIndicator) # ------------------------------------------------------------------------- # Observers # ------------------------------------------------------------------------- @observe('size', 'color') def _update_proxy(self, change): """ An observer which sends the state change to the proxy. """ # The superclass implementation is sufficient. super(ActivityIndicator, self)._update_proxy(change)
class TabLayout(LayoutNode): """ A layout object for defining tabbed dock layouts. """ #: The position of the tabs in the tab layout. tab_position = Enum('top', 'bottom', 'left', 'right') #: The index of the currently selected tab. index = Int(0) #: Whether or not the tab layout is maximized. maximized = Bool(False) #: The list of item layouts to include in the tab layout. items = List(Coerced(ItemLayout)) def __init__(self, *items, **kwargs): super(TabLayout, self).__init__(items=list(items), **kwargs) def children(self): """ Get the list of children of the tab layout. """ return self.items[:]
class Plot1DLine(Plot1D): """""" #: Color of the plot color = ColorMember() #: Weight of the line line_weight = Float(1.0) #: Style of the line line_style = Str() #: Should markers be displayed markers_enabled = Bool() #: Size of the markers markers_size = Float() #: Shape of the marker # FIXME complete marker_shape = Enum(( "*", "+", ))
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 #self.plotter.pd.set_data(zname, z) 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)) #xdata=img_plot.index.get_data()[0].get_data() #ydata=img_plot.index.get_data()[1].get_data() if xname!=None: xdata=self.plotter.get_data(xname) else: xdata=img_plot.index.get_data()[0].get_data() if yname!=None: ydata=self.plotter.get_data(yname) else: ydata=img_plot.index.get_data()[1].get_data() img_plot.index.set_data(xdata,ydata) img_plot.request_redraw() self.rend_list[2]=img_plot def draw_plot(self, name, zname, zdata=None, xname='', 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.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] xdata=self.plotter.get_data(self.xname) if xdata!=None: renderer.index.set_data(xdata) renderer.request_redraw() self.rend_list[0]=renderer def draw_scatter_plot(self): renderer=self.plotter.plot.plot(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] xdata=self.plotter.get_data(self.xname) if xdata!=None: renderer.index.set_data(xdata) renderer.request_redraw() self.rend_list[1]=renderer
class Plotter(Atom): name=Unicode() title=Unicode("yoyoyoyoyo") xlabel=Unicode() ylabel=Unicode() xyfs=Dict() #pd=Typed(ArrayPlotData, ()) plot= ForwardTyped(lambda: Plot) color_index=Int() clts=Dict() fig=Typed(Figure) axe=Typed(Axes) #clt=Typed(PolyCollection) plottables=Dict() overall_plot_type=Enum("XY", "img", "polygon") value_scale=Enum('linear', 'log') index_scale=Enum('linear', 'log') #def _default_clt(self): # return PolyCollection([((0,0), (0,0))], alpha=0.6, antialiased=True)#, rasterized=False, antialiased=False) def _default_axe(self): axe=self.fig.add_subplot(111) axe.autoscale_view(True) return axe def _default_fig(self): return Figure() 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]) def _observe_title(self, change): self.axe.set_title(self.title) #self.plot.request_redraw() def _observe_xlabel(self, change): self.axe.set_xlabel(self.xlabel) #self.plot.x_axis.title=self.xlabel #self.plot.request_redraw() def _observe_ylabel(self, change): self.axe.set_ylabel(self.ylabel) # self.plot.request_redraw() def _default_xyfs(self): xyf=AllXYFormat(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): global PlotGraphicsContext if PlotGraphicsContext==None: from chaco.plot_graphics_context import PlotGraphicsContext 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, zcolor): if zdata!=None: if self.overall_plot_type=="polygon": if zname not in self.clts: #plottables['plotted']:#self.pd.list_data(): clt=PolyCollection(zdata, alpha=0.5, antialiased=True)#, rasterized=False, antialiased=False) clt.set_color(colorConverter.to_rgba(zcolor)) self.clts[zname]=clt self.axe.add_collection(self.clts[zname], autolim=True) else: self.clts[zname].set_verts(zdata) if self.overall_plot_type=="XY": if zname not in self.clts: clt = LineCollection(zdata)#, offsets=offs) clt.set_color(colors) #print dir(clt) self.clts[zname]=clt self.axe.add_collection(self.clts[zname], autolim=True) self.axe.autoscale_view() else: self.clts[zname].set_segments(zdata) if self.overall_plot_type=="img": if zname not in self.clts: axeimg=self.axe.imshow( Magvec, vmin=amin(Magvec), vmax=0.001, #amax(Magvec), aspect="auto", origin="lower", extent=[amin(yoko),amax(yoko), amin(freq),amax(freq)], #cmap='RdBu' ) self.fig.colorbar(axeimg) def draw(self): if self.fig.canvas!=None: #trans = transforms.Affine2D().scale(self.fig.dpi/72.0) #self.clt.set_transform(trans) # the points to pixels transform #self.clt.set_color(colors) #self.axe.autoscale_view(True) self.fig.canvas.draw() def set_xlim(self, xmin, xmax): self.axe.set_xlim(xmin, xmax) def set_ylim(self, ymin, ymax): self.axe.set_ylim(ymin, ymax) def get_data(self, zname, index=None, axis=0): data=[c.to_polygons() for c in self.clt.get_paths()] if index==None: return data if axis==0: return atleast_2d(data)[index, :] return atleast_2d(data)[:, index] def add_poly_plot_old(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') #coord='x' is likely redundant or a metadata tag 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_poly_plot(self, n, verts, cn="green", polyname=""): #for n,p in enumerate(self.polylist): log_debug("drawing polygon #: {0}".format(n)) #npoints = p.verts #n_gon(center=p, r=2, nsides=nsides) nxarray, nyarray = transpose(verts) self.pd.set_data("x" + str(n), nxarray) self.pd.set_data("y" + str(n), nyarray) log_debug("data set") self.plot.plot(("x"+str(n), "y"+str(n)), type="polygon", face_color=cn, #colors[nsides], hittest_type="poly" )[0] log_debug("plot occured") def add_img_plot(self, zname, zdata, xname=None, xdata=None, yname=None, ydata=None): self.add_data(zname=zname, zdata=zdata, xname=xname, xdata=xdata, yname=yname, ydata=ydata, overwrite=True, concat=False) print self.pd.get_data(zname) xyf=XYFormat(plotter=self) xyf.draw_img_plot(name='img_plot', 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='', xdata=None): #self.add_data(zname=zname, zdata=zdata, xname=xname, xdata=xdata, overwrite=True) self.set_data(zname, zdata) self.set_data(xname, xdata) xyf=XYFormat(plotter=self) zdata=self.get_data(zname) #if 1: #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): # global Plot, PanTool, ZoomTool, LegendTool # if Plot==None: # from chaco.plot import Plot # if PanTool==None or ZoomTool==None or LegendTool==None: # from chaco.tools.api import PanTool, ZoomTool, LegendTool #, LineInspector # # plot=Plot(self.pd, padding=50, fill_padding=True, # bgcolor="white", use_backbuffer=True, unified_draw=True)#, use_downsampling=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=0): if arr.ndim<2: return atleast_2d(arr) else: return split(arr, arr.shape[axis], axis=axis) def gatherMultiD(self, name, arrs, appen=None, concat=True, overwrite=False): if not isinstance(arrs, tuple): arrs=(arrs,) if appen==None: if shape(arrs)==(1,): appen=True else: appen=False orig=self.get_data(name) if orig!=None and not overwrite: arrs=(orig,)+arrs if appen: axis=1 else: axis=0 print arrs[0]==atleast_2d(*arrs) #if ndim(arrs[0])>1: # concat=False if concat: data=concatenate(atleast_2d(*arrs), axis) self.set_data(name, data) def add_data(self, zname, zdata, xname=None, xdata=None, yname=None, ydata=None, appen=None, concat=True, overwrite=False): if xname!=None: self.gatherMultiD(xname, xdata, appen=appen, overwrite=overwrite, concat=concat) if yname!=None: self.gatherMultiD(yname, ydata, appen=appen, overwrite=overwrite, concat=concat) self.gatherMultiD(zname, zdata, appen=appen, overwrite=overwrite, concat=concat) def show(self): with imports(): from e_Plotter import PlotMain app = QtApplication() view = PlotMain(plotr=self) view.show() app.start()
class FFTAlazarTask(InstrumentTask): """ Get the raw or averaged quadratures of the signal. Can also get raw or averaged traces of the signal. Custom shape for demodulation can be used. """ tracetimeaftertrig = Str('0').tag(pref=True, feval=VAL_REAL) tracetimeaftertrigB = Str('0').tag(pref=True, feval=VAL_REAL) traceduration = Str('0').tag(pref=True) tracedurationB = Str('0').tag(pref=True) tracesbuffer = Str('20').tag(pref=True, feval=VAL_INT) tracesnumber = Str('1000').tag(pref=True, feval=VAL_INT) average = Bool(True).tag(pref=True) Npoints = Str('0').tag(pref=True, feval=VAL_INT) trigrange = Enum('2.5V', '5V').tag(pref=True) triglevel = Str('0.3').tag(pref=True, feval=VAL_REAL) powerPhaseA = Bool(False).tag(pref=True) powerPhaseB = Bool(False).tag(pref=True) database_entries = set_default({ 'FFT': {}, 'freq': {}, 'power': {}, 'phase': {} }) def format_string(self, string, factor, n): s = self.format_and_eval_string(string) if isinstance(s, list) or isinstance(s, tuple) or isinstance( s, np.ndarray): return [elem * factor for elem in s] else: return [s * factor] * n def check(self, *args, **kwargs): """ """ test, traceback = super(FFTAlazarTask, self).check(*args, **kwargs) if (self.format_and_eval_string(self.tracesnumber) % self.format_and_eval_string(self.tracesbuffer) != 0): test = False traceback[self.path + '/' + self.name + '-get_demod'] = \ cleandoc('''The number of traces must be an integer multiple of the number of traces per buffer.''') if not (self.format_and_eval_string(self.tracesnumber) >= 1000): test = False traceback[self.path + '/' + self.name + '-get_demod'] = \ cleandoc('''At least 1000 traces must be recorded. Please make real measurements and not noisy s***.''') tracetime = self.format_string(self.tracetimeaftertrig, 10**-9, 1) traceduration = self.format_string(self.traceduration, 10**-9, 1) tracetimeB = self.format_string(self.tracetimeaftertrigB, 10**-9, 1) tracedurationB = self.format_string(self.tracedurationB, 10**-9, 1) for t, d in ((tracetime, traceduration), (tracetimeB, tracedurationB)): if len(t) != len(d): test = False traceback[self.path + '/' + self.name + '-get_demod'] = \ cleandoc('''An equal number of "Start time after trig" and "Duration" should be given.''') else: for tt, dd in zip(t, d): if not (tt >= 0 and dd >= 0): test = False traceback[self.path + '/' + self.name + '-get_demod'] = \ cleandoc('''Both "Start time after trig" and "Duration" must be >= 0.''') if ((0 in traceduration) and (0 in tracedurationB)): test = False traceback[self.path + '/' + self.name + '-get_demod'] = \ cleandoc('''All measurements are disabled.''') return test, traceback def perform(self): """ """ if not self.driver: self.start_driver() if self.trigrange == '5V': trigrange = 5 else: trigrange = 2.5 triglevel = self.format_and_eval_string(self.triglevel) self.driver.configure_board(trigrange, triglevel) recordsPerCapture = self.format_and_eval_string(self.tracesnumber) recordsPerBuffer = int(self.format_and_eval_string(self.tracesbuffer)) Npoints = self.format_and_eval_string(self.Npoints) tracetimeA = self.format_string(self.tracetimeaftertrig, 10**-9, 1) tracedurationA = self.format_string(self.traceduration, 10**-9, 1) tracetimeB = self.format_string(self.tracetimeaftertrigB, 10**-9, 1) tracedurationB = self.format_string(self.tracedurationB, 10**-9, 1) NtraceA = len(tracedurationA) if 0 in tracedurationA: NtraceA = 0 tracetimeA = [] tracedurationA = [] NtraceB = len(tracedurationB) if 0 in tracedurationB: NtraceB = 0 tracetimeB = [] tracedurationB = [] startaftertrig = tracetimeA + tracetimeB duration = tracedurationA + tracedurationB powerPhase = [self.powerPhaseA, self.powerPhaseB] answerFFT, answerFreq, answerFFTpower, answerFFTphase = self.driver.get_FFT( startaftertrig, duration, recordsPerCapture, recordsPerBuffer, self.average, NtraceA, NtraceB, Npoints, powerPhase) self.write_in_database('FFT', answerFFT) self.write_in_database('freq', answerFreq) self.write_in_database('power', answerFFTpower) self.write_in_database('phase', answerFFTphase)
class Scintilla(Control): """ A Scintilla text editing control. Notes ----- The 'background', 'foreground', and 'font' attributes have no effect on this widget. All styling is supplied via the 'theme' attribute. """ #: Enable autocompletion autocomplete = d_(Enum('none', 'all', 'document', 'apis')) #: Autocompletion values and call signatures. #: Images can be used by appending "?<image_no>" to the completion value. #: The images are defined by passing a list of image paths as the #: "autocompletion_images" settings key. autocompletions = d_(List(str)) #: Position of the cursor within the editor in the format (line, column) #: This is needed for autocompletion engines to determine the current text cursor_position = d_(Tuple(int, default=(0, 0)), writable=False) #: The scintilla document buffer to use in the editor. A default #: document will be created automatically for each editor. This #: value only needs to be supplied when swapping buffers or when #: using a single buffer in multiple editors. document = d_(Typed(ScintillaDocument, ())) #: The language syntax to apply to the document. syntax = d_(Enum(*SYNTAXES)) #: The theme to apply to the widget. See the './THEMES' document #: for how to create a theme dict for the widget. theme = d_(Typed(dict, ())) #: The settings to apply to the widget. See the './SETTINGS' #: document for how to create a settings dict for the widget. settings = d_(Typed(dict, ())) #: The zoom factor for the editor. The value is internally clamped #: to the range -10 to 20, inclusive. zoom = d_(Int()) #: An event emitted when the text is changed. text_changed = d_(Event(), writable=False) #: Text Editors expand freely in height and width by default. hug_width = set_default('ignore') hug_height = set_default('ignore') #: Markers to display. markers = d_(List(ScintillaMarker)) #: Indicators to display. indicators = d_(List(ScintillaIndicator)) #: A reference to the ProxyScintilla object. proxy = Typed(ProxyScintilla) #-------------------------------------------------------------------------- # Post Validators #-------------------------------------------------------------------------- def _post_validate_document(self, old, new): """ Post validate the text document. A new document is created when the existing document is set to None. This ensures that the proxy object never receives a null document and helps keep the state synchronized. """ return new or ScintillaDocument() def _post_validate_theme(self, old, new): """" Post validate the theme. The theme is reset to an empty dictionary if set to None. """ return new or {} def _post_validate_settings(self, old, new): """" Post validate the settings. The settings are reset to an empty dictionary if set to None. """ return new or {} #-------------------------------------------------------------------------- # Observers #-------------------------------------------------------------------------- @observe('document', 'syntax', 'theme', 'settings', 'zoom', 'autocomplete', 'autocompletions', 'indicators', 'markers') def _update_proxy(self, change): """ An observer which sends the document change to the proxy. """ # The superclass implementation is sufficient. super(Scintilla, self)._update_proxy(change) #-------------------------------------------------------------------------- # Public API #-------------------------------------------------------------------------- def get_text(self): """ Get the text in the current document. Returns ------- result : unicode The text in the current document. """ if self.proxy_is_active: return self.proxy.get_text() return u'' def set_text(self, text): """ Set the text in the current document. Parameters ---------- text : unicode The text to apply to the current document. """ if self.proxy_is_active: self.proxy.set_text(text)
class VNAAlazarTask(InstrumentTask): """ Allows to used an Alazar card as a VNA. """ freq = Str('[]').tag(pref=True) freqB = Str('[]').tag(pref=True) timeaftertrig = Str('0').tag(pref=True) timeaftertrigB = Str('0').tag(pref=True) duration = Str('1000').tag(pref=True) durationB = Str('0').tag(pref=True) tracesbuffer = Str('20').tag(pref=True, feval=VAL_INT) tracesnumber = Str('1000').tag(pref=True, feval=VAL_INT) average = Bool(True).tag(pref=True) trigrange = Enum('2.5V', '5V').tag(pref=True) triglevel = Str('0.3').tag(pref=True, feval=VAL_REAL) demodFormFile = Str('[]').tag(pref=True) aux_trig = Bool(False).tag(pref=True) database_entries = set_default({'VNADemod': {}}) def format_string(self, string, factor, n): s = self.format_and_eval_string(string) if isinstance(s, list) or isinstance(s, tuple) or isinstance( s, np.ndarray): return [elem * factor for elem in s] else: return [s * factor] * n def check(self, *args, **kwargs): """ """ test, traceback = super(VNAAlazarTask, self).check(*args, **kwargs) if (self.format_and_eval_string(self.tracesnumber) % self.format_and_eval_string(self.tracesbuffer) != 0): test = False traceback[self.path + '/' + self.name + '-get_demod'] = \ cleandoc('''The number of traces must be an integer multiple of the number of traces per buffer.''') if not (self.format_and_eval_string(self.tracesnumber) >= 1000): test = False traceback[self.path + '/' + self.name + '-get_demod'] = \ cleandoc('''At least 1000 traces must be recorded. Please make real measurements and not noisy s***.''') time = self.format_string(self.timeaftertrig, 10**-9, 1) duration = self.format_string(self.duration, 10**-9, 1) timeB = self.format_string(self.timeaftertrigB, 10**-9, 1) durationB = self.format_string(self.durationB, 10**-9, 1) for t, d in ((time, duration), (timeB, durationB)): if len(t) != len(d): test = False traceback[self.path + '/' + self.name + '-get_demod'] = \ cleandoc('''An equal number of "Start time after trig" and "Duration" should be given.''') else: for tt, dd in zip(t, d): if not (tt >= 0 and dd >= 0): test = False traceback[self.path + '/' + self.name + '-get_demod'] = \ cleandoc('''Both "Start time after trig" and "Duration" must be >= 0.''') if ((0 in duration) and (0 in durationB)): test = False traceback[self.path + '/' + self.name + '-get_demod'] = \ cleandoc('''All measurements are disabled.''') demodFormFile = self.format_and_eval_string(self.demodFormFile) samplesPerSec = 500000000.0 if demodFormFile != []: duration = duration + durationB for d in duration: if len(demodFormFile[0]) > samplesPerSec * d: test = False traceback[self.path + '/' + self.name + '-get_demod'] = \ cleandoc('''Acquisition's duration must be larger than demodulation fonction's duration''') return test, traceback def perform(self): """ """ if not self.driver: self.start_driver() if self.trigrange == '5V': trigrange = 5 else: trigrange = 2.5 triglevel = self.format_and_eval_string(self.triglevel) self.driver.configure_board(trigrange, triglevel) recordsPerCapture = self.format_and_eval_string(self.tracesnumber) recordsPerBuffer = int(self.format_and_eval_string(self.tracesbuffer)) timeA = self.format_string(self.timeaftertrig, 10**-9, 1) durationA = self.format_string(self.duration, 10**-9, 1) timeB = self.format_string(self.timeaftertrigB, 10**-9, 1) durationB = self.format_string(self.durationB, 10**-9, 1) demodFormFile = self.format_and_eval_string(self.demodFormFile) NdemodA = len(durationA) if 0 in durationA: NdemodA = 0 timeA = [] durationA = [] NdemodB = len(durationB) if 0 in durationB: NdemodB = 0 timeB = [] durationB = [] if len(demodFormFile) == 0: demodCosinus = 1 else: demodCosinus = 0 startaftertrig = timeA + timeB duration = durationA + durationB freqA = self.format_string(self.freq, 10**6, NdemodA) freqB = self.format_string(self.freqB, 10**6, NdemodB) freq = freqA + freqB freqA = self.format_string(self.freq, 10**6, 1) if freqA != []: Nfreq = len(freqA) else: Nfreq = len(self.format_string(self.freqB, 10**6, 1)) answerDemod = self.driver.get_VNAdemod(startaftertrig, duration, recordsPerCapture, recordsPerBuffer, freq, self.average, Nfreq, NdemodA, NdemodB, demodFormFile, demodCosinus, self.aux_trig) self.write_in_database('VNADemod', answerDemod)
class DemodAlazarTask(InstrumentTask): """ Get the raw or averaged quadratures of the signal. Can also get raw or averaged traces of the signal. Custom shape for demodulation can be used. """ freq = Str('50').tag(pref=True) freqB = Str('50').tag(pref=True) timeaftertrig = Str('0').tag(pref=True) timeaftertrigB = Str('0').tag(pref=True) timestep = Str('0').tag(pref=True) timestepB = Str('0').tag(pref=True) tracetimeaftertrig = Str('0').tag(pref=True) tracetimeaftertrigB = Str('0').tag(pref=True) duration = Str('1000').tag(pref=True) durationB = Str('0').tag(pref=True) traceduration = Str('0').tag(pref=True) tracedurationB = Str('0').tag(pref=True) tracesbuffer = Str('20').tag(pref=True, feval=VAL_INT) tracesnumber = Str('1000').tag(pref=True, feval=VAL_INT) average = Bool(True).tag(pref=True) Npoints = Str('0').tag(pref=True, feval=VAL_INT) IQtracemode = Bool(False).tag(pref=True) trigrange = Enum('2.5V', '5V').tag(pref=True) triglevel = Str('0.3').tag(pref=True, feval=VAL_REAL) demodFormFile = Str('[]').tag(pref=True) powerBoolA = Bool(False).tag(pref=True) powerBoolB = Bool(False).tag(pref=True) aux_trig = Bool(False).tag(pref=True) database_entries = set_default({'Demod': {}, 'Trace': {}, 'Power': {}}) def format_string(self, string, factor, n): s = self.format_and_eval_string(string) if isinstance(s, list) or isinstance(s, tuple) or isinstance( s, np.ndarray): return [elem * factor for elem in s] else: return [s * factor] * n def check(self, *args, **kwargs): """ """ test, traceback = super(DemodAlazarTask, self).check(*args, **kwargs) if (self.format_and_eval_string(self.tracesnumber) % self.format_and_eval_string(self.tracesbuffer) != 0): test = False traceback[self.path + '/' + self.name + '-get_demod'] = \ cleandoc('''The number of traces must be an integer multiple of the number of traces per buffer.''') if not (self.format_and_eval_string(self.tracesnumber) >= 1000): test = False traceback[self.path + '/' + self.name + '-get_demod'] = \ cleandoc('''At least 1000 traces must be recorded. Please make real measurements and not noisy s***.''') time = self.format_string(self.timeaftertrig, 10**-9, 1) duration = self.format_string(self.duration, 10**-9, 1) timeB = self.format_string(self.timeaftertrigB, 10**-9, 1) durationB = self.format_string(self.durationB, 10**-9, 1) tracetime = self.format_string(self.tracetimeaftertrig, 10**-9, 1) traceduration = self.format_string(self.traceduration, 10**-9, 1) tracetimeB = self.format_string(self.tracetimeaftertrigB, 10**-9, 1) tracedurationB = self.format_string(self.tracedurationB, 10**-9, 1) for t, d in ((time, duration), (timeB, durationB), (tracetime, traceduration), (tracetimeB, tracedurationB)): if len(t) != len(d): test = False traceback[self.path + '/' + self.name + '-get_demod'] = \ cleandoc('''An equal number of "Start time after trig" and "Duration" should be given.''') else: for tt, dd in zip(t, d): if not (tt >= 0 and dd >= 0): test = False traceback[self.path + '/' + self.name + '-get_demod'] = \ cleandoc('''Both "Start time after trig" and "Duration" must be >= 0.''') if ((0 in duration) and (0 in durationB) and (0 in traceduration) and (0 in tracedurationB)): test = False traceback[self.path + '/' + self.name + '-get_demod'] = \ cleandoc('''All measurements are disabled.''') timestep = self.format_string(self.timestep, 10**-9, len(time)) timestepB = self.format_string(self.timestepB, 10**-9, len(timeB)) freq = self.format_string(self.freq, 10**6, len(time)) freqB = self.format_string(self.freqB, 10**6, len(timeB)) samplesPerSec = 500000000.0 if 0 in duration: duration = [] timestep = [] freq = [] if 0 in durationB: durationB = [] timestepB = [] freqB = [] for d, ts in zip(duration + durationB, timestep + timestepB): if ts and np.mod(int(samplesPerSec * d), int(samplesPerSec * ts)): test = False traceback[self.path + '/' + self.name + '-get_demod'] = \ cleandoc('''The number of samples in "IQ time step" must divide the number of samples in "Duration".''') for f, ts in zip(freq + freqB, timestep + timestepB): if ts and np.mod(f * int(samplesPerSec * ts), samplesPerSec): test = False traceback[self.path + '/' + self.name + '-get_demod'] = \ cleandoc('''The "IQ time step" does not cover an integer number of demodulation periods.''') demodFormFile = self.format_and_eval_string(self.demodFormFile) if demodFormFile != []: duration = duration + durationB for d in duration: if len(demodFormFile[0]) > samplesPerSec * d: test = False traceback[self.path + '/' + self.name + '-get_demod'] = \ cleandoc('''Acquisition's duration must be larger than demodulation fonction's duration''') #RAM estimation and test #Prepare the parameters recordsPerCapture = self.format_and_eval_string(self.tracesnumber) timeA = self.format_string(self.timeaftertrig, 10**-9, 1) durationA = self.format_string(self.duration, 10**-9, 1) timeB = self.format_string(self.timeaftertrigB, 10**-9, 1) durationB = self.format_string(self.durationB, 10**-9, 1) tracetimeA = self.format_string(self.tracetimeaftertrig, 10**-9, 1) tracedurationA = self.format_string(self.traceduration, 10**-9, 1) tracetimeB = self.format_string(self.tracetimeaftertrigB, 10**-9, 1) tracedurationB = self.format_string(self.tracedurationB, 10**-9, 1) demodFormFile = self.format_and_eval_string(self.demodFormFile) NdemodA = len(durationA) if 0 in durationA: NdemodA = 0 timeA = [] durationA = [] NdemodB = len(durationB) if 0 in durationB: NdemodB = 0 timeB = [] durationB = [] NtraceA = len(tracedurationA) if 0 in tracedurationA: NtraceA = 0 tracetimeA = [] tracedurationA = [] NtraceB = len(tracedurationB) if 0 in tracedurationB: NtraceB = 0 tracetimeB = [] tracedurationB = [] if len(demodFormFile) == 0: demodCosinus = 1 else: demodCosinus = 0 startaftertrig = timeA + timeB + tracetimeA + tracetimeB duration = durationA + durationB + tracedurationA + tracedurationB timestepA = self.format_string(self.timestep, 10**-9, NdemodA) timestepB = self.format_string(self.timestepB, 10**-9, NdemodB) timestep = timestepA + timestepB freqA = self.format_string(self.freq, 10**6, NdemodA) freqB = self.format_string(self.freqB, 10**6, NdemodB) freq = freqA + freqB samplesPerSec = 500000000.0 #Initialize the RAM quantities size_data = 0 RAM_DEMOD = 0 #RAM coming from demodulations RAM_TRACE = 0 #RAM coming from traces RAM_list = [ ] #storage of the RAM estimations from each demodulation/trace #Quantities of reference RAM_USAGE_1_REF = 15.265243530273438 #15.265243530273438 MB = deep_getsizeof(data,set())/(1024*1024) #where data is generated with NdemodA=1,duration=200e-9,recordsPerCapture=20000 (these are the parameters relevant to the size of data) and timestep=20ns #NOTE : the deep_getsizeof function can be found at github.com/the-gigi/deep/blob/master/deeper.py, line 80 (thanks to the author by the way) RAM_USAGE_2_REF = 0.1529388427734375 #0.1530609130859375 MB = deepgetsizeof(np.empty((20000,1)),set())/(1024*1024) #Calculate the RAM needed samplesPerDemod_RAM = [] #Calculate RAM_DEMOD (in MB) coming from demodulations for i in range(NdemodA + NdemodB): samplesPerDemod_RAM.append(int(samplesPerSec * duration[i])) if timestep[i] or not demodCosinus: RAM_DEMOD += RAM_USAGE_1_REF * (duration[i] / 200e-9) * ( recordsPerCapture / 20000) RAM_list.append(RAM_USAGE_1_REF * (duration[i] / 200e-9) * (recordsPerCapture / 20000)) else: # Check wheter it is possible to cut each record in blocks of size equal # to an integer number of periods periodsPerBlock = 1 while (periodsPerBlock * samplesPerSec < freq[i] * samplesPerDemod_RAM[i] and periodsPerBlock * samplesPerSec % freq[i]): periodsPerBlock += 1 RAM_DEMOD += RAM_USAGE_2_REF * ( recordsPerCapture / 20000) * int( np.minimum(periodsPerBlock * samplesPerSec / freq[i], samplesPerDemod_RAM[i])) RAM_list.append(RAM_DEMOD) #We make the assumption that the size of np.empty((a,b)) becomes linearly dependent on a and b at sufficiently high vallues #of a and b. Here, recordsPerCapture will not be under 1000, which guaranties this assumption #Calculate RAM_TRACE (in MB) coming from traces for i in (np.arange(NtraceA + NtraceB) + NdemodA + NdemodB): RAM_TRACE += RAM_USAGE_1_REF * (duration[i] / 200e-9) * ( recordsPerCapture / 20000) RAM_list.append(RAM_USAGE_1_REF * (duration[i] / 200e-9) * (recordsPerCapture / 20000)) size_data = RAM_DEMOD + RAM_TRACE #RAM used by the data array in MB #Determine the heights of RAM peaks linked to the wanted demodulations/traces RAM_peaks = [] for k in range(len(RAM_list)): RAM_peaks.append(RAM_list[k] * 3 + (size_data - RAM_list[k])) #The demodulation/trace being calculated takes 3 times the RAM needed by its #data and we still have to take into account the RAM taken by the other demodulation/traces that have been or will be processed. estimation = max( RAM_peaks ) #The higher peak is the one that matters to determine if the calculation is possible or not estimation = (estimation / 1024) #Conversion into GB #In the case with no timestep, we have to take into account the RAM used by the buffers RAM_BUFFERS_REF = 1.0 #RAM (in GB) used by buffers with following parameters : recordsPerCapture = 1000000 ; duration = 1000ns #(it has been measured) total_duration_max = np.max( np.array(startaftertrig) + np.array(duration)) RAM_BUFFERS = RAM_BUFFERS_REF * (recordsPerCapture / 1000000) * ( total_duration_max / 1000e-9) if len(timestep) != 0 and not timestep[0]: estimation = max( estimation, RAM_BUFFERS ) #measurements showed that the higher quantity overshadows the other and is the one #that matter for the RAM used in the end #Retrieval of quantities of available RAM : physical and total (physical+virtual) and conversion into GB RAM_physique_dispo = psutil.virtual_memory()[1] / (1024**3) RAM_totale_dispo = psutil.swap_memory()[2] / (1024**3) if (estimation + 2) > RAM_physique_dispo: test = False traceback[self.path + '/' + self.name + '-get_demod'] = \ cleandoc('''Available RAM may be insufficient. RAM needed for this calculation = '''+str(round(estimation,3))+''' (+1/-2) GB VS Available physical RAM = '''+str(round(RAM_physique_dispo,3))+''' GB and Total available RAM (physical and virtual) = '''+str(round(RAM_totale_dispo,3))+''' GB.''') return test, traceback def perform(self): """ """ if not self.driver: self.start_driver() if self.trigrange == '5V': trigrange = 5 else: trigrange = 2.5 triglevel = self.format_and_eval_string(self.triglevel) self.driver.configure_board(trigrange, triglevel) recordsPerCapture = self.format_and_eval_string(self.tracesnumber) recordsPerBuffer = int(self.format_and_eval_string(self.tracesbuffer)) Npoints = self.format_and_eval_string(self.Npoints) timeA = self.format_string(self.timeaftertrig, 10**-9, 1) durationA = self.format_string(self.duration, 10**-9, 1) timeB = self.format_string(self.timeaftertrigB, 10**-9, 1) durationB = self.format_string(self.durationB, 10**-9, 1) tracetimeA = self.format_string(self.tracetimeaftertrig, 10**-9, 1) tracedurationA = self.format_string(self.traceduration, 10**-9, 1) tracetimeB = self.format_string(self.tracetimeaftertrigB, 10**-9, 1) tracedurationB = self.format_string(self.tracedurationB, 10**-9, 1) demodFormFile = self.format_and_eval_string(self.demodFormFile) NdemodA = len(durationA) if 0 in durationA: NdemodA = 0 timeA = [] durationA = [] NdemodB = len(durationB) if 0 in durationB: NdemodB = 0 timeB = [] durationB = [] NtraceA = len(tracedurationA) if 0 in tracedurationA: NtraceA = 0 tracetimeA = [] tracedurationA = [] NtraceB = len(tracedurationB) if 0 in tracedurationB: NtraceB = 0 tracetimeB = [] tracedurationB = [] if len(demodFormFile) == 0: demodCosinus = 1 else: demodCosinus = 0 startaftertrig = timeA + timeB + tracetimeA + tracetimeB duration = durationA + durationB + tracedurationA + tracedurationB timestepA = self.format_string(self.timestep, 10**-9, NdemodA) timestepB = self.format_string(self.timestepB, 10**-9, NdemodB) timestep = timestepA + timestepB freqA = self.format_string(self.freq, 10**6, NdemodA) freqB = self.format_string(self.freqB, 10**6, NdemodB) freq = freqA + freqB power = [self.powerBoolA, self.powerBoolB] answerDemod, answerTrace, answerPower = self.driver.get_demod( startaftertrig, duration, recordsPerCapture, recordsPerBuffer, timestep, freq, self.average, NdemodA, NdemodB, NtraceA, NtraceB, Npoints, demodFormFile, demodCosinus, self.aux_trig, power) self.write_in_database('Demod', answerDemod) self.write_in_database('Trace', answerTrace) self.write_in_database('Power', answerPower)
class Driver(Declarator): """Declarator used to register a new driver for an instrument. """ #: Path to the driver object. Path should be dot separated and the class #: name preceded by ':'. #: TODO complete : ex: ecpy_hqc_legacy.instruments. #: The path of any parent Drivers object will be prepended to it. driver = d_(Unicode()) #: Name identifying the system the driver is built on top of (lantz, hqc, #: slave, etc ...). Allow to handle properly multiple drivers declared in #: a single extension package for the same instrument. architecture = d_(Unicode()) #: Name of the instrument manufacturer. Can be inferred from parent #: Drivers. manufacturer = d_(Unicode()) #: Serie this instrument is part of. This is optional as it does not always #: make sense to be specified but in some cases it can help finding a #: a driver. Can be inferred from parent Drivers. serie = d_(Unicode()) #: Model of the instrument this driver has been written for. model = d_(Unicode()) #: Kind of the instrument, to ease instrument look up. If no kind match, #: leave 'Other' as the kind. Can be inferred from parent #: Drivers. kind = d_(Enum(None, *INSTRUMENT_KINDS)) #: Starter to use when initializing/finialzing this driver. #: Can be inferred from parent Drivers. starter = d_(Unicode()) #: Supported connections and default values for some parameters. The #: admissible values for a given kind can be determined by looking at the #: Connection object whose id match. #: ex : {'visa_tcpip' : {'port': 7500, 'resource_class': 'SOCKET'}} #: Can be inferred from parent Drivers. connections = d_(Dict()) #: Special settings for the driver, not fitting the connections. Multiple #: identical connection infos with different settings can co-exist in a #: profile. The admissible values for a given kind can be determined by #: looking at the Settings object whose id match. #: ex : {'lantz': {'resource_manager': '@py'}} #: Can be inferred from parent Drivers. settings = d_(Dict()) #: Id of the driver computed from the top-level package and the driver name id = Property(cached=True) def register(self, collector, traceback): """Collect driver and add infos to the DeclaratorCollector contributions member. """ # Build the driver id by assembling the package name, the architecture # and the class name try: driver_id = self.id except KeyError: # Handle the lack of architecture traceback[self.driver] = format_exc() return # Determine the path to the driver. path = self.get_path() try: d_path, driver = (path + '.' + self.driver if path else self.driver).split(':') except ValueError: msg = 'Incorrect %s (%s), path must be of the form a.b.c:Class' traceback[driver_id] = msg % (driver_id, self.driver) return # Check that the driver does not already exist. if driver_id in collector.contributions or driver_id in traceback: i = 0 while True: i += 1 err_id = '%s_duplicate%d' % (driver_id, i) if err_id not in traceback: break msg = 'Duplicate definition of {}, found in {}' traceback[err_id] = msg.format(self.architecture + '.' + driver, d_path) return try: meta_infos = { k: getattr(self, k) for k in ('architecture', 'manufacturer', 'serie', 'model', 'kind') } infos = DriverInfos(id=driver_id, infos=meta_infos, starter=self.starter, connections=self.connections, settings=self.settings) # ValueError catch wrong kind value except (KeyError, ValueError): traceback[driver_id] = format_exc() return # Get the driver class. d_cls = import_and_get(d_path, driver, traceback, driver_id) if d_cls is None: return try: infos.cls = d_cls except TypeError: msg = '{} should be a callable.\n{}' traceback[driver_id] = msg.format(d_cls, format_exc()) return collector.contributions[driver_id] = infos self.is_registered = True def unregister(self, collector): """Remove contributed infos from the collector. """ if self.is_registered: # Remove infos. driver_id = self.id try: del collector.contributions[driver_id] except KeyError: pass self.is_registered = False def __str__(self): """Identify the decl by its members. """ members = ('driver', 'architecture', 'manufacturer', 'serie', 'model', 'kind', 'starter', 'connections', 'settings') st = '{} whose known members are :\n{}' st_m = '\n'.join(' - {} : {}'.format(m, v) for m, v in [(m, getattr(self, m)) for m in members]) return st.format(type(self).__name__, st_m) # ========================================================================= # --- Private API --------------------------------------------------------- # ========================================================================= def _default_manufacturer(self): """Default value grabbed from parent if not provided explicitely. """ return self._get_inherited_member('manufacturer') def _default_serie(self): """Default value grabbed from parent if not provided explicitely. """ return self._get_inherited_member('serie') def _default_kind(self): """Default value grabbed from parent if not provided explicitely. """ return self._get_inherited_member('kind') def _default_architecture(self): """Default value grabbed from parent if not provided explicitely. """ return self._get_inherited_member('architecture') def _default_starter(self): """Default value grabbed from parent if not provided explicitely. """ return self._get_inherited_member('starter') def _default_connections(self): """Default value grabbed from parent if not provided explicitely. """ return self._get_inherited_member('connections') def _default_settings(self): """Default value grabbed from parent if not provided explicitely. """ return self._get_inherited_member('settings') def _get_inherited_member(self, member, parent=None): """Get the value of a member found in a parent declarator. """ parent = parent or self.parent if isinstance(parent, Drivers): value = getattr(parent, member) if value: return value else: parent = parent.parent else: parent = None if parent is None: if member == 'settings': return {} # Settings can be empty elif member == 'serie': return '' # An instrument can have no serie elif member == 'kind': return 'Other' raise KeyError('No inherited member was found for %s' % member) return self._get_inherited_member(member, parent) def _get_id(self): """Create the unique identifier of the driver using the top level package the architecture and the class name. """ if ':' in self.driver: path = self.get_path() d_path, d = (path + '.' + self.driver if path else self.driver).split(':') # Build the driver id by assembling the package name, architecture # and the class name return '.'.join((d_path.split('.', 1)[0], self.architecture, d)) else: return self.driver
class Widget(ToolkitObject): """ The base class of visible widgets in Enaml. """ #: Whether or not the widget is enabled. enabled = d_(Bool(True)) #: Whether or not the widget is visible. visible = d_(Bool(True)) #: The background color of the widget. background = d_(ColorMember()) # TODO remove in Enaml version 0.8.0 bgcolor = _warn_prop('bgcolor', 'background') #: The foreground color of the widget. foreground = d_(ColorMember()) # TODO remove in Enaml version 0.8.0 fgcolor = _warn_prop('fgcolor', 'foreground') #: The font used for the widget. font = d_(FontMember()) #: The minimum size for the widget. The default means that the #: client should determine an intelligent minimum size. minimum_size = d_(Coerced(Size, (-1, -1))) #: The maximum size for the widget. The default means that the #: client should determine and inteliigent maximum size. maximum_size = d_(Coerced(Size, (-1, -1))) #: The tool tip to show when the user hovers over the widget. tool_tip = d_(Unicode()) #: The status tip to show when the user hovers over the widget. status_tip = d_(Unicode()) #: A flag indicating whether or not to show the focus rectangle for #: the given widget. This is not necessarily support by all widgets #: on all clients. A value of None indicates to use the default as #: supplied by the client. show_focus_rect = d_(Enum(None, True, False)) #: A reference to the ProxyWidget object. proxy = Typed(ProxyWidget) #-------------------------------------------------------------------------- # Observers #-------------------------------------------------------------------------- @observe(('enabled', 'visible', 'background', 'foreground', 'font', 'minimum_size', 'maximum_size', 'show_focus_rect', 'tool_tip', 'status_tip')) def _update_proxy(self, change): """ Update the proxy widget when the Widget data changes. This method only updates the proxy when an attribute is updated; not when it is created or deleted. """ # The superclass implementation is sufficient. super(Widget, self)._update_proxy(change) #-------------------------------------------------------------------------- # Public API #-------------------------------------------------------------------------- def show(self): """ Ensure the widget is shown. Calling this method will also set the widget visibility to True. """ self.visible = True if self.proxy_is_active: self.proxy.ensure_visible() def hide(self): """ Ensure the widget is hidden. Calling this method will also set the widget visibility to False. """ self.visible = False if self.proxy_is_active: self.proxy.ensure_hidden()
class Field(Control): """ A single line editable text widget. """ #: The unicode text to display in the field. text = d_(Unicode()) #: 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_(Unicode()) #: 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'])) #: 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_(Unicode()) #: 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') 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''