Exemplo n.º 1
0
class ExposureView(wx.Panel):
    def __init__(self, *args, **kwargs):
        wx.Panel.__init__(self, *args, **kwargs)

        vbox = wx.BoxSizer(wx.VERTICAL)

        self.image_view = ImageView(self,
                                    ID_EXPOSURE_VIEW,
                                    size=(487, 195),
                                    style=wx.BORDER_SUNKEN)
        vbox.Add(self.image_view, 1, wx.EXPAND)

        self.figure = Figure()
        self.plot = FigureCanvas(self, wx.ID_ANY, self.figure)
        self.plot.SetSize((487, 195))
        self.plot.SetWindowStyle(wx.BORDER_SUNKEN)
        vbox.Add(self.plot, 1, wx.EXPAND)
        self.plot.Hide()

        self.toolbar = NavigationToolbar2WxAgg(self.plot)
        vbox.Add(self.toolbar, 0, wx.EXPAND)
        self.plot.Hide()

        self.SetSizerAndFit(vbox)

    def SetViewMode(self, mode):
        if mode == VIEW_MODE_SPECTRUM:
            self.image_view.Hide()
            self.plot.Show()
            self.toolbar.Show()
        else:
            self.image_view.Show()
            self.plot.Hide()
            self.toolbar.Hide()

        self.Layout()
Exemplo n.º 2
0
class PlotPanel(wx.Panel):
    def __init__(self, parent, choices, *args, **kwargs):
        wx.Panel.__init__(self, parent=parent, *args, **kwargs)

        self.initPieMenu(choices)
        self.initFeatureCanvas()
        self.initLayout()

    def initPieMenu(self, choices):
        self.pieMenu = widgets.PieMenu(
            self,
            choices=choices,
            rotation=np.pi / len(choices) + np.pi / 2.0,
            #colors=('red', (50,220,50), 'yellow', 'blue'))
            colors=('turquoise', 'red', 'blue violet', 'orange', 'blue',
                    'yellow'))

    def initFeatureCanvas(self):
        self.featureFig = plt.Figure()
        ##self.featureFig.subplots_adjust(hspace=0.32, wspace=0.02,
        ##    left=0.065, right=0.95, top=0.97, bottom=0.18)

        self.featureAx = self.featureFig.add_subplot(1, 1, 1)

        self.featureCanvas = FigureCanvas(parent=self,
                                          id=wx.ID_ANY,
                                          figure=self.featureFig)

    def initLayout(self):
        plotSizer = wx.BoxSizer(orient=wx.VERTICAL)

        plotSizer.Add(self.pieMenu, proportion=1, flag=wx.EXPAND | wx.ALL)
        plotSizer.Add(self.featureCanvas,
                      proportion=1,
                      flag=wx.EXPAND | wx.ALL)

        self.SetSizer(plotSizer)

        self.featureCanvas.Hide()
        self.Layout()

    def showPieMenu(self):
        self.featureCanvas.Hide()
        self.pieMenu.Show()
        self.Layout()

    def showFeatureCanvas(self):
        self.featureCanvas.Show()
        self.pieMenu.Hide()
        self.Layout()

    def plotFeatures(self, trainData, freqs, choices, chanNames):
        self.featureAx.cla()

        meanFeat = [np.mean(cls, axis=0) for cls in trainData]
        for cls, choice in zip(meanFeat, choices):
            self.featureAx.plot(cls, label=choice, marker='o', linewidth=2)

        self.featureAx.set_xlabel(r'Frequency ($Hz$)')
        self.featureAx.set_ylabel(
            r'Mean Log$_{10}$ Power $(uV^2 / Hz)^{\frac{1}{2}}$')
        self.featureAx.legend()

        nFreq = len(freqs)
        mn = np.min(np.concatenate(meanFeat))
        mx = np.max(np.concatenate(meanFeat))
        for i, cn in enumerate(chanNames):
            if i > 0:
                self.featureAx.vlines(i * float(nFreq), mn, mx, linestyle='--')
            self.featureAx.text((i + 0.25) * float(nFreq),
                                mx - 0.1 * (mx - mn),
                                cn,
                                fontsize=14)

        tickStride = int(np.ceil(nFreq / 3.0))
        tickFreqs = freqs[::tickStride]
        tickPlaces = np.arange(nFreq)[::tickStride]
        tickLocs = np.concatenate(
            [tickPlaces + nFreq * i for i, c in enumerate(chanNames)])
        tickLabels = np.round(np.tile(tickFreqs,
                                      len(chanNames))).astype(np.int)

        self.featureAx.set_xticks(tickLocs)
        self.featureAx.set_xticklabels(tickLabels)

        self.featureAx.autoscale(tight=True)
        self.featureFig.tight_layout()

        self.showFeatureCanvas()
