コード例 #1
0
ファイル: output.py プロジェクト: felixplasser/orbkit
    class MyModel(HasTraits):
        select = Range(0, len(data) - 1, 0)
        last_select = deepcopy(select)
        iso_value = Range(iso_min, iso_max, iso_val, mode='logslider')
        opacity = Range(0, 1.0, 1.0)
        show_atoms = Bool(True)
        label = Str()
        available = List(Str)
        available = datalabels

        prev_button = Button('Previous')
        next_button = Button('Next')

        scene = Instance(MlabSceneModel, ())
        plot_atoms = Instance(PipelineBase)
        plot0 = Instance(PipelineBase)

        # When the scene is activated, or when the parameters are changed, we
        # update the plot.
        @on_trait_change(
            'select,iso_value,show_atoms,opacity,label,scene.activated')
        def update_plot(self):
            if self.plot0 is None:
                if not is_vectorfield:
                    src = mlab.pipeline.scalar_field(X, Y, Z,
                                                     data[self.select])
                    self.plot0 = self.scene.mlab.pipeline.iso_surface(
                        src,
                        contours=[-self.iso_value, self.iso_value],
                        opacity=self.opacity,
                        colormap='blue-red',
                        vmin=-1e-8,
                        vmax=1e-8)
                else:
                    self.plot0 = self.scene.mlab.quiver3d(
                        X, Y, Z, *data[self.select])  #flow
                self.plot0.scene.background = (1, 1, 1)
            elif self.select != self.last_select:
                if not is_vectorfield:
                    self.plot0.mlab_source.set(scalars=data[self.select])
                else:
                    self.plot0.mlab_source.set(
                        vectors=data[self.select].reshape((3, -1)).T)
            if not is_vectorfield:
                self.plot0.contour.contours = [-self.iso_value, self.iso_value]
                self.plot0.actor.property.opacity = self.opacity
            self.last_select = deepcopy(self.select)
            if datalabels is not None:
                self.label = datalabels[self.select]
            if geo_spec is not None:
                if self.plot_atoms is None:
                    self.plot_atoms = self.scene.mlab.points3d(
                        geo_spec[:, 0],
                        geo_spec[:, 1],
                        geo_spec[:, 2],
                        scale_factor=0.75,
                        resolution=20)
                self.plot_atoms.visible = self.show_atoms

        def _prev_button_fired(self):
            if self.select > 0:
                self.select -= 1

        def _next_button_fired(self):
            if self.select < len(data) - 1:
                self.select += 1

        # The layout of the dialog created
        items = (Item('scene',
                      editor=SceneEditor(scene_class=MayaviScene),
                      height=400,
                      width=600,
                      show_label=False), )
        items0 = ()
        if len(data) > 1:
            items0 += (Group(
                'select',
                HSplit(Item('prev_button', show_label=False),
                       Item('next_button', show_label=False))), )
        items0 += (Group('iso_value', 'opacity', 'show_atoms'), )

        if datalabels is not None:
            if len(datalabels) > 1:
                items1 = (Item('available',
                               editor=ListStrEditor(title='Available Data',
                                                    editable=False),
                               show_label=False,
                               style='readonly',
                               width=300), )
                items0 = HSplit(items0, items1)
            items += (
                Group(
                    Item('label',
                         label='Selected Data',
                         style='readonly',
                         show_label=True), '_'),
                items0,
            )
        else:
            items += items0
        view = View(VSplit(items[0], items[1:]), resizable=True)
コード例 #2
0
class MView(MWorkbenchPart, PerspectiveItem):
    """ Mixin containing common code for toolkit-specific implementations. """

    implements(IView)

    #### 'IView' interface ####################################################

    # Is the view busy? (i.e., should the busy cursor (often an hourglass) be
    # displayed?).
    busy = Bool(False)

    # The category that the view belongs to (this can be used to group views
    # when they are displayed to the user).
    category = Str('General')

    # An image used to represent the view to the user (shown in the view tab
    # and in the view chooser etc).
    image = Instance(ImageResource)

    # Whether the view is visible or not.
    visible = Bool(False)

    ###########################################################################
    # 'IWorkbenchPart' interface.
    ###########################################################################

    def _id_default(self):
        """ Trait initializer. """

        id = '%s.%s' % (type(self).__module__, type(self).__name__)
        logger.warn('view %s has no Id - using <%s>' % (self, id))

        # If no Id is specified then use the name.
        return id

    def _name_default(self):
        """ Trait initializer. """

        name = camel_case_to_words(type(self).__name__)
        logger.warn('view %s has no name - using <%s>' % (self, name))

        return name

    ###########################################################################
    # 'IView' interface.
    ###########################################################################

    def activate(self):
        """ Activate the view.

        """

        self.window.activate_view(self)

        return

    def hide(self):
        """ Hide the view. """

        self.window.hide_view(self)

        return

    def show(self):
        """ Show the view. """

        self.window.show_view(self)

        return
コード例 #3
0
class TensorEigenvectorsEigenvalues(Filter):
    """
    Computes the eigenvectors and eigenvalues of tensor fields.
    """

    # The version of this class.  Used for persistence.
    __version__ = 0

    grid = Instance(tvtk.UnstructuredGrid, allow_none=False)

    processed_tensors_for_eigenvectors_eigenvalues = List()
    processed_tensors_for_edgelengths = List()
    processed_tensors_for_proportionaleigenvectors = List()

    active_tensor = String
    dimensions = Int

    eigenvector_eigenvalue_choice = DEnum(values_name='_dimension_list')
    _dimension_list = List(String)

    edgelength_on = Bool
    proprotionaleigenvectors_on = Bool

    ######################################################################
    # The view.
    ######################################################################
    traits_view = \
        View(
            Group(
                Item(name='eigenvector_eigenvalue_choice', label='Eigenvectors/eigenvalues'),
                Item(name='edgelength_on', label='Edge lengths'),
                Item(name='proprotionaleigenvectors_on', label='Proportional eigenvectors'),
            )
        )

    ######################################################################
    # `Filter` interface.
    ######################################################################
    def update_pipeline(self):
        if len(self.inputs) == 0 or len(self.inputs[0].outputs) == 0:
            return

        self.grid = tvtk.UnstructuredGrid()
        ## This doesn't work - there must be more to copy.
        #self.grid.points = tvtk.Points()
        #self.grid.points.deep_copy(self.inputs[0].outputs[0].points)
        self.grid.deep_copy(self.inputs[0].outputs[0])

        self.dimensions = size(self.grid.points[0])

        for i in range(self.dimensions):
            self._dimension_list.append(i)

        self.active_tensor = self.inputs[0].outputs[0].point_data.tensors.name
        self._set_outputs([self.grid])

    def update_data(self):
        self.active_tensor = self.inputs[0].outputs[0].point_data.tensors.name
        self.data_changed = True

    ######################################################################
    # Non-public interface.
    ######################################################################
    def _eigenvector_eigenvalue_choice_changed(self):
        self._update_output()

    def _edgelength_on_changed(self):
        self._update_output()

    def _proprotionaleigenvectors_on_changed(self):
        self._update_output()

    def _active_tensor_changed(self):
        self.calculate_eigenvectors_eigenvalues()
        self._update_output()

    def _update_output(self):
        if (self.edgelength_on):
            self.calculate_edgelengths()
            self.grid.point_data.set_active_scalars(
                self.active_tensor + '_edgelengths_' +
                self.eigenvector_eigenvalue_choice)
        else:
            self.grid.point_data.set_active_scalars(
                self.active_tensor + '_eigenvalues_' +
                self.eigenvector_eigenvalue_choice)

        if (self.proprotionaleigenvectors_on):
            self.calculate_propotionaleigenvectors()
            self.grid.point_data.set_active_vectors(
                self.active_tensor + '_proportionaleigenvectors_' +
                self.eigenvector_eigenvalue_choice)
        else:
            self.grid.point_data.set_active_vectors(
                self.active_tensor + '_eigenvectors_' +
                self.eigenvector_eigenvalue_choice)

        self.pipeline_changed = True

    def calculate_eigenvectors_eigenvalues(self):
        if not (self.active_tensor
                in self.processed_tensors_for_eigenvectors_eigenvalues):
            self.processed_tensors_for_eigenvectors_eigenvalues.append(
                self.active_tensor)

            input_grid = self.inputs[0].outputs[0]
            tensor_field = array(
                input_grid.point_data.get_array(self.active_tensor))

            result = map(
                lambda x: linalg.eig(
                    reshape(x, (self.dimensions, self.dimensions))),
                tensor_field)
            sorted_indices = map(lambda x: argsort(x[0]), result)

            for i in range(self.dimensions):
                eigenvalues = map(lambda x, y: x[0][y[i]], result,
                                  sorted_indices)
                eigenvectors = map(lambda x, y: x[1][y[i]], result,
                                   sorted_indices)

                eigenvalues_field = tvtk.FloatArray(name=self.active_tensor +
                                                    '_eigenvalues_' + ` i `)
                eigenvalues_field.from_array(eigenvalues)
                self.grid.point_data.add_array(eigenvalues_field)

                eigenvectors_field = tvtk.FloatArray(name=self.active_tensor +
                                                     '_eigenvectors_' + ` i `)
                eigenvectors_field.from_array(eigenvectors)
                self.grid.point_data.add_array(eigenvectors_field)

    def calculate_edgelengths(self):
        if not (self.active_tensor in self.processed_tensors_for_edgelengths):
            self.processed_tensors_for_edgelengths.append(self.active_tensor)

            input_grid = self.inputs[0].outputs[0]

            for i in range(self.dimensions):
                eigenvalues = array(
                    self.grid.point_data.get_array(self.active_tensor +
                                                   '_eigenvalues_' + ` i `))
                edgelengths = map(lambda x: 1 / sqrt(x), eigenvalues)

                edgelengths_field = tvtk.FloatArray(name=self.active_tensor +
                                                    '_edgelengths_' + ` i `)
                edgelengths_field.from_array(edgelengths)
                self.grid.point_data.add_array(edgelengths_field)

    def calculate_propotionaleigenvectors(self):
        if not (self.active_tensor
                in self.processed_tensors_for_proportionaleigenvectors):
            self.processed_tensors_for_proportionaleigenvectors.append(
                self.active_tensor)

            self.calculate_edgelengths()
            input_grid = self.inputs[0].outputs[0]

            for i in range(self.dimensions):
                eigenvectors = array(
                    self.grid.point_data.get_array(self.active_tensor +
                                                   '_eigenvectors_' + ` i `))
                edgelengths = array(
                    self.grid.point_data.get_array(self.active_tensor +
                                                   '_edgelengths_' + ` i `))
                proportionaleigenvectors = map(multiply, eigenvectors,
                                               edgelengths)

                proportionaleigenvectors_field = tvtk.FloatArray(
                    name=self.active_tensor + '_proportionaleigenvectors_' +
                    ` i `)
                proportionaleigenvectors_field.from_array(
                    proportionaleigenvectors)
                self.grid.point_data.add_array(proportionaleigenvectors_field)
コード例 #4
0
ファイル: plot_editors.py プロジェクト: sflarkin/yt-agora
class MPLAction(Action):
    event = Instance(MPLEvent)
