Example #1
0
class Sp4ArrayFileSource(ArraySource):

    file_name = Str

    component = Enum('Amp', 'Phase', 'Real', 'Imag')
    set_component = Str

    f = Instance(sp4.Sp4File)

    view = View(Group(Item(name='transpose_input_array'),
        Item(name='file_name', editor=TextEditor(auto_set=False,\
                enter_set=True)),
        Item(name='component', editor=EnumEditor(values=component)),
                      Item(name='scalar_name'),
                      Item(name='vector_name'),
                      Item(name='spacing'),
                      Item(name='origin'),
                      Item(name='update_image_data', show_label=False),
                      show_labels=True)
                )

    def __init__(self, **kw_args):
        super(Sp4ArrayFileSource, self).__init__(**kw_args)
        fn = kw_args.pop('file_name', None)
        if fn is not None:
            self.file_name = fn
            self._open(self.file_name)
        self.component = "Amp"
        self._component_changed('Amp')

    def _open(self, fn):
        self.f = sp4.Sp4File(self.file_name)

    def _component_changed(self, info):
        if info == "Amp":
            self.scalar_data = numpy.abs(self.f.GetArray())
        if info == "Phase":
            self.scalar_data = numpy.angle(self.f.GetArray())
        self.update()

    def _file_name_changed(self, info):
        print self.file_name
class Shape(HasTraits):
    shape_type = Enum("rectangle", "circle")
    editable = Bool
    x, y, w, h, r = [Int] * 5

    view = View(VGroup(
        HGroup(Item("shape_type"), Item("editable")),
        VGroup(Item("x"),
               Item("y"),
               Item("w"),
               Item("h"),
               visible_when="shape_type=='rectangle'",
               enabled_when="editable"),
        VGroup(Item("x"),
               Item("y"),
               Item("r"),
               visible_when="shape_type=='circle'",
               enabled_when="editable"),
    ),
                resizable=True)
class ShapeSelector(HasTraits):
    select = Enum(*[cls.__name__ for cls in Shape.__subclasses__()]) 
    shape = Instance(Shape) 
    
    view = View(
        VGroup(
            Item("select"),
            Item("shape", style="custom"), 
            Item("object.shape.info", style="custom"), 
            show_labels = False
        ),
        width = 350, height = 300, resizable = True
    )
    
    def __init__(self, **traits):
        super(ShapeSelector, self).__init__(**traits)
        self._select_changed()
    
    def _select_changed(self):
        klass =  [c for c in Shape.__subclasses__() if c.__name__ == self.select][0]
        self.shape = klass()    
Example #4
0
class Line(AbstractOverlay):
    orientation = Enum("h", "v")
    color = ColorTrait("green")
    width = Int(1)

    def overlay(self, component, gc, *args, **kw):
        if component is None:
            return
        gc.save_state()
        gc.set_stroke_color(self.color_)
        gc.set_line_width(self.width)
        if self.orientation == "h":
            mid = component.y + component.height / 2
            gc.move_to(component.x, mid)
            gc.line_to(component.x2, mid)
        else:
            mid = component.x + component.width / 2
            gc.move_to(mid, component.y)
            gc.line_to(mid, component.y2)
        gc.stroke_path()
        gc.restore_state()
Example #5
0
    def __init__(self, nodelabels, matdict, **traits):
        """ Starts a matrix inspector
        
        Parameters
        ----------
        nodelables : list
            List of strings of labels for the rows of the matrix
        matdict : dictionary
            Keys are the edge type and values are NxN Numpy arrays """
        super(HasTraits, self).__init__(**traits)

        self.add_trait('data_name', Enum(matdict.keys()))

        self.data_name = matdict.keys()[0]
        self.data = matdict
        self.nodelables = nodelabels
        self.plot = self._create_plot_component()

        # set trait notification on customtool
        self.custtool.on_trait_change(self._update_fields, "xval")
        self.custtool.on_trait_change(self._update_fields, "yval")
Example #6
0
class Label(HasTraits):
    """ The Label class implements the data model for a label. """

    #### 'Label' interface ####################################################

    # The name.
    name = Unicode

    # The size in points.
    size = Int(18)

    # The style.
    style = Scriptable(Enum('normal', 'bold', 'italic'))

    ###########################################################################
    # 'Label' interface.
    ###########################################################################

    @scriptable
    def __init__(self, **traits):
        """ Initialise the object.  We only implement this so that it can be
        decorated and so the script manager knows how to recreate it. """

        super(Label, self).__init__(**traits)

    @scriptable
    def increment_size(self, by):
        """ Increment the current font size.  This demonstrates a scriptable
        method.
        """

        self.size += by

    @scriptable
    def decrement_size(self, by):
        """ decrement the current font size.  This demonstrates a scriptable
        method.
        """

        self.size -= by
    def __init__(self, net_ref, **traits):
        """ net_ref is a reference to a cnetwork """
        super(MatrixViewer, self).__init__(**traits)

        self.network_reference = net_ref
        self.edge_parameter = self.network_reference._edge_para
        self.matrix_data_ref = self.network_reference.datasourcemanager._srcobj.edgeattributes_matrix_dict
        self.labels = self.network_reference.datasourcemanager._srcobj.labels

        # get the currently selected edge
        self.curr_edge = self.edge_parameter.parameterset.name
        # create plot
        self.plot = self._create_plot_component()

        # set trait notification on customtool
        self.custtool.on_trait_change(self._update_fields, "xval")
        self.custtool.on_trait_change(self._update_fields, "yval")

        # add edge parameter enum
        self.add_trait('edge_parameter_name',
                       Enum(self.matrix_data_ref.keys()))
        self.edge_parameter_name = self.curr_edge
Example #8
0
class MlabPreferencesHelper(PreferencesHelper):

    # The preferences path for which we use.
    preferences_path = 'enthought.mayavi.mlab'

    ######################################################################
    # Our preferences.

    # The mlab backend to use.
    backend = Enum('auto',
                   'envisage',
                   'simple',
                   'test',
                   desc='the mlab backend to use')

    # The background color of the renderer.
    background_color = Tuple(Range(0., 1.),
                             Range(0., 1.),
                             Range(0., 1.),
                             editor=RGBColorEditor,
                             desc='the background color of the scene')

    # The foreground color of the renderer.
    foreground_color = Tuple(Range(0., 1.),
                             Range(0., 1.),
                             Range(0., 1.),
                             editor=RGBColorEditor,
                             desc='the foreground color of the scene')

    # Offscreen rendering.
    offscreen = Bool(desc='if mlab should use offscreen rendering'
                     ' (no window will show up in this case)')

    ######################################################################
    # Traits UI view.

    traits_view = View(Group(Item('backend'), Item('background_color'),
                             Item('foreground_color'), Item('offscreen')),
                       resizable=True)
Example #9
0
class BooleanOpFilter(ProcessObject):
    name = "Boolean Operation"
    input = Input
    tool = Input
    
    operation = Enum("cut", "fuse", "common")
    
    map = {'cut': BRepAlgoAPI.BRepAlgoAPI_Cut,
           'fuse': BRepAlgoAPI.BRepAlgoAPI_Fuse,
           'common': BRepAlgoAPI.BRepAlgoAPI_Common}
    
    traits_view = View('operation')
    
    def _operation_changed(self, vnew):
        self.name = "Boolean Op: %s"%vnew
        self.modified = True
        
    def execute(self):
        builder = self.map[self.operation]
        s1 = self.input.shape
        s2 = self.tool.shape
        return builder(s1, s2).Shape()
Example #10
0
class CfgFile(HasTraits):
    name = Str
    parent = Any
    directory = DelegatesTo('parent')
    descendents = List(This)
    config_type = Enum('appman', 'XM', 'PVA', 'task_state',
                       'target_positions', 'start_positions',
                       'auto_control_config', 'grasp_event',
                       'auto_pilot', 'module_config', 'tool_change')

    def _descendents_default(self):
        if self.config_type == 'XM':
            fd = parse_XM_config(self.directory + '/' + self.name)
            task_state_config_files = fd['task_state_config_files']
            l = []
            for kid in task_state_config_files:
                l.append(CfgFile(name=kid, config_type='task_state',
                                 parent=self))
            if fd.has_key('tool_change_config_files'):
                tool_change_config_files = fd['tool_change_config_files']
                for kid in tool_change_config_files:
                    l.append(CfgFile(name=kid, config_type='tool_change',
                                     parent=self))

        elif self.config_type == 'task_state':
            fd = parse_XM_config(self.directory + '/' + self.name)
            l = [CfgFile(name=fd['target_configurations_file'],
                         config_type='target_positions', parent=self)]
        elif self.config_type == 'appman':
            fd = parse_appman(self.directory + '/' + self.name, self.parent.name)
            kids = fd['module_config_files']
            l = []
            for kid in kids:
                l.append(CfgFile(name=os.path.relpath(kid, self.directory),
                                 config_type='module_config', parent=self))
        else:
            l = []
        return l