Exemplo n.º 3
0
class MainWindow(wx.Frame):

    # Constructor
    def __init__(self):
        wx.Frame.__init__(self, parent = None, title = "PyStrEmbed-1")
        self.SetBackgroundColour('white')



        ### MENU BAR
        menuBar  = wx.MenuBar()

        fileMenu = wx.Menu()
        menuBar.Append(fileMenu, "&File")
        fileOpen = fileMenu.Append(wx.ID_OPEN, "&Open", "Open file")
        fileSave = fileMenu.Append(wx.ID_SAVE, "&Save", "Save file")
        fileSaveAs = fileMenu.Append(wx.ID_SAVEAS, "&Save as", "Save file as")
        fileClose = fileMenu.Append(wx.ID_CLOSE, "&Close", "Close file")
        fileExit = fileMenu.Append(wx.ID_EXIT, "&Exit", "Exit program")

        partMenu = wx.Menu()
        menuBar.Append(partMenu, "&Parts")

        geomMenu = wx.Menu()
        menuBar.Append(geomMenu, "&Geometry")

        lattMenu = wx.Menu()
        menuBar.Append(lattMenu, "&Lattice")

        abtMenu   = wx.Menu()
        menuBar.Append(abtMenu,  "&About")
        menuAbout = abtMenu.Append(wx.ID_ABOUT,"&About", "About PyStrEmbed-1")

        self.SetMenuBar(menuBar)



        # Bindings for menu items
        self.Bind(wx.EVT_MENU, self.OnFileOpen,      fileOpen)
        self.Bind(wx.EVT_MENU, self.DoNothingDialog, fileSave)
        self.Bind(wx.EVT_MENU, self.DoNothingDialog, fileSaveAs)
        self.Bind(wx.EVT_MENU, self.OnExit,  fileClose)
        self.Bind(wx.EVT_MENU, self.OnExit,  fileExit)
        self.Bind(wx.EVT_MENU, self.OnAbout, menuAbout)



        ### TOOLBAR
        # Main window toolbar with assembly operations
        self.tb = wx.ToolBar(self, style = wx.TB_NODIVIDER | wx.TB_FLAT)
        self.SetToolBar(self.tb)
        self.tb.SetToolBitmapSize((40,40))
        self.tb.SetBackgroundColour('white')
        # File tools
        self.fileOpenTool  = self.tb.AddTool(wx.ID_ANY, 'Open',  wx.Bitmap("Images/fileopen.bmp"),  bmpDisabled = wx.NullBitmap,
                                   shortHelp = 'File open',  longHelp = 'File open')
        self.exitTool      = self.tb.AddTool(wx.ID_ANY, 'Exit', wx.Bitmap("Images/fileclose.bmp"), bmpDisabled = wx.NullBitmap,
                                   shortHelp = 'Exit', longHelp = 'Exit')
        self.tb.AddSeparator()
        # Assembly tools
        self.insertLeftTool   = self.tb.AddTool(wx.ID_ANY, 'Insert node to left', wx.Bitmap("Images/insertleft1.bmp"), bmpDisabled = wx.NullBitmap,
                                 shortHelp = 'Insert left', longHelp = 'Insert left')
        self.insertRightTool  = self.tb.AddTool(wx.ID_ANY, 'Insert node to right', wx.Bitmap("Images/insertright1.bmp"), bmpDisabled = wx.NullBitmap,
                                 shortHelp = 'Insert right', longHelp = 'Insert right')
        self.adoptTool        = self.tb.AddTool(wx.ID_ANY, 'Adopt node', wx.Bitmap("Images/adopt1.bmp"), bmpDisabled = wx.NullBitmap,
                                 shortHelp = 'Adopt',  longHelp = 'Adopt')
        self.aggregateTool    = self.tb.AddTool(wx.ID_ANY, 'Aggregate nodes', wx.Bitmap("Images/aggregate1.bmp"), bmpDisabled = wx.NullBitmap,
                                 shortHelp = 'Aggregate',   longHelp = 'Aggregate')
        self.disaggregateTool = self.tb.AddTool(wx.ID_ANY, 'Disaggregate nodes', wx.Bitmap("Images/disaggregate1.bmp"), bmpDisabled = wx.NullBitmap,
                                 shortHelp = 'Disaggregate', longHelp = 'Disaggregate')
        self.tb.Realize()



        # Bind toolbar tools to actions
        self.Bind(wx.EVT_TOOL, self.OnFileOpen, self.fileOpenTool)
        self.Bind(wx.EVT_TOOL, self.OnExit,     self.exitTool)

        self.Bind(wx.EVT_TOOL, self.DoNothingDialog, self.insertLeftTool)
        self.Bind(wx.EVT_TOOL, self.DoNothingDialog, self.insertRightTool)
        self.Bind(wx.EVT_TOOL, self.DoNothingDialog, self.adoptTool)
        self.Bind(wx.EVT_TOOL, self.DoNothingDialog, self.aggregateTool)
        self.Bind(wx.EVT_TOOL, self.DoNothingDialog, self.disaggregateTool)



        ### STATUS BAR
        # Status bar
        self.statbar = self.CreateStatusBar()
        self.statbar.SetBackgroundColour('white')
        # Update status bar with window size on (a) first showing and (b) resizing
        self.Bind(wx.EVT_SIZE, self.OnResize, self)



        # Create main panel
        self.InitMainPanel()



    def InitMainPanel(self):

        ### MAIN PANEL
        #
        # Create main panel to contain everything
        self.panel = wx.Panel(self)
        self.box   = wx.BoxSizer(wx.VERTICAL)

        # Create FlexGridSizer to have 3 panes
        # 2nd and 3rd arguments are hgap and vgap b/t panes (cosmetic)
        self.grid = wx.FlexGridSizer(cols = 3, rows = 2, hgap = 10, vgap = 10)

        self.part_header = wx.StaticText(self.panel, label = "Parts view")
        self.geom_header = wx.StaticText(self.panel, label = "Geometry view")
        self.latt_header = wx.StaticText(self.panel, label = "Lattice view")

        self.panel_style = wx.SIMPLE_BORDER
        self.part_panel = wx.Panel(self.panel, style = self.panel_style)
        self.geom_panel = wx.Panel(self.panel, style = self.panel_style)
        self.latt_panel = wx.Panel(self.panel, style = self.panel_style)

        self.part_sizer = wx.BoxSizer(wx.VERTICAL)
        self.latt_sizer = wx.BoxSizer(wx.VERTICAL)
        
        # Some special setup for geometry sizer (grid)
        self.image_cols = 2
        self.geom_sizer = wx.GridSizer(cols = self.image_cols, rows = 0, hgap = 5, vgap = 5)
        # Defines tightness of images in grid (i.e. produces blank border)
        self.geom_tight = 0.7


        # PARTS VIEW SETUP
        # Custom tree ctrl implementation
        self.treeStyle = (ctc.TR_MULTIPLE | ctc.TR_EDIT_LABELS | ctc.TR_HAS_BUTTONS)
        self.partTree_ctc = ctc.CustomTreeCtrl(self.part_panel, agwStyle = self.treeStyle)
        self.partTree_ctc.SetBackgroundColour('white')
        self.part_sizer.Add(self.partTree_ctc, 1, wx.EXPAND)



        # GEOMETRY VIEW SETUP
        # Set up image-view grid, where "rows = 0" means the sizer updates dynamically
        # according to the number of elements it holds