コード例 #5
0
ファイル: i_command_stack.py プロジェクト: sjl421/code-2
class ICommandStack(Interface):
    """ The command stack interface.  A command stack is responsible for
    managing the changes to a data model and recording those changes so that
    they can be undone or redone.
    """

    #### 'ICommandStack' interface ############################################

    # This is the clean state of the stack.  Its value changes as commands are
    # undone and redone.  It can also be explicity set to mark the current
    # stack position as being clean (when the data is saved to disk for
    # example).
    clean = Bool

    # This is the name of the command that can be redone.  It will be empty if
    # there is no command that can be redone.  It is maintained by the undo
    # stack.
    redo_name = Unicode

    # This is the undo manager that manages this stack.
    undo_manager = Instance(IUndoManager)

    # This is the name of the command that can be undone.  It will be empty if
    # there is no command that can be undone.  It is maintained by the undo
    # stack.
    undo_name = Unicode

    ###########################################################################
    # 'ICommandStack' interface.
    ###########################################################################

    def begin_macro(self, name):
        """ This begins a macro by creating an empty command with the given
        'name'.  The commands passed to all subsequent calls to 'push()' will
        be contained in the macro until the next call to 'end_macro()'.  Macros
        may be nested.  The stack is disabled (ie. nothing can be undone or
        redone) while a macro is being created (ie. while there is an
        outstanding 'end_macro()' call).
        """

    def clear(self):
        """ This clears the stack, without undoing or redoing any commands, and
        leaves the stack in a clean state.  It is typically used when all
        changes to the data have been abandoned.
        """

    def end_macro(self):
        """ This ends a macro. """

    def push(self, command):
        """ This executes a command and saves it on the command stack so that
        it can be subsequently undone and redone.  'command' is an instance
        that implements the ICommand interface.  Its 'do()' method is called
        to execute the command.  If any value is returned by 'do()' then it is
        returned by 'push()'.  The command stack will keep a reference to the
        result so that it can recognise it as an argument to a subsequent
        command (which allows a script to properly save a result needed later).
        """

    def redo(self, sequence_nr=0):
        """ If 'sequence_nr' is 0 then the last command that was undone is
        redone and any result returned.  Otherwise commands are redone up to
        and including the given 'sequence_nr' and any result of the last of
        these is returned.
        """

    def undo(self, sequence_nr=0):
        """ If 'sequence_nr' is 0 then the last command is undone.  Otherwise
コード例 #6
0
ファイル: feature_bar.py プロジェクト: sjl421/code-2
class FeatureBar(HasPrivateTraits):

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

    # The wx.Window which is the parent for the FeatureBar:
    parent = Instance(wx.Window)

    # The DockControl whose features are being displayed:
    dock_control = Instance(DockControl)

    # The wx.Window being used for the FeatureBar:
    control = Instance(wx.Window)

    # Event posted when the user has completed using the FeatureBar:
    completed = Event

    # The background color for the FeatureBar:
    bg_color = Color(0xDBEEF7, allow_none=True)

    # The border color for the FeatureBar:
    border_color = Color(0X2583AF, allow_none=True)

    # Should the feature bar display horizontally (or vertically)?
    horizontal = Bool(True)

    #---------------------------------------------------------------------------
    #  Hides the feature bar:
    #---------------------------------------------------------------------------

    def hide(self):
        """ Hides the feature bar.
        """
        if self.control is not None:
            self.control.Hide()

    #---------------------------------------------------------------------------
    #  Shows the feature bar:
    #---------------------------------------------------------------------------

    def show(self):
        """ Shows the feature bar.
        """
        # Make sure all prerequisites are met:
        dock_control, parent = self.dock_control, self.parent
        if (dock_control is None) or (parent is None):
            return

        # Create the actual control (if needed):
        control = self.control
        if control is None:
            self.control = control = wx.Frame(None,
                                              -1,
                                              '',
                                              style=wx.BORDER_NONE)

            # Set up the 'erase background' event handler:
            wx.EVT_ERASE_BACKGROUND(control, self._erase_background)

            # Set up the 'paint' event handler:
            wx.EVT_PAINT(control, self._paint)

            # Set up mouse event handlers:
            wx.EVT_LEFT_DOWN(control, self._left_down)
            wx.EVT_LEFT_UP(control, self._left_up)
            wx.EVT_RIGHT_DOWN(control, self._right_down)
            wx.EVT_RIGHT_UP(control, self._right_up)
            wx.EVT_MOTION(control, self._mouse_move)
            wx.EVT_ENTER_WINDOW(control, self._mouse_enter)

            control.SetDropTarget(PythonDropTarget(self))

        # Calculate the best size and position for the feature bar:
        size = wx.Size(32, 32)
        width = height = 0
        horizontal = self.horizontal
        for feature in dock_control.active_features:
            bitmap = feature.bitmap
            if bitmap is not None:
                if horizontal:
                    width += (bitmap.GetWidth() + 3)
                    height = max(height, bitmap.GetHeight())
                else:
                    width = max(width, bitmap.GetWidth())
                    height += (bitmap.GetHeight() + 3)

        if width > 0:
            if horizontal:
                size = wx.Size(width + 5, height + 8)
            else:
                size = wx.Size(width + 8, height + 5)

        control.SetSize(size)
        px, py = parent.GetScreenPosition()
        fx, fy = dock_control.feature_popup_position
        control.SetPosition(wx.Point(px + fx, py + fy))
        control.Show()

    #-- Window Event Handlers --------------------------------------------------

    #---------------------------------------------------------------------------
    #  Handles repainting the window:
    #---------------------------------------------------------------------------

    def _paint(self, event):
        """ Handles repainting the window.
        """
        window = self.control
        dx, dy = window.GetSizeTuple()
        dc = wx.PaintDC(window)

        # Draw the feature container:
        bg_color = self.bg_color
        border_color = self.border_color
        if (bg_color is not None) or (border_color is not None):
            if border_color is None:
                dc.SetPen(wx.TRANSPARENT_PEN)
            else:
                dc.SetPen(wx.Pen(border_color, 1, wx.SOLID))
            if bg_color is None:
                dc.SetBrush(wx.TRANSPARENT_PEN)
            else:
                dc.SetBrush(wx.Brush(bg_color, wx.SOLID))
            dc.DrawRectangle(0, 0, dx, dy)

        # Draw the feature icons:
        if self.horizontal:
            x = 4
            for feature in self.dock_control.active_features:
                bitmap = feature.bitmap
                if bitmap is not None:
                    dc.DrawBitmap(bitmap, x, 4, True)
                    x += (bitmap.GetWidth() + 3)
        else:
            y = 4
            for feature in self.dock_control.active_features:
                bitmap = feature.bitmap
                if bitmap is not None:
                    dc.DrawBitmap(bitmap, 4, y, True)
                    y += (bitmap.GetHeight() + 3)

    #---------------------------------------------------------------------------
    #  Handles erasing the window background:
    #---------------------------------------------------------------------------

    def _erase_background(self, event):
        """ Handles erasing the window background.
        """
        pass

    #---------------------------------------------------------------------------
    #  Handles the left mouse button being pressed:
    #---------------------------------------------------------------------------

    def _left_down(self, event):
        """ Handles the left mouse button being pressed.
        """
        self._feature = self._feature_at(event)
        self._dragging = False
        self._xy = (event.GetX(), event.GetY())
        #self.control.CaptureMouse()

    #---------------------------------------------------------------------------
    #  Handles the left mouse button being released:
    #---------------------------------------------------------------------------

    def _left_up(self, event):
        """ Handles the left mouse button being released.
        """
        #self.control.ReleaseMouse()
        self._dragging = None
        feature, self._feature = self._feature, None
        if feature is not None:
            if feature is self._feature_at(event):
                self.control.ReleaseMouse()
                self.completed = True
                feature._set_event(event)
                feature.click()

    #---------------------------------------------------------------------------
    #  Handles the right mouse button being pressed:
    #---------------------------------------------------------------------------

    def _right_down(self, event):
        """ Handles the right mouse button being pressed.
        """
        self._feature = self._feature_at(event)
        self._dragging = False
        self._xy = (event.GetX(), event.GetY())
        #self.control.CaptureMouse()

    #---------------------------------------------------------------------------
    #  Handles the right mouse button being released:
    #---------------------------------------------------------------------------

    def _right_up(self, event):
        """ Handles the right mouse button being released.
        """
        #self.control.ReleaseMouse()
        self._dragging = None
        feature, self._feature = self._feature, None
        if feature is not None:
            if feature is self._feature_at(event):
                self.control.ReleaseMouse()
                self.completed = True
                feature._set_event(event)
                feature.right_click()

    #---------------------------------------------------------------------------
    #  Handles the mouse moving over the window:
    #---------------------------------------------------------------------------

    def _mouse_move(self, event):
        """ Handles the mouse moving over the window.
        """
        # Update tooltips if no mouse button is currently pressed:
        if self._dragging is None:
            feature = self._feature_at(event)
            if feature is not self._tooltip_feature:
                self._tooltip_feature = feature
                tooltip = ''
                if feature is not None:
                    tooltip = feature.tooltip
                wx.ToolTip.Enable(False)
                wx.ToolTip.Enable(True)
                self.control.SetToolTip(wx.ToolTip(tooltip))

            # Check to see if the mouse has left the window, and mark it
            # completed if it has:
            x, y = event.GetX(), event.GetY()
            dx, dy = self.control.GetSizeTuple()
            if (x < 0) or (y < 0) or (x >= dx) or (y >= dy):
                self.control.ReleaseMouse()
                self._tooltip_feature = None
                self.completed = True

            return

        # Check to see if we are in 'drag mode' yet:
        if not self._dragging:
            x, y = self._xy
            if (abs(x - event.GetX()) + abs(y - event.GetY())) < 3:
                return

            self._dragging = True

            # Check to see if user is trying to drag a 'feature':
            feature = self._feature
            if feature is not None:
                feature._set_event(event)

                prefix = button = ''
                if event.RightIsDown():
                    button = 'right_'
                if event.ControlDown():
                    prefix = 'control_'
                elif event.AltDown():
                    prefix = 'alt_'
                elif event.ShiftDown():
                    prefix = 'shift_'

                object = getattr(feature, '%s%sdrag' % (prefix, button))()
                if object is not None:
                    self.control.ReleaseMouse()
                    self._feature = None
                    self.completed = True
                    self.dock_control.pre_drag_all(object)
                    PythonDropSource(self.control, object)
                    self.dock_control.post_drag_all()
                    self._dragging = None

    #---------------------------------------------------------------------------
    #  Handles the mouse entering the window:
    #---------------------------------------------------------------------------

    def _mouse_enter(self, event):
        """ Handles the mouse entering the window.
        """
        self.control.CaptureMouse()

#-- Drag and drop event handlers: ----------------------------------------------

#---------------------------------------------------------------------------
#  Handles a Python object being dropped on the control:
#---------------------------------------------------------------------------

    def wx_dropped_on(self, x, y, data, drag_result):
        """ Handles a Python object being dropped on the window.
        """
        # Determine what, if any, feature the object was dropped on:
        feature = self._can_drop_on_feature(x, y, data)

        # Indicate use of the feature bar is complete:
        self.completed = True

        # Reset any drag state information:
        self.dock_control.post_drag(FEATURE_EXTERNAL_DRAG)

        # Check to see if the data was dropped on a feature or not:
        if feature is not None:
            if isinstance(data, IFeatureTool):
                # Handle an object implementing IFeatureTool being dropped:
                dock_control = feature.dock_control
                data.feature_dropped_on_dock_control(dock_control)
                data.feature_dropped_on(dock_control.object)
            else:
                # Handle a normal object being dropped:
                wx, wy = self.control.GetScreenPosition()
                feature.set(x=wx + x, y=wy + y)
                feature.drop(data)

            return drag_result

        return wx.DragNone

    #---------------------------------------------------------------------------
    #  Handles a Python object being dragged over the control:
    #---------------------------------------------------------------------------

    def wx_drag_over(self, x, y, data, drag_result):
        """ Handles a Python object being dragged over the control.
        """
        # Handle the case of dragging a normal object over a 'feature':
        if self._can_drop_on_feature(x, y, data) is not None:
            return drag_result

        return wx.DragNone

    #---------------------------------------------------------------------------
    #  Handles a dragged Python object leaving the window:
    #---------------------------------------------------------------------------

    def wx_drag_leave(self, data):
        """ Handles a dragged Python object leaving the window.
        """
        # Indicate use of the feature bar is complete:
        self.completed = True

        # Reset any drag state information:
        self.dock_control.post_drag(FEATURE_EXTERNAL_DRAG)

    #-- Private Methods --------------------------------------------------------

    #---------------------------------------------------------------------------
    #  Returns a feature that the pointer is over and which can accept the
    #  specified data:
    #---------------------------------------------------------------------------

    def _can_drop_on_feature(self, x, y, data):
        """ Returns a feature that the pointer is over and which can accept the
            specified data.
        """
        feature = self._feature_at(FakeEvent(x, y))
        if (feature is not None) and feature.can_drop(data):
            return feature

        return None

    #---------------------------------------------------------------------------
    #  Returns the DockWindowFeature (if any) at a specified window position:
    #---------------------------------------------------------------------------

    def _feature_at(self, event):
        """ Returns the DockWindowFeature (if any) at a specified window
            position.
        """
        if self.horizontal:
            x = 4
            for feature in self.dock_control.active_features:
                bitmap = feature.bitmap
                if bitmap is not None:
                    bdx = bitmap.GetWidth()
                    if self._is_in(event, x, 4, bdx, bitmap.GetHeight()):
                        return feature

                    x += (bdx + 3)
        else:
            y = 4
            for feature in self.dock_control.active_features:
                bitmap = feature.bitmap
                if bitmap is not None:
                    bdy = bitmap.GetHeight()
                    if self._is_in(event, 4, y, bitmap.GetWidth(), bdy):
                        return feature

                    y += (bdy + 3)

        return None

    #---------------------------------------------------------------------------
    #  Returns whether or not an event is within a specified bounds:
    #---------------------------------------------------------------------------

    def _is_in(self, event, x, y, dx, dy):
        """ Returns whether or not an event is within a specified bounds.
        """
        return ((x <= event.GetX() < (x + dx)) and (y <= event.GetY() <
                                                    (y + dy)))
コード例 #7
0
class Bar(HasTraits):
    foo = Instance(Foo, ())
    s = Delegate('foo')
コード例 #8
0
ファイル: builtin_surface.py プロジェクト: sjl421/code-2
class BuiltinSurface(Source):
    # The version of this class.  Used for persistence.
    __version__ = 0

    # Flag to set the poly data type.
    source = Enum('arrow',
                  'cone',
                  'cube',
                  'cylinder',
                  'disk',
                  'earth',
                  'line',
                  'outline',
                  'plane',
                  'point',
                  'polygon',
                  'sphere',
                  'superquadric',
                  'textured sphere',
                  'glyph2d',
                  desc='which poly data source to be used')

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

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

    # Create the UI for the traits.
    view = View(Group(Item(name='source'),
                      Item(name='data_source', style='custom', resizable=True),
                      label='Surface Source',
                      show_labels=False),
                resizable=True)

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

    # A dictionary that maps the source names to instances of the
    # poly data sources.
    _source_dict = Dict(Str, Instance(tvtk.PolyDataAlgorithm,
                                      allow_none=False))

    ######################################################################
    # `object` interface
    ######################################################################
    def __init__(self, **traits):
        # Call parent class' init.
        super(BuiltinSurface, self).__init__(**traits)

        # Initialize the source to the default mode's instance from
        # the dictionary if needed.
        if 'source' not in traits:
            self._source_changed(self.source)

    def __set_pure_state__(self, state):
        self.source = state.source
        super(BuiltinSurface, self).__set_pure_state__(state)

    ######################################################################
    # Non-public methods.
    ######################################################################
    def _source_changed(self, value):
        """This method is invoked (automatically) when the `source`
        trait is changed.
        """
        self.data_source = self._source_dict[self.source]

    def _data_source_changed(self, old, new):
        """This method is invoked (automatically) when the
        poly data source is changed ."""

        self.outputs = [self.data_source.output]

        if old is not None:
            old.on_trait_change(self.render, remove=True)
        new.on_trait_change(self.render)

    def __source_dict_default(self):
        """Default value for source dict."""
        sd = {
            'arrow': tvtk.ArrowSource(),
            'cone': tvtk.ConeSource(),
            'cube': tvtk.CubeSource(),
            'cylinder': tvtk.CylinderSource(),
            'disk': tvtk.DiskSource(),
            'earth': tvtk.EarthSource(),
            'line': tvtk.LineSource(),
            'outline': tvtk.OutlineSource(),
            'plane': tvtk.PlaneSource(),
            'point': tvtk.PointSource(),
            'polygon': tvtk.RegularPolygonSource(),
            'sphere': tvtk.SphereSource(),
            'superquadric': tvtk.SuperquadricSource(),
            'textured sphere': tvtk.TexturedSphereSource(),
            'glyph2d': tvtk.GlyphSource2D()
        }
        return sd
コード例 #9
0
ファイル: plot.py プロジェクト: pmrup/labtools
class Plot(Figure2D):
    r"""Plot object, for data plotting. Use this for data oplotting in a traits gui
    You can also use it without calling :meth:`configure_traits` and display figure
    with matplotlib interactively by calling :meth:`figure`
    
    >>> p = Plot()
    
    You can define attributes afterwards:
        
    >>> p.title = 'My graph'
    >>> p.xscale = 'log'
    >>> p.xlabel = 'time'
    >>> p.ylabel = 'speed'
    >>> p.figtext.text = 'This text is also displayed\nThis is the second row'
    >>> p.figtext.position = (0.2,0.4)
    
    Finally you can plot data and display it:
        
    >>> p.plot([1,2,3],[1,2,3]) #plots actual data
    >>> ok = p.configure_traits()
    
    Or you can use matplotlib by
    
    #>>> f = p.figure()
    #>>> f.show()
    
    """
    #: defines x scale
    xscale = Enum('linear', 'log')
    #: defines y scale
    yscale = Enum('linear', 'log')
    #: title of the figure
    title = Str('')
    #: x axis label
    xlabel = Str('x')
    #: y axis label
    ylabel = Str('y')
    #: text that is displayed, '' for empty text
    figtext = Instance(FigText, ())

    view = View(HSplit(
        Group('title', 'xlabel', 'ylabel', 'xscale', 'yscale', 'figtext'),
        Item('fig', show_label=False, editor=MPLFigureEditor())),
                width=500,
                height=400,
                resizable=True,
                handler=Figure2DHandler)

    def __init__(self, *args, **kw):
        super(Plot, self).__init__(*args, **kw)
        self.init_axis()
        self._init_figtext()
        self.update = True

    def init_axis(self):
        """ Clears axis and initializes label, title, etc..
        """
        #self.fig = Figure()
        #ax = self.fig.add_subplot(111)
        log.debug('Initializing plot')
        self.ax.cla()
        #ax = self.fig.axes[0]
        for name in SETTABLE_TRAITS:
            value = getattr(self, name)
            self.set_axis(name, value)

    def _init_figtext(self):
        x, y = self.figtext.position
        self.fig.text(x, y, self.figtext.text)

    def plot(self, x, y, *args, **kw):
        """Plots x,y
        
        :param array x: 
            X data
        :param array y: 
            X data
        :param args:
            Aditional arguments to pass to plot function
        :key kw: 
            Additional keys supported by matplotlib plot and function
        """
        #if sigma:
        #    raise NotImplemented, 'specifying sgima does not work yet'
        log.debug('Plotting data')
        self.ax.plot(x, y, *args, **kw)
        self.update = True

    def errorbar(self, x, y, **kw):
        """Plots x,y, and optional sigma data
        
        :param array x: 
            X data
        :param array y: 
            X data
        :key kw: 
            Additional keys supported by matplotlib errorbar function
        """
        log.debug('Plotting data')
        kw.setdefault('fmt', 'o')
        self.ax.errorbar(x, y, **kw)
        self.update = True

    @on_trait_change(','.join(SETTABLE_TRAITS))
    def set_axis(self, name, value):
        """Sets axis parameter
        
        :param str name: 
            defines the name of the axis parameter to set
        :param value: 
            defines parameter value
        """
        try:
            setter = getattr(self.ax, 'set_' + name)
            setter(value)
            self.update = True
        except:
            pass

    @on_trait_change('figtext.text,figtext.position')
    def set_figtext(self, name, value):
        """Sets figure text,
        
        :param str name: 
            defines the name of the figtext parameter to set
        :param value: 
            defines parameter value
        """
        try:
            setter = getattr(self.fig.texts[0], 'set_' + name)
            setter(value)
            self.update = True
        except:
            pass

    def figure(self, *arg, **kw):
        """Creates a figure object for interactive use. figure is drawn with texts and axes
        defined by :attr:`Figure2D.fig`.
        """
        f = plt.figure(*arg, **kw)
        f.axes = self.fig.axes
        f.texts = self.fig.texts
        return f

    def savefig(self, fname, *args, **kw):
        """Saves plot to disk, see :func:`matplotlib.pyplot.savefig`
        
        :param str fname:
            Filename string
        """
        f = self.figure()
        f.savefig(fname, *args, **kw)
        plt.close(f)
コード例 #10
0
class Demo(HasTraits):
    plot = Instance(Component)
    fileName = "default.txt"
    case = List(UncertaintyValue)
    cases = {}

    defaultCase = []

    # Attributes to use for the plot view.
    size = (400, 250)

    traits_view = View(Group(
        Group(Item('plot', editor=ComponentEditor(size=size),
                   show_label=False),
              orientation="vertical",
              show_border=True),
        Group(Item('case',
                   editor=TabularEditor(adapter=CaseAdapter(can_edit=False)),
                   show_label=False),
              orientation="vertical",
              show_border=True),
        layout='split',
        orientation='horizontal'),
                       title='Interactive Lines',
                       resizable=True)

    def setFileName(self, newName):
        self.fileName = newName

    def _update_case(self, name):

        if name:
            self.case = self.cases.get(name)

        else:
            self.case = self.defaultCase

    def _plot_default(self):
        results = cPickle.load(open(self.fileName, 'r'))
        outcomes = results[0][1].keys()
        outcomes.pop(outcomes.index('TIME'))
        x = results[0][1]['TIME']

        for j, aCase in enumerate(results):
            aCase = [
                UncertaintyValue(name=key, value=value)
                for key, value in aCase[0][0].items()
            ]
            self.cases['y' + str(j)] = aCase

        uncertainties = results[0][0][0]
        uncertaintynames = uncertainties.keys()
        uncertaintyvalues = []
        for key in uncertainties.keys():
            uncertaintyvalues.append(uncertainties[key])

        case = []
        for i in range(len(uncertainties)):
            case.append(
                UncertaintyValue(name=str(uncertaintynames[i]),
                                 value=""))  #haydaa
        self.case = case
        self.defaultCase = case

        # Create some x-y data series to plot
        pds = []
        for i, outcome in enumerate(outcomes):
            pd = ArrayPlotData(index=x)
            for j in range(len(results)):
                pd.set_data("y" + str(j), results[j][1].get(outcome))
            pds.append(pd)

        # Create a container and add our plots
        container = GridContainer(bgcolor="lightgray",
                                  use_backbuffer=True,
                                  shape=(1, 1))

        #plot data
        tools = []
        for j in range(len(outcomes)):
            pd1 = pds[j]

            # Create some line plots of some of the data
            plot = Plot(pd1,
                        title=outcomes[j],
                        border_visible=True,
                        border_width=1)
            plot.legend.visible = False

            for i in range(len(results)):
                plotvalue = "y" + str(i)
                color = colors[i % len(colors)]
                plot.plot(("index", plotvalue), name=plotvalue, color=color)

            for value in plot.plots.values():
                for entry in value:
                    entry.index.sort_order = 'ascending'

            # Attach the selector tools to the plot
            selectorTool1 = LineSelectorTool(component=plot)
            plot.tools.append(selectorTool1)
            tools.append(selectorTool1)

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

            container.add(plot)

        #make sure the selector tools know each other

        for tool in tools:
            tool._demo = self

        return container
コード例 #11
0
ファイル: vtk_xml_file_reader.py プロジェクト: sjl421/code-2
class VTKXMLFileReader(FileDataSource):

    """A VTK XML file reader.  The reader supports all the different
    types of data sets.  This reader also supports a time series.
    Currently, this reader assumes that there is only one output that
    has configurable attributes.
    """

    # The version of this class.  Used for persistence.
    __version__ = 0

    ########################################
    # Dynamic traits: These traits are dynamic and are automatically
    # updated depending on the contents of the file.

    # The active point scalar name.  An empty string indicates that
    # the attribute is "deactivated".  This is useful when you have
    # both point and cell attributes and want to use cell data by
    # default.
    point_scalars_name = DEnum(values_name='_point_scalars_list',
                               desc='scalar point data attribute to use')
    # The active point vector name.
    point_vectors_name = DEnum(values_name='_point_vectors_list',
                               desc='vectors point data attribute to use')
    # The active point tensor name.
    point_tensors_name = DEnum(values_name='_point_tensors_list',
                               desc='tensor point data attribute to use')

    # The active cell scalar name.
    cell_scalars_name = DEnum(values_name='_cell_scalars_list',
                               desc='scalar cell data attribute to use')
    # The active cell vector name.
    cell_vectors_name = DEnum(values_name='_cell_vectors_list',
                               desc='vectors cell data attribute to use')
    # The active cell tensor name.
    cell_tensors_name = DEnum(values_name='_cell_tensors_list',
                               desc='tensor cell data attribute to use')
    ########################################
    
    # The VTK data file reader.
    reader = Instance(tvtk.XMLReader)

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

    # Our view.
    view = View(Group(Include('time_step_group'),
                      Item(name='point_scalars_name'),
                      Item(name='point_vectors_name'),
                      Item(name='point_tensors_name'),
                      Item(name='cell_scalars_name'),
                      Item(name='cell_vectors_name'),
                      Item(name='cell_tensors_name'),
                      Item(name='reader'),
                      ))

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

    # These private traits store the list of available data
    # attributes.  The non-private traits use these lists internally.
    _point_scalars_list = List(Str)
    _point_vectors_list = List(Str)
    _point_tensors_list = List(Str)
    _cell_scalars_list = List(Str)
    _cell_vectors_list = List(Str)
    _cell_tensors_list = List(Str)

    # This filter allows us to change the attributes of the data
    # object and will ensure that the pipeline is properly taken care
    # of.  Directly setting the array in the VTK object will not do
    # this.
    _assign_attribute = Instance(tvtk.AssignAttribute, args=(),
                                 allow_none=False)

    # Toggles if this is the first time this object has been used.
    _first = Bool(True)
    
    ######################################################################
    # `object` interface
    ######################################################################
    def __get_pure_state__(self):
        d = super(VTKXMLFileReader, self).__get_pure_state__()
        for name in ('_assign_attribute', '_first'):
            d.pop(name, None)
        # Pickle the 'point_scalars_name' etc. since these are
        # properties and not in __dict__.
        attr = {}
        for name in ('point_scalars', 'point_vectors',
                     'point_tensors', 'cell_scalars',
                     'cell_vectors', 'cell_tensors'):
            d.pop('_' + name + '_list', None)
            d.pop('_' + name + '_name', None)
            x = name + '_name'
            attr[x] = getattr(self, x)
        d.update(attr)
        return d
    
    def __set_pure_state__(self, state):
        # The reader has its own file_name which needs to be fixed.
        state.reader.file_name = state.file_path.abs_pth
        # Now call the parent class to setup everything.
        super(VTKXMLFileReader, self).__set_pure_state__(state)

    ######################################################################
    # `Base` interface
    ######################################################################
    def start(self):
        """This is invoked when this object is added to the mayavi
        pipeline.
        """
        # Do nothing if we are already running.
        if self.running:
            return

        # Call the parent method to do its thing.  This will typically
        # start all our children.
        super(VTKXMLFileReader, self).start()

    def stop(self):
        """Invoked when this object is removed from the mayavi
        pipeline.
        """
        if not self.running:
            return

        # Call the parent method to do its thing.
        super(VTKXMLFileReader, self).stop()
    
    
    ######################################################################
    # `FileDataSource` interface
    ######################################################################
    def update(self):
        if len(self.file_path.get()) == 0:
            return
        reader = self.reader
        reader.update()
        self.render()

    def update_data(self):
        if len(self.file_path.get()) == 0:
            return
        self.reader.update()
        pnt_attr, cell_attr = get_all_attributes(self.reader.output)

        def _setup_data_traits(obj, attributes, d_type):
            """Given the object, the dict of the attributes from the
            `get_all_attributes` function and the data type
            (point/cell) data this will setup the object and the data.
            """
            attrs = ['scalars', 'vectors', 'tensors']
            aa = obj._assign_attribute
            data = getattr(obj.reader.output, '%s_data'%d_type)
            for attr in attrs:
                values = attributes[attr]
                values.append('')
                setattr(obj, '_%s_%s_list'%(d_type, attr), values)
                if len(values) > 1:
                    default = getattr(obj, '%s_%s_name'%(d_type, attr))
                    if obj._first and len(default) == 0:
                        default = values[0]
                    getattr(data, 'set_active_%s'%attr)(default)
                    aa.assign(default, attr.upper(),
                              d_type.upper() +'_DATA')
                    aa.update()
                    kw = {'%s_%s_name'%(d_type, attr): default,
                          'trait_change_notify': False}
                    obj.set(**kw)
                    
        
        _setup_data_traits(self, cell_attr, 'cell')
        _setup_data_traits(self, pnt_attr, 'point')
        if self._first:
            self._first = False
        # Propagate the data changed event.
        self.data_changed = True
    

    ######################################################################
    # Non-public interface
    ######################################################################
    def _file_path_changed(self, fpath):
        value = fpath.get()
        if len(value) == 0:
            return
        else:
            if self.reader is None:
                d_type = find_file_data_type(fpath.get())
                self.reader = eval('tvtk.XML%sReader()'%d_type)
            reader = self.reader
            reader.file_name = value
            reader.update()

            # Setup the outputs by resetting self.outputs.  Changing
            # the outputs automatically fires a pipeline_changed
            # event.
            try:
                n = reader.number_of_outputs
            except AttributeError: # for VTK >= 4.5
                n = reader.number_of_output_ports
            outputs = []
            for i in range(n):
                outputs.append(reader.get_output(i))

            # FIXME: Only the first output goes through the assign
            # attribute filter.
            aa = self._assign_attribute
            aa.input = outputs[0]        
            outputs[0] = aa.output
            self.update_data()

            self.outputs = outputs

            # FIXME: The output info is only based on the first output.
            self.output_info.datasets = [get_tvtk_dataset_name(outputs[0])]

            # Change our name on the tree view
            self.name = self._get_name()

    def _set_data_name(self, data_type, attr_type, value):
        if value is None:
            return
        
        reader_output = self.reader.output
        if len(value) == 0:
            # If the value is empty then we deactivate that attribute.
            d = getattr(reader_output, attr_type + '_data')
            method = getattr(d, 'set_active_%s'%data_type)
            method(None)
            self.data_changed = True
            return
        
        aa = self._assign_attribute
        data = None
        if attr_type == 'point':
            data = reader_output.point_data
        elif attr_type == 'cell':
            data = reader_output.cell_data

        method = getattr(data, 'set_active_%s'%data_type)
        method(value)
        aa.assign(value, data_type.upper(), attr_type.upper() +'_DATA')
        aa.update()
        # Fire an event, so the changes propagate.
        self.data_changed = True

    def _point_scalars_name_changed(self, value):
        self._set_data_name('scalars', 'point', value)

    def _point_vectors_name_changed(self, value):
        self._set_data_name('vectors', 'point', value)

    def _point_tensors_name_changed(self, value):
        self._set_data_name('tensors', 'point', value)

    def _cell_scalars_name_changed(self, value):
        self._set_data_name('scalars', 'cell', value)

    def _cell_vectors_name_changed(self, value):
        self._set_data_name('vectors', 'cell', value)

    def _cell_tensors_name_changed(self, value):
        self._set_data_name('tensors', 'cell', value)

    def _get_name(self):
        """ Gets the name to display on the tree view.
        """
        fname = basename(self.file_path.get())
        ret = "VTK XML file (%s)"%fname
        if len(self.file_list) > 1:
            ret += " (timeseries)"
        if '[Hidden]' in self.name:
            ret += ' [Hidden]'

        return ret
コード例 #12
0
ファイル: fit.py プロジェクト: pmrup/labtools
class DlsAnalyzer(BaseFileAnalyzer):
    """
    DlsAnalyzer is used to analyze multiple dls files. First you must define a function 
    that returns x value for the data analyzed. A default function :attr:'get_x_value' returns just index value.
    This function must have two erguments as an input: index value and filename.
    It is up to you how the return value uses these inputs. For instance:
    
    >>> def get_x(fnames, index):
    ...    return 100 + 0.1 * index
    
    Then create :class:`Filenames` instance (optional)
    
    >>> filenames = Filenames(directory = '../testdata', pattern = *.ASC)
    
    Now you cen create analyzer and do some analysis
    
    >>> fitter = create_dls_fitter('single_stretch_exp')
    >>> analyzer = DlsAnalyzer(filenames = filenames, 
    ...                        fitter = fitter, 
    ...                        get_x_value = get_x)
    
    >>> analyzer.log_name = 'analysis.rst' #specify logname to log results in reStructuredText format
    >>> analyzer.constants = (('s','n'),()) #set constant parameters in fitting process, 
    >>> analyzer.x_name = 'position' #specify x data name
    
    When everything is set you can call process to fit all data.
    
    >>> analyzer.process()
    >>> analyzer.save_result('..testdata/output.npy')
    
    """
    #: Filenames instance
    filenames = Instance(Filenames, ())
    #: selected filename
    selected = DelegatesTo('filenames')
    #: data fitter object for data fitting
    fitter = Instance(DlsFitter)
    #: defines a list of constants tuple that are set in each fit run. See :meth:`process`
    constants = List(List(Str))
    #: defines whethere fit plots are saved
    saves_fits = Bool(False)
    #: if defined it will generate a valif reStructuredText file
    log_name = Str
    #: actual log is written here
    log = Str
    #: fit results are storred here
    results = Instance(StructArrayData, ())
    #: This function is used to get x value from index integer and filename string
    get_x_value = Function
    #: this specifies name of the x data of results
    x_name = Str('index')
    #: if this list is not empty it will be used to obtain x_values
    x_values = List(Float)

    view = View(Group(dls_analyzer_group, 'saves_fits', 'results'),
                Item('fitter', style='custom'),
                resizable=True)

    @on_trait_change('selected')
    def _open_dls(self, name):
        self.fitter.open_dls(name)
        self.fitter._plot()

    def _constants_default(self):
        return [['f', 's'], ['']]

    def _get_x_value_default(self):
        def get(fnames, index):
            return index

        return get

    def _selected_changed(self):
        self.process_selected()

    def process_selected(self):
        """Opens fname and fits data according to self.constants
        
        :param str fname: 
            filename of asc data to be opened and fitted
        """
        fname = self.selected
        self.fitter.open_dls(fname)
        self.fitter.function.reset()
        print(self.constants)
        for constants in self.constants:
            try:
                self.fitter.fit(constants=constants)
            except:
                self.fitter.configure_traits()
        if self.saves_fits:
            path, fname = os.path.split(fname)
            path = os.path.join(path, 'fits')
            try:
                os.mkdir(path)
            except:
                pass
            fname = os.path.join(path, fname)
            imagename = fname + '.png'
            log.info('Plotting %s' % imagename)
            self.fitter.plotter.title = imagename
            self.fitter.plotter.savefig(imagename)
        result = self.fitter.function.get_parameters()
        self._process_result(result, self.selected, self.index)
        return result

    def _process_result(self, result, fname, index):
        result = (i for sub in result
                  for i in sub)  #flatten results list first
        try:
            self.results.data[index] = (self.x_values[index], ) + tuple(result)
        except:
            self.results.data[index] = (self.get_x_value(
                self.filenames.filenames, index), ) + tuple(result)
        self.results.data_updated = True

    @on_trait_change('filenames.filenames')
    def _init(self):
        array_names = [self.x_name]
        for name in self.fitter.function.pnames:
            array_names.append(name)
            array_names.append(name + '_err')

        dtype = np.dtype(list(zip(array_names, ['float'] * len(array_names))))
        self.results = StructArrayData(
            data=np.zeros(len(self.filenames), dtype=dtype))
        #self.results_err = StructArrayData(data = np.zeros(len(self.filenames), dtype = dtype))
        self.results.data_updated = True
        #self.results_err.data_updated = True
        #self.log = '===========\nFit results\n===========\n\n'
        return True

    def save_results(self, fname):
        """Saves results to disk
        
        :param str fname:
            output filename
        """
        np.save(fname, self.results.data)
        if self.log_name:
            self.log = '===========\nFit results\n===========\n\n'
            for fname in self.filenames.filenames:
                imagename = fname + '.png'
                self.log += '.. image:: %s\n' % os.path.basename(imagename)
            with open(self.log_name, 'w') as f:
                f.write(self.log)
コード例 #13
0
class MainWindow(HasTraits):
    """Main window for the viewer built using Traits."""

    # mpl figure
    figure = Instance(Figure)

    # Range slider for selecing slice to view
    slice_index_low = Int(0)  # These have to be trait ints or they don't work
    slice_index_high = Int(
        91)  # with the dynamic updating of the Range slider.
    slice_index = Range(low='slice_index_low', high='slice_index_high')

    # Radio box for selecting orthogonal slice
    slice_plane = Enum(_slice_planes)

    # Affine TextCtrl
    affine = Array(Float, (4, 4))

    def __init__(self):
        super(MainWindow, self).__init__()
        # Initialize our nipy image object
        self.img = ImageData()
        # Initialize our matplotlib figure
        self.img_plot = SingleImage(self.figure, self.img.data)

    #
    # Initializers for Traited attrs
    #
    def _figure_default(self):
        """Initialize matplotlib figure."""
        figure = Figure()
        return figure

    def _slice_index_default(self):
        """Initialize slice_index attr without triggering the
        on_trait_change method.
        """
        return 0

    #
    # Event handlers
    #
    @on_trait_change('slice_index, slice_plane')
    def update_slice_index(self):
        self.img.set_slice_index(self.slice_index)
        self.update_image_slicing()
        self.image_show()

    #
    # Data Model methods
    #
    def update_affine(self):
        self.affine = self.img.get_affine()

    def update_image_slicing(self):

        # XXX: BUG: self.slice_index is set by the slider of the
        # current slice.  When we switch the slice plane, this index
        # may be outside the range of the new slice.  Need to handle
        # this.

        if self.slice_plane == 'Axial':
            self.img.set_slice_plane(_slice_planes[0])
        elif self.slice_plane == 'Sagittal':
            self.img.set_slice_plane(_slice_planes[1])
        elif self.slice_plane == 'Coronal':
            self.img.set_slice_plane(_slice_planes[2])
        else:
            raise AttributeError('Unknown slice plane')

        # update image array
        self.img.update_data()

        # update figure data
        self.img_plot.set_data(self.img.data)

        # get range information for slider
        low, high = self.img.get_range()
        # update range slider
        self.slice_index_low = low
        self.slice_index_high = high

    def image_show(self):
        self.img_plot.draw()

    #
    # View code
    #

    # Menus
    def open_menu(self):
        dlg = FileDialog()
        dlg.open()
        if dlg.return_code == OK:
            self.img.load_image(dlg.path)
            self.update_affine()
            self.update_slice_index()

    menu_open_action = Action(name='Open Nifti', action='open_menu')

    file_menubar = MenuBar(Menu(menu_open_action, name='File'))

    # Items
    fig_item = Item('figure', editor=MPLFigureEditor())
    # radio button to pick slice
    _slice_opts = {
        'Axial': '1:Axial',
        'Sagittal': '2:Sagittal',
        'Coronal': '3:Coronal'
    }
    slice_opt_item = Item(name='slice_plane',
                          editor=EnumEditor(values=_slice_opts),
                          style='custom')

    affine_item = Item('affine', label='Affine', style='readonly')
    # BUG: The rendering with the 'readonly' style creates an ugly wx
    # "multi-line" control.

    traits_view = View(HSplit(
        Group(fig_item), Group(affine_item, slice_opt_item,
                               Item('slice_index'))),
                       menubar=file_menubar,
                       width=0.80,
                       height=0.80,
                       resizable=True)
コード例 #14
0
ファイル: scene.py プロジェクト: sjl421/code-2
class Scene(TVTKScene, Widget):
    """A VTK interactor scene widget for pyface and wxPython.

    This widget uses a RenderWindowInteractor and therefore supports
    interaction with VTK widgets.  The widget uses TVTK.  In addition
    to the features that the base TVTKScene provides this widget
    supports:

    - saving the rendered scene to the clipboard.

    - picking data on screen.  Press 'p' or 'P' when the mouse is over
      a point that you need to pick.

    - The widget also uses a light manager to manage the lighting of
      the scene.  Press 'l' or 'L' to activate a GUI configuration
      dialog for the lights.

    - Pressing the left, right, up and down arrow let you rotate the
      camera in those directions.  When shift-arrow is pressed then
      the camera is panned.  Pressing the '+' (or '=')  and '-' keys
      let you zoom in and out.

    - Pressing the 'f' key will set the camera focal point to the
      current point.

    - full screen rendering via the full_screen button on the UI.

    """

    # The version of this class.  Used for persistence.
    __version__ = 0

    ###########################################################################
    # Traits.
    ###########################################################################

    # Turn on full-screen rendering.
    full_screen = Button('Full Screen')

    # The picker handles pick events.
    picker = Instance(picker.Picker)

    ########################################

    # Render_window's view.
    _stereo_view = Group(
        Item(name='stereo_render'),
        Item(name='stereo_type'),
        show_border=True,
        label='Stereo rendering',
    )

    # The default view of this object.
    default_view = View(Group(
        Group(
            Item(name='background'),
            Item(name='foreground'),
            Item(name='parallel_projection'),
            Item(name='disable_render'),
            Item(name='off_screen_rendering'),
            Item(name='jpeg_quality'),
            Item(name='jpeg_progressive'),
            Item(name='magnification'),
            Item(name='anti_aliasing_frames'),
            Item(name='full_screen', show_label=False),
        ),
        Group(
            Item(name='render_window',
                 style='custom',
                 visible_when='object.stereo',
                 editor=InstanceEditor(view=View(_stereo_view)),
                 show_label=False), ),
        label='Scene'),
                        Group(Item(name='light_manager',
                                   style='custom',
                                   show_label=False),
                              label='Lights'),
                        buttons=['OK', 'Cancel'])

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

    _vtk_control = Instance(wxVTKRenderWindowInteractor)
    _fullscreen = Any
    _interacting = Bool

    ###########################################################################
    # 'object' interface.
    ###########################################################################
    def __init__(self, parent=None, **traits):
        """ Initializes the object. """

        # Base class constructor.
        super(Scene, self).__init__(parent, **traits)

        # Setup the default picker.
        self.picker = picker.Picker(self)

    def __get_pure_state__(self):
        """Allows us to pickle the scene."""
        # The control attribute is not picklable since it is a VTK
        # object so we remove it.
        d = super(Scene, self).__get_pure_state__()
        for x in ['_vtk_control', '_fullscreen', '_interacting']:
            d.pop(x, None)
        return d

    ###########################################################################
    # 'Scene' interface.
    ###########################################################################
    def render(self):
        """ Force the scene to be rendered. Nothing is done if the
        `disable_render` trait is set to True."""
        if not self.disable_render:
            self._vtk_control.Render()

    def get_size(self):
        """Return size of the render window."""
        return self._vtk_control.GetSize()

    def set_size(self, size):
        """Set the size of the window."""
        self._vtk_control.SetSize(size)

    def hide_cursor(self):
        """Hide the cursor."""
        self._vtk_control.HideCursor()

    def show_cursor(self):
        """Show the cursor."""
        self._vtk_control.ShowCursor()

    ###########################################################################
    # 'TVTKScene' interface.
    ###########################################################################
    def save_to_clipboard(self):
        """Saves a bitmap of the scene to the clipboard."""
        handler, name = tempfile.mkstemp()
        self.save_bmp(name)
        bmp = wx.Bitmap(name, wx.BITMAP_TYPE_BMP)
        bmpdo = wx.BitmapDataObject(bmp)
        wx.TheClipboard.Open()
        wx.TheClipboard.SetData(bmpdo)
        wx.TheClipboard.Close()
        os.close(handler)
        os.unlink(name)

    ###########################################################################
    # `wxVTKRenderWindowInteractor` interface.
    ###########################################################################
    def OnKeyDown(self, event):
        """This method is overridden to prevent the 's'/'w'/'e'/'q'
        keys from doing the default thing which is generally useless.
        It also handles the 'p' and 'l' keys so the picker and light
        manager are called.
        """
        keycode = event.GetKeyCode()
        modifiers = event.HasModifiers()
        camera = self.camera
        if keycode < 256:
            key = chr(keycode)
            if key == '-':
                camera.zoom(0.8)
                self.render()
                self._record_methods('camera.zoom(0.8)\nrender()')
                return
            if key in ['=', '+']:
                camera.zoom(1.25)
                self.render()
                self._record_methods('camera.zoom(1.25)\nrender()')
                return
            if key.lower() in ['q', 'e'] or keycode == wx.WXK_ESCAPE:
                self._disable_fullscreen()
            if key.lower() in ['w']:
                event.Skip()
                return
            if key.lower() in ['r']:
                self._record_methods('reset_zoom()')
            # Handle picking.
            if key.lower() in ['p']:
                # In wxPython-2.6, there appears to be a bug in
                # EVT_CHAR so that event.GetX() and event.GetY() are
                # not correct.  Therefore the picker is called on
                # KeyUp.
                event.Skip()
                return
            # Camera focal point.
            if key.lower() in ['f']:
                event.Skip()
                return
            # Light configuration.
            if key.lower() in ['l'] and not modifiers:
                self.light_manager.configure()
                return
            if key.lower() in ['s'] and not modifiers:
                parent = self._vtk_control.GetParent()
                fname = popup_save(parent)
                if len(fname) != 0:
                    self.save(fname)
                return

        shift = event.ShiftDown()
        if keycode == wx.WXK_LEFT:
            if shift:
                camera.yaw(-5)
                self._record_methods('camera.yaw(-5)')
            else:
                camera.azimuth(5)
                self._record_methods('camera.azimuth(5)')
            self.render()
            self._record_methods('render()')
            return
        elif keycode == wx.WXK_RIGHT:
            if shift:
                camera.yaw(5)
                self._record_methods('camera.yaw(5)')
            else:
                camera.azimuth(-5)
                self._record_methods('camera.azimuth(-5)')
            self.render()
            self._record_methods('render()')
            return
        elif keycode == wx.WXK_UP:
            if shift:
                camera.pitch(-5)
                self._record_methods('camera.pitch(-5)')
            else:
                camera.elevation(-5)
                self._record_methods('camera.elevation(-5)')
            camera.orthogonalize_view_up()
            self.render()
            self._record_methods('camera.orthogonalize_view_up()\nrender()')
            return
        elif keycode == wx.WXK_DOWN:
            if shift:
                camera.pitch(5)
                self._record_methods('camera.pitch(5)')
            else:
                camera.elevation(5)
                self._record_methods('camera.elevation(5)')
            camera.orthogonalize_view_up()
            self.render()
            self._record_methods('camera.orthogonalize_view_up()\nrender()')
            return

        self._vtk_control.OnKeyDown(event)

        # Skipping the event is not ideal but necessary because we
        # have no way of knowing of the event was really handled or
        # not and not skipping will break any keyboard accelerators.
        # In practice this does not seem to pose serious problems.
        event.Skip()

    def OnKeyUp(self, event):
        """This method is overridden to prevent the 's'/'w'/'e'/'q'
        keys from doing the default thing which is generally useless.
        It also handles the 'p' and 'l' keys so the picker and light
        manager are called.  The 'f' key sets the camera focus.
        """
        keycode = event.GetKeyCode()
        modifiers = event.HasModifiers()
        if keycode < 256:
            key = chr(keycode)
            if key.lower() in ['s', 'w', 'e', 'q']:
                event.Skip()
                return
            # Set camera focal point.
            if key.lower() in ['f']:
                if not modifiers:
                    if sys.platform == 'darwin':
                        x, y = self._interactor.event_position
                    else:
                        x = event.GetX()
                        y = self._vtk_control.GetSize()[1] - event.GetY()
                    data = self.picker.pick_world(x, y)
                    coord = data.coordinate
                    if coord is not None:
                        self.camera.focal_point = coord
                        self.render()
                        self._record_methods('camera.focal_point = %r\n'\
                                             'render()'%list(coord))
                        return
            # Handle picking.
            if key.lower() in ['p']:
                if not modifiers:
                    if sys.platform == 'darwin':
                        x, y = self._interactor.event_position
                    else:
                        x = event.GetX()
                        y = self._vtk_control.GetSize()[1] - event.GetY()
                    self.picker.pick(x, y)
                    return
                else:
                    # This is here to disable VTK's own pick handler
                    # which can get called when you press Alt/Ctrl +
                    # 'p'.
                    event.Skip()
                    return
            # Light configuration.
            if key.lower() in ['l']:
                event.Skip()
                return

        self._vtk_control.OnKeyUp(event)
        event.Skip()

    def OnPaint(self, event):
        """This method is overridden temporarily in order to create
        the light manager.  This is necessary because it makes sense
        to create the light manager only when the widget is realized.
        Only when the widget is realized is the VTK render window
        created and only then are the default lights all setup
        correctly.  This handler is removed on the first Paint event
        and the default paint handler of the
        wxVTKRenderWindowInteractor is used instead."""

        # Call the original handler (this will Show the widget)
        self._vtk_control.OnPaint(event)
        if len(self.renderer.lights) == 0:
            # The renderer is not ready yet, we do not do anything, and
            # we do not remove this callback, so that it will be called
            # later.
            return
        # Now create the light manager.
        self.light_manager = light_manager.LightManager(self)

        renwin = self._renwin
        renwin.update_traits()

        vtk_rw = tvtk.to_vtk(renwin)
        renwin.add_observer('StartEvent', messenger.send)
        messenger.connect(vtk_rw, 'StartEvent', self._start_event_callback)
        renwin.add_observer('EndEvent', messenger.send)
        messenger.connect(vtk_rw, 'EndEvent', self._end_event_callback)

        # Reset the event handler to the default since our job is done.
        wx.EVT_PAINT(self._vtk_control, None)  # Remove the default handler.
        wx.EVT_PAINT(self._vtk_control, self._vtk_control.OnPaint)

    def OnSize(self, event):
        """Overrides the default OnSize in order to refresh the traits
        of the render window."""
        if self._renwin is not None:
            self._vtk_control.OnSize(event)
            self._renwin.update_traits()

    def OnButtonDown(self, event):
        """Overrides the default on button down method.
        """
        self._interacting = True
        self._vtk_control.OnButtonDown(event)

    def OnButtonUp(self, event):
        self._interacting = False
        self._vtk_control.OnButtonUp(event)

    ###########################################################################
    # Non-public interface.
    ###########################################################################
    def _create_control(self, parent):
        """ Create the toolkit-specific control that represents the widget. """

        # Create the VTK widget.
        self._vtk_control = window = wxVTKRenderWindowInteractor(
            parent, -1, stereo=self.stereo)

        # Override these handlers.
        wx.EVT_CHAR(window, None)  # Remove the default handler.
        wx.EVT_CHAR(window, self.OnKeyDown)
        wx.EVT_KEY_UP(window, None)  # Remove the default handler.
        wx.EVT_KEY_UP(window, self.OnKeyUp)
        wx.EVT_PAINT(window, None)  # Remove the default handler.
        wx.EVT_PAINT(window, self.OnPaint)
        wx.EVT_SIZE(window, None)  # Remove the default handler.
        wx.EVT_SIZE(window, self.OnSize)
        # Override the button down and up handlers as well to note the
        # interaction.  This is to toggle the busy status nicely.
        for evt in (wx.EVT_LEFT_DOWN, wx.EVT_RIGHT_DOWN, wx.EVT_MIDDLE_DOWN):
            evt(window, None)
            evt(window, self.OnButtonDown)
        for evt in (wx.EVT_LEFT_UP, wx.EVT_RIGHT_UP, wx.EVT_MIDDLE_UP):
            evt(window, None)
            evt(window, self.OnButtonUp)

        # Enable the widget.
        window.Enable(1)
        # Switch the default interaction style to the trackball one.
        window.GetInteractorStyle().SetCurrentStyleToTrackballCamera()

        # Grab the renderwindow.
        renwin = self._renwin = tvtk.to_tvtk(window.GetRenderWindow())
        renwin.set(point_smoothing=self.point_smoothing,
                   line_smoothing=self.line_smoothing,
                   polygon_smoothing=self.polygon_smoothing)
        # Create a renderer and add it to the renderwindow
        self._renderer = tvtk.Renderer()
        renwin.add_renderer(self._renderer)
        # Save a reference to our camera so it is not GC'd -- needed for
        # the sync_traits to work.
        self._camera = self.camera

        # Sync various traits.
        self._renderer.background = self.background
        self.sync_trait('background', self._renderer)
        self.renderer.on_trait_change(self.render, 'background')
        self._camera.parallel_projection = self.parallel_projection
        self.sync_trait('parallel_projection', self._camera)
        renwin.off_screen_rendering = self.off_screen_rendering
        self.sync_trait('off_screen_rendering', self._renwin)
        self.render_window.on_trait_change(self.render, 'off_screen_rendering')
        self.render_window.on_trait_change(self.render, 'stereo_render')
        self.render_window.on_trait_change(self.render, 'stereo_type')
        self.camera.on_trait_change(self.render, 'parallel_projection')

        def _show_parent_hack(window, parent):
            """A hack to get the VTK scene properly setup for use."""
            # Force the parent to show itself.
            parent.Show(1)
            # on some platforms, this SetSize() is necessary to cause
            # an OnPaint() when the event loop begins; else we get an
            # empty window until we force a redraw.
            window.SetSize(parent.GetSize())
            # This is necessary on slow machines in order to force the
            # wx events to be handled.
            wx.GetApp().Yield(True)
            window.Render()

        if wx.Platform == '__WXMSW__':
            _show_parent_hack(window, parent)
        else:
            if (wx.VERSION[0] == 2) and (wx.VERSION[1] < 5):
                _show_parent_hack(window, parent)
            window.Update()

        # Because of the way the VTK widget is setup, and because we
        # set the size above, the window sizing is usually completely
        # messed up when the application window is shown.  To work
        # around this a dynamic IDLE event handler is added and
        # immediately removed once it executes.  This event handler
        # simply forces a resize to occur.  The _idle_count allows us
        # to execute the idle function a few times (this seems to work
        # better).
        def _do_idle(event, window=window):
            w = wx.GetTopLevelParent(window)
            # Force a resize
            sz = w.GetSize()
            w.SetSize((sz[0] - 1, sz[1] - 1))
            w.SetSize(sz)
            window._idle_count -= 1
            if window._idle_count < 1:
                wx.EVT_IDLE(window, None)
                del window._idle_count

        window._idle_count = 2
        wx.EVT_IDLE(window, _do_idle)

        self._interactor = tvtk.to_tvtk(window._Iren)
        return window

    def _lift(self):
        """Lift the window to the top. Useful when saving screen to an
        image."""
        if self.render_window.off_screen_rendering:
            # Do nothing if off screen rendering is being used.
            return

        w = self._vtk_control
        while w and not w.IsTopLevel():
            w = w.GetParent()
        if w:
            w.Raise()
            wx.GetApp().Yield(True)
            self.render()

    def _start_event_callback(self, obj, event):
        if self._interacting:
            return
        else:
            self.busy = True

    def _end_event_callback(self, obj, event):
        if self._interacting:
            return
        else:
            self.busy = False

    def _busy_changed(self, val):
        GUI.set_busy(val)

    def _full_screen_fired(self):
        fs = self._fullscreen
        if isinstance(fs, PopupScene):
            fs.close()
            self._fullscreen = None
        elif fs is None:
            ver = tvtk.Version()
            popup = False
            if wx.Platform == '__WXMSW__':
                popup = True
            elif ver.vtk_major_version > 5:
                popup = True
            elif (ver.vtk_major_version == 5) and \
                 ((ver.vtk_minor_version >= 1) or \
                  (ver.vtk_build_version > 2)):
                popup = True
            if popup:
                # There is a bug with earlier versions of VTK that
                # breaks reparenting a window which is why we test for
                # the version above.
                f = PopupScene(self)
                self._fullscreen = f
                f.fullscreen()
            else:
                f = FullScreen(self)
                f.run()  # This will block.
                self._fullscreen = None

    def _disable_fullscreen(self):
        fs = self._fullscreen
        if isinstance(fs, PopupScene):
            fs.close()
            self._fullscreen = None
コード例 #15
0
class InPaintDemo(HasTraits):
    plot = Instance(Plot)
    painter = Instance(CirclePainter)
    r = Range(2.0, 20.0, 10.0)  # inpaint的半径参数
    method = Enum("INPAINT_NS", "INPAINT_TELEA")  # inpaint的算法
    show_mask = Bool(False)  # 是否显示选区
    clear_mask = Button("清除选区")
    apply = Button("保存结果")

    view = View(VGroup(
        VGroup(
            Item("object.painter.r", label="画笔半径"), Item("r",
                                                         label="inpaint半径"),
            HGroup(
                Item("method", label="inpaint算法"),
                Item("show_mask", label="显示选区"),
                Item("clear_mask", show_label=False),
                Item("apply", show_label=False),
            )),
        Item("plot", editor=ComponentEditor(), show_label=False),
    ),
                title="inpaint Demo控制面板",
                width=500,
                height=450,
                resizable=True)

    def __init__(self, *args, **kwargs):
        super(InPaintDemo, self).__init__(*args, **kwargs)
        self.img = cv.imread("stuff.jpg")  # 原始图像
        self.img2 = self.img.clone()  # inpaint效果预览图像
        self.mask = cv.Mat(self.img.size(), cv.CV_8UC1)  # 储存选区的图像
        self.mask[:] = 0
        self.data = ArrayPlotData(img=self.img[:, :, ::-1])
        self.plot = Plot(self.data,
                         padding=10,
                         aspect_ratio=float(self.img.size().width) /
                         self.img.size().height)
        self.plot.x_axis.visible = False
        self.plot.y_axis.visible = False
        imgplot = self.plot.img_plot("img", origin="top left")[0]
        self.painter = CirclePainter(component=imgplot)
        imgplot.overlays.append(self.painter)

    @on_trait_change("r,method")
    def inpaint(self):
        cv.inpaint(self.img, self.mask, self.img2, self.r,
                   getattr(cv, self.method))
        self.draw()

    @on_trait_change("painter:updated")
    def painter_updated(self):
        for _, _, x, y in self.painter.track:
            # 在储存选区的mask上绘制圆形
            cv.circle(self.mask,
                      cv.Point(int(x), int(y)),
                      int(self.painter.r),
                      cv.Scalar(255, 255, 255, 255),
                      thickness=-1)  # 宽度为负表示填充圆形
        self.inpaint()
        self.painter.track = []
        self.painter.request_redraw()

    def _clear_mask_fired(self):
        self.mask[:] = 0
        self.inpaint()

    def _apply_fired(self):
        """保存inpaint的处理结果,并清除选区"""
        self.img[:] = self.img2[:]
        self._clear_mask_fired()

    @on_trait_change("show_mask")
    def draw(self):
        if self.show_mask:
            data = self.img[:, :, ::-1].copy()
            data[self.mask[:] > 0] = 255
            self.data["img"] = data
        else:
            self.data["img"] = self.img2[:, :, ::-1]
コード例 #16
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)
コード例 #17
0
ファイル: cursor_tool.py プロジェクト: raj347/iocbio
class IocbioCursorTool2D(CursorTool2D):

    # Allow using subclasses of CircleMarker:
    marker = Instance(CircleMarker, ())
    invisible_layout = None
コード例 #18
0
ファイル: node_tree.py プロジェクト: sjl421/code-2
class NodeTree(Tree):
    """ A tree control with extensible node types. """

    #### 'Tree' interface #####################################################

    # The model that provides the data for the tree.
    model = Instance(NodeTreeModel, ())

    #### 'NodeTree' interface #################################################

    # The node manager looks after all node types.
    node_manager = Property(Instance(NodeManager))

    # The node types in the tree.
    node_types = Property(List(NodeType))

    ###########################################################################
    # 'NodeTree' interface.
    ###########################################################################

    #### Properties ###########################################################

    # node_manager
    def _get_node_manager(self):
        """ Returns the root node of the tree. """

        return self.model.node_manager

    def _set_node_manager(self, node_manager):
        """ Sets the root node of the tree. """

        self.model.node_manager = node_manager

        return

    # node_types
    def _get_node_types(self):
        """ Returns the node types in the tree. """

        return self.model.node_manager.node_types

    def _set_node_types(self, node_types):
        """ Sets the node types in the tree. """

        self.model.node_manager.node_types = node_types

        return

    ###########################################################################
    # 'Tree' interface.
    ###########################################################################

    #### Trait event handlers #################################################

    def _node_activated_changed(self, obj):
        """ Called when a node has been activated (i.e., double-clicked). """

        default_action = self.model.get_default_action(obj)
        if default_action is not None:
            self._perform_default_action(default_action, obj)

        return

    def _node_right_clicked_changed(self, (obj, point)):
        """ Called when the right mouse button is clicked on the tree. """

        # Add the node that the right-click occurred on to the selection.
        self.select(obj)

        # fixme: This is a hack to allow us to attach the node that the
        # right-clicked occurred on to the action event.
        self._context = obj

        # Ask the model for the node's context menu.
        menu_manager = self.model.get_context_menu(obj)
        if menu_manager is not None:
            self._popup_menu(menu_manager, obj, point)

        return
コード例 #19
0
ファイル: exception_handler.py プロジェクト: sjl421/code-2
class ExceptionHandler(HasTraits):
    """ Provides standardized exception handling.

    Instantiate immediately after 'except:' to capture the exception and
    stack frame information.
    """

    # Application message.
    message = Str

    # Initialized form rom sys.exc_info on object creation.
    ex_type = Instance(EXCEPTION_BASE_TYPE)

    # Initialized form rom sys.exc_info on object creation.
    ex_value = Any # Instance(Exception)

    # Initialized form rom sys.exc_info on object creation.
    ex_traceback = Instance(types.TracebackType)

    # Formatted text for the exception.
    exception_text = Str

    # Formatted text for the exception only. I.e. without stack trace.
    exception_only_text = Str

    # Enter message in the log using enthought.logger; default is True.
    use_logger = Bool(True)

    def __init__(self, **traits):
        """ Creates an ExceptionHandler initialized with the most recent
        traceback information.
        Optionally logs the exception using enthought.logger.
        """
        super(ExceptionHandler,self).__init__(**traits)
        self.ex_type, self.ex_value, self.ex_traceback = sys.exc_info()
        if self.use_logger:
            logger.error( str(self) )
        return

    def __str__(self):
        """ Returns string representation of self. """
        text = self.message + '\n' + self.exception_text
        return text

    def _exception_text_default(self):
        """ Returns formatted exception. """
        list_o_lines = traceback.format_exception( self.ex_type,
                                                   self.ex_value,
                                                   self.ex_traceback)

        lines = ''.join(list_o_lines)

        # remove trailing \n
        return lines.strip()


    def _exception_only_text_default(self):
        """ Returns formatted exception only (see traceback).
        I.e. without stack trace.
        """
        list_o_lines = traceback.format_exception_only( self.ex_type,
                                                        self.ex_value)

        lines = ''.join(list_o_lines)

        # remove trailing \n
        return lines.strip()

    def trait_view(self, name=None, view_element=None):
        """ Returns a View """
        if (name or view_element) != None:
            return super(ExceptionHandler, self).trait_view( name=name,
                                                view_element=view_element )

        from exception_handler_view import ExceptionHandlerView
        return ExceptionHandlerView()
コード例 #20
0
ファイル: tree_viewer.py プロジェクト: sjl421/code-2
class TreeViewer(ContentViewer):
    """ A viewer based on a tree control. """

    # The default tree style.
    STYLE = wx.TR_EDIT_LABELS | wx.TR_HAS_BUTTONS | wx.CLIP_CHILDREN
    
    #### 'TreeViewer' interface ###############################################
    
    # The content provider provides the actual tree data.
    content_provider = Instance(TreeContentProvider)

    # The label provider provides, err, the labels for the items in the tree
    # (a label can have text and/or an image).
    label_provider = Instance(TreeLabelProvider, ())

    # Selection mode (must be either of 'single' or 'extended').
    selection_mode = Enum('single', 'extended')
    
    # The currently selected elements.
    selection = List

    # Should an image be shown for each element?
    show_images = Bool(True)
    
    # Should the root of the tree be shown?
    show_root = Bool(True)

    #### Events ####
    
    # An element has been activated (ie. double-clicked).
    element_activated = Event

    # A drag operation was started on an element.
    element_begin_drag = Event

    # An element that has children has been collapsed.
    element_collapsed = Event
        
    # An element that has children has been expanded.
    element_expanded = Event

    # A left-click occurred on an element.
    element_left_clicked = Event

    # A right-click occurred on an element.
    element_right_clicked = Event

    # A key was pressed while the tree is in focus.
    key_pressed = Event

    ###########################################################################
    # 'object' interface.
    ###########################################################################

    def __init__(self, parent, image_size=(16, 16), **traits):
        """ Creates a new tree viewer.

	'parent' is the toolkit-specific control that is the tree's parent.

        'image_size' is a tuple in the form (int width, int height) that
        specifies the size of the label images (if any) displayed in the tree.

        """

        # Base class constructor.
        super(TreeViewer, self).__init__(**traits)

        # Create the toolkit-specific control.
        self.control = tree = wx.TreeCtrl(parent, -1, style=self._get_style())
        
        # Get our actual Id.
        wxid = tree.GetId()
        
        # Wire up the wx tree events.
        wx.EVT_CHAR(tree, self._on_char)
        wx.EVT_LEFT_DOWN(tree, self._on_left_down)
        wx.EVT_RIGHT_DOWN(tree, self._on_right_down)
        wx.EVT_TREE_ITEM_ACTIVATED(tree, wxid, self._on_tree_item_activated)
        wx.EVT_TREE_ITEM_COLLAPSED(tree, wxid, self._on_tree_item_collapsed)
        wx.EVT_TREE_ITEM_COLLAPSING(tree, wxid, self._on_tree_item_collapsing)
        wx.EVT_TREE_ITEM_EXPANDED(tree, wxid, self._on_tree_item_expanded)
        wx.EVT_TREE_ITEM_EXPANDING(tree, wxid, self._on_tree_item_expanding)
        wx.EVT_TREE_BEGIN_LABEL_EDIT(tree, wxid,self._on_tree_begin_label_edit)
        wx.EVT_TREE_END_LABEL_EDIT(tree, wxid, self._on_tree_end_label_edit)
        wx.EVT_TREE_BEGIN_DRAG(tree, wxid, self._on_tree_begin_drag)
        wx.EVT_TREE_SEL_CHANGED(tree, wxid, self._on_tree_sel_changed)

        # The image list is a wxPython-ism that caches all images used in the
        # control.
        self._image_list = ImageList(image_size[0], image_size[1])
        if self.show_images:
            tree.AssignImageList(self._image_list)

        # Mapping from element to wx tree item Ids.
        self._element_to_id_map = {}

        # Add the root item.
        if self.input is not None:
            self._add_element(None, self.input)
        
        return

    ###########################################################################
    # 'TreeViewer' interface. 
    ###########################################################################

    def is_expanded(self, element):
        """ Returns True if the element is expanded, otherwise False. """

        key = self._get_key(element)
        
        if key in self._element_to_id_map:
            is_expanded = self.control.IsExpanded(self._element_to_id_map[key])

        else:
            is_expanded = False

        return is_expanded

    def is_selected(self, element):
        """ Returns True if the element is selected, otherwise False. """

        key = self._get_key(element)

        if key in self._element_to_id_map:
            is_selected = self.control.IsSelected(self._element_to_id_map[key])

        else:
            is_selected = False
        
        return is_selected
    
    def refresh(self, element):
        """ Refresh the tree starting from the specified element.

        Call this when the STRUCTURE of the content has changed.

        """

        # Has the element actually appeared in the tree yet?
        pid = self._element_to_id_map.get(self._get_key(element), None)
        if pid is not None:
            # The item data is a tuple.  The first element indicates whether or
            # not we have already populated the item with its children.  The
            # second element is the actual item data.
            populated, element = self.control.GetPyData(pid)

            # fixme: We should find a cleaner way other than deleting all of
            # the element's children and re-adding them!
            self._delete_children(pid)
            self.control.SetPyData(pid, (False, element))

            # Does the element have any children?
            has_children = self.content_provider.has_children(element)
            self.control.SetItemHasChildren(pid, has_children)

            # Expand it.
            self.control.Expand(pid)

        else:
            print '**** pid is None!!! ****'

        return

    def update(self, element):
        """ Update the tree starting from the specified element.

        Call this when the APPEARANCE of the content has changed.

        """
        
        pid = self._element_to_id_map.get(self._get_key(element), None)
        if pid is not None:
            self._refresh_element(pid, element)

            for child in self.content_provider.get_children(element):
                cid = self._element_to_id_map.get(self._get_key(child), None)
                if cid is not None:
                    self._refresh_element(cid, child)

        return
    
    ###########################################################################
    # Private interface. 
    ###########################################################################

    def _get_style(self):
        """ Returns the wx style flags for creating the tree control. """

        # Start with the default flags.
        style = self.STYLE

        if not self.show_root:
            style = style | wx.TR_HIDE_ROOT | wx.TR_LINES_AT_ROOT

        if self.selection_mode != 'single':
            style = style | wx.TR_MULTIPLE | wx.TR_EXTENDED

        return style
    
    def _add_element(self, pid, element):
        """ Adds 'element' as a child of the element identified by 'pid'.

        If 'pid' is None then we are adding the root element.

        """

        # Get the tree item image index and text.
        image_index = self._get_image_index(element)
        text = self._get_text(element)

        # Add the element.
        if pid is None:
            wxid = self.control.AddRoot(text, image_index, image_index)

        else:
            wxid = self.control.AppendItem(pid, text, image_index, image_index)

        # If we are adding the root element but the root is hidden, get its
        # children.
        if pid is None and not self.show_root:
            children = self.content_provider.get_children(element)
            for child in children:
                self._add_element(wxid, child)

        # Does the element have any children?
        has_children = self.content_provider.has_children(element)
        self.control.SetItemHasChildren(wxid, has_children)

        # The item data is a tuple. The first element indicates whether or not
        # we have already populated the item with its children. The second
        # element is the actual item data.
        if pid is None:
            if self.show_root:
                self.control.SetPyData(wxid,  (False, element))

        else:
            self.control.SetPyData(wxid,  (False, element))
            
        # Make sure that we can find the element's Id later.
        self._element_to_id_map[self._get_key(element)] = wxid
        
        # If we are adding the root item then automatically expand it.
        if pid is None and self.show_root:
            self.control.Expand(wxid)
        
        return

    def _get_image_index(self, element):
        """ Returns the tree item image index for an element. """

        # Get the image used to represent the element.
        image = self.label_provider.get_image(self, element)
        if image is not None:
            image_index = self._image_list.GetIndex(image.absolute_path)

        else:
            image_index = -1

        return image_index

    def _get_key(self, element):
        """ Generate the key for the element to id map. """

        try:
            key = hash(element)

        except:
            key = id(element)
        
        return key
    
    def _get_text(self, element):
        """ Returns the tree item text for an element. """

        text = self.label_provider.get_text(self, element)
        if text is None:
            text = ''

        return text

    def _refresh_element(self, wxid, element):
        """ Refreshes the image and text of the specified element. """

        # Get the tree item image index.
        image_index = self._get_image_index(element)
        self.control.SetItemImage(wxid, image_index, wx.TreeItemIcon_Normal)
        self.control.SetItemImage(wxid, image_index, wx.TreeItemIcon_Selected)

        # Get the tree item text.
        text = self._get_text(element)
        self.control.SetItemText(wxid, text)

        # Does the item have any children?
        has_children = self.content_provider.has_children(element)
        self.control.SetItemHasChildren(wxid, has_children)

        return

    def _unpack_event(self, event):
        """ Unpacks the event to see whether a tree element was involved. """
        
        try:
            point = event.GetPosition()

        except:
            point = event.GetPoint()

        wxid, flags = self.control.HitTest(point)
        
        # Warning: On GTK we have to check the flags before we call 'GetPyData'
        # because if we call it when the hit test returns 'nowhere' it will
        # barf (on Windows it simply returns 'None' 8^()
        if flags & wx.TREE_HITTEST_NOWHERE:
            data = None
            
        else:
            data = self.control.GetPyData(wxid)
            
        return data, wxid, flags, point
  
    def _get_selection(self):
        """ Returns a list of the selected elements. """

        elements = []
        for wxid in self.control.GetSelections():
            data = self.control.GetPyData(wxid)
            if data is not None:
                populated, element = data
                elements.append(element)

            # 'data' can be None here if (for example) the element has been
            # deleted.
            #
            # fixme: Can we stop this happening?!?!?
            else:
                pass
                
        return elements

    def _delete_children(self, pid):
        """ Recursively deletes the children of the specified element. """

        cookie = 0
        
        (cid, cookie) = self.control.GetFirstChild(pid, cookie)
        while cid.IsOk():
            # Recursively delete the child's children.
            self._delete_children(cid)

            # Remove the reference to the item's data.
            populated, element = self.control.GetPyData(cid)
            del self._element_to_id_map[self._get_key(element)]
            self.control.SetPyData(cid, None)

            # Next!
            (cid, cookie) = self.control.GetNextChild(pid, cookie)

        self.control.DeleteChildren(pid)
        
        return
        
    #### Trait event handlers #################################################

    def _input_changed(self):
        """ Called when the tree's input has been changed. """

        # Delete everything...
        if self.control is not None:
            self.control.DeleteAllItems()

            self._element_to_id_map = {}

            # ... and then add the root item back in.
            if self.input is not None:
                self._add_element(None, self.input)

        return

    def _element_begin_drag_changed(self, element):
        """ Called when a drag is started on a element. """

        # We ask the label provider for the actual value to drag.
        drag_value = self.label_provider.get_drag_value(self, element)
        
        # Start the drag.
        PythonDropSource(self.control, drag_value)

        return

    #### wx event handlers ####################################################

    def _on_right_down(self, event):
        """ Called when the right mouse button is clicked on the tree. """

        data, id, flags, point = self._unpack_event(event)
        
        # Did the right click occur on a tree item?
        if data is not None:
            populated, element = data

            # Trait notification.
            self.element_right_clicked = (element, point)

        # Give other event handlers a chance.
        event.Skip()

        return

    def _on_left_down(self, event):
        """ Called when the left mouse button is clicked on the tree. """

        data, wxid, flags, point = self._unpack_event(event)

        # Save point for tree_begin_drag method to workaround a bug in ?? when
        # wx.TreeEvent.GetPoint returns only (0,0).  This happens under linux
        # when using wx-2.4.2.4, for instance.
        self._point_left_clicked = point

        # Did the left click occur on a tree item?
        if data is not None:
            populated, element = data

            # Trait notification.
            self.element_left_clicked = (element, point)

        # Give other event handlers a chance.
        event.Skip()

        return

    def _on_tree_item_expanding(self, event):
        """ Called when a tree item is about to expand. """

        # Which item is expanding?
        wxid = event.GetItem()

        # The item data is a tuple. The first element indicates whether or not
        # we have already populated the item with its children.  The second
        # element is the actual item data.
        populated, element = self.control.GetPyData(wxid)

        # Give the label provider a chance to veto the expansion.
        if self.label_provider.is_expandable(self, element):
            # Lazily populate the item's children.
            if not populated:
                children = self.content_provider.get_children(element)

                # Sorting...
                if self.sorter is not None:
                    self.sorter.sort(self, element, children)

                # Filtering....
                for child in children:
                    for filter in self.filters:
                        if not filter.select(self, element, child):
                            break

                    else:
                        self._add_element(wxid, child)

                # The element is now populated!
                self.control.SetPyData(wxid, (True, element))

        else:
            event.Veto()
            
        return

    def _on_tree_item_expanded(self, event):
        """ Called when a tree item has been expanded. """

        # Which item was expanded?
        wxid = event.GetItem()

        # The item data is a tuple.  The first element indicates whether or not
        # we have already populated the item with its children.  The second
        # element is the actual item data.
        populated, element = self.control.GetPyData(wxid)
        
        # Make sure that the element's 'open' icon is displayed etc.
        self._refresh_element(wxid, element)

        # Trait notification.
        self.element_expanded = element
        
        return

    def _on_tree_item_collapsing(self, event):
        """ Called when a tree item is about to collapse. """

        # Which item is collapsing?
        wxid = event.GetItem()

        # The item data is a tuple.  The first element indicates whether or not
        # we have already populated the item with its children.  The second
        # element is the actual item data.
        populated, element = self.control.GetPyData(wxid)

        # Give the label provider a chance to veto the collapse.
        if not self.label_provider.is_collapsible(self, element):
            event.Veto()
        
        return

    def _on_tree_item_collapsed(self, event):
        """ Called when a tree item has been collapsed. """

        # Which item was collapsed?
        wxid = event.GetItem()

        # The item data is a tuple.  The first element indicates whether or not
        # we have already populated the item with its children.  The second
        # element is the actual item data.
        populated, element = self.control.GetPyData(wxid)

        # Make sure that the element's 'closed' icon is displayed etc.
        self._refresh_element(wxid, element)

        # Trait notification.
        self.element_collapsed = element
        
        return

    def _on_tree_item_activated(self, event):
        """ Called when a tree item is activated (i.e., double clicked). """

        # Which item was activated?
        wxid = event.GetItem()

        # The item data is a tuple.  The first element indicates whether or not
        # we have already populated the item with its children.  The second
        # element is the actual item data.
        populated, element = self.control.GetPyData(wxid)

        # Trait notification.
        self.element_activated = element

        return

    def _on_tree_sel_changed(self, event):
        """ Called when the selection is changed. """

        # Trait notification.
        self.selection = self._get_selection()

        return
        
    def _on_tree_begin_drag(self, event):
        """ Called when a drag operation is starting on a tree item. """

        # Get the element, its id and the point where the event occurred.
        data, wxid, flags, point = self._unpack_event(event)

        if point == (0,0):
            # Apply workaround.
            point = self._point_left_clicked
            wxid, flags = self.control.HitTest(point)
            data = self.control.GetPyData(wxid)

        if data is not None:
            populated, element = data

            # Trait notification.
            self.element_begin_drag = element
            
        return

    def _on_tree_begin_label_edit(self, event):
        """ Called when the user has started editing an item's label. """

        wxid = event.GetItem()
        
        # The item data is a tuple.  The first element indicates whether or not
        # we have already populated the item with its children.  The second
        # element is the actual item data.
        populated, element = self.control.GetPyData(wxid)

        # Give the label provider a chance to veto the edit.
        if not self.label_provider.is_editable(self, element):
            event.Veto()
            
        return

    def _on_tree_end_label_edit(self, event):
        """ Called when the user has finished editing an item's label. """

        wxid = event.GetItem()
        
        # The item data is a tuple.  The first element indicates whether or not
        # we have already populated the item with its children. The second
        # element is the actual item data.
        populated, element = self.control.GetPyData(wxid)

        # Give the label provider a chance to veto the edit.
        label = event.GetLabel()
        if not self.label_provider.set_text(self, element, label):
            event.Veto()

        return

    def _on_char(self, event):
        """ Called when a key is pressed when the tree has focus. """

        # Trait notification.
        self.key_pressed = event.GetKeyCode()

        return