Example #11
0
class SimplePlotDecoder(DataDecoder):
  """
      Decodes lines of text formatted using a simple format.
  """
  
  name = Str('SimplePlot Decoder')
  
  view = View(
    Item(name="pass_through", label="Pass-through"),
    title='SimplePlot decoder'
  )
  
  pass_through = Enum('User messages', 'Plot-o-matic messages', 'Both', 'None')
  
  _sub_re = re.compile('\W+')

  def decode(self, data):
    """
        Decode an input string of the form ~variable_name#value.
    """
    if data[0] != '~':
      if self.pass_through == 'User messages' or self.pass_through == 'Both':
        print data[:-1]
      return None

    if self.pass_through == 'Plot-o-matic messages' or self.pass_through == 'Both':
      print data[:-1]

    var_name, val = data[1:].split('#')
    var_name = self._sub_re.sub('_', var_name)

    new_dict = {}
    try:
      new_dict[var_name] = float(val)
    except:
      new_dict[var_name] = val

    return new_dict
Example #12
0
class MandelbrotController(AbstractController):
    application = Instance("MandelbrotDemo")
    event_state = Enum("normal", "moving")
    start_x = Float
    start_y = Float
    
    def normal_left_down(self, evt):
        self.event_state = "moving"
        self.start_x = evt.x
        self.start_y = evt.y

    def moving_mouse_move(self, evt):
        app = self.application
        dx = evt.x - self.start_x
        dy = evt.y - self.start_y
        app.cx -= dx/float(self.component.x2)*2*app.d
        app.cy -= dy/float(self.component.y2)*2*app.d
        self.start_x = evt.x
        self.start_y = evt.y
        app.update_plot()
        
    def moving_left_up(self, evt):
        self.event_state = "normal"
        
    def normal_mouse_wheel(self, evt):
        app = self.application
        x0, x1, y0, y1 = app.cx-app.d, app.cx+app.d, app.cy-app.d, app.cy+app.d
        x = x0 + evt.x/float(self.component.x2)*2*app.d
        y = y0 + evt.y/float(self.component.y2)*2*app.d
        if evt.mouse_wheel < 0:
            d2 = app.d * 1.2
        else:
            d2 = app.d / 1.2
        scale = d2/app.d
        app.cx = (2*x+(x0+x1-2*x)*scale)/2
        app.cy = (2*y+(y0+y1-2*y)*scale)/2
        app.d = d2
        app.update_plot()
Example #13
0
class ISplitWidget(Interface):
    """ Mix-in class for split widgets.

    A split widget is one that is split in two either horizontally or
    vertically.
    """

    #### 'ISplitWidget' interface #############################################

    # The direction in which the widget is split.
    #
    # Splitting vertically means there will be a left hand panel and a right
    # hand panel, splitting horizontally means there will be a top panel and
    # a bottom panel.
    direction = Enum('vertical', 'vertical', 'horizontal')

    # The ratio of the size of the left/top pane to the right/bottom pane.
    ratio = Float(0.5)

    # An optional callable that provides the left hand/top panel.
    lhs = Callable

    # An optional callable that provides the right hand/bottom panel.
    rhs = Callable

    ###########################################################################
    # Protected 'ISplitWidget' interface.
    ###########################################################################

    def _create_splitter(self, parent):
        """ Create the toolkit-specific control that represents the widget. """

    def _create_lhs(self, parent):
        """ Creates the left hand/top panel depending on the direction. """

    def _create_rhs(self, parent):
        """ Creates the right hand/bottom panel depending on the direction. """
Example #14
0
class Guest(HasPrivateTraits):

    # The name of the guest:
    name = Str

    # The hotel the guest is staying at:
    hotel = Instance(Hotel)

    # The room plan the guest has chosen:
    plan = Enum('Flop house', 'Cheap', 'Cozy', 'Deluxe')

    # The maximum temperature allowed by the guest's plan:
    max_temperature = Property(depends_on='plan')

    # The current room temperature as set by the guest:
    temperature = Range('hotel.min_temperature', 'max_temperature')

    # The view of the guest:
    view = View(Item('plan'), Item('temperature'))

    # Property implementations:
    @cached_property
    def _get_max_temperature(self):
        return {
            'Flop house': 62,
            'Cheap': 66,
            'Cozy': 75,
            'Deluxe': 85
        }[self.plan]

    # Default values:
    def _name_default(self):
        return choice([
            'Leah', 'Vibha', 'Janet', 'Jody', 'Dave', 'Evan', 'Ilan', 'Gael',
            'Peter', 'Robert', 'Judah', 'Eric', 'Travis', 'Mike', 'Bryce',
            'Chris'
        ])
Example #15
0
class ImagePlot(HasTraits):

    plot = Instance(Plot)

    colormap = Enum(sorted(color_map_name_dict.keys()))

    data = Array

    traits_view = View(Item('colormap'),
                       Item('plot', editor=ComponentEditor(),
                            show_label=False),
                       width=600,
                       height=400,
                       title="Color Map")

    def __init__(self):
        # Create plot data.
        row = linspace(0, 1, 100)
        self.data = ones([10, 100]) * row
        plotdata = ArrayPlotData(imagedata=self.data)

        # Create a Plot and associate it with the PlotData
        plot = Plot(plotdata)
        # Create a line plot in the Plot
        plot.img_plot("imagedata",
                      xbounds=(0, 1),
                      colormap=color_map_name_dict[self.colormap])[0]
        plot.y_axis.visible = False
        self.plot = plot
        self.plot.aspect_ratio = 5

    def _colormap_changed(self, new):
        colormap = color_map_name_dict[self.colormap]
        colormap = colormap(self.plot.color_mapper.range)
        self.plot.color_mapper = colormap
        self.plot.request_redraw()
Example #16
0
#-------------------------------------------------------------------------------
#  Imports:
#-------------------------------------------------------------------------------

from enthought.traits.api \
    import HasTraits, Trait, Enum, Range

from enthought.traits.ui.api \
    import EnumEditor

#-------------------------------------------------------------------------------
#  Trait definitions:
#-------------------------------------------------------------------------------

values = ['one', 'two', 'three', 'four']
enum = Enum(*values)
range = Range(1, 4)

#-------------------------------------------------------------------------------
#  'TestEnumEditor' class:
#-------------------------------------------------------------------------------