#        self.geom_sizer.Add(self.image_grid, 1, wx.EXPAND)

        # Binding for toggling of part/assembly images
        # though toggle buttons not yet realised
        self.Bind(wx.EVT_TOGGLEBUTTON, self.ImageToggled)
        
        self.no_image_ass  = 'Images/noimage_ass.png'
        self.no_image_part = 'Images/noimage_part.png'



        # LATTICE VIEW SETUP
        # Set up matplotlib FigureCanvas with toolbar for zooming and movement
        self.latt_figure = mpl.figure.Figure()
        self.latt_canvas = FigureCanvas(self.latt_panel, -1, self.latt_figure)
        self.latt_axes   = self.latt_figure.add_subplot(111)
        self.latt_canvas.Hide()

        # Realize but hide, to be shown later when file loaded/data updated
        self.latt_tb = NavigationToolbar(self.latt_canvas)
#        self.latt_tb.Realize()
        self.latt_tb.Hide()

        self.latt_sizer.Add(self.latt_canvas, 1, wx.EXPAND | wx.ALIGN_BOTTOM | wx.ALL, border = 5)
        self.latt_sizer.Add(self.latt_tb, 0, wx.EXPAND)

        self.selected_colour = 'blue'
        


        # OVERALL SIZERS SETUP
        self.part_panel.SetSizer(self.part_sizer)
        self.geom_panel.SetSizer(self.geom_sizer)
        self.latt_panel.SetSizer(self.latt_sizer)

        self.grid.AddMany([(self.part_header), (self.geom_header), (self.latt_header),
                           (self.part_panel, 1, wx.EXPAND), (self.geom_panel, 1, wx.EXPAND), (self.latt_panel, 1, wx.EXPAND)])

        # Set all grid elements to "growable" upon resizing
        # Flags (second argument is proportional size)
        self.grid.AddGrowableRow(1,0)
        self.grid.AddGrowableCol(0,3)
        self.grid.AddGrowableCol(1,2)
        self.grid.AddGrowableCol(2,3)

        # Set sizer for/update main panel
        self.box.Add(self.grid, 1, wx.ALL | wx.EXPAND, 5)
        self.panel.SetSizer(self.box)



    def GetFilename(self, dialog_text = "Open file", starter = None, ender = None):

        ### General file-open method; takes list of file extensions as argument
        ### and can be used for specific file names ("starter", string)
        ### or types ("ender", string or list)

        # Convert "ender" to list if only one element
        if isinstance(ender, str):
            ender = [ender]

        # Check that only one kwarg is present
        # Create text for file dialog
        if starter is not None and ender is None:
            file_open_text = starter.upper() + " files (" + starter.lower() + "*)|" + starter.lower() + "*"
        elif starter is None and ender is not None:
            file_open_text = [el.upper() + " files (*." + el.lower() + ")|*." + el.lower() for el in ender]
            file_open_text = "|".join(file_open_text)
        else:
            raise ValueError("Requires starter or ender only")

        # Create file dialog
        fileDialog = wx.FileDialog(self, dialog_text, "", "",
                                   file_open_text,
                                   wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
        fileDialog.ShowModal()
        filename = fileDialog.GetPath()
        fileDialog.Destroy()

        # Return file name, ignoring rest of path
        return filename



    def DisplayPartsList(self):

        # Create root node...
        root_id  = self.assembly.tree.root
        root_tag = self.assembly.tree.get_node(root_id).tag

        # Exception handler if file loaded previously
        try:
            self.partTree_ctc.DeleteAllItems()
        except:
            pass
        ctc_root_item = self.partTree_ctc.AddRoot(text = root_tag, ct_type = 1)
        self.ctc_dict[root_id] = ctc_root_item
        self.ctc_dict_inv[ctc_root_item] = root_id

        # ...then all others
        # Assumes treelib ordering ensures parents are defined before children
        for el in self.assembly.tree_dict:
            if el != root_id:
                parent_id = self.assembly.tree.parent(el).identifier
                ctc_parent = self.ctc_dict[parent_id]
                ctc_text = self.assembly.part_dict[self.assembly.tree_dict[el]]
                ctc_item = self.partTree_ctc.AppendItem(ctc_parent, text = ctc_text, ct_type = 1)
                self.ctc_dict[el] = ctc_item
                self.ctc_dict_inv[ctc_item] = el
        
        # Binding for checking of list items
        self.Bind(ctc.EVT_TREE_ITEM_CHECKED, self.TreeItemChecked)
        self.Bind(ctc.EVT_TREE_SEL_CHANGED,  self.TreeItemSelected)

        self.partTree_ctc.ExpandAll()
        


    def TreeItemChecked(self, event):
        
        def ScaleImage(img):
            # Resize image to geometry panel
            # NEEDS IMPROVEMENT TO BE MORE GENERAL (IN TERMS OF ASPECT RATIO)
            p_w, p_h   = self.geom_panel.GetSize()
            h          = img.GetHeight()
            w          = img.GetWidth()
            
            w_new = p_w*self.geom_tight/self.image_cols
            h_new = w_new*h/w
            img = img.Scale(w_new, h_new)

            return img
        
        
        
        # Get checked item and search for corresponding image
        #
        item = event.GetItem()
        id_  = self.ctc_dict_inv[item]
        
        self.selected_items = self.partTree_ctc.GetSelections()

        if item.IsChecked():
            # Get image
            if id_ in self.assembly.leaf_ids:
                img = self.assembly.tree_dict[id_]
                img = os.path.join('Images', img + '.png')
                if os.path.isfile(img):
                    img = wx.Image(img, wx.BITMAP_TYPE_ANY)
                else:
                    img = wx.Image(self.no_image_part, wx.BITMAP_TYPE_ANY)
            else:
                img = wx.Image(self.no_image_ass, wx.BITMAP_TYPE_ANY)
                
            # Create/add button in geom_panel
            # 
            # Includes rescaling to panel
            img = ScaleImage(img)
            button = wx.BitmapToggleButton(self.geom_panel, id_, wx.Bitmap(img))
            button.SetBackgroundColour('white')
            self.geom_sizer.Add(button, 0, wx.EXPAND)
            
            # Update global list and dict
            #
            # Data is list, i.e. same format as "selected_items"
            # but ctc lacks "get selections" method for checked items
            self.checked_items.append(item)
            self.button_dict[id_] = button
            self.button_dict_inv[button] = id_
            
            # Toggle if already selected elsewhere
            if self.ctc_dict[id_] in self.selected_items:
                button.SetValue(True)
            else:
                pass
            
        else:
            # Remove button from geom_panel
            obj = self.button_dict[id_]
            obj.Destroy()
            
            # Update global list and dict
            self.checked_items.remove(item)
            self.button_dict.pop(id_)
            self.button_dict_inv.pop(obj)
           
        # Update image sizer
        self.geom_sizer.Layout()
            


    def TreeItemSelected(self, event):
        
        # Get selected item and update global list of items
        #
        # Using GetSelection rather than maintaining list of items
        # as with checked items b/c releasing ctrl key during multiple
        # selection means not all selections are tracked easily
        self.selected_items = self.partTree_ctc.GetSelections()
        
        self.UpdateToggledImages()
        self.UpdateLatticeSelections()



    def ImageToggled(self, event):
        
        id_ = event.GetId()
        self.UpdateListSelections(id_)
        
        self.UpdateLatticeSelections()

        

    def UpdateListSelections(self, id_):
        
        # Select/deselect parts list item
        item = self.ctc_dict[id_]
        if item in self.selected_items:
            self.selected_items.remove(item)
        else:
            self.selected_items.append(item)
        
        # With "select = True", SelectItem toggles state if multiple selections enabled
        self.partTree_ctc.SelectItem(self.ctc_dict[id_], select = True)



    def UpdateLatticeSelections(self):
        
        # Update colour of selected items
        #
        # Set all back to default colour first
        for node in self.assembly.g.nodes():
            self.assembly.g.nodes[node]['colour'] = self.assembly.default_colour
        # Then selected nodes
        for item in self.selected_items:
            id_ = self.ctc_dict_inv[item]
            self.assembly.g.nodes[id_]['colour'] = self.selected_colour
        
        # Redraw lattice
        self.DisplayLattice()


    
    def UpdateToggledImages(self):
        
        for id_, button in self.button_dict.items():
            button.SetValue(False)
        
        for item in self.selected_items:
            id_    = self.ctc_dict_inv[item]
            if id_ in self.button_dict:
                button = self.button_dict[id_]
                button.SetValue(True)
            else:
                pass
        


    def DisplayLattice(self):

        # Get node positions, colour map, labels
        pos         = nx.get_node_attributes(self.assembly.g, 'pos')
        colour_map  = [self.assembly.g.nodes[el]['colour'] for el in self.assembly.g.nodes]
#        node_labels = nx.get_node_attributes(self.assembly.g, 'label')
        
        # Draw to lattice panel figure
        try:
            self.latt_axes.clear()
        except:
            pass
        nx.draw(self.assembly.g, pos, node_color = colour_map, with_labels = True, ax = self.latt_axes)
#        nx.draw_networkx_labels(self.assembly.g, pos, labels = node_labels, ax = self.latt_axes)

        # Minimise white space around plot in panel
        self.latt_figure.subplots_adjust(left = 0.01, bottom = 0.01, right = 0.99, top = 0.99)

        # Show lattice figure
        self.latt_canvas.draw()
        self.latt_canvas.Show()
        self.latt_tb.Show()

        # Update lattice panel layout
        self.latt_panel.Layout()



    def DoNothingDialog(self, event):

        nowt = wx.MessageDialog(self, "Functionality to be added", "Do nothing dialog", wx.OK)
        # Create modal dialogue that stops process
        nowt.ShowModal()
        nowt.Destroy()



    def OnFileOpen(self, event):

#        # Delete if exists from previous file load
#        # TO BE COMPLETED FOR VERSION 1-2
#        try:
#            del self.assembly
#        except AttributeError:
#            pass
        
        # Get STEP filename
        self.open_filename = self.GetFilename(ender = ["stp", "step"]).split("\\")[-1]

        # Load data, create nodes and edges, etc.
        self.assembly = StepParse()
        self.assembly.load_step(self.open_filename)
        self.assembly.create_tree()

        # Checked and selected items lists, shared b/t all views
        self.checked_items  = []
        self.selected_items = []

        # Toggle buttons
        self.button_dict     = {}
        self.button_dict_inv = {}
        
        # Write interactive parts list using WX customtreectrl, from treelib nodes
        self.ctc_dict     = {}
        self.ctc_dict_inv = {}



        # Show parts list and lattice
        self.DisplayPartsList()
        
        # Clear geometry window if necessary
        try:
            self.geom_sizer.Clear(True)
        except:
            pass    
        
        # Clear lattice plot if necessary
        try:
            self.latt_axes.clear()
        except:
            pass
        
        # Display lattice
        self.DisplayLattice()



    def OnInsertLeft(self, event):
        pass



    def OnInsertRight(self, event):
        pass



    def OnAdopt(self, event):

        pass



    def OnAggregate(self, event):

        pass



    def OnDisaggregate(self, event):

        pass



    def OnAbout(self, event):

        # Show program info
        abt_text = """StrEmbed-5-1: A user interface for manipulation of design configurations\n
            Copyright (C) 2019 Hugh Patrick Rice\n
            This program is free software: you can redistribute it and/or modify
            it under the terms of the GNU General Public License as published by
            the Free Software Foundation, either version 3 of the License, or
            (at your option) any later version.\n
            This program is distributed in the hope that it will be useful,
            but WITHOUT ANY WARRANTY; without even the implied warranty of
            MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
            GNU General Public License for more details.\n
            You should have received a copy of the GNU General Public License
            along with this program. If not, see <https://www.gnu.org/licenses/>."""
 
        abt = wx.MessageDialog(self, abt_text, 'About StrEmbed-5-1', wx.OK)
        abt.ShowModal()         # Shows dialogue that stops process (modal)
        abt.Destroy()



    def OnExit(self, event):

        self.Close(True)        # Close program



    def OnResize(self, event):

        # Display window size in status bar
        self.statbar.SetStatusText("Window size = " + format(self.GetSize()))
        event.Skip()
Exemplo n.º 4
0
class Spectrogram(StandardMonitorPage):
    """Main class for a page that generates real-time spectrogram plots of EEG.
    """
    def __init__(self, *args, **kwargs):
        """Construct a new Spectrogram page.

        Args:
            *args, **kwargs:  Arguments to pass to the Page base class.
        """
        self.initConfig()

        # initialize Page base class
        StandardMonitorPage.__init__(self,
                                     name='Spectrogram',
                                     configPanelClass=ConfigPanel,
                                     *args,
                                     **kwargs)

        self.initCanvas()
        self.initLayout()

    def initConfig(self):
        self.filter = True  # use raw or filtered signal
        self.chanIndex = 0  # index of channel to show
        self.width = 5.0  # width of window to use for computing PSD

        self.decimationFactor = 1  # decimation factor, e.g., 2 will decimate to half sampRate

        self.interpolation = 'none'

        self.normScale = 'log'
        self.scale = -2

        self.method = 'Wavelet'

        self.setRefreshDelay(200)

        self.waveletConfig = util.Holder(nFreq=100, span=10)

        self.fourierConfig = util.Holder()

    def initCanvas(self):
        """Initialize a new matplotlib canvas, figure and axis.
        """
        self.plotPanel = wx.Panel(self)
        self.plotPanel.SetBackgroundColour('white')
        plotSizer = wx.BoxSizer(orient=wx.VERTICAL)
        self.plotPanel.SetSizer(plotSizer)

        self.fig = plt.Figure(facecolor='white')
        #self.canvas = FigureCanvas(parent=self, id=wx.ID_ANY, figure=self.fig)
        self.canvas = FigureCanvas(parent=self.plotPanel,
                                   id=wx.ID_ANY,
                                   figure=self.fig)

        self.ax = self.fig.add_subplot(1, 1, 1)
        self.ax.set_xlabel('Time (s)')
        self.ax.set_ylabel('Frequency (Hz)')

        self.cbAx = self.fig.add_axes([0.91, 0.05, 0.03, 0.93])

        #self.fig.subplots_adjust(hspace=0.0, wspace=0.0,
        #    left=0.035, right=0.92, top=0.98, bottom=0.05)

        self.adjustMargins()

        self.firstPlot()

        self.lastSize = (0, 0)
        self.needsResizePlot = True
        self.canvas.Bind(wx.EVT_SIZE, self.resizePlot)
        self.canvas.Bind(wx.EVT_IDLE, self.idleResizePlot)

        ##self.plotToolbar = widgets.PyPlotNavbar(self.canvas)
        ##plotSizer.Add(self.plotToolbar, proportion=0, flag=wx.EXPAND)
        plotSizer.Add(self.canvas, proportion=1, flag=wx.EXPAND)

        #self.plotToolbar.Hide()

    def initLayout(self):
        self.initStandardLayout()

        plotPaneAuiInfo = aui.AuiPaneInfo().Name('canvas').Caption(
            'Spectrogram').CenterPane()
        #self.auiManager.AddPane(self.canvas, plotPaneAuiInfo)
        self.auiManager.AddPane(self.plotPanel, plotPaneAuiInfo)

        self.auiManager.Update()

        self.canvas.Hide()

    def afterUpdateSource(self):
        self.configPanel.updateChannels()

    def afterStart(self):
        # make sure canvas is visible
        self.canvas.Show()
        self.plotPanel.Layout()

        # trigger initial plot update
        self.needsFirstPlot = True

    def getCap(self):
        cap = self.src.getEEGSecs(self.width, filter=self.filter, copy=False)
        if self.decimationFactor > 1:
            cap.decimate(self.decimationFactor)

        return cap

    def getSpectrum(self, cap):
        # configurable XXX - idfah
        data = cap.data[:, self.chanIndex] * sig.windows.tukey(
            cap.data.shape[0])  # tukey or hann? XXX - idfah

        freqs, powers, phases = self.cwt.apply(data)

        # configurable XXX - idfah
        powers = np.clip(powers, 1.0e-10, np.inf)

        return freqs, powers

    def firstPlot(self, event=None):
        cap = self.getCap()

        self.cwt = sig.CWT(sampRate=cap.getSampRate(),
                           freqs=self.waveletConfig.nFreq,
                           span=self.waveletConfig.span)

        if self.isRunning():
            freqs, powers = self.getSpectrum(cap)
        else:
            freqs = np.arange(1, self.src.getSampRate() // 2 + 1)
            powers = np.zeros((128, 10, 1))
            powers[0, 0, 0] = 1.0

        self.ax.cla()
        self.cbAx.cla()

        self.ax.set_xlabel('Time (s)')
        self.ax.set_ylabel('Frequency (Hz)')

        self.wimg = self.ax.imshow(powers[:, :, 0].T,
                                   interpolation=self.interpolation,
                                   origin='lower',
                                   aspect='auto',
                                   norm=self.getNorm(),
                                   extent=self.getExtent(cap, freqs),
                                   cmap=plt.cm.get_cmap('jet'),
                                   animated=True)

        self.cbar = self.fig.colorbar(self.wimg, cax=self.cbAx)
        self.cbar.set_label(r'Power Density ($V^2 / Hz$)')

        #self.updateNorm(powers)

        self.canvas.draw()

        #self.background = self.canvas.copy_from_bbox(self.fig.bbox)
        self.background = self.canvas.copy_from_bbox(self.ax.bbox)

        self.needsFirstPlot = False

    def adjustMargins(self):
        self.fig.subplots_adjust(hspace=0.0,
                                 wspace=0.0,
                                 left=0.045,
                                 right=0.90,
                                 top=0.98,
                                 bottom=0.07)

    def resizePlot(self, event):
        # prevents handling extra resize events, hack XXX - idfah
        size = self.canvas.GetSize()
        if self.lastSize == size:
            return
        else:
            self.lastSize = size

        # this is all a hack to do resizing on idle when page is not running
        # should this be a custom FigureCanvas derived widget? XXX - idfah
        if self.isRunning():
            # when running, just do event.Skip() this will
            # call canvas._onSize since it is second handler
            self.needsResizePlot = False
            event.Skip()
        else:
            # flag to resize on next idle event
            self.needsResizePlot = True

    def idleResizePlot(self, event):
        # if not running and flagged for resize
        if not self.isRunning() and self.needsResizePlot:
            ##self.adjustMargins()
            self.needsResizePlot = False
            # call canvas resize method manually
            # hack alert, we just pass None as event
            # since it's not used anyway
            self.canvas._onSize(None)

    def getExtent(self, cap, freqs):
        return (0.0, cap.getNObs() / float(cap.getSampRate()), np.min(freqs),
                np.max(freqs))

    def getNorm(self):
        mx = 10**self.scale

        if self.normScale == 'linear':
            mn = 0.0
            norm = pltLinNorm(mn, mx)

        elif self.normScale == 'log':
            mn = 1e-10
            norm = pltLogNorm(mn, mx)

        else:
            raise RuntimeError('Invalid norm %s.' % norm)

        return norm

    def updatePlot(self, event=None):
        """Draw the spectrogram plot.
        """
        if self.needsFirstPlot:
            self.firstPlot()

        else:
            cap = self.getCap()
            freqs, powers = self.getSpectrum(cap)

            #self.updateNorm(powers)

            self.canvas.restore_region(self.background)
            self.wimg.set_array(powers[:, :, 0].T)
            self.wimg.set_extent(self.getExtent(cap, freqs))
            self.ax.draw_artist(self.wimg)

            ##self.cbAx.draw_artist(self.cbar.patch)
            ##self.cbAx.draw_artist(self.cbar.solids)

            #self.cbar.draw_all()
            #self.canvas.blit(self.cbAx.bbox)

            #self.canvas.blit(self.fig.bbox)
            self.canvas.blit(self.ax.bbox)

            # for debugging, redraws everything
            ##self.canvas.draw()

    def captureImage(self, event=None):
        ## Parts borrowed from backends_wx.py from matplotlib
        # Fetch the required filename and file type.
        filetypes, exts, filter_index = self.canvas._get_imagesave_wildcards()
        default_file = self.canvas.get_default_filename()
        dlg = wx.FileDialog(self, "Save to file", "", default_file, filetypes,
                            wx.SAVE | wx.OVERWRITE_PROMPT)
        dlg.SetFilterIndex(filter_index)
        if dlg.ShowModal() == wx.ID_OK:
            dirname = dlg.GetDirectory()
            filename = dlg.GetFilename()
            format = exts[dlg.GetFilterIndex()]
            basename, ext = os.path.splitext(filename)
            if ext.startswith('.'):
                ext = ext[1:]
            if ext in ('svg', 'pdf', 'ps', 'eps', 'png') and format != ext:
                #looks like they forgot to set the image type drop
                #down, going with the extension.
                format = ext
            self.canvas.print_figure(os.path.join(dirname, filename),
                                     format=format)
Exemplo n.º 5
0
class PlotPanel(wx.Panel):
    def __init__(self, parent, pg, *args, **kwargs):
        wx.Panel.__init__(self, parent=parent, *args, **kwargs)
        self.pg = pg

        # various initialization routines
        self.initPieMenu()
        self.initERPCanvas()
        self.initLayout()

    def initPieMenu(self):
        self.pieMenu = widgets.PieMenu(self,
                choices=self.pg.choices,
                rotation=4.0*np.pi/len(self.pg.choices),
                colors=('turquoise', 'red', 'blue violet', 'orange',
                        'blue', 'yellow'))
                #colors=('turquoise', 'red', 'blue', 'green',
                #        'yellow', 'blue violet'))

    def initERPCanvas(self):
        #self.erpFig = plt.Figure()
        #self.erpAx = self.erpFig.add_subplot(1,1,1)
        #self.erpCanvas = FigureCanvas(parent=self, id=wx.ID_ANY, figure=self.erpFig)
        self.erpFig = plt.Figure()
        self.erpFig.subplots_adjust(hspace=0.32, wspace=0.02,
            left=0.065, right=0.95, top=0.97, bottom=0.18)
        gs = pltgs.GridSpec(2,4)
        self.erpAx = self.erpFig.add_subplot(gs[0,:])
        self.h1Ax  = self.erpFig.add_subplot(gs[1,0])
        self.h2Ax  = self.erpFig.add_subplot(gs[1,1])
        self.h3Ax  = self.erpFig.add_subplot(gs[1,2])
        self.h4Ax  = self.erpFig.add_subplot(gs[1,3])
        self.cbAx  = self.erpFig.add_axes([0.05, 0.08, 0.9, 0.05])
        self.erpCanvas = FigureCanvas(parent=self, id=wx.ID_ANY, figure=self.erpFig)

    def initLayout(self):
        plotSizer = wx.BoxSizer(orient=wx.VERTICAL)

        plotSizer.Add(self.pieMenu, proportion=1, flag=wx.EXPAND)
        plotSizer.Add(self.erpCanvas, proportion=1, flag=wx.EXPAND)

        self.SetSizer(plotSizer)

        self.erpCanvas.Hide()
        self.Layout()

    def showPieMenu(self):
        self.erpCanvas.Hide()
        self.pieMenu.Show()
        self.Layout()

    def showERPCanvas(self):
        self.erpCanvas.Show()
        #self.erpCanvas.draw()
        self.pieMenu.Hide()
        self.Layout()

    def plotERP(self, cap):
        chanIndex = cap.getChanIndices(('cz',))[0]
        if chanIndex is None:
            chans = (0,)
            chanIndex = 0
            wx.LogWarning('Could not find channel Cz.  Using first channel instead.')
        else:
            chans = ('Cz',)

        cap = cap.copy().bandpass(0.5, np.inf, order=3)

        seg = cap.segment(start=-0.2, end=0.75)

        targ = seg.select(matchFunc=lambda mark: self.pg.markToStim(mark) == self.pg.targStr)
        nonTarg = seg.select(matchFunc=lambda mark: self.pg.markToStim(mark) == self.pg.nonTargStr)

        for ax in (self.erpAx, self.h1Ax, self.h2Ax, self.h3Ax, self.h4Ax):
            ax.cla()

        targPlot = targ.plotAvg(chans=chans, ax=self.erpAx, linewidth=2, color='blue')
        targPlot['lines'][0].set_label(self.pg.targStr + ' ERP')

        nonTargPlot = nonTarg.plotAvg(chans=chans, ax=self.erpAx, linewidth=2, color='green')
        nonTargPlot['lines'][0].set_label(self.pg.nonTargStr + ' ERP')

        erp = np.mean(targ.data, axis=0)

        mn = np.min(erp[:,chanIndex])
        mx = np.max(erp[:,chanIndex])

        self.erpAx.hlines(0.0, 0.0, 0.8, linestyle='--', linewidth=2, color='grey')
        self.erpAx.vlines(0.0, mn, mx, linestyle='--', linewidth=2, color='grey')
        self.erpAx.vlines((200, 300, 400, 500), mn, mx,
                          linestyle='--', linewidth=1, color='red')

        self.erpAx.legend()
        self.erpAx.set_xlabel('Time (s)')
        self.erpAx.set_ylabel(r'Signal ($\mu V$)')

        sampRate = targ.getSampRate()
        erp1 = erp[int((0.2+0.2)*sampRate),:]
        erp2 = erp[int((0.2+0.3)*sampRate),:]
        erp3 = erp[int((0.2+0.4)*sampRate),:]
        erp4 = erp[int((0.2+0.5)*sampRate),:]

        erpAll = np.concatenate((erp1, erp2, erp3, erp4))

        mn = np.min(erpAll)
        mx = np.max(erpAll)

        interpMethod = 'multiquadric'
        coord = '3d'
        h1 = eeg.plotHeadInterp(erp1, chanNames=targ.getChanNames(),
            method=interpMethod, coord=coord, mn=mn, mx=mx, ax=self.h1Ax)
        self.h1Ax.set_title('200ms')
        h2 = eeg.plotHeadInterp(erp2, chanNames=targ.getChanNames(),
            method=interpMethod, coord=coord, mn=mn, mx=mx, ax=self.h2Ax)
        self.h2Ax.set_title('300ms')
        h3 = eeg.plotHeadInterp(erp3, chanNames=targ.getChanNames(),
            method=interpMethod, coord=coord, mn=mn, mx=mx, ax=self.h3Ax)
        self.h3Ax.set_title('400ms')
        h4 = eeg.plotHeadInterp(erp4, chanNames=targ.getChanNames(),
            method=interpMethod, coord=coord, mn=mn, mx=mx, ax=self.h4Ax)
        self.h4Ax.set_title('500ms')

        cbar = plt.colorbar(h1['im'], ax=self.erpAx, orientation='horizontal', cax=self.cbAx)

        cbar.set_label(r'Target ERP ($\mu V$)')

        self.showERPCanvas()
Exemplo n.º 6
0
class mainFrame(wx.Frame):

    Data = None

    def __init__(self, parent):
        wx.Frame.__init__(self,
                          parent,
                          id=wx.ID_ANY,
                          title=u"Обработка данных детектора",
                          pos=wx.DefaultPosition,
                          size=wx.Size(737, 425),
                          style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL)

        self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize)

        bSizer1 = wx.BoxSizer(wx.VERTICAL)

        self.m_panel2 = wx.Panel(self, wx.ID_ANY, wx.DefaultPosition,
                                 wx.DefaultSize, wx.TAB_TRAVERSAL)
        self.m_panel2.SetForegroundColour(
            wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW))
        self.m_panel2.SetBackgroundColour(
            wx.SystemSettings.GetColour(wx.SYS_COLOUR_3DLIGHT))

        bSizer61 = wx.BoxSizer(wx.VERTICAL)

        gSizer21 = wx.GridSizer(0, 2, 0, 0)

        bSizer6 = wx.BoxSizer(wx.VERTICAL)

        self.graphPanel1 = wx.Panel(self.m_panel2, wx.ID_ANY,
                                    wx.DefaultPosition, wx.DefaultSize,
                                    wx.TAB_TRAVERSAL)
        bSizer14 = wx.BoxSizer(wx.VERTICAL)

        self.graphPanel1.SetSizer(bSizer14)
        self.graphPanel1.Layout()
        bSizer14.Fit(self.graphPanel1)
        bSizer6.Add(self.graphPanel1, 1, wx.EXPAND | wx.ALL, 5)

        ###########
        self.figure1 = Figure()
        #self.axes1 = self.figure.add_subplot(111)
        self.canvas1 = FigureCanvas(self, wx.ID_ANY, self.figure1)
        bSizer14.Add(self.canvas1, 1, wx.LEFT | wx.TOP | wx.EXPAND)
        self.toolbar1 = NavigationToolbar2Wx(self.canvas1)
        self.toolbar1.Realize()
        bSizer14.Add(self.toolbar1, 0, wx.LEFT | wx.EXPAND)
        self.toolbar1.Show()
        self.Fit()
        ################

        gSizer21.Add(bSizer14, 2, wx.EXPAND, 5)

        bSizer7 = wx.BoxSizer(wx.VERTICAL)

        self.m_staticText4 = wx.StaticText(self.m_panel2, wx.ID_ANY,
                                           u"MyLabel", wx.DefaultPosition,
                                           wx.DefaultSize, 0)
        self.m_staticText4.Wrap(-1)
        self.m_staticText4.SetForegroundColour(
            wx.SystemSettings.GetColour(wx.SYS_COLOUR_INFOTEXT))

        bSizer7.Add(self.m_staticText4, 0, wx.ALL, 5)

        self.m_staticText5 = wx.StaticText(self.m_panel2, wx.ID_ANY,
                                           u"MyLabel", wx.DefaultPosition,
                                           wx.DefaultSize, 0)
        self.m_staticText5.Wrap(-1)
        self.m_staticText5.SetForegroundColour(
            wx.SystemSettings.GetColour(wx.SYS_COLOUR_INFOTEXT))

        bSizer7.Add(self.m_staticText5, 0, wx.ALL, 5)

        self.m_staticText6 = wx.StaticText(self.m_panel2, wx.ID_ANY,
                                           u"MyLabel", wx.DefaultPosition,
                                           wx.DefaultSize, 0)
        self.m_staticText6.Wrap(-1)
        self.m_staticText6.SetForegroundColour(
            wx.SystemSettings.GetColour(wx.SYS_COLOUR_INFOTEXT))

        bSizer7.Add(self.m_staticText6, 0, wx.ALL, 5)

        gSizer21.Add(bSizer7, 0, wx.EXPAND, 5)

        bSizer61.Add(gSizer21, 1, wx.EXPAND, 5)

        gSizer3 = wx.GridSizer(0, 2, 0, 0)

        bSizer62 = wx.BoxSizer(wx.VERTICAL)

        gSizer3.Add(bSizer62, 1, wx.EXPAND, 5)

        bSizer71 = wx.BoxSizer(wx.VERTICAL)

        self.m_staticText41 = wx.StaticText(self.m_panel2, wx.ID_ANY,
                                            u"MyLabel", wx.DefaultPosition,
                                            wx.DefaultSize, 0)
        self.m_staticText41.Wrap(-1)
        self.m_staticText41.SetForegroundColour(
            wx.SystemSettings.GetColour(wx.SYS_COLOUR_INFOTEXT))

        bSizer71.Add(self.m_staticText41, 0, wx.ALL, 5)

        self.m_staticText51 = wx.StaticText(self.m_panel2, wx.ID_ANY,
                                            u"MyLabel", wx.DefaultPosition,
                                            wx.DefaultSize, 0)
        self.m_staticText51.Wrap(-1)
        self.m_staticText51.SetForegroundColour(
            wx.SystemSettings.GetColour(wx.SYS_COLOUR_INFOTEXT))

        bSizer71.Add(self.m_staticText51, 0, wx.ALL, 5)

        self.m_staticText61 = wx.StaticText(self.m_panel2, wx.ID_ANY,
                                            u"MyLabel", wx.DefaultPosition,
                                            wx.DefaultSize, 0)
        self.m_staticText61.Wrap(-1)
        self.m_staticText61.SetForegroundColour(
            wx.SystemSettings.GetColour(wx.SYS_COLOUR_INFOTEXT))

        bSizer71.Add(self.m_staticText61, 0, wx.ALL, 5)

        gSizer3.Add(bSizer71, 1, wx.EXPAND, 5)

        bSizer61.Add(gSizer3, 1, wx.EXPAND, 5)

        self.m_panel2.SetSizer(bSizer61)
        self.m_panel2.Layout()
        bSizer61.Fit(self.m_panel2)
        bSizer1.Add(self.m_panel2, 1, wx.EXPAND, 5)

        self.SetSizer(bSizer1)
        self.Layout()
        self.m_menubar1 = wx.MenuBar(0)
        self.m_menu1 = wx.Menu()
        self.m_menuItem1 = wx.MenuItem(self.m_menu1, wx.ID_ANY, u"Открыть...",
                                       wx.EmptyString, wx.ITEM_NORMAL)
        self.m_menu1.AppendItem(self.m_menuItem1)

        self.m_menu1.AppendSeparator()

        self.m_menuItem2 = wx.MenuItem(self.m_menu1, wx.ID_ANY, u"Выход",
                                       wx.EmptyString, wx.ITEM_NORMAL)
        self.m_menu1.AppendItem(self.m_menuItem2)

        self.m_menubar1.Append(self.m_menu1, u"Файл")

        self.m_menu2 = wx.Menu()
        self.m_menuItem3 = wx.MenuItem(self.m_menu2, wx.ID_ANY, u"График 1",
                                       wx.EmptyString, wx.ITEM_CHECK)
        self.m_menu2.AppendItem(self.m_menuItem3)
        self.m_menuItem3.Check(True)

        self.m_menuItem4 = wx.MenuItem(self.m_menu2, wx.ID_ANY, u"График 2",
                                       wx.EmptyString, wx.ITEM_CHECK)
        self.m_menu2.AppendItem(self.m_menuItem4)
        self.m_menuItem4.Check(True)

        self.m_menubar1.Append(self.m_menu2, u"Показать")

        self.SetMenuBar(self.m_menubar1)

        self.Centre(wx.BOTH)

        # COnnect events
        self.Bind(wx.EVT_MENU, self.openFile, id=self.m_menuItem1.GetId())
        self.Bind(wx.EVT_MENU, self.showGraph1, id=self.m_menuItem3.GetId())

    def showGraph1(self, event):
        if self.m_menuItem3.IsChecked() == False:
            self.graphPanel1.Hide()
            self.canvas1.Hide()
            self.toolbar1.Hide()
        else:
            self.graphPanel1.Show()
            self.canvas1.Show()
            self.toolbar1.Show()

    def __del__(self):
        pass

    def openFile(self, event):
        with wx.FileDialog(self,
                           "Открыть файл данных детектора",
                           wildcard="DAT файлы (*.dat)|*.dat",
                           style=wx.FD_OPEN
                           | wx.FD_FILE_MUST_EXIST) as fileDialog:

            if fileDialog.ShowModal() == wx.ID_CANCEL:
                return  # the user changed their mind

            # Proceed loading the file chosen by the user
            pathname = fileDialog.GetPath()
            try:
                self.Data = DetectorData(pathname)
                self.axes1 = self.figure1.add_subplot(111)
                self.axes1.plot(self.Data.datTim, self.Data.inten)
                self.axes1.set_xlabel("Время хуемя")
                self.axes1.set_ylabel("Интенсивность")

                self.axes2 = self.figure1.add_subplot(111)
                self.axes2.plot(self.Data.datTim, self.Data.press)
                self.axes2.set_ylabel("Давление")

            except IOError:
                wx.LogError("Не удалось открыть файл '%s'." % newfile)