コード例 #21
0
class RunConfig(HasTraits):
    runcase = Instance(RunCase)
    runcase_config = Instance(RunOptionsConfig)

    def _runcase_config_default(self):
        return AdvCaseConfig(runcase=self.runcase)

    runtype = Trait('advanced', {'trim flight': 'c', 'advanced': 'm'})
    calc_eigenmodes = Bool(True)

    def _runtype_changed(self, name, old, new):
        if self.runtype_ == 'm':
            self.runcase_config = AdvCaseConfig(runcase=self.runcase)
        else:
            if isinstance(self.runcase_config, TrimCaseConfig):
                self.runcase_config.trimcase.type = new
            else:
                trimcase = TrimCase(runcase=self.runcase)
                trimcase.update_parameters_from_avl()
                self.runcase_config = TrimCaseConfig(runcase=self.runcase,
                                                     trimcase=trimcase)

    run_button = Button(label='Run Calculation')
    view = View(
        Item(label='Note: Case *must* be saved before running'),
        Item('runtype'),
        Group(
            Item('runcase_config',
                 editor=InstanceEditor(),
                 style='custom',
                 show_label=False)),
        #HGroup(Item('calc_eigenmodes')),
        #spring, Item('run_button', show_label=False)),
        buttons=['OK', 'Cancel'],
        resizable=True)

    def get_constraints(self):
        consts, vars = {}, {}
        for cc in self.runcase_config.constraint_config:
            cmd = '%s %s {0}' % (cc.constraint.cmd,
                                 self.runcase.constraint_variables[
                                     cc.constraint.constraint_name].cmd)
            if 'x' in cc.expr_.co_names:
                vars[cmd] = cc.expr_
            else:
                consts[cmd] = cc.expr_
        return consts, vars

    def get_parameters(self):
        consts, vars = {}, {}
        if self.runtype_ == 'm':
            type = 'm'
            for pc in self.runcase_config.parameter_config:
                cmd = '%s {0}' % pc.parameter.cmd
                if 'x' in pc.expr_.co_names:
                    vars[cmd] = pc.expr_
                else:
                    consts[cmd] = pc.expr_
        else:
            type = self.runcase_config.trimcase.type_  # type of parameter, cmd to be set in oper menu to set the parameter
            vpn = self.runcase_config.varying_param  # varying parameter name
            for n, p in self.runcase_config.trimcase.parameters.iteritems(
            ):  # name, parameter
                if n != vpn:
                    consts['%s {0}' % p.cmd] = compile(str(p.value),
                                                       '<string>', 'eval')
            vp = self.runcase_config.trimcase.parameters[vpn]
            vars['%s {0}' % vp.cmd] = self.runcase_config.varying_expr_
        return type, consts, vars

    @on_trait_change('run_button')
    def run(self, progressbar=True):
        consts_c, vars_c = self.get_constraints()
        type_p, consts_p, vars_p = self.get_parameters()
        # confirm that we are in good state
        avl = self.runcase.avl
        avl.sendline()
        avl.expect(AVL.patterns['/'])
        avl.sendline('oper')
        avl.expect(AVL.patterns['/oper'])
        # first set the constants once and for all
        # constraints
        for c, v in consts_c.iteritems():
            avl.sendline(c.format(eval(v)))
        # paramters
        avl.sendline(type_p)
        for p, v in consts_p.iteritems():
            avl.sendline(p.format(eval(v)))
        avl.sendline()
        avl.sendline()
        avl.expect(AVL.patterns['/'])

        outs, modes, matrices = [], [], []
        # now run the case and get output while changing the vars each time
        if progressbar:
            progress = ProgressDialog(title="progress",
                                      message="calculating...",
                                      max=self.runcase_config.x.shape[0],
                                      show_time=True,
                                      can_cancel=True)
            try:
                progress.open()
            except Exception, e:
                logger.warning(e)
        #print 'x[] = ', self.runcase_config.x
        for i, x in enumerate(self.runcase_config.x):
            # set the variables
            avl.sendline('oper')
            avl.expect(AVL.patterns['/oper'])
            # constraints
            logger.info('running case %d for x=%f' % (i + 1, x))
            for c, v in vars_c.iteritems():
                avl.sendline(c.format(eval(v)))
            # paramters
            avl.sendline(type_p)
            for p, v in vars_p.iteritems():
                avl.sendline(p.format(eval(v)))
            avl.sendline()

            # go back to home state
            avl.sendline()
            avl.expect(AVL.patterns['/'])
            # get the output
            try:
                outs.append(self.runcase.get_run_output())

                if self.calc_eigenmodes:
                    modes.append(self.runcase.get_modes())
                    matrices.append(self.runcase.get_system_matrix())

            except AttributeError, e:
                logger.warning(e)
            if progressbar:
                try:
                    cont, skip = progress.update(i + 1)
                    if not cont or skip:
                        break
                    pass
                except Exception, e:
                    logger.warning(e)