class TestEnumEditor(HasTraits):

    #---------------------------------------------------------------------------
    #  Trait definitions:
    #---------------------------------------------------------------------------

    value = Trait(1,
                  enum,
Example #17
0
class IDialog(IWindow):
    """ The abstract interface for all pyface dialogs.

    Usage: Sub-class this class and either override '_create_contents' or
    more simply, just override the two methods that do the real work:-

    1) '_create_dialog_area' creates the main content of the dialog.
    2) '_create_buttons'     creates the dialog buttons.
    """

    #### 'IDialog' interface ##################################################

    # The label for the 'cancel' button.  The default is toolkit specific.
    cancel_label = Unicode

    # The context sensitive help Id (the 'Help' button is only shown iff this
    # is set).
    help_id = Str

    # The label for the 'help' button.  The default is toolkit specific.
    help_label = Unicode

    # The label for the 'ok' button.  The default is toolkit specific.
    ok_label = Unicode

    # Is the dialog resizeable?
    resizeable = Bool(True)

    # The return code after the window is closed to indicate whether the dialog
    # was closed via 'Ok' or 'Cancel').
    return_code = Int(OK)

    # The dialog style (is it modal or not).
    # FIXME v3: It doesn't seem possible to use non-modal dialogs.  (How do you
    # get access to the buttons?)
    style = Enum('modal', 'nonmodal')

    ###########################################################################
    # 'IDialog' interface.
    ###########################################################################

    def open(self):
        """ Opens the dialog.

        If the dialog is modal then the dialog's event loop is entered and the
        dialog closed afterwards.  The 'return_code' trait is updated according
        to the button the user pressed and this value is also returned.

        If the dialog is non-modal 'OK' is returned.
        """

    ###########################################################################
    # Protected 'IDialog' interface.
    ###########################################################################

    def _create_buttons(self, parent):
        """ Create and return the buttons.

        parent is the parent control.
        """

    def _create_contents(self, parent):
        """ Create the dialog contents.

        parent is the parent control.
        """

    def _create_dialog_area(self, parent):
        """ Create and return the main content of the dialog.

        parent is the parent control.
        """

    def _show_modal(self):
        """ Opens the dialog as a modal dialog and returns the return code. """
Example #18
0
class PointSelectionDemo(HasTraits):
    color = Enum(Colors.keys())
    green_selection = List()
    red_selection = List()
    plot = Instance(Plot)
    data = Instance(ArrayPlotData)

    traits_view = View(HSplit(
        Item('plot', editor=ComponentEditor(), show_label=False),
        VGroup(
            Item("color", show_label=False, style="custom"),
            Heading(u"绿色选择点"),
            Item("green_selection", show_label=False, style="readonly"),
            Heading(u"红色选择点"),
            Item("red_selection", show_label=False, style="readonly"),
        )),
                       width=800,
                       height=400,
                       resizable=True,
                       title=u"数据点选择演示")

    def __init__(self, **traits):
        super(PointSelectionDemo, self).__init__(**traits)
        x = np.random.rand(100)
        y = np.random.rand(100)
        data = ArrayPlotData(x=x, y=y)

        plot = Plot(data, padding=25)
        self.scatter = scatter = plot.plot(("x", "y"),
                                           type="scatter",
                                           marker_size=4)[0]

        self.select_tools = {}
        for i, c in enumerate(Colors.keys()):
            hover_name = "hover_%s" % c
            selection_name = "selections_%s" % c
            self.select_tools[c] = ScatterInspector(
                scatter,
                hover_metadata_name=hover_name,
                selection_metadata_name=selection_name)

            scatter.overlays.append(
                ScatterInspectorOverlay(
                    scatter,
                    hover_metadata_name=hover_name,
                    selection_metadata_name=selection_name,
                    hover_color="transparent",
                    hover_outline_color=c,
                    hover_marker_size=6,
                    hover_line_width=1,
                    selection_color=Colors[c],
                ))

        scatter.active_tool = self.select_tools[self.color]
        scatter.index.on_trait_change(self.selection_changed,
                                      'metadata_changed')
        self.plot = plot
        self.data = data

    def _color_changed(self):
        self.scatter.active_tool = self.select_tools[self.color]

    def selection_changed(self):
        x = self.scatter.index.get_data()
        y = self.scatter.value.get_data()
        metadata = self.scatter.index.metadata
        selection = metadata.get("selections_green", [])
        self.green_selection = [
            "%d, (%f, %f)" % (s, x[s], y[s]) for s in selection
        ]
        selection = metadata.get("selections_red", [])
        self.red_selection = [
            "%d, (%f, %f)" % (s, x[s], y[s]) for s in selection
        ]
Example #19
0
class Subgraph(BaseGraph):
    """ Defines a representation of a subgraph in Graphviz's dot language.
    """

    #--------------------------------------------------------------------------
    #  Trait definitions:
    #--------------------------------------------------------------------------

    # An ID is one of the following:
    #  * Any string of alphabetic ([a-zA-Z\200-\377]) characters, underscores
    #    ('_') or digits ([0-9]), not beginning with a digit;
    #  * a number [-]?(.[0-9]+ | [0-9]+(.[0-9]*)? );
    #  * any double-quoted string ("...") possibly containing escaped
    #    quotes (\")1;
    #  * an HTML string (<...>).
    #    ID = Str
    #
    #    name = Alias("ID", desc="synonym for ID") # Used by InstanceEditor
    #
    #    # Subgraph nodes.
    #    nodes = List(Instance(Node))
    #
    #    # Subgraph edges.
    #    edges = List(Instance(Edge))
    #
    #    # Subgraphs of the subgraph.
    #    subgraphs = List(Instance("godot.subgraph.Subgraph"))
    #
    #    # Separate rectangular layout regions.
    #    clusters = List(Instance("godot.cluster.Cluster"))

    # Parent graph in the graph heirarchy.
    #    parent = Instance("godot.graph.Graph")

    # Root graph instance.
    #    root = Instance("godot.graph.Graph")

    #--------------------------------------------------------------------------
    #  Xdot trait definitions:
    #--------------------------------------------------------------------------

    # For a given graph object, one will typically a draw directive before the
    # label directive. For example, for a node, one would first use the
    # commands in _draw_ followed by the commands in _ldraw_.
    #    _draw_ = Str(desc="xdot drawing directive")
    #
    #    # Label draw directive.
    #    _ldraw_ = Str(desc="xdot label drawing directive")

    #--------------------------------------------------------------------------
    #  Dot trait definitions.
    #--------------------------------------------------------------------------

    # Rank constraints on the nodes in a subgraph. If rank="same", all nodes
    # are placed on the same rank. If rank="min", all nodes are placed on the
    # minimum rank. If rank="source", all nodes are placed on the minimum rank,
    # and the only nodes on the minimum rank belong to some subgraph whose rank
    # attribute is "source" or "min". Analogous criteria hold for rank="max"
    # and rank="sink". (Note: the minimum rank is topmost or leftmost, and the
    # maximum rank is bottommost or rightmost.)
    rank = Enum("same",
                "min",
                "source",
                "max",
                "sink",
                desc="rank constraints on the nodes in a subgraph",
                graphviz=True)

    #--------------------------------------------------------------------------
    #  Views:
    #--------------------------------------------------------------------------

    traits_view = View(
        VGroup(
            Group(
                Item("vp",
                     editor=ComponentEditor(height=100),
                     show_label=False), Item("arrange", show_label=False)),
            VGroup(
                HGroup(Item("ID"), Item("rank")),
                Tabbed(nodes_item, edges_item, dock="tab"),
                #            subgraphs_notebook_group
            ),
            layout="split"),
        title="Subgraph",
        id="godot.subgraph",
        buttons=["OK", "Cancel", "Help"],
        resizable=True)

    #--------------------------------------------------------------------------
    #  "object" interface:
    #--------------------------------------------------------------------------

    def __str__(self):
        """ Returns a string representation of the cluster in dot language.
        """
        s = "subgraph"

        return "%s %s" % (s, super(Subgraph, self).__str__())
Example #20
0
class ExampleModel(HasTraits):
    valid_models = Property(List)
    root = Enum(values='valid_models')

    def _get_valid_models(self):
        return ['model1', 'model2', 'model3']
class MatrixViewer(HasTraits):

    tplot = Instance(Plot)
    plot = Instance(Component)
    custtool = Instance(CustomTool)
    colorbar = Instance(ColorBar)

    edge_para = Any
    data_name = Enum("a", "b")

    fro = Int
    to = Int
    data = None
    val = Float

    traits_view = View(Group(Item('plot',
                                  editor=ComponentEditor(size=(800, 600)),
                                  show_label=False),
                             HGroup(
                                 Item('fro',
                                      label="From",
                                      style='readonly',
                                      springy=True),
                                 Item('to',
                                      label="To",
                                      style='readonly',
                                      springy=True),
                                 Item('val',
                                      label="Value",
                                      style='readonly',
                                      springy=True),
                             ),
                             orientation="vertical"),
                       Item('data_name', label="Image data"),
                       handler=CustomHandler(),
                       resizable=True,
                       title="Matrix Viewer")

    def __init__(self, data, **traits):
        """ Data is a nxn numpy array """
        super(HasTraits, self).__init__(**traits)

        self.data_name = data.keys()[0]
        self.data = data
        self.plot = self._create_plot_component()

        # set trait notification on customtool
        self.custtool.on_trait_change(self._update_fields, "xval")
        self.custtool.on_trait_change(self._update_fields, "yval")

    def _data_name_changed(self, old, new):
        self.pd.set_data("imagedata", self.data[self.data_name])
        self.my_plot.set_value_selection((0, 2))

    def _update_fields(self):
        from numpy import trunc

        # map mouse location to array index
        frotmp = int(trunc(self.custtool.yval))
        totmp = int(trunc(self.custtool.xval))

        # check if within range
        sh = self.data[self.data_name].shape
        # assume matrix whose shape is (# of rows, # of columns)
        if frotmp >= 0 and frotmp < sh[0] and totmp >= 0 and totmp < sh[1]:
            self.fro = frotmp
            self.to = totmp
            self.val = self.data[self.data_name][self.fro, self.to]

    def _create_plot_component(self):

        # Create a plot data object and give it this data
        self.pd = ArrayPlotData()
        self.pd.set_data("imagedata", self.data[self.data_name])

        # Create the plot
        self.tplot = Plot(self.pd, default_origin="top left")
        self.tplot.x_axis.orientation = "top"
        self.tplot.img_plot(
            "imagedata",
            name="my_plot",
            #xbounds=(0,10),
            #ybounds=(0,10),
            colormap=jet)

        # Tweak some of the plot properties
        self.tplot.title = "Matrix"
        self.tplot.padding = 50

        # Right now, some of the tools are a little invasive, and we need the
        # actual CMapImage object to give to them
        self.my_plot = self.tplot.plots["my_plot"][0]

        # Attach some tools to the plot
        self.tplot.tools.append(PanTool(self.tplot))
        zoom = ZoomTool(component=self.tplot, tool_mode="box", always_on=False)
        self.tplot.overlays.append(zoom)

        # my custom tool to get the connection information
        self.custtool = CustomTool(self.tplot)
        self.tplot.tools.append(self.custtool)

        # Create the colorbar, handing in the appropriate range and colormap
        colormap = self.my_plot.color_mapper
        self.colorbar = ColorBar(
            index_mapper=LinearMapper(range=colormap.range),
            color_mapper=colormap,
            plot=self.my_plot,
            orientation='v',
            resizable='v',
            width=30,
            padding=20)

        self.colorbar.padding_top = self.tplot.padding_top
        self.colorbar.padding_bottom = self.tplot.padding_bottom

        # create a range selection for the colorbar
        self.range_selection = RangeSelection(component=self.colorbar)
        self.colorbar.tools.append(self.range_selection)
        self.colorbar.overlays.append(
            RangeSelectionOverlay(component=self.colorbar,
                                  border_color="white",
                                  alpha=0.8,
                                  fill_color="lightgray"))

        # we also want to the range selection to inform the cmap plot of
        # the selection, so set that up as well
        self.range_selection.listeners.append(self.my_plot)

        # Create a container to position the plot and the colorbar side-by-side
        container = HPlotContainer(use_backbuffer=True)
        container.add(self.tplot)
        container.add(self.colorbar)
        container.bgcolor = "white"

        return container
Example #22
0
class Outline(Module):   
    # The version of this class.  Used for persistence.
    __version__ = 0

    # The `Outline` filter which can either be an instance of
    # `OutlineFilter` or `OutlineCornerFilter`. The `ObjectBase` class
    # is the superclass of both the `OutlineFilter` and the
    # `OutlineCornerFilter`.
    outline_filter = Property(Instance(tvtk.ObjectBase,
                                        allow_none=False), record=True)

    # Enum to set the outline type.
    outline_mode = Enum('full', 'cornered',
                        desc='if outline mode is "full" or "cornered"')

    actor = Instance(Actor, allow_none=False, record=True)

    input_info = PipelineInfo(datasets=['any'],
                              attribute_types=['any'],
                              attributes=['any'])    

    # An outline source, optionally used to choose the bounds of the
    # outline.
    outline_source = Instance(tvtk.OutlineSource, ())

    bounds = DelegatesTo('outline_source',
                desc="the bounds of the outline: xmin, xmax, ymin, ymax")

    manual_bounds = Bool(
                desc="whether the bounds are automatically inferred from "
                     "the data source")

    # Create the UI for the traits.

    # The controls for the outline_filter should be enabled only when the
    # Cornered Outline Filter is selected.
    view = View(Group(
                    Group(
                        Item(name='outline_mode'),
                        Item(name='outline_filter',
                                style='custom',
                                enabled_when='outline_mode == "cornered"',
                                visible_when='outline_mode == "cornered"',
                                resizable=True,
                                show_label=False),
                    label='Outline',
                    show_labels=False),
                    Group('manual_bounds',
                            Item('bounds', enabled_when='manual_bounds'),
                            label='Bounds',
                            ),
                    Item(name='actor', style='custom'),
                    layout='tabbed',
                    show_labels=False),
                resizable=True)

    ########################################
    # Private traits.

    # We make these private traits and cache them because if we create
    # these anew each time the `outline_mode` changes, then we loose
    # any settings the user changed on the previous mode.
    _full_outline = Instance(tvtk.OutlineFilter, args=(),
                             allow_none=False)
    _cornered_outline = Instance(tvtk.OutlineCornerFilter, args=(),
                                 allow_none=False)

    ######################################################################
    # `Module` interface
    ######################################################################
    def setup_pipeline(self):
        """Override this method so that it *creates* the tvtk
        pipeline.

        This method is invoked when the object is initialized via
        `__init__`.  Note that at the time this method is called, the
        tvtk data pipeline will *not* yet be setup.  So upstream data
        will not be available.  The idea is that you simply create the
        basic objects and setup those parts of the pipeline not
        dependent on upstream sources and filters.  You should also
        set the `actors` attribute up at this point.
        """
        # When any trait on the outline filters change call the render
        # method.
        self._full_outline.on_trait_change(self.render)
        self._cornered_outline.on_trait_change(self.render)

        self.actor = Actor()
        
    def update_pipeline(self):
        """Override this method so that it *updates* the tvtk pipeline
        when data upstream is known to have changed.

        This method is invoked (automatically) when any of the inputs
        sends a `pipeline_changed` event.
        """
        mm = self.module_manager
        if mm is None:
            return
        self._outline_mode_changed(self.outline_mode)
        self.pipeline_changed = True

    def update_data(self):
        """Override this method so that it flushes the vtk pipeline if
        that is necessary.

        This method is invoked (automatically) when any of the inputs
        sends a `data_changed` event.
        """
        # Just set data_changed, the component should do the rest.
        self.data_changed = True

    ######################################################################
    # Non-public methods.
    ######################################################################
    def _outline_mode_changed(self, value):
        """This method is invoked (automatically) when the 'outline_mode'
        attribute is changed.
        """
        # Properties don't fire events, so we fire an event here so UI
        # elements and any listners can update due to the changed mode.
        new = self.outline_filter
        old = self._cornered_outline
        if new is self._full_outline:
            old = self._cornered_outline
        self.trait_property_changed('outline_filter', old, new)

        mm = self.module_manager
        if mm is None:
            return

        # Set the input of the filter.
        self._manual_bounds_changed()

        # The module has a list of outputs, but at this stage,
        # the output of the newly instantiated filter will be its only output.
        self.outputs = [self.outline_filter.output]

    def _get_outline_filter(self):
        if self.outline_mode == 'full':
            return self._full_outline
        else:
            return self._cornered_outline

    def _actor_changed(self, old, new):
        new.scene = self.scene
        new.inputs = [self]
        self._change_components(old, new)

    def _manual_bounds_changed(self):
        if self.manual_bounds:
            self.outline_filter.input = self.outline_source.output 
        else:
            # Set the input of the filter.
            mm = self.module_manager
            self.outline_filter.input = mm.source.outputs[0]

    def _bounds_changed(self):
        self.pipeline_changed = True
Example #23
0
"""
 Defines the class that describes the information on the inputs and
 outputs of an object in the pipeline.
"""
# Author: Prabhu Ramachandran <*****@*****.**>
# Copyright (c) 2008, Prabhu Ramachandran Enthought, Inc.
# License: BSD Style.

# Enthought library imports.
from enthought.traits.api import HasTraits, Enum, List

# The list of datasets supported.
DataSet = Enum('none', 'any', 'image_data', 'rectilinear_grid',
               'poly_data', 'structured_grid', 'unstructured_grid')

# Attribute type.
AttributeType = Enum('any', 'cell', 'point', 'none')

# Attribute.
Attribute = Enum('any', 'none', 'scalars', 'vectors', 'tensors')


################################################################################
# Utility functions.
################################################################################ 
def get_tvtk_dataset_name(dataset):
    """Given a TVTK dataset `dataset` return the string dataset type of
    the dataset.
    """
    result = 'none'
    if hasattr(dataset, 'is_a'):
Example #24
0
class tcProject(HasTraits):
    c_states = List(tcGeneric)
    p_states = List(tcGeneric)
    processes = List(tcProcess)
    selected = List(tcProcess)
    filtered_processes = List(tcProcess)
    remove_filter = Button(image=ImageResource("clear.png"),
                           width_padding=0,
                           height_padding=0,
                           style='toolbar')
    minimum_time_filter = Enum((0, 1000, 10000, 50000, 100000, 500000, 1000000,
                                5000000, 1000000, 5000000, 10000000, 50000000))
    minimum_events_filter = Enum(
        (0, 2, 4, 8, 10, 20, 40, 100, 1000, 10000, 100000, 1000000))
    plot_redraw = Long()
    filter = Str("")
    filter_invalid = Property(depends_on="filter")
    filename = Str("")
    power_event = CArray
    num_cpu = Property(Int, depends_on='c_states')
    num_process = Property(Int, depends_on='process')
    traits_view = View(
        VGroup(
            HGroup(
                Item(
                    'filter',
                    invalid="filter_invalid",
                    width=1,
                    tooltip=
                    'filter the process list using a regular expression,\nallowing you to quickly find a process'
                ),
                Item('remove_filter',
                     show_label=False,
                     style='custom',
                     tooltip='clear the filter')),
            HGroup(
                Item(
                    'minimum_time_filter',
                    width=1,
                    label='dur',
                    tooltip=
                    'filter the process list with minimum duration process is scheduled'
                ),
                Item(
                    'minimum_events_filter',
                    width=1,
                    label='num',
                    tooltip=
                    'filter the process list with minimum number of events process is generating'
                ),
            )),
        Item('filtered_processes',
             show_label=False,
             height=40,
             editor=process_table_editor))
    first_ts = 0

    def _get_filter_invalid(self):
        try:
            r = re.compile(self.filter)
        except:
            return True
        return False

    def _remove_filter_changed(self):
        self.filter = ""

    def _filter_changed(self):
        try:
            r = re.compile(self.filter)
        except:
            r = None
        filtered_processes = self.processes
        if self.minimum_events_filter:
            filtered_processes = filter(
                lambda p: self.minimum_events_filter < len(p.start_ts),
                filtered_processes)
        if self.minimum_time_filter:
            filtered_processes = filter(
                lambda p: self.minimum_time_filter < p.total_time,
                filtered_processes)
        if r:
            filtered_processes = filter(lambda p: r.search(p.comm),
                                        filtered_processes)
        self.filtered_processes = filtered_processes

    _minimum_time_filter_changed = _filter_changed
    _minimum_events_filter_changed = _filter_changed

    def _processes_changed(self):
        self._filter_changed()

    def _on_show(self):
        for i in self.selected:
            i.show = True
        self.plot_redraw += 1

    def _on_hide(self):
        for i in self.selected:
            i.show = False
        self.plot_redraw += 1

    def _on_select_all(self):
        if self.selected == self.filtered_processes:
            self.selected = []
        else:
            self.selected = self.filtered_processes
        self.plot_redraw += 1

    def _on_invert(self):
        for i in self.filtered_processes:
            i.show = not i.show
        self.plot_redraw += 1

    @cached_property
    def _get_num_cpu(self):
        return len(self.c_states)

    def _get_num_process(self):
        return len(self.processes)

    def process_list_selected(self, selection):
        print selection
######### stats part ##########

    def process_stats(self, start, end):
        fact = 100. / (end - start)
        for tc in self.processes:
            starts, ends, types = tc.get_partial_tables(start, end)
            inds = np.where(types == colors.get_color_id("running"))
            tot = sum(ends[inds] - starts[inds])
            tc.selection_time = int(tot)
            tc.selection_pc = tot * fact

    def get_selection_text(self, start, end):
        low_line = -1
        high_line = -1
        low_i = searchsorted(self.timestamps, start)
        high_i = searchsorted(self.timestamps, end)
        low_line = self.linenumbers[low_i]
        high_line = self.linenumbers[high_i]
        return self.get_partial_text(self.filename, low_line, high_line)
######### generic parsing part ##########

    def generic_find_process(self,
                             pid,
                             comm,
                             ptype,
                             same_pid_match_timestamp=0):
        if self.tmp_process.has_key((pid, comm)):
            return self.tmp_process[(pid, comm)]
        # else try to find if there has been a process with same pid recently, and different name. Only for user_process because other traces set pid to 0
        if same_pid_match_timestamp != 0 and ptype == "user_process":
            for k, p in self.tmp_process.items():
                if k[0] == pid and p['type'] == "user_process":
                    if len(
                            p['start_ts']
                    ) > 0 and p['start_ts'][-1] > same_pid_match_timestamp:
                        p['comm'] = comm
                        self.tmp_process[(pid, comm)] = p
                        del self.tmp_process[k]
                        return p
        tmp = {
            'type': ptype,
            'comm': comm,
            'pid': pid,
            'start_ts': [],
            'end_ts': [],
            'types': [],
            'cpus': [],
            'comments': []
        }
        if not (pid == 0 and ptype == "user_process"):
            self.tmp_process[(pid, comm)] = tmp
        return tmp

    def generic_process_start(self, process, event, build_p_stack=True):
        if process['type'] == "user_process" and process['pid'] == 0:
            return  # ignore swapper event
        if len(process['start_ts']) > len(process['end_ts']):
            process['end_ts'].append(event.timestamp)
        if self.first_ts == 0:
            self.first_ts = event.timestamp
        self.cur_process_by_pid[process['pid']] = process
        if build_p_stack:
            p_stack = self.cur_process[event.common_cpu]
            if p_stack:
                p = p_stack[-1]
                if len(p['start_ts']) > len(p['end_ts']):
                    p['end_ts'].append(event.timestamp)
                # mark old process to wait for cpu
                p['start_ts'].append(int(event.timestamp))
                p['types'].append(colors.get_color_id("waiting_for_cpu"))
                p['cpus'].append(event.common_cpu)
                p_stack.append(process)
            else:
                self.cur_process[event.common_cpu] = [process]
        # mark process to use cpu
        process['start_ts'].append(event.timestamp)
        process['types'].append(colors.get_color_id("running"))
        process['cpus'].append(event.common_cpu)

    def generic_process_end(self, process, event, build_p_stack=True):
        if process['type'] == "user_process" and process['pid'] == 0:
            return  # ignore swapper event
        if len(process['start_ts']) > len(process['end_ts']):
            process['end_ts'].append(event.timestamp)
        if build_p_stack:
            p_stack = self.cur_process[event.common_cpu]
            if p_stack:
                p = p_stack.pop()
                if p['pid'] != process['pid']:
                    print "warning: process premption stack following failure on CPU", event.common_cpu, p[
                        'comm'], p['pid'], process['comm'], process[
                            'pid'], map(
                                lambda a: "%s:%d" % (a['comm'], a['pid']),
                                p_stack), event.linenumber
                    p_stack = []

                if p_stack:
                    p = p_stack[-1]
                    if len(p['start_ts']) > len(p['end_ts']):
                        p['end_ts'].append(event.timestamp)
                    # mark old process to run on cpu
                    p['start_ts'].append(event.timestamp)
                    p['types'].append(colors.get_color_id("running"))
                    p['cpus'].append(event.common_cpu)

    def generic_process_single_event(self, process, event):
        if len(process['start_ts']) > len(process['end_ts']):
            process['end_ts'].append(event.timestamp)
        # mark process to use cpu
        process['start_ts'].append(event.timestamp)
        process['types'].append(colors.get_color_id("running"))
        process['cpus'].append(event.common_cpu)
        process['end_ts'].append(event.timestamp)

    def generic_add_wake(self, caller, callee, event):
        self.wake_events.append(
            ((caller['comm'], caller['pid']), (callee['comm'], callee['pid']),
             event.timestamp))

    def do_function_default(self, event):
        process = self.generic_find_process(
            0, "kernel function:%s" % (event.callee), "function")
        self.generic_process_single_event(process, event)

    def do_event_default(self, event):
        event.name = event.event.split(":")[0]
        process = self.generic_find_process(0, "event:%s" % (event.name),
                                            "event")
        self.generic_process_single_event(process, event)
        process['comments'].append(event.event)

    def start_parsing(self, get_partial_text):
        # we build our data into python data formats, who are resizeable
        # once everything is parsed, we will transform it into numpy array, for fast access
        self.tmp_c_states = []
        self.tmp_p_states = []
        self.tmp_process = {}
        self.timestamps = []
        self.linenumbers = []
        self.cur_process_by_pid = {}
        self.wake_events = []
        self.cur_process = [None] * 20
        self.last_irq = {}
        self.last_spi = []
        self.missed_power_end = 0
        self.get_partial_text = get_partial_text
        self.methods = {}
        import plugin
        colors.parse_colors(plugin.get_plugins_additional_colors())
        plugin.get_plugins_methods(self.methods)
        self.process_types = {
            "function": (tcProcess, plugin.MISC_TRACES_CLASS),
            "event": (tcProcess, plugin.MISC_TRACES_CLASS)
        }
        self.process_types.update(
            plugin.get_plugins_additional_process_types())

    def finish_parsing(self):
        #put generated data in unresizable numpy format
        c_states = []
        i = 0
        for tc in self.tmp_c_states:
            t = tcIdleState(name='cpu%d' % (i))
            while len(tc['start_ts']) > len(tc['end_ts']):
                tc['end_ts'].append(tc['start_ts'][-1])
            t.start_ts = numpy.array(tc['start_ts'])
            t.end_ts = numpy.array(tc['end_ts'])
            t.types = numpy.array(tc['types'])
            c_states.append(t)
            i += 1
        self.c_states = c_states
        i = 0
        p_states = []
        for tc in self.tmp_p_states:
            t = tcFrequencyState(name='cpu%d' % (i))
            t.start_ts = numpy.array(tc['start_ts'])
            t.end_ts = numpy.array(tc['end_ts'])
            t.types = numpy.array(tc['types'])
            i += 1
            p_states.append(t)
        self.wake_events = numpy.array(self.wake_events,
                                       dtype=[('waker', tuple),
                                              ('wakee', tuple),
                                              ('time', 'uint64')])
        self.p_states = p_states
        processes = []
        last_ts = 0
        for pid, comm in self.tmp_process:
            tc = self.tmp_process[pid, comm]
            if len(tc['end_ts']) > 0 and last_ts < tc['end_ts'][-1]:
                last_ts = tc['end_ts'][-1]
        if len(self.tmp_process) > 0:
            progress = ProgressDialog(title="precomputing data",
                                      message="precomputing overview data...",
                                      max=len(self.tmp_process),
                                      show_time=False,
                                      can_cancel=False)
            progress.open()
        i = 0
        for pid, comm in self.tmp_process:
            tc = self.tmp_process[pid, comm]
            if self.process_types.has_key(tc['type']):
                klass, order = self.process_types[tc['type']]
                t = klass(pid=pid, comm=tc['comm'], project=self)
            else:
                t = tcProcess(pid=pid, comm=comm, project=self)
            while len(tc['start_ts']) > len(tc['end_ts']):
                tc['end_ts'].append(last_ts)
            t.start_ts = numpy.array(tc['start_ts'])
            t.end_ts = numpy.array(tc['end_ts'])
            t.types = numpy.array(tc['types'])
            t.cpus = numpy.array(tc['cpus'])
            t.comments = tc['comments']  #numpy.array(tc['comments'])
            t.process_type = tc["type"]
            # precompute 16 levels of overview cache
            t.get_overview_ts(1 << 16)
            processes.append(t)
            progress.update(i)
            i += 1
        if len(self.tmp_process) > 0:
            progress.close()
            self.tmp_process = []

        def cmp_process(x, y):
            # sort process by type, pid, comm
            def type_index(t):
                try:
                    return self.process_types[t][1]
                except ValueError:
                    return len(order) + 1

            c = cmp(type_index(x.process_type), type_index(y.process_type))
            if c != 0:
                return c
            c = cmp(x.pid, y.pid)
            if c != 0:
                return c
            c = cmp(x.comm, y.comm)
            return c

        processes.sort(cmp_process)
        self.processes = processes
        self.p_states = p_states
        self.tmp_c_states = []
        self.tmp_p_states = []
        self.tmp_process = {}

    def ensure_cpu_allocated(self, cpu):
        # ensure we have enough per_cpu p/c_states timecharts
        while len(self.tmp_c_states) <= cpu:
            self.tmp_c_states.append({
                'start_ts': [],
                'end_ts': [],
                'types': []
            })
        while len(self.tmp_p_states) <= cpu:
            self.tmp_p_states.append({
                'start_ts': [],
                'end_ts': [],
                'types': []
            })

    def run_callbacks(self, callback, event):
        if callback in self.methods:
            for m in self.methods[callback]:
                try:
                    m(self, event)
                except AttributeError:
                    if not hasattr(m, "num_exc"):
                        m.num_exc = 0
                    m.num_exc += 1
                    if m.num_exc < 10:
                        print "bug in ", m, "still continue.."
                        traceback.print_exc()
                        print event
                    if m.num_exc == 10:
                        print m, "is too buggy, disabling, please report bug!"
                        self.methods[callback].remove(m)
                        if len(self.methods[callback]) == 0:
                            del self.methods[callback]
            return True
        return False

    def handle_trace_event(self, event):
        self.linenumbers.append(event.linenumber)
        self.timestamps.append(event.timestamp)
        if event.event == 'function':
            callback = "do_function_" + event.callee
            self.run_callbacks("do_all_functions", event)
        else:
            callback = "do_event_" + event.event
            self.run_callbacks("do_all_events", event)

        if not self.run_callbacks(callback, event):
            if event.event == 'function':
                self.do_function_default(event)
            else:
                self.do_event_default(event)
Example #25
0
class ParametricSurface(Source):
    # The version of this class.  Used for persistence.
    __version__ = 0

    # Flag to set the parametric function type.
    function = Enum('boy',
                    'conic_spiral',
                    'cap',
                    'dini',
                    'ellipsoid',
                    'enneper',
                    'figure8klein',
                    'klein',
                    'mobius',
                    'random_hills',
                    'roman',
                    'spline',
                    'super_ellipsoid',
                    'super_toroid',
                    'torus',
                    desc='which parametric function to be used')

    # Define the trait 'parametric_function' whose value must be an instance of
    # type ParametricFunction
    parametric_function = Instance(tvtk.ParametricFunction,
                                   allow_none=False,
                                   record=True)

    # The Parametric function source which generates the data.
    source = Instance(tvtk.ParametricFunctionSource,
                      args=(),
                      kw={'scalar_mode': 'distance'},
                      allow_none=False,
                      record=True)

    # Information about what this object can produce.
    output_info = PipelineInfo(datasets=['poly_data'],
                               attribute_types=['any'],
                               attributes=['any'])

    ########################################
    # Private traits.

    # A dictionary that maps the function names to instances of the
    # parametric surfaces
    _function_dict = Dict(Str,
                          Instance(tvtk.ParametricFunction, allow_none=False))

    ######################################################################
    # `object` interface
    ######################################################################
    def __init__(self, **traits):
        # Setup the function dict.
        fd = {
            'boy': tvtk.ParametricBoy(),
            'conic_spiral': tvtk.ParametricConicSpiral(),
            'cap': tvtk.ParametricCrossCap(),
            'dini': tvtk.ParametricDini(),
            'ellipsoid': tvtk.ParametricEllipsoid(),
            'enneper': tvtk.ParametricEnneper(),
            'figure8klein': tvtk.ParametricFigure8Klein(),
            'klein': tvtk.ParametricKlein(),
            'mobius': tvtk.ParametricMobius(),
            'random_hills': tvtk.ParametricRandomHills(),
            'roman': tvtk.ParametricRoman(),
            'spline': tvtk.ParametricSpline(),
            'super_ellipsoid': tvtk.ParametricSuperEllipsoid(),
            'super_toroid': tvtk.ParametricSuperToroid(),
            'torus': tvtk.ParametricTorus()
        }
        self._function_dict = fd

        # Call parent class' init.
        super(ParametricSurface, self).__init__(**traits)

        # Initialize the function to the default mode's instance from
        # the dictionary
        self.parametric_function = self._function_dict[self.function]

        # Call render everytime source traits change.
        self.source.on_trait_change(self.render)
        # Setup the outputs.
        self.outputs = [self.source.output]

    ######################################################################
    # Non-public methods.
    ######################################################################
    def _function_changed(self, value):
        """This method is invoked (automatically) when the `function`
        trait is changed.
        """
        self.parametric_function = self._function_dict[self.function]

    def _parametric_function_changed(self, old, new):
        """This method is invoked (automatically) when the
        `parametric_function` attribute is changed.
        """
        self.source.parametric_function = self.parametric_function

        # Setup the handlers so that
        if old is not None:
            old.on_trait_change(self.render, remove=True)
        new.on_trait_change(self.render)

        self.data_changed = True
Example #26
0
class CircleSelection(AbstractController):
    metadata = Property(depends_on='component')
    event_state = Enum('normal', 'selecting', 'selected', 'moving')
    selection_update = Event
    x = Float  # 圆心X坐标
    y = Float  # 圆心Y坐标
    r = Float  # 半径
    mx = Float  # 移动开始时的鼠标的X坐标
    my = Float  # 移动开始时的鼠标的Y坐标
    x0 = Float  # 移动开始时的圆心X坐标
    y0 = Float  # 移动开始时的圆心Y坐标

    def _get_metadata(self):
        return self.component.index.metadata

    def normal_left_down(self, event):
        self.x, self.y = event.x, event.y
        self.metadata['circle_center'] = self.x, self.y
        self.metadata['circle_radius'] = 0
        self.event_state = 'selecting'

    def selecting_mouse_move(self, event):
        self.r = np.sqrt((self.x - event.x)**2 + (self.y - event.y)**2)
        self.metadata['circle_radius'] = self.r
        self._update_selection()

    def selecting_left_up(self, event):
        self.event_state = 'selected'

    def selected_left_down(self, event):
        r = np.sqrt((self.x - event.x)**2 + (self.y - event.y)**2)
        if r > self.r:
            del self.metadata['circle_center']
            del self.metadata['circle_radius']
            del self.metadata['selections']
            self.selection_update = True
            self.event_state = 'normal'
        else:
            self.mx, self.my = event.x, event.y
            self.x0, self.y0 = self.x, self.y
            self.event_state = 'moving'

    def moving_mouse_move(self, event):
        self.x = self.x0 + event.x - self.mx
        self.y = self.y0 + event.y - self.my
        self.metadata['circle_center'] = self.x, self.y
        self._update_selection()

    def moving_left_up(self, event):
        self.event_state = 'selected'

    def _update_selection(self):
        points = np.transpose(
            np.array((self.component.index.get_data(),
                      self.component.value.get_data())))
        screen_points = self.component.map_screen(points)
        tmp = screen_points - np.array([self.x, self.y])
        tmp **= 2
        dist = np.sum(tmp, axis=1)
        self.metadata['selections'] = dist < self.r * self.r
        self.selection_update = True
Example #27
0
class SmithCircleRenderer(BaseXYPlot):
    """ Plots a circle in dataspace.

    If you don't want the edge of the polygon to be drawn, set **edge_color**
    to transparent; don't try to do this by setting **edge_width** to 0. In
    some drawing systems, such as PostScript, a line width of 0 means to make
    the line as small as possible while still putting ink on the page.
    """

    # The color of the line on the edge of the polygon.
    color = black_color_trait

    # The thickness of the edge of the polygon.
    line_width = Float(1.0)

    # The line dash style for the edge of the polygon.
    line_style = LineStyle

    # The color of the face of the polygon.
    face_color = transparent_color_trait

    # Override the hittest_type trait inherited from BaseXYPlot
    hittest_type = Enum("poly", "point", "line")

    #### Private 'BaseXYPlot' interface ########################################

    #    def __init__(self, *args, **kw):
    #        super(self.__class__, self).__init__(*args, **kw)

    def _downsample(self):
        #return self.map_screen(self._cached_data_pts)
        return self._cached_data_pts

    def _draw_plot(self, *args, **kw):
        """ Draws the 'plot' layer.
        """
        # Simple compatibility with new-style rendering loop
        return self._draw_component(*args, **kw)

    def _draw_component(self, gc, view_bounds=None, mode='normal'):
        """ Renders the component. 
        """
        self._gather_points()
        self._render(gc, self._cached_data_pts)

    def _gather_points(self):
        """ Collects the data points that are within the bounds of the plot and
        caches them.
        """
        if self._cache_valid:
            return

        data = transpose(self.value.get_data())
        x_center = data[0].real.astype(float)
        y_center = data[0].imag.astype(float)
        radius = data[1].astype(float)

        if not self.index or not self.value:
            return

        if len(x_center) == 0 or len(
                radius) == 0 or len(x_center) != len(radius):
            self._cached_data_pts = []
            self._cache_valid = True
            return

        circles = np.transpose(np.array((x_center, y_center, radius)))
        self._cached_data_pts = circles
        self._cache_valid = True

    def _render(self, gc, circles):
        """ Renders a circle."""
        map_x = self.index_mapper.map_screen
        map_y = self.value_mapper.map_screen

        for circle in circles:
            x_center = map_x(circle[0])
            y_center = map_y(circle[1])
            radius = map_x(circle[2]) - map_x(0)
            with gc:
                gc.clip_to_rect(
                    map_x(self.x_mapper.range.low),
                    map_y(self.y_mapper.range.low),
                    map_x(self.x_mapper.range.high) -
                    map_x(self.x_mapper.range.low),
                    map_y(self.y_mapper.range.high) -
                    map_y(self.y_mapper.range.low))

                gc.set_stroke_color(self.color_)
                gc.set_line_width(self.line_width)
                gc.set_line_dash(self.line_style_)
                gc.set_fill_color(self.face_color_)

                gc.arc(x_center, y_center, radius, 0, 2 * pi)
                gc.draw_path()

    def _render_icon(self, gc, x, y, width, height):
        """ Renders a representation of this plot as an icon into the box
        defined by the parameters.

        Used by the legend.
        """
        with gc:
            gc.set_stroke_color(self.edge_color_)
            gc.set_line_width(self.line_width)
            gc.set_fill_color(self.face_color_)
            if hasattr(self, 'line_style_'):
                gc.set_line_dash(self.line_style_)
            gc.draw_rect((x, y, width, height))
        return

    #------------------------------------------------------------------------
    # AbstractPlotRenderer interface
    #------------------------------------------------------------------------

#    def map_screen(self, data_array):
#        """ Maps an array of data points into screen space and returns it as
#        an array.

#        Implements the AbstractPlotRenderer interface.
#        """
#        print "map_screen"
#        # data_array is Nx2 array
#        if len(data_array) == 0:
#            return []
#        x_ary, y_ary, r_ary = transpose(data_array)
#        sx = self.index_mapper.map_screen(x_ary)
#        sy = self.value_mapper.map_screen(y_ary)
#        sr = (self.index_mapper.map_screen(r_ary) -
#              self.index_mapper.map_screen(0))
#        for i in range(len(sx)):
#            print "center = ({0}, {1}), radius = {2}".format(x_ary[i], y_ary[i],
#                                                             r_ary[i])
#        if self.orientation == "h":
#            return transpose(array((sx, sy, sr)))
#        else:
#            return transpose(array((sy, sx, sr)))

    def hittest(self, screen_pt, threshold=7.0, return_distance=False):
        """ Performs point-in-polygon testing or point/line proximity testing.
        If self.hittest_type is "line" or "point", then behaves like the
        parent class BaseXYPlot.hittest().

        If self.hittest_type is "poly", then returns True if the given
        point is inside the polygon, and False otherwise.
        """
        if self.hittest_type in ("line", "point"):
            return BaseXYPlot.hittest(self, screen_pt, threshold,
                                      return_distance)

        data_pt = self.map_data(screen_pt, all_values=True)
        index = self.index.get_data()
        value = self.value.get_data()
        poly = np.vstack((index, value)).T
        if points_in_polygon([data_pt], poly)[0] == 1:
            return True
        else:
            return False

    #------------------------------------------------------------------------
    # Event handlers
    #------------------------------------------------------------------------

    def _alpha_changed(self):
        self.color_ = self.color_[0:3] + (self.alpha, )
        self.face_color_ = self.face_color_[0:3] + (self.alpha, )
        self.invalidate_draw()
        self.request_redraw()
Example #28
0
class TriangleWave(HasTraits):
    # 指定三角波的最窄和最宽范围,由于Range类型不能将常数和Traits属性名混用
    # 所以定义这两个值不变的Trait属性
    low = Float(0.02)
    hi = Float(1.0)

    # 三角波形的宽度
    wave_width = Range("low", "hi", 0.5)

    # 三角波的顶点C的x轴坐标
    length_c = Range("low", "wave_width", 0.5)

    # 三角波的定点的y轴坐标
    height_c = Float(1.0)

    # FFT计算所使用的取样点数,这里用一个Enum类型的属性以供用户从列表中选择
    fftsize = Enum([(2**x) for x in range(6, 12)])

    # FFT频谱图的x轴上限值
    fft_graph_up_limit = Range(0, 400, 20)

    # 用于显示FFT的结果
    peak_list = Str

    # 采用多少个频率合成三角波
    N = Range(1, 40, 4)

    # 保存绘图数据的对象
    plot_data = Instance(AbstractPlotData)

    # 绘制波形图的容器
    plot_wave = Instance(Component)

    # 绘制FFT频谱图的容器
    plot_fft = Instance(Component)

    # 包括两个绘图的容器
    container = Instance(Component)

    # 设置用户界面的视图, 注意一定要指定窗口的大小,这样绘图容器才能正常初始化
    view = View(HSplit(
        VSplit(
            VGroup(Item("wave_width", editor=scrubber, label="波形宽度"),
                   Item("length_c", editor=scrubber, label="最高点x坐标"),
                   Item("height_c", editor=scrubber, label="最高点y坐标"),
                   Item("fft_graph_up_limit", editor=scrubber, label="频谱图范围"),
                   Item("fftsize", label="FFT点数"), Item("N", label="合成波频率数")),
            Item("peak_list",
                 style="custom",
                 show_label=False,
                 width=100,
                 height=250)),
        VGroup(Item("container",
                    editor=ComponentEditor(size=(600, 300)),
                    show_label=False),
               orientation="vertical")),
                resizable=True,
                width=800,
                height=600,
                title="三角波FFT演示")

    # 创建绘图的辅助函数,创建波形图和频谱图有很多类似的地方,因此单独用一个函数以
    # 减少重复代码
    def _create_plot(self, data, name, type="line"):
        p = Plot(self.plot_data)
        p.plot(data, name=name, title=name, type=type)
        p.tools.append(PanTool(p))
        zoom = ZoomTool(component=p, tool_mode="box", always_on=False)
        p.overlays.append(zoom)
        p.title = name
        return p

    def __init__(self):
        # 首先需要调用父类的初始化函数
        super(TriangleWave, self).__init__()

        # 创建绘图数据集,暂时没有数据因此都赋值为空,只是创建几个名字,以供Plot引用
        self.plot_data = ArrayPlotData(x=[], y=[], f=[], p=[], x2=[], y2=[])

        # 创建一个垂直排列的绘图容器,它将频谱图和波形图上下排列
        self.container = VPlotContainer()

        # 创建波形图,波形图绘制两条曲线: 原始波形(x,y)和合成波形(x2,y2)
        self.plot_wave = self._create_plot(("x", "y"), "Triangle Wave")
        self.plot_wave.plot(("x2", "y2"), color="red")

        # 创建频谱图,使用数据集中的f和p
        self.plot_fft = self._create_plot(("f", "p"), "FFT", type="scatter")

        # 将两个绘图容器添加到垂直容器中
        self.container.add(self.plot_wave)
        self.container.add(self.plot_fft)

        # 设置
        self.plot_wave.x_axis.title = "Samples"
        self.plot_fft.x_axis.title = "Frequency pins"
        self.plot_fft.y_axis.title = "(dB)"

        # 改变fftsize为1024,因为Enum的默认缺省值为枚举列表中的第一个值
        self.fftsize = 1024

    # FFT频谱图的x轴上限值的改变事件处理函数,将最新的值赋值给频谱图的响应属性
    def _fft_graph_up_limit_changed(self):
        self.plot_fft.x_axis.mapper.range.high = self.fft_graph_up_limit

    def _N_changed(self):
        self.plot_sin_combine()

    # 多个trait属性的改变事件处理函数相同时,可以用@on_trait_change指定
    @on_trait_change("wave_width, length_c, height_c, fftsize")
    def update_plot(self):
        # 计算三角波
        global y_data
        x_data = np.arange(0, 1.0, 1.0 / self.fftsize)
        func = self.triangle_func()
        # 将func函数的返回值强制转换成float64
        y_data = np.cast["float64"](func(x_data))

        # 计算频谱
        fft_parameters = np.fft.fft(y_data) / len(y_data)

        # 计算各个频率的振幅
        fft_data = np.clip(
            20 * np.log10(np.abs(fft_parameters))[:self.fftsize / 2 + 1], -120,
            120)

        # 将计算的结果写进数据集
        self.plot_data.set_data("x", np.arange(0, self.fftsize))  # x坐标为取样点
        self.plot_data.set_data("y", y_data)
        self.plot_data.set_data("f", np.arange(0, len(fft_data)))  # x坐标为频率编号
        self.plot_data.set_data("p", fft_data)

        # 合成波的x坐标为取样点,显示2个周期
        self.plot_data.set_data("x2", np.arange(0, 2 * self.fftsize))

        # 更新频谱图x轴上限
        self._fft_graph_up_limit_changed()

        # 将振幅大于-80dB的频率输出
        peak_index = (fft_data > -80)
        peak_value = fft_data[peak_index][:20]
        result = []
        for f, v in zip(np.flatnonzero(peak_index), peak_value):
            result.append("%s : %s" % (f, v))
        self.peak_list = "\n".join(result)

        # 保存现在的fft计算结果,并计算正弦合成波
        self.fft_parameters = fft_parameters
        self.plot_sin_combine()

    # 计算正弦合成波,计算2个周期
    def plot_sin_combine(self):
        index, data = fft_combine(self.fft_parameters, self.N, 2)
        self.plot_data.set_data("y2", data)

    # 返回一个ufunc计算指定参数的三角波
    def triangle_func(self):
        c = self.wave_width
        c0 = self.length_c
        hc = self.height_c

        def trifunc(x):
            x = x - int(x)  # 三角波的周期为1,因此只取x坐标的小数部分进行计算
            if x >= c: r = 0.0
            elif x < c0: r = x / c0 * hc
            else: r = (c - x) / (c - c0) * hc
            return r

        # 用trifunc函数创建一个ufunc函数,可以直接对数组进行计算, 不过通过此函数
        # 计算得到的是一个Object数组,需要进行类型转换
        return np.frompyfunc(trifunc, 1, 1)
Example #29
0
class StarComponent(Component):
    stars = List(Star)
    star_color = Color((255,255,255))
    edges = Range(3, 10, 5)
    sx = Float # 移动开始时的星星中心X坐标
    sy = Float # 移动开始时的星星中心Y坐标
    mx = Float # 移动开始时的鼠标X坐标
    my = Float # 移动开始时的鼠标Y坐标
    moving_star = Instance(Star)
    
    event_state = Enum("normal", "drawing", "moving") 


    def normal_left_down(self, event):
        "添加一个Star对象进stars列表,并切换到drawing状态"
        self.stars.append(
            Star(x=event.x, y=event.y, r=0, theta=0, n=self.edges,
                s = 0.5, c=convert_color(self.star_color)))
        self.event_state = "drawing" 
        self.request_redraw()
        
    def drawing_mouse_move(self, event):
        "修改stars中最后一个Star对象的半径和起始角度"
        star = self.stars[-1]
        star.r = np.sqrt((event.x-star.x)**2+(event.y-star.y)**2)
        star.theta = np.arctan2(event.y-star.y, event.x-star.x)
        self.request_redraw()
        
    def drawing_left_up(self, event):
        "完成一个星形的绘制,回到normal状态"
        self.event_state = "normal"        
        
    def normal_mouse_wheel(self, event):
        "找到包含鼠标坐标的星形,并修改其半径比例"
        star = self.find_star(event.x, event.y) 
        if star is not None:
            star.s += event.mouse_wheel * 0.02
            if star.s < 0.05: star.s = 0.05
            self.request_redraw()
                
    def normal_right_down(self, event):
        "找到包含鼠标坐标的星形,用moving_star属性保存它,并进入moving状态"
        star = self.find_star(event.x, event.y)
        if star is not None:
            self.mx, self.my = event.x, event.y # 记录鼠标位置
            self.sx, self.sy = star.x, star.y # 记录星形的中心位置
            self.moving_star = star
            self.event_state = "moving"
    
    def moving_mouse_move(self, event):
        "修改moving_star的x,y坐标,实现星形的移动"
        self.moving_star.x = self.sx + event.x - self.mx
        self.moving_star.y = self.sy + event.y - self.my
        self.request_redraw()
        
    def moving_right_up(self, event):
        "移动操作结束,回到normal状态"
        self.event_state = "normal"

        
    def _draw_overlay(self, gc, view_bounds=None, mode="normal"):
        gc.clear((0,0,0,1)) #填充为全黑
        gc.save_state()
        for star in self.stars:
            draw_star(gc, star.x, star.y, star.r, star.c, star.theta, star.n, star.s)
            gc.draw_path()
        gc.restore_state()        


    def find_star(self, x, y):
        from enthought.kiva.agg import points_in_polygon
        for star in self.stars[::-1]:
            if points_in_polygon((x, y), star.polygon()):        
                return star
        return None
Example #30
0
class CfgFile(HasTraits):
    name = Str
    config_name = Str
    parent = Any
    directory = Str
    descendents = List
    config_type = Enum('MT', 'appman', 'XM', 'PVA', 'task_state',
                       'target_positions', 'start_positions',
                       'auto_control_config', 'grasp_event', 'auto_pilot',
                       'module_config', 'tool_change')

    def _descendents_default(self):
        if self.config_type == 'MT':
            multi_task_file = self.directory + '/' + self.name
            parser = SafeConfigParser()
            parser.read(multi_task_file)
            mt_config = dict(parser.items('config'))
            mt_app_list = re.sub(r"[\n\r]+", '',
                                 mt_config['config_names']).split(',')
            l = []
            files = {'XM': 'XM.config', 'appman': 'appman.conf'}
            for app in mt_app_list:
                app_dir = CONFIG_DIR + '/' + app
                l.append(
                    SubSession(name=app,
                               files=files,
                               directory=app_dir,
                               parent=self))

        elif self.config_type == 'XM':
            fd = parse_XM_config(self.directory + '/' + self.name)
            task_state_config_files = fd['task_state_config_files']
            l = []
            for kid in task_state_config_files:
                l.append(
                    CfgFile(name=kid,
                            config_type='task_state',
                            directory=self.directory,
                            parent=self))
            if fd.has_key('tool_change_config_files'):
                tool_change_config_files = fd['tool_change_config_files']
                for kid in tool_change_config_files:
                    l.append(
                        CfgFile(name=kid,
                                config_type='tool_change',
                                directory=self.directory,
                                parent=self))

        elif self.config_type == 'task_state':
            fd = parse_XM_config(self.directory + '/' + self.name)
            l = [
                CfgFile(name=fd['target_configurations_file'],
                        config_type='target_positions',
                        parent=self,
                        directory=self.directory)
            ]

        elif self.config_type == 'appman':
            parent_name = self.parent.name
            if parent_name == 'multi_task.config':
                parent_name = self.config_name
            l = []
            try:
                fd = parse_appman(self.directory + '/' + self.name,
                                  parent_name)
                kids = fd['module_config_files']
                for kid in kids:
                    l.append(
                        CfgFile(name=os.path.relpath(kid, self.directory),
                                config_type='module_config',
                                parent=self,
                                directory=self.directory))
            except (ValueError) as e:
                print "Error while reading 'appman.conf' file: ", e
        else:
            l = []

        return l