コード例 #22
0
ファイル: i_script_manager.py プロジェクト: sjl421/code-2
class IScriptManager(Interface):
    """ The script manager interface.  A script manager is responsible for the
    recording of appropriately annotated user actions as scripts that can be
    executed without user intervention at a later time.  Typically an
    application would have a single script manager.
    """

    #### 'IScriptManager' interface ###########################################

    # This event is fired whenever a scriptable object is bound or unbound.  It
    # is intended to be used by an interactive Python shell to give the
    # advanced user access to the scriptable objects.  If an object is created
    # via a factory then the event is fired when the factory is called, and not
    # when the factory is bound.
    bind_event = Event(IBindEvent)

    # This is set if user actions are being recorded as a script.  It is
    # maintained by the script manager.
    recording = Bool(False)

    # This is the text of the script currently being recorded (or the last
    # recorded script if none is currently being recorded).  It is updated
    # automatically as the user performs actions.
    script = Unicode

    # This event is fired when the recorded script changes.  The value of the
    # event will be the ScriptManager instance.
    script_updated = Event(
        Instance('enthought.appscripting.api.IScriptManager'))

    ###########################################################################
    # 'IScriptManager' interface.
    ###########################################################################

    def bind(self,
             obj,
             name=None,
             bind_policy='unique',
             api=None,
             includes=None,
             excludes=None):
        """ Bind obj to name and make (by default) its public methods and
        traits (ie. those not beginning with an underscore) scriptable.  The
        default value of name is the type of obj with the first character
        forced to lower case.

        bind_policy determines what happens if the name is already bound.  If
        the policy is 'auto' then a numerical suffix will be added to the name,
        if necessary, to make it unique.  If the policy is 'unique' then an
        exception is raised.  If the policy is 'rebind' then the previous
        binding is discarded.  The default is 'unique'

        If api is given then it is a class, or a list of classes, that define
        the attributes that will be made scriptable.

        Otherwise if includes is given it is a list of names of attributes that
        will be made scriptable.

        Otherwise all the public attributes of scripted_type will be made
        scriptable except those in the excludes list.
        """

    def bind_factory(self,
                     factory,
                     name,
                     bind_policy='unique',
                     api=None,
                     includes=None,
                     excludes=None):
        """ Bind factory to name.  This does the same as the bind() method
        except that it uses a factory that will be called later on to create
        the object only if the object is needed.

        See the documentation for bind() for a description of the remaining
        arguments.
        """

    def run(self, script):
        """ Run the given script, either a string or a file-like object.
        """

    def run_file(self, file_name):
        """ Run the given script file.
        """

    def start_recording(self):
        """ Start the recording of user actions.  The 'script' trait is cleared
        and all subsequent actions are added to 'script'.  The 'recording'
        trait is updated appropriately.
        """

    def stop_recording(self):
        """ Stop the recording of user actions.  The 'recording' trait is
コード例 #23
0
class PolyDataReader(FileDataSource):
    """A PolyData file reader. The reader supports all the
    different types of poly data files.
    """

    # The version of this class.  Used for persistence.
    __version__ = 0

    # The PolyData file reader
    reader = Instance(tvtk.Object, allow_none=False, record=True)

    ######################################################################
    # Private Traits
    _reader_dict = Dict(Str, Instance(tvtk.Object))

    # Our View.
    view = View(Group(Include('time_step_group'),
                      Item(name='base_file_name'),
                      Item(name='reader', style='custom', resizable=True),
                      show_labels=False),
                resizable=True)

    #output_info = PipelineInfo(datasets=['none'])
    output_info = PipelineInfo(datasets=['poly_data'],
                               attribute_types=['any'],
                               attributes=['any'])

    ######################################################################
    # `object` interface
    ######################################################################
    def __set_pure_state__(self, state):
        # The reader has its own file_name which needs to be fixed.
        state.reader.file_name = state.file_path.abs_pth
        # Now call the parent class to setup everything.
        super(PolyDataReader, self).__set_pure_state__(state)

    ######################################################################
    # `FileDataSource` interface
    ######################################################################
    def update(self):
        self.reader.update()
        if len(self.file_path.get()) == 0:
            return
        self.render()

    ######################################################################
    # Non-public interface
    ######################################################################
    def _file_path_changed(self, fpath):
        value = fpath.get()
        if len(value) == 0:
            return

        # Extract the file extension
        splitname = value.strip().split('.')
        extension = splitname[-1].lower()
        # Select polydata reader based on file type
        old_reader = self.reader
        if self._reader_dict.has_key(extension):
            self.reader = self._reader_dict[extension]
        else:
            error('Invalid extension for file: %s' % value)
            return

        self.reader.file_name = value.strip()
        self.reader.update()
        self.reader.update_information()

        if old_reader is not None:
            old_reader.on_trait_change(self.render, remove=True)
        self.reader.on_trait_change(self.render)

        old_outputs = self.outputs
        self.outputs = [self.reader.output]
        if self.outputs == old_outputs:
            self.data_changed = True

        # Change our name on the tree view
        self.name = self._get_name()

    def _get_name(self):
        """ Returns the name to display on the tree view.  Note that
        this is not a property getter.  
        """
        fname = basename(self.file_path.get())
        ret = "%s" % fname
        if len(self.file_list) > 1:
            ret += " (timeseries)"
        if '[Hidden]' in self.name:
            ret += ' [Hidden]'

        return ret

    def __reader_dict_default(self):
        """Default value for reader dict."""
        rd = {
            'stl': tvtk.STLReader(),
            'stla': tvtk.STLReader(),
            'stlb': tvtk.STLReader(),
            'txt': tvtk.SimplePointsReader(),
            'raw': tvtk.ParticleReader(),
            'ply': tvtk.PLYReader(),
            'pdb': tvtk.PDBReader(),
            'slc': tvtk.SLCReader(),
            'xyz': tvtk.XYZMolReader(),
            'obj': tvtk.OBJReader(),
            'facet': tvtk.FacetReader(),
            'cube': tvtk.GaussianCubeReader(),
            'g': tvtk.BYUReader(),
        }
        return rd

    # Callable to check if the reader can actually read the file
    def can_read(cls, filename):
        """ Class method to check if the reader can actually
        read the file. Returns 'True' if it can read it succesfully
        else 'False'
        """
        # Extract the file extension
        splitname = filename.strip().split('.')
        extension = splitname[-1].lower()

        if extension == 'xyz':
            from vtk import vtkObject
            o = vtkObject
            w = o.GetGlobalWarningDisplay()
            o.SetGlobalWarningDisplay(0)  # Turn it off.

            r = tvtk.XYZMolReader()
            r.file_name = filename
            r.update()
            o.SetGlobalWarningDisplay(w)

            if len(r.output.points) != 0:
                return True
            return False

        return None

    can_read = classmethod(can_read)
コード例 #24
0
class TVTKBranchNode(TreeNodeObject):
    """Represents a branch in the tree view.  The `children` trait
    produces an iterable that represents the children of the branch.
    """
    # The tvtk object being wrapped.
    object = Instance(TVTKBase)
    # Children of the object.
    children = Property
    # Name to show on the view.
    name = Property
    # Tree generator to use.
    tree_generator = Instance(TreeGenerator)
    # Cache of children.
    children_cache = Dict

    # Work around problem with HasPrivateTraits.
    __ = Python

    def __init__(self, **traits):
        super(TVTKBranchNode, self).__init__(**traits)

    def __del__(self):
        try:
            self._remove_listners()
        except:
            pass

    def __hash__(self):
        return hash(tvtk.to_vtk(self.object))

    def _get_children_from_cache(self):
        return [x for x in self.children_cache.values() if x is not None]

    def _create_children(self):
        kids = self.tree_generator.get_children(self.object)
        self.children_cache = kids
        self._setup_listners()

    def _setup_listners(self):
        object = self.object
        kids = self.children_cache
        for key, val in kids.items():
            if isinstance(val, tvtk.Collection):
                vtk_obj = tvtk.to_vtk(val)
                messenger.connect(vtk_obj, 'ModifiedEvent',
                                  self._notify_children)
            else:
                object.on_trait_change(self._notify_children, key)

    def _remove_listners(self):
        object = self.object
        kids = self.children_cache
        for key, val in kids.items():
            if isinstance(val, tvtk.Collection):
                vtk_obj = tvtk.to_vtk(val)
                messenger.disconnect(vtk_obj, 'ModifiedEvent',
                                     self._notify_children)
            else:
                object.on_trait_change(self._notify_children, key, remove=True)

    def _notify_children(self, obj=None, name=None, old=None, new=None):
        old_val = self._get_children_from_cache()
        self._remove_listners()
        self._create_children()
        new_val = self._get_children_from_cache()
        self.trait_property_changed('children', old_val, new_val)

    def _get_children(self):
        if not self.children_cache:
            self._create_children()
        kids = self._get_children_from_cache()
        tg = self.tree_generator
        return CompositeIterable(kids, tree_generator=tg)

    def _get_name(self):
        return self.object.__class__.__name__

    ######################################################################
    # `TreeNodeObject` interface
    ######################################################################
    def tno_get_icon(self, node, is_expanded):
        """ Returns the icon for a specified object.
        """
        icon = get_icon(self.name)
        if icon:
            return icon
        else:
            return super(TVTKBranchNode, self).tno_get_icon(node, is_expanded)
コード例 #25
0
ファイル: view.py プロジェクト: jtomase/matplotlib
from item \
    import Item

from include \
    import Include

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

# Name of the view trait
id_trait = Str(desc='the name of the view')

# Contents of the view trait (i.e., a single Group object)
content_trait = Instance(Group, desc='the content of the view')

# The menu bar for the view
#menubar_trait = Instance( 'enthought.pyface.action.MenuBarManager',
#                          desc = 'the menu bar for the view' )

# The tool bar for the view
#toolbar_trait = Instance( 'enthought.pyface.action.ToolBarManager',
#                          desc = 'the tool bar for the view' )

# An optional model/view factory for converting the model into a viewable
# 'model_view' object
model_view_trait = Callable(desc='the factory function for converting a'
                            'model into a model/view object')

# Reference to a Handler object trait
コード例 #26
0
class PipelineBrowser(HasTraits):
    # The tree generator to use.
    tree_generator = Trait(FullTreeGenerator(), Instance(TreeGenerator))

    # The TVTK render window(s) associated with this browser.
    renwins = List

    # The root object to view in the pipeline.  If None (default), the
    # root object is the render_window of the Scene instance passed at
    # object instantiation time.
    root_object = List(TVTKBase)

    # Private traits.
    # The root of the tree to display.
    _root = Any

    ###########################################################################
    # `object` interface.
    ###########################################################################
    def __init__(self, renwin=None, **traits):
        """Initializes the object.

        Parameters
        ----------

        - renwin: `Scene` instance.  Defaults to None.

          This may be passed in addition to the renwins attribute
          which can be a list of scenes.

        """
        super(PipelineBrowser, self).__init__(**traits)
        self.ui = None
        self.view = None
        if renwin:
            self.renwins.append(renwin)

        self._root_object_changed(self.root_object)
        menu = Menu(Action(name='Refresh', action='editor.update_editor'),
                    Action(name='Expand all', action='editor.expand_all'))
        self.menu = menu

        nodes = self.tree_generator.get_nodes(menu)

        self.tree_editor = TreeEditor(nodes=nodes,
                                      editable=False,
                                      orientation='vertical',
                                      hide_root=True,
                                      on_dclick=self._on_dclick)
        self.view = View(Group(Item(name='_root',
                                    editor=self.tree_editor,
                                    resizable=True),
                               show_labels=False,
                               show_border=False,
                               orientation='vertical'),
                         title='Pipeline browser',
                         help=False,
                         resizable=True,
                         undo=False,
                         revert=False,
                         width=.3,
                         height=.3)

    ###########################################################################
    # `PipelineBrowser` interface.
    ###########################################################################
    def show(self, parent=None):
        """Show the tree view if not already show.  If optional
        `parent` widget is passed, the tree is displayed inside the
        passed parent widget."""
        # If UI already exists, raise it and return.
        if self.ui and self.ui.control:
            try:
                self.ui.control.Raise()
            except AttributeError:
                pass
            else:
                return
        else:
            # No active ui, create one.
            if parent:
                self.ui = self.view.ui(self, parent=parent, kind='subpanel')
            else:
                self.ui = self.view.ui(self, parent=parent)

    def update(self):
        """Update the tree view."""
        # This is a hack.
        if self.ui and self.ui.control:
            try:
                ed = self.ui._editors[0]
                ed.update_editor()
                self.ui.control.Refresh()
            except (AttributeError, IndexError):
                pass

    # Another name for update.
    refresh = update

    def render(self):
        """Calls render on all render windows associated with this
        browser."""
        for rw in self.renwins:
            rw.render()

    ###########################################################################
    # Non-public interface.
    ###########################################################################
    def _make_default_root(self):
        tree_gen = self.tree_generator
        objs = [x.render_window for x in self.renwins]
        node = TVTKCollectionNode(object=objs,
                                  name="Root",
                                  tree_generator=tree_gen)
        return node

    def _tree_generator_changed(self, tree_gen):
        """Traits event handler."""
        if self._root:
            root_obj = self._root.object
        else:
            root_obj = self.root_object
        if root_obj:
            ro = root_obj
            if not hasattr(root_obj, '__len__'):
                ro = [root_obj]

            self._root = TVTKCollectionNode(object=ro,
                                            name="Root",
                                            tree_generator=tree_gen)
        else:
            self._root = self._make_default_root()

        self.tree_editor.nodes = tree_gen.get_nodes(self.menu)
        self.update()

    def _root_object_changed(self, root_obj):
        """Trait handler called when the root object is assigned to."""
        tg = self.tree_generator
        if root_obj:
            self._root = TVTKCollectionNode(object=root_obj,
                                            name="Root",
                                            tree_generator=tg)
        else:
            self._root = self._make_default_root()
            self.root_object = self._root.object
        self.update()

    def _root_object_items_changed(self, list_event):
        """Trait handler called when the items of the list change."""
        self._root_object_changed(self.root_object)

    def _on_dclick(self, obj):
        """Callback that is called when nodes are double-clicked."""
        if hasattr(obj, 'object') and hasattr(obj.object, 'edit_traits'):
            object = obj.object
            view = object.trait_view()
            view.handler = UICloseHandler(browser=self)
            object.on_trait_change(self.render)
            ui = object.edit_traits(view=view)
コード例 #27
0
ファイル: triangle_reader.py プロジェクト: jhill1/stk
class TriangleReader(FileDataSource):
    """
    Reader for the Triangle file formats:
        2D <http://www.cs.cmu.edu/~quake/triangle.html>
            Supports opening .egde files to construct a surface mesh comprised of lines
            and .ele files to construct a solid mesh comprised of triangles.
        3D <http://tetgen.berlios.de/fformats.html>
            Supports opening .face files to construct a surface mesh comprised of triangles
            and .ele files to construct a solid mesh comprised of tetrahedra.
    Outputs an unstructured grid dataset.
    """

    # The version of this class.  Used for persistence.
    __version__ = 0

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

    # The active point scalar name.
    point_scalars_name = DEnum(values_name='_point_scalars_list',
                               desc='scalar point data attribute to use')

    # The active cell scalar name.
    cell_scalars_name = DEnum(values_name='_cell_scalars_list',
                              desc='scalar cell data attribute to use')

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

    # These private traits store the list of available data
    # attributes.  The non-private traits use these lists internally.
    _cell_scalars_list = List(String)
    _point_scalars_list = List(String)

    # The VTK dataset to manage.
    _grid = Instance(tvtk.UnstructuredGrid, args=(), allow_none=False)

    # The basename of the file which has been loaded.
    _basename = String

    # Indicates whether nodes are numbered from 0 or 1 (the file
    # format allows both).
    _numbered_from = Int

    # This filter allows us to change the attributes of the data
    # object and will ensure that the pipeline is properly taken care
    # of.
    _assign_attribute = Instance(tvtk.AssignAttribute,
                                 args=(),
                                 allow_none=False)

    ########################################
    # The view.

    view = View(Item(name='point_scalars_name'),
                Item(name='cell_scalars_name'))

    ########################################
    # `FileDataSource` interface.

    def initialize(self, base_file_name):
        split = path.splitext(base_file_name)
        self._basename = split[0]
        extension = split[1]

        self._assign_attribute.input = self._grid

        self._read_node_file()
        if (extension == '.face' or extension == '.edge'):
            self._read_face_edge_file(extension)
        else:
            self._read_ele_file()

        self.outputs = [self._assign_attribute.output]
        self.name = 'Triangle file (%s%s)' % (path.basename(
            self._basename), extension)

    ########################################
    # File reading methods.

    def _read_node_file(self):
        """
        Loads data from {basename}.node, and inserts points and point
        scalars into the unstructured grid.
        """
        file_name = '%s.node' % self._basename

        # Load all data.
        all_data = self._get_data(file_name)
        # Grab values from the first line of data file.
        points, dimensions, attributes, boundary_marker = map(
            int, all_data[0:4])
        # Reshape remainder of array.
        data_array = all_data[4:].reshape(
            points, 1 + dimensions + attributes + boundary_marker)

        self._numbered_from = int(data_array[0][0])

        points_array = array(data_array[:, 1:(1 + dimensions)], 'double')
        if (dimensions == 2):
            # Add a 0 to each point if it is 2D.
            points_array = array(map(lambda a: append(a, 0), points_array))
        self._grid.points = points_array

        for i in range(attributes):
            attribute_array = data_array[:, (i + dimensions +
                                             1):(i + dimensions + 2)]
            self._add_attribute_array(attribute_array, i, 'point')

        if (boundary_marker):
            boundary_marker_array = data_array[:, (dimensions + attributes +
                                                   1):(dimensions +
                                                       attributes + 2)]
            self._add_boundary_marker_array(boundary_marker_array, 'point')

    def _read_face_edge_file(self, extension):
        """
        Loads data from 2D {basename}.edge or 3D {basename}.face, and inserts
        triangle/line cells and cell scalars into the unstructured grid.
        """
        file_name = '%s%s' % (self._basename, extension)

        if (extension == '.edge'):
            # 2D. Expect two endpoints which form a line.
            npoints = 2
            cell_type = tvtk.Line().cell_type
        else:
            # 3D. Expect three points which form a triangle.
            npoints = 3
            cell_type = tvtk.Triangle().cell_type

        # Load all data.
        all_data = self._get_data(file_name)
        # Grab values from the first line of data file.
        faces_edges, boundary_marker = map(int, all_data[0:2])
        # Reshape remainder of array.
        data_array = all_data[2:].reshape(faces_edges,
                                          npoints + 1 + boundary_marker)

        nodes_array = data_array[:, 1:npoints + 1] - self._numbered_from
        self._grid.set_cells(cell_type, nodes_array)

        if (boundary_marker):
            boundary_marker_array = data_array[:, npoints + 1:npoints + 2]
            self._add_boundary_marker_array(boundary_marker_array, 'cell')

    def _read_ele_file(self):
        """
        Loads data from {basename}.ele, and inserts triangle/tetrahedron cells
        and cell scalars into the unstructured grid.
        """
        file_name = '%s.ele' % self._basename

        # Load all data.
        all_data = self._get_data(file_name)
        # Grab values from the first line of data file.
        tet_tri, nodes_per_tet_tri, attributes = map(int, all_data[0:3])
        # Reshape remainder of array.
        data_array = all_data[3:].reshape(tet_tri,
                                          1 + nodes_per_tet_tri + attributes)

        nodes_array = data_array[:, 1:(nodes_per_tet_tri +
                                       1)] - self._numbered_from

        if (nodes_per_tet_tri == 3):
            cell_type = tvtk.Triangle().cell_type
        else:
            cell_type = tvtk.Tetra().cell_type

        self._grid.set_cells(cell_type, nodes_array)

        for i in range(attributes):
            attribute_array = data_array[:, (i + nodes_per_tet_tri +
                                             1):(i + nodes_per_tet_tri + 2)]
            self._add_attribute_array(attribute_array, i, 'cell')

    def _get_data(self, file_name):
        """
        Returns a 1D array containing all the data from the given file.
        """
        file = open(file_name)
        file_string = file.read()

        # Strip comments.
        pattern = compile('#.*?$', MULTILINE)
        file_string = pattern.sub('', file_string)

        # Load all data into array.
        return fromstring(file_string, dtype=float, sep=" ")

    ########################################
    # Unstructured grid construction
    # methods.

    def _add_attribute_array(self, attribute_array, i, type):
        """
        Adds the given attribute array to either point_data or
        cell_data of the unstructured grid.
        """
        attribute_array_name = 'Attribute %i' % i
        if (type == 'cell'):  # .ele file attributes are of type Int
            tvtk_attribute_array = tvtk.IntArray(name=attribute_array_name)
            attribute_array = map(int, attribute_array)
        else:  # .node file attributes are of type Float
            tvtk_attribute_array = tvtk.FloatArray(name=attribute_array_name)
        tvtk_attribute_array.from_array(attribute_array)
        getattr(self._grid, '%s_data' % type).add_array(tvtk_attribute_array)
        getattr(self, '_%s_scalars_list' % type).append(attribute_array_name)

        if (i == 0):
            self._set_data_name(type, 'Attribute 0')

    def _add_boundary_marker_array(self, boundary_marker_array, type):
        """
        Adds the given boundary marker array to either point_data or
        cell_data of the unstructured grid.
        """
        boundary_marker_array_name = 'Boundary Marker'
        tvtk_boundary_marker_array = tvtk.IntArray(
            name=boundary_marker_array_name)
        tvtk_boundary_marker_array.from_array(boundary_marker_array)
        getattr(self._grid,
                '%s_data' % type).add_array(tvtk_boundary_marker_array)
        getattr(self,
                '_%s_scalars_list' % type).append(boundary_marker_array_name)
        self._set_data_name(type, 'Boundary Marker')

    ########################################
    # Methods taken and modified from
    # SetActiveAttribute filter.

    def _point_scalars_name_changed(self, value):
        self._set_data_name('point', value)

    def _cell_scalars_name_changed(self, value):
        self._set_data_name('cell', value)

    def _set_data_name(self, attr_type, value):
        """
        Sets the selected point or cell scalar to be active, and
        deactivates the scalar of the other type.
        """
        if value is None:
            return

        if (attr_type == 'point'):
            data = self._grid.point_data
            other_data = self._grid.cell_data
        else:
            data = self._grid.cell_data
            other_data = self._grid.point_data

        method = getattr(data, 'set_active_scalars')
        method(value)

        # Deactivate other attribute.
        method = getattr(other_data, 'set_active_scalars')
        method(None)

        self._assign_attribute.assign(value, 'SCALARS',
                                      attr_type.upper() + '_DATA')
        self._assign_attribute.update()

        # Fire an event, so the changes propagate.
        self.data_changed = True
コード例 #28
0
ファイル: edge.py プロジェクト: jcrabtree/godot
class Edge(HasTraits):
    """ Defines a graph edge. """

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

    # Tail/from/source/start node.
    tail_node = Instance(Node, allow_none=False)

    # Head/to/target/end node.
    head_node = Instance(Node, allow_none=False)

    # String identifier (TreeNode label).
    name = Property(
        Str,
        depends_on=["tail_node", "tail_node.ID", "head_node", "head_node.ID"])

    # Connection string used in string output.
    conn = Enum("->", "--")

    # Nodes from which the tail and head nodes may be selected.
    _nodes = List(Instance(Node))  # GUI specific.

    #--------------------------------------------------------------------------
    #  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")
    _ldraw_ = Str(desc="xdot label drawing directive", label="ldraw")

    _hdraw_ = Str(desc="edge head arrowhead drawing directive.", label="hdraw")
    _tdraw_ = Str(desc="edge tail arrowhead drawing directive.", label="tdraw")
    _hldraw_ = Str(desc="edge head label drawing directive.", label="hldraw")
    _tldraw_ = Str(desc="edge tail label drawing directive.", label="tldraw")

    #--------------------------------------------------------------------------
    #  Enable trait definitions:
    #--------------------------------------------------------------------------

    # Container of drawing components, typically the edge spline.
    drawing = Instance(Container)

    # Container of label components.
    label_drawing = Instance(Container)

    # Container of head arrow components.
    arrowhead_drawing = Instance(Container)

    # Container of tail arrow components.
    arrowtail_drawing = Instance(Container)

    # Container of head arrow label components.
    arrowhead_label_drawing = Instance(Container)

    # Container of tail arrow label components.
    arrowtail_label_drawing = Instance(Container)

    # Container for the drawing, label, arrow and arrow label components.
    component = Instance(Container, desc="container of graph components.")

    # A view into a sub-region of the canvas.
    vp = Instance(Viewport, desc="a view of a sub-region of the canvas")

    # Use Graphviz to arrange all graph components.
    arrange = Button("Arrange All")

    #--------------------------------------------------------------------------
    #  Dot trait definitions:
    #--------------------------------------------------------------------------

    # Style of arrowhead on the head node of an edge.
    # See also the <html:a rel="attr">dir</html:a> attribute,
    # and the <html:a rel="note">undirected</html:a> note.
    arrowhead = arrow_trait

    # Multiplicative scale factor for arrowheads.
    arrowsize = Float(1.0,
                      desc="multiplicative scale factor for arrowheads",
                      label="Arrow size",
                      graphviz=True)

    # Style of arrowhead on the tail node of an edge.
    # See also the <html:a rel="attr">dir</html:a> attribute,
    # and the <html:a rel="note">undirected</html:a> note.
    arrowtail = arrow_trait

    # Basic drawing color for graphics, not text. For the latter, use the
    # <html:a rel="attr">fontcolor</html:a> attribute.
    #
    # For edges, the value
    # can either be a single <html:a rel="type">color</html:a> or a <html:a rel="type">colorList</html:a>.
    # In the latter case, the edge is drawn using parallel splines or lines,
    # one for each color in the list, in the order given.
    # The head arrow, if any, is drawn using the first color in the list,
    # and the tail arrow, if any, the second color. This supports the common
    # case of drawing opposing edges, but using parallel splines instead of
    # separately routed multiedges.
    color = color_trait

    # This attribute specifies a color scheme namespace. If defined, it specifies
    # the context for interpreting color names. In particular, if a
    # <html:a rel="type">color</html:a> value has form <html:code>xxx</html:code> or <html:code>//xxx</html:code>,
    # then the color <html:code>xxx</html:code> will be evaluated according to the current color scheme.
    # If no color scheme is set, the standard X11 naming is used.
    # For example, if <html:code>colorscheme=bugn9</html:code>, then <html:code>color=7</html:code>
    # is interpreted as <html:code>/bugn9/7</html:code>.
    colorscheme = color_scheme_trait

    # Comments are inserted into output. Device-dependent.
    comment = comment_trait

    # If <html:span class="val">false</html:span>, the edge is not used in
    # ranking the nodes.
    constraint = Bool(True,
                      desc="if edge is used in ranking the nodes",
                      graphviz=True)

    # If <html:span class="val">true</html:span>, attach edge label to edge by a 2-segment
    # polyline, underlining the label, then going to the closest point of spline.
    decorate = Bool(
        False,
        desc="to attach edge label to edge by a 2-segment "
        "polyline, underlining the label, then going to the closest point of "
        "spline",
        graphviz=True)

    # Set edge type for drawing arrowheads. This indicates which ends of the
    # edge should be decorated with an arrowhead. The actual style of the
    # arrowhead can be specified using the <html:a rel="attr">arrowhead</html:a>
    # and <html:a rel="attr">arrowtail</html:a> attributes.
    # See <html:a rel="note">undirected</html:a>.
    dir = Enum("forward",
               "back",
               "both",
               "none",
               label="Direction",
               desc="edge type for drawing arrowheads",
               graphviz=True)

    # Synonym for <html:a rel="attr">edgeURL</html:a>.
    #    edgehref = Alias("edgeURL", desc="synonym for edgeURL")
    edgehref = Synced(sync_to="edgeURL", graphviz=True)

    # If the edge has a URL or edgeURL  attribute, this attribute determines
    # which window of the browser is used for the URL attached to the non-label
    # part of the edge. Setting it to "_graphviz" will open a new window if it
    # doesn't already exist, or reuse it if it does. If undefined, the value of
    # the target is used.
    edgetarget = Str("",
                     desc="which window of the browser is used for the "
                     "URL attached to the non-label part of the edge",
                     label="Edge target",
                     graphviz=True)

    # Tooltip annotation attached to the non-label part of an edge.
    # This is used only if the edge has a <html:a rel="attr">URL</html:a>
    # or <html:a rel="attr">edgeURL</html:a> attribute.
    edgetooltip = Str("",
                      desc="annotation attached to the non-label part of "
                      "an edge",
                      label="Edge tooltip",
                      graphviz=True)
    #    edgetooltip = EscString

    # If <html:a rel="attr">edgeURL</html:a> is defined, this is the link used for the non-label
    # parts of an edge. This value overrides any <html:a rel="attr">URL</html:a>
    # defined for the edge.
    # Also, this value is used near the head or tail node unless overridden
    # by a <html:a rel="attr">headURL</html:a> or <html:a rel="attr">tailURL</html:a> value,
    # respectively.
    # See <html:a rel="note">undirected</html:a>.
    edgeURL = Str("",
                  desc="link used for the non-label parts of an edge",
                  label="Edge URL",
                  graphviz=True)  #LabelStr

    # Color used for text.
    fontcolor = fontcolor_trait

    # Font used for text. This very much depends on the output format and, for
    # non-bitmap output such as PostScript or SVG, the availability of the font
    # when the graph is displayed or printed. As such, it is best to rely on
    # font faces that are generally available, such as Times-Roman, Helvetica or
    # Courier.
    #
    # If Graphviz was built using the
    # <html:a href="http://pdx.freedesktop.org/~fontconfig/fontconfig-user.html">fontconfig library</html:a>, the latter library
    # will be used to search for the font. However, if the <html:a rel="attr">fontname</html:a> string
    # contains a slash character "/", it is treated as a pathname for the font
    # file, though font lookup will append the usual font suffixes.
    #
    # If Graphviz does not use fontconfig, <html:a rel="attr">fontname</html:a> will be
    # considered the name of a Type 1 or True Type font file.
    # If you specify <html:code>fontname=schlbk</html:code>, the tool will look for a
    # file named  <html:code>schlbk.ttf</html:code> or <html:code>schlbk.pfa</html:code> or <html:code>schlbk.pfb</html:code>
    # in one of the directories specified by
    # the <html:a rel="attr">fontpath</html:a> attribute.
    # The lookup does support various aliases for the common fonts.
    fontname = fontname_trait

    # Font size, in <html:a rel="note">points</html:a>, used for text.
    fontsize = fontsize_trait

    # If <html:span class="val">true</html:span>, the head of an edge is clipped to the boundary of the head node;
    # otherwise, the end of the edge goes to the center of the node, or the
    # center of a port, if applicable.
    headclip = Bool(True,
                    desc="head of an edge to be clipped to the boundary "
                    "of the head node",
                    label="Head clip",
                    graphviz=True)

    # Synonym for <html:a rel="attr">headURL</html:a>.
    headhref = Alias("headURL", desc="synonym for headURL", graphviz=True)

    # Text label to be placed near head of edge.
    # See <html:a rel="note">undirected</html:a>.
    headlabel = Str("",
                    desc="text label to be placed near head of edge",
                    label="Head label",
                    graphviz=True)

    headport = port_pos_trait

    # If the edge has a headURL, this attribute determines which window of the
    # browser is used for the URL. Setting it to "_graphviz" will open a new
    # window if it doesn't already exist, or reuse it if it does. If undefined,
    # the value of the target is used.
    headtarget = Str(desc="which window of the browser is used for the URL",
                     label="Head target",
                     graphviz=True)

    # Tooltip annotation attached to the head of an edge. This is used only
    # if the edge has a <html:a rel="attr">headURL</html:a> attribute.
    headtooltip = Str("",
                      desc="tooltip annotation attached to the head of an "
                      "edge",
                      label="Head tooltip",
                      graphviz=True)

    # If <html:a rel="attr">headURL</html:a> is defined, it is
    # output as part of the head label of the edge.
    # Also, this value is used near the head node, overriding any
    # <html:a rel="attr">URL</html:a> value.
    # See <html:a rel="note">undirected</html:a>.
    headURL = Str("",
                  desc="output as part of the head label of the edge",
                  label="Head URL",
                  graphviz=True)

    # Synonym for <html:a rel="attr">URL</html:a>.
    href = Alias("URL", desc="synonym for URL", graphviz=True)

    # Text label attached to objects.
    # If a node's <html:a rel="attr">shape</html:a> is record, then the label can
    # have a <html:a href="http://www.graphviz.org/doc/info/shapes.html#record">special format</html:a>
    # which describes the record layout.
    label = label_trait

    # This, along with <html:a rel="attr">labeldistance</html:a>, determine
    # where the
    # headlabel (taillabel) are placed with respect to the head (tail)
    # in polar coordinates. The origin in the coordinate system is
    # the point where the edge touches the node. The ray of 0 degrees
    # goes from the origin back along the edge, parallel to the edge
    # at the origin.
    #
    # The angle, in degrees, specifies the rotation from the 0 degree ray,
    # with positive angles moving counterclockwise and negative angles
    # moving clockwise.
    labelangle = Float(
        -25.0,
        desc=", along with labeldistance, where the "
        "headlabel (taillabel) are placed with respect to the head (tail)",
        label="Label angle",
        graphviz=True)

    # Multiplicative scaling factor adjusting the distance that
    # the headlabel (taillabel) is from the head (tail) node.
    # The default distance is 10 points. See <html:a rel="attr">labelangle</html:a>
    # for more details.
    labeldistance = Float(
        1.0,
        desc="multiplicative scaling factor adjusting "
        "the distance that the headlabel (taillabel) is from the head (tail) "
        "node",
        label="Label distance",
        graphviz=True)

    # If true, allows edge labels to be less constrained in position. In
    # particular, it may appear on top of other edges.
    labelfloat = Bool(False,
                      desc="edge labels to be less constrained in "
                      "position",
                      label="Label float",
                      graphviz=True)

    # Color used for headlabel and taillabel.
    # If not set, defaults to edge's fontcolor.
    labelfontcolor = Color("black",
                           desc="color used for headlabel and "
                           "taillabel",
                           label="Label font color",
                           graphviz=True)

    # Font used for headlabel and taillabel.
    # If not set, defaults to edge's fontname.
    labelfontname = Font("Times-Roman",
                         desc="Font used for headlabel and "
                         "taillabel",
                         label="Label font name",
                         graphviz=True)

    # Font size, in <html:a rel="note">points</html:a>, used for headlabel and taillabel.
    # If not set, defaults to edge's fontsize.
    labelfontsize = Float(14.0,
                          desc="Font size, in points, used for "
                          "headlabel and taillabel",
                          label="label_font_size",
                          graphviz=True)

    # Synonym for <html:a rel="attr">labelURL</html:a>.
    labelhref = Alias("labelURL", desc="synonym for labelURL", graphviz=True)

    # If the edge has a URL or labelURL  attribute, this attribute determines
    # which window of the browser is used for the URL attached to the label.
    # Setting it to "_graphviz" will open a new window if it doesn't already
    # exist, or reuse it if it does. If undefined, the value of the target is
    # used.
    labeltarget = Str("",
                      desc="which window of the browser is used for the "
                      "URL attached to the label",
                      label="Label target",
                      graphviz=True)

    # Tooltip annotation attached to label of an edge.
    # This is used only if the edge has a <html:a rel="attr">URL</html:a>
    # or <html:a rel="attr">labelURL</html:a> attribute.
    labeltooltip = Str("",
                       desc="tooltip annotation attached to label of an "
                       "edge",
                       label="Label tooltip",
                       graphviz=True)

    # If <html:a rel="attr">labelURL</html:a> is defined, this is the link used for the label
    # of an edge. This value overrides any <html:a rel="attr">URL</html:a>
    # defined for the edge.
    labelURL = Str(desc="link used for the label of an edge", graphviz=True)

    # Specifies layers in which the node or edge is present.
    layer = layer_trait

    # Preferred edge length, in inches.
    len = Float(1.0, desc="preferred edge length, in inches",
                graphviz=True)  #0.3(fdp)

    # Logical head of an edge. When compound is true, if lhead is defined and
    # is the name of a cluster containing the real head, the edge is clipped to
    # the boundary of the cluster.
    lhead = Str(desc="Logical head of an edge", graphviz=True)

    # Label position, in points. The position indicates the center of the label.
    lp = point_trait

    # Logical tail of an edge. When compound is true, if ltail is defined and
    # is the name of a cluster containing the real tail, the edge is clipped to
    # the boundary of the cluster.
    ltail = Str(desc="logical tail of an edge", graphviz=True)

    # Minimum edge length (rank difference between head and tail).
    minlen = Int(1, desc="minimum edge length", graphviz=True)

    # By default, the justification of multi-line labels is done within the
    # largest context that makes sense. Thus, in the label of a polygonal node,
    # a left-justified line will align with the left side of the node (shifted
    # by the prescribed margin). In record nodes, left-justified line will line
    # up with the left side of the enclosing column of fields. If nojustify is
    # "true", multi-line labels will be justified in the context of itself. For
    # example, if the attribute is set, the first label line is long, and the
    # second is shorter and left-justified, the second will align with the
    # left-most character in the first line, regardless of how large the node
    # might be.
    nojustify = nojustify_trait

    # Position of node, or spline control points.
    # For nodes, the position indicates the center of the node.
    # On output, the coordinates are in <html:a href="#points">points</html:a>.
    #
    # In neato and fdp, pos can be used to set the initial position of a node.
    # By default, the coordinates are assumed to be in inches. However, the
    # <html:a href="http://www.graphviz.org/doc/info/command.html#d:s">-s</html:a> command line flag can be used to specify
    # different units.
    #
    # When the <html:a href="http://www.graphviz.org/doc/info/command.html#d:n">-n</html:a> command line flag is used with
    # neato, it is assumed the positions have been set by one of the layout
    # programs, and are therefore in points. Thus, <html:code>neato -n</html:code> can accept
    # input correctly without requiring a <html:code>-s</html:code> flag and, in fact,
    # ignores any such flag.
    pos = List(Tuple(Float, Float), desc="spline control points")

    # Edges with the same head and the same <html:a rel="attr">samehead</html:a> value are aimed
    # at the same point on the head.
    # See <html:a rel="note">undirected</html:a>.
    samehead = Str("",
                   desc="dges with the same head and the same samehead "
                   "value are aimed at the same point on the head",
                   graphviz=True)

    # Edges with the same tail and the same <html:a rel="attr">sametail</html:a> value are aimed
    # at the same point on the tail.
    # See <html:a rel="note">undirected</html:a>.
    sametail = Str("",
                   desc="edges with the same tail and the same sametail "
                   "value are aimed at the same point on the tail",
                   graphviz=True)

    # Print guide boxes in PostScript at the beginning of
    # routesplines if 1, or at the end if 2. (Debugging)
    showboxes = showboxes_trait

    # Set style for node or edge. For cluster subgraph, if "filled", the
    # cluster box's background is filled.
    style = ListStr(desc="style for node or edge", graphviz=True)

    # If <html:span class="val">true</html:span>, the tail of an edge is clipped to the boundary of the tail node;
    # otherwise, the end of the edge goes to the center of the node, or the
    # center of a port, if applicable.
    tailclip = Bool(True,
                    desc="tail of an edge to be clipped to the boundary "
                    "of the tail node",
                    graphviz=True)

    # Synonym for <html:a rel="attr">tailURL</html:a>.
    tailhref = Alias("tailURL", desc="synonym for tailURL", graphviz=True)

    # Text label to be placed near tail of edge.
    # See <html:a rel="note">undirected</html:a>.
    taillabel = Str(desc="text label to be placed near tail of edge",
                    graphviz=True)

    # Indicates where on the tail node to attach the tail of the edge.
    tailport = port_pos_trait

    # If the edge has a tailURL, this attribute determines which window of the
    # browser is used for the URL. Setting it to "_graphviz" will open a new
    # window if it doesn't already exist, or reuse it if it does. If undefined,
    # the value of the target is used.
    tailtarget = Str(desc="which window of the browser is used for the URL",
                     graphviz=True)

    # Tooltip annotation attached to the tail of an edge. This is used only
    # if the edge has a <html:a rel="attr">tailURL</html:a> attribute.
    tailtooltip = Str("",
                      desc="tooltip annotation attached to the tail of an "
                      "edge",
                      label="Tail tooltip",
                      graphviz=True)

    # If <html:a rel="attr">tailURL</html:a> is defined, it is
    # output as part of the tail label of the edge.
    # Also, this value is used near the tail node, overriding any
    # <html:a rel="attr">URL</html:a> value.
    # See <html:a rel="note">undirected</html:a>.
    tailURL = Str("",
                  desc="output as part of the tail label of the edge",
                  label="Tail URL",
                  graphviz=True)

    # If the object has a URL, this attribute determines which window
    # of the browser is used for the URL.
    # See <html:a href="http://www.w3.org/TR/html401/present/frames.html#adef-target">W3C documentation</html:a>.
    target = target_trait

    # Tooltip annotation attached to the node or edge. If unset, Graphviz
    # will use the object's <html:a rel="attr">label</html:a> if defined.
    # Note that if the label is a record specification or an HTML-like
    # label, the resulting tooltip may be unhelpful. In this case, if
    # tooltips will be generated, the user should set a <html:tt>tooltip</html:tt>
    # attribute explicitly.
    tooltip = tooltip_trait

    # Hyperlinks incorporated into device-dependent output.
    # At present, used in ps2, cmap, i*map and svg formats.
    # For all these formats, URLs can be attached to nodes, edges and
    # clusters. URL attributes can also be attached to the root graph in ps2,
    # cmap and i*map formats. This serves as the base URL for relative URLs in the
    # former, and as the default image map file in the latter.
    #
    # For svg, cmapx and imap output, the active area for a node is its
    # visible image.
    # For example, an unfilled node with no drawn boundary will only be active on its label.
    # For other output, the active area is its bounding box.
    # The active area for a cluster is its bounding box.
    # For edges, the active areas are small circles where the edge contacts its head
    # and tail nodes. In addition, for svg, cmapx and imap, the active area
    # includes a thin polygon approximating the edge. The circles may
    # overlap the related node, and the edge URL dominates.
    # If the edge has a label, this will also be active.
    # Finally, if the edge has a head or tail label, this will also be active.
    #
    # Note that, for edges, the attributes <html:a rel="attr">headURL</html:a>,
    # <html:a rel="attr">tailURL</html:a>, <html:a rel="attr">labelURL</html:a> and
    # <html:a rel="attr">edgeURL</html:a> allow control of various parts of an
    # edge. Also note that, if active areas of two edges overlap, it is unspecified
    # which area dominates.
    URL = url_trait

    # Weight of edge. In dot, the heavier the weight, the shorter, straighter
    # and more vertical the edge is.
    weight = Float(1.0, desc="weight of edge", graphviz=True)

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

    traits_view = View(VGroup(
        Group(
            Item(name="vp",
                 editor=ComponentEditor(height=100),
                 show_label=False,
                 id=".component"), Item("arrange", show_label=False)),
        Tabbed(
            Group(Item(name="tail_node",
                       editor=InstanceEditor(name="_nodes", editable=False)),
                  Item(name="head_node",
                       editor=InstanceEditor(name="_nodes", editable=False)), [
                           "style", "layer", "color", "colorscheme", "dir",
                           "arrowsize", "constraint", "decorate", "showboxes",
                           "tooltip", "edgetooltip", "edgetarget", "target",
                           "comment"
                       ],
                  label="Edge"),
            Group([
                "label", "fontname", "fontsize", "fontcolor", "nojustify",
                "labeltarget", "labelfloat", "labelfontsize", "labeltooltip",
                "labelangle", "lp", "labelURL", "labelfontname",
                "labeldistance", "labelfontcolor", "labelhref"
            ],
                  label="Label"),
            Group(["minlen", "weight", "len", "pos"], label="Dimension"),
            Group([
                "arrowhead", "samehead", "headURL", "headtooltip", "headclip",
                "headport", "headlabel", "headtarget", "lhead", "headhref"
            ],
                  label="Head"),
            Group([
                "arrowtail", "tailtarget", "tailhref", "ltail", "sametail",
                "tailport", "taillabel", "tailtooltip", "tailURL", "tailclip"
            ],
                  label="Tail"),
            Group(["URL", "href", "edgeURL", "edgehref"], label="URL"),
            Group([
                "_draw_", "_ldraw_", "_hdraw_", "_tdraw_", "_hldraw_",
                "_tldraw_"
            ],
                  label="Xdot"),
            dock="tab"),
        layout="split",
        id=".splitter"),
                       title="Edge",
                       id="godot.edge",
                       buttons=["OK", "Cancel", "Help"],
                       resizable=True)

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

    def __init__(self,
                 tailnode_or_ID,
                 headnode_or_ID,
                 directed=False,
                 **traits):
        """ Initialises a new Edge instance.
        """
        if not isinstance(tailnode_or_ID, Node):
            tailnodeID = str(tailnode_or_ID)
            tail_node = Node(tailnodeID)
        else:
            tail_node = tailnode_or_ID

        if not isinstance(headnode_or_ID, Node):
            headnodeID = str(headnode_or_ID)
            head_node = Node(headnodeID)
        else:
            head_node = headnode_or_ID

        self.tail_node = tail_node
        self.head_node = head_node

        if directed:
            self.conn = "->"
        else:
            self.conn = "--"

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

    def __str__(self):
        """ Returns a string representation of the edge.
        """
        attrs = []
        # Traits to be included in string output have 'graphviz' metadata.
        for trait_name, trait in self.traits(graphviz=True).iteritems():
            # Get the value of the trait for comparison with the default.
            value = getattr(self, trait_name)

            # Only print attribute value pairs if not defaulted.
            # FIXME: Alias/Synced traits default to None.
            if (value != trait.default) and (trait.default is not None):
                # Add quotes to the value if necessary.
                if isinstance(value, basestring):
                    valstr = '"%s"' % value
                else:
                    valstr = str(value)

                attrs.append('%s=%s' % (trait_name, valstr))

        if attrs:
            attrstr = " [%s]" % ", ".join(attrs)
        else:
            attrstr = ""

        edge_str = "%s%s %s %s%s%s;" % (self.tail_node.ID, self.tailport,
                                        self.conn, self.head_node.ID,
                                        self.headport, attrstr)
        return edge_str

    #--------------------------------------------------------------------------
    #  Trait initialisers:
    #--------------------------------------------------------------------------

    def _component_default(self):
        """ Trait initialiser.
        """
        component = Container(auto_size=True, bgcolor="green")
        #        component.tools.append( MoveTool(component) )
        #        component.tools.append( TraitsTool(component) )
        return component

    def _vp_default(self):
        """ Trait initialiser.
        """
        vp = Viewport(component=self.component)
        vp.enable_zoom = True
        vp.tools.append(ViewportPanTool(vp))
        return vp

    #--------------------------------------------------------------------------
    #  Property getters:
    #--------------------------------------------------------------------------

    def _get_name(self):
        """ Property getter.
        """
        if (self.tail_node is not None) and (self.head_node is not None):
            return "%s %s %s" % (self.tail_node.ID, self.conn,
                                 self.head_node.ID)
        else:
            return "Edge"

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

    @on_trait_change("arrange")
    def arrange_all(self):
        """ Arrange the components of the node using Graphviz.
        """
        # FIXME: Circular reference avoidance.
        import godot.dot_data_parser
        import godot.graph

        graph = godot.graph.Graph(ID="g", directed=True)
        self.conn = "->"
        graph.edges.append(self)

        xdot_data = graph.create(format="xdot")
        #        print "XDOT DATA:", xdot_data

        parser = godot.dot_data_parser.GodotDataParser()
        ndata = xdot_data.replace('\\\n', '')
        tokens = parser.dotparser.parseString(ndata)[0]

        for element in tokens[3]:
            cmd = element[0]
            if cmd == "add_edge":
                cmd, src, dest, opts = element
                self.set(**opts)

#    @on_trait_change("_draw_,_hdraw_")

    def _parse_xdot_directive(self, name, new):
        """ Handles parsing Xdot drawing directives.
        """
        parser = XdotAttrParser()
        components = parser.parse_xdot_data(new)

        # The absolute coordinate of the drawing container wrt graph origin.
        x1 = min([c.x for c in components])
        y1 = min([c.y for c in components])

        print "X1/Y1:", name, x1, y1

        # Components are positioned relative to their container. This
        # function positions the bottom-left corner of the components at
        # their origin rather than relative to the graph.
        #        move_to_origin( components )

        for c in components:
            if isinstance(c, Ellipse):
                component.x_origin -= x1
                component.y_origin -= y1
#                c.position = [ c.x - x1, c.y - y1 ]

            elif isinstance(c, (Polygon, BSpline)):
                print "Points:", c.points
                c.points = [(t[0] - x1, t[1] - y1) for t in c.points]
                print "Points:", c.points

            elif isinstance(c, Text):
                #                font = str_to_font( str(c.pen.font) )
                c.text_x, c.text_y = c.x - x1, c.y - y1

        container = Container(auto_size=True,
                              position=[x1, y1],
                              bgcolor="yellow")

        container.add(*components)

        if name == "_draw_":
            self.drawing = container
        elif name == "_hdraw_":
            self.arrowhead_drawing = container
        else:
            raise

    @on_trait_change("drawing,arrowhead_drawing")
    def _on_drawing(self, object, name, old, new):
        """ Handles the containers of drawing components being set.
        """
        attrs = ["drawing", "arrowhead_drawing"]

        others = [getattr(self, a) for a in attrs \
            if (a != name) and (getattr(self, a) is not None)]

        x, y = self.component.position
        print "POS:", x, y, self.component.position

        abs_x = [d.x + x for d in others]
        abs_y = [d.y + y for d in others]

        print "ABS:", abs_x, abs_y

        # Assume that he new drawing is positioned relative to graph origin.
        x1 = min(abs_x + [new.x])
        y1 = min(abs_y + [new.y])

        print "DRAW:", new.position
        new.position = [new.x - x1, new.y - y1]
        print "DRAW:", new.position

        #        for i, b in enumerate( others ):
        #            self.drawing.position = [100, 100]
        #            self.drawing.request_redraw()
        #            print "OTHER:", b.position, abs_x[i] - x1
        #            b.position = [ abs_x[i] - x1, abs_y[i] - y1 ]
        #            b.x = 50
        #            b.y = 50
        #            print "OTHER:", b.position, abs_x[i], x1

        #        for attr in attrs:
        #            if attr != name:
        #                if getattr(self, attr) is not None:
        #                    drawing = getattr(self, attr)
        #                    drawing.position = [50, 50]

        if old is not None:
            self.component.remove(old)
        if new is not None:
            self.component.add(new)

        print "POS NEW:", self.component.position
        self.component.position = [x1, y1]
        print "POS NEW:", self.component.position
        self.component.request_redraw()
        print "POS NEW:", self.component.position
コード例 #29
0
class VariableMeshPannerView(HasTraits):

    plot = Instance(Plot)
    spawn_zoom = Button
    vm_plot = Instance(VMImagePlot)
    use_tools = Bool(True)
    full_container = Instance(HPlotContainer)
    container = Instance(OverlayPlotContainer)

    traits_view = View(
        Group(Item('full_container',
                   editor=ComponentEditor(size=(512, 512)),
                   show_label=False),
              Item('field', show_label=False),
              orientation="vertical"),
        width=800,
        height=800,
        resizable=True,
        title="Pan and Scan",
    )

    def _vm_plot_default(self):
        return VMImagePlot(panner=self.panner)

    def __init__(self, **kwargs):
        super(VariableMeshPannerView, self).__init__(**kwargs)
        # Create the plot
        self.add_trait("field", DelegatesTo("vm_plot"))

        plot = self.vm_plot.plot
        img_plot = self.vm_plot.img_plot

        if self.use_tools:
            plot.tools.append(PanTool(img_plot))
            zoom = ZoomTool(component=img_plot,
                            tool_mode="box",
                            always_on=False)
            plot.overlays.append(zoom)
            imgtool = ImageInspectorTool(img_plot)
            img_plot.tools.append(imgtool)
            overlay = ImageInspectorOverlay(component=img_plot,
                                            image_inspector=imgtool,
                                            bgcolor="white",
                                            border_visible=True)
            img_plot.overlays.append(overlay)

        image_value_range = DataRange1D(self.vm_plot.fid)
        cbar_index_mapper = LinearMapper(range=image_value_range)
        self.colorbar = ColorBar(index_mapper=cbar_index_mapper,
                                 plot=img_plot,
                                 padding_right=40,
                                 resizable='v',
                                 width=30)

        self.colorbar.tools.append(
            PanTool(self.colorbar, constrain_direction="y", constrain=True))
        zoom_overlay = ZoomTool(self.colorbar,
                                axis="index",
                                tool_mode="range",
                                always_on=True,
                                drag_button="right")
        self.colorbar.overlays.append(zoom_overlay)

        # create a range selection for the colorbar
        range_selection = RangeSelection(component=self.colorbar)
        self.colorbar.tools.append(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
        range_selection.listeners.append(img_plot)

        self.full_container = HPlotContainer(padding=30)
        self.container = OverlayPlotContainer(padding=0)
        self.full_container.add(self.colorbar)
        self.full_container.add(self.container)
        self.container.add(self.vm_plot.plot)
コード例 #30
0
class IODriver(t.Thread, HasTraits):
  """ 
      Base class for a generic input driver. Runs in its own thread and grabs input from the 
      source and passes it out to the decoding layer. 
  """
  _variables = Instance(Variables)
  _decoders = List(DataDecoder)
  _wants_to_terminate = False
  _use_thread = True
  name = Str('Input Driver')
  
  def __init__(self, **kwargs):
    t.Thread.__init__(self)
    HasTraits.__init__(self, **kwargs)
  
  def open(self):
    """
        Here is a place to put any initialisation needed to start your driver, e.g. opening 
        a port or file.
    """
    pass

  def close(self):
    """
        Here is a place to put any code needed to cleanly stop your input driver e.g. closing a port
    """
    pass
  
  def receive(self):
    """ 
        In this function you should add the code to setup and read from
        your input source. Return the received data to be passed to the data 
        decoding layer. This function is called repeatedly while the driver 
        is running and should not block indefinately (a timeout should be 
        used to allow the driver to stop). You can return None is no data is available.
    """
    return None
    
  def run(self):
    """ Used internally for the threading interface, you should put your code in receive. """
    if self._use_thread:
      while not self._wants_to_terminate:
        data = self.receive()
        if data:
          self.pass_data(data)
      print "IO driver thread terminating:", self.name
      self.close()
    
  def start(self):
    """ Used internally to start the thread for the input driver, if you have init code put it in open. """
    self.open()
    t.Thread.start(self)

  def stop(self):
    """ Used internally to stop the thread for the input driver, if you have clean-up code put it in close. """
    if self._use_thread:
      self._wants_to_terminate = True
    else:
      self.close()
   
  def _add_decoder(self, decoder):
    """ Used internally to add decoders so they receive data from the input driver. """
    decoder._variables = self._variables
    self._decoders += [decoder]

  def _remove_decoder(self, decoder):
    """ Used internally to remove decoders from an input driver. """
    self._decoders.remove(decoder)

  def _remove_all_decoders(self):
    for decoder in self._decoders:
      self._remove_decoder(decoder)
    
  def pass_data(self, data):
    """ Pass data on to the decoding layer. """
    for decoder in self._decoders: #self._decoder_list.get_decoders():
      decoder._receive_callback(data)

  def get_config(self):
    print "Warning: using defualt get_config handler on io driver '%s' (which may not work)." % self.__class__.__name__
    state = self.__getstate__()
    for key in list(state.iterkeys()):
      if key.startswith('_'):
        del state[key]
    print "  config:", state
    return state

  def set_config(self, config):
    print "Warning: using defualt set_config handler on io driver '%s' (which may not work)." % self.__class__.__name__
    print "  config:", config
    self.__setstate__(config)

  def _get_config(self):
    # get decoders
    decoder_configs = []
    for decoder in self._decoders:
      decoder_config = {decoder.__class__.__name__: decoder.get_config()}
      decoder_configs.append(decoder_config)
    
    config = self.get_config()
    config.update({'decoders': decoder_configs})
    return config

  def _set_config(self, config):
    from plugin_manager import get_decoder_plugin_by_name
    # add decoders
    self._remove_all_decoders()
    for decoder_config in config['decoders']:
      decoder_plugin_name = list(decoder_config.iterkeys())[0]
      decoder_plugin_config = decoder_config[decoder_plugin_name]
      new_decoder = get_decoder_plugin_by_name(decoder_plugin_name)()
      self._add_decoder(new_decoder)
      new_decoder.set_config(decoder_plugin_config)

    del config['decoders']
    self.set_config(config)