コード例 #1
0
    def __init__(
        self,
        parent=None,
        spike_times=None,
        sorted=None,
        colors=None,
        show_button=True,
        plotParams=None,
    ):
        QWidget.__init__(self, parent)
        PlotBase.__init__(self, plotParams=plotParams)

        self.colors = colors

        self.spikeSortingWin = self.parent()
        mainLayout = QVBoxLayout()
        self.setLayout(mainLayout)

        h = QHBoxLayout()
        mainLayout.addLayout(h)
        self.combo1 = QComboBox()
        h.addWidget(self.combo1)
        self.connect(self.combo1, SIGNAL('currentIndexChanged( int )'),
                     self.comboChanged)
        self.combo2 = QComboBox()
        h.addWidget(self.combo2)
        self.connect(self.combo2, SIGNAL('currentIndexChanged( int )'),
                     self.comboChanged)

        self.canvas = SimpleCanvasAndTool(orientation=Qt.Horizontal)
        self.fig = self.canvas.fig
        self.ax = self.fig.add_subplot(1, 1, 1)
        mainLayout.addWidget(self.canvas)

        if show_button:
            but = QPushButton('', self.canvas.canvas)
            #~ but = QPushButton('',parent = self.canvas)
            but.setIcon(QIcon(':/configure.png'))
            but.setGeometry(10, 10, 30, 30)
            self.canvas.stackUnder(but)
            self.connect(but, SIGNAL('clicked()'), self.changePlotOptions)

        self.changeData(spike_times, sorted=sorted)
コード例 #2
0
    def __init__(self , parent=None ,
                        
                        spike_times = None,
                        sorted = None,
                        colors = None,
                        
                        show_button = True,
                        plotParams = None,
                        
                        
                        ):
        QWidget.__init__(self,parent )
        PlotBase.__init__(self,plotParams = plotParams)

        
        self.colors = colors

        self.spikeSortingWin = self.parent()
        mainLayout = QVBoxLayout()
        self.setLayout(mainLayout)
        
        h = QHBoxLayout()
        mainLayout.addLayout(h)
        self.combo1 = QComboBox()
        h.addWidget( self.combo1 )
        self.connect( self.combo1, SIGNAL('currentIndexChanged( int )') , self.comboChanged )
        self.combo2 = QComboBox()
        h.addWidget( self.combo2 )
        self.connect( self.combo2, SIGNAL('currentIndexChanged( int )') , self.comboChanged )
        
        
        
        self.canvas = SimpleCanvasAndTool(orientation = Qt.Horizontal )
        self.fig = self.canvas.fig
        self.ax = self.fig.add_subplot(1,1,1)
        mainLayout.addWidget(self.canvas)
        
        if show_button:
            but = QPushButton('',self.canvas.canvas)
            #~ but = QPushButton('',parent = self.canvas)
            but.setIcon(QIcon(':/configure.png'))
            but.setGeometry(10,10,30,30)
            self.canvas.stackUnder(but)
            self.connect(but, SIGNAL('clicked()') , self.changePlotOptions)
        
        self.changeData(spike_times , sorted = sorted )
コード例 #3
0
class PlotCrossCorrelogram(QWidget, PlotBase):
    """
    widget to plot PlotCrossCorrelogram
    """
    plotParamDefault = [
        ['plot_type', {
            'value': 'line',
            'possible': ['bar', 'line']
        }],
        ['bin_width', {
            'value': 2.,
            'label': 'bin width (ms)'
        }],
        ['limit', {
            'value': 500.,
            'label': 'max limit (ms)'
        }],
        ['exact', {
            'value': False,
            'label': 'Compute exact crosscorrelogram'
        }],
        ['max_spike', {
            'value': 300,
            'label': 'Otherwise bootstrap with'
        }],
    ]

    def __init__(
        self,
        parent=None,
        spike_times=None,
        sorted=None,
        colors=None,
        show_button=True,
        plotParams=None,
    ):
        QWidget.__init__(self, parent)
        PlotBase.__init__(self, plotParams=plotParams)

        self.colors = colors

        self.spikeSortingWin = self.parent()
        mainLayout = QVBoxLayout()
        self.setLayout(mainLayout)

        h = QHBoxLayout()
        mainLayout.addLayout(h)
        self.combo1 = QComboBox()
        h.addWidget(self.combo1)
        self.connect(self.combo1, SIGNAL('currentIndexChanged( int )'),
                     self.comboChanged)
        self.combo2 = QComboBox()
        h.addWidget(self.combo2)
        self.connect(self.combo2, SIGNAL('currentIndexChanged( int )'),
                     self.comboChanged)

        self.canvas = SimpleCanvasAndTool(orientation=Qt.Horizontal)
        self.fig = self.canvas.fig
        self.ax = self.fig.add_subplot(1, 1, 1)
        mainLayout.addWidget(self.canvas)

        if show_button:
            but = QPushButton('', self.canvas.canvas)
            #~ but = QPushButton('',parent = self.canvas)
            but.setIcon(QIcon(':/configure.png'))
            but.setGeometry(10, 10, 30, 30)
            self.canvas.stackUnder(but)
            self.connect(but, SIGNAL('clicked()'), self.changePlotOptions)

        self.changeData(spike_times, sorted=sorted)

    def refresh(self):
        self.changeData(self.spike_times)

    def changeData(self, spike_times, sorted=None, colors=None):
        if spike_times is None: return
        self.spike_times = spike_times

        # sorted
        if sorted is not None:
            self.sorted = sorted
        if self.sorted is None:
            self.sorted = ones(waveforms.shape[0], dtype='i')
        # colors
        if colors is not None:
            self.colors = colors
        if self.colors is None:
            self.colors = {}
            cmap = get_cmap('jet', unique(self.sorted).size + 3)
            for i, c in enumerate(unique(self.sorted)):
                self.colors[c] = cmap(i + 2)

        # combobox
        self.allNeurons = unique(self.sorted)
        self.combo1.clear()
        self.combo1.addItems(['Neuron %d' % c for c in self.allNeurons])

        self.combo2.clear()
        self.combo2.addItems(['Neuron %d' % c for c in self.allNeurons])

    def comboChanged(self, ind):
        c1 = self.allNeurons[self.combo1.currentIndex()]
        c2 = self.allNeurons[self.combo2.currentIndex()]

        self.ax.clear()

        width = self.plotParams['bin_width'] / 1000.
        limit = self.plotParams['limit'] / 1000.

        # corss correlogram

        t1 = self.spike_times[c1 == self.sorted]
        t2 = self.spike_times[c2 == self.sorted]

        if not (self.plotParams['exact']):

            max_spike = self.plotParams['max_spike']
            t1 = t1[unique(random.randint(0, high=t1.size, size=max_spike))]
            t2 = t2[unique(random.randint(0, high=t2.size, size=max_spike))]

        m1 = numpy.tile(t1[:, numpy.newaxis], (1, t2.size))
        m2 = numpy.tile(t2[numpy.newaxis, :], (t1.size, 1))
        m = m2 - m1
        m = m.flatten()
        #~ m = m.reshape(m.size)

        y, x = numpy.histogram(m, bins=numpy.arange(-limit, limit, width))

        if self.plotParams['plot_type'] == 'bar':
            self.ax.bar(x[:-1] * 1000, y, width=width * 1000)
        elif self.plotParams['plot_type'] == 'line':
            self.ax.plot(x[:-1] * 1000, y)

        self.ax.set_xlim(-limit * 1000., limit * 1000.)

        self.canvas.draw()
コード例 #4
0
class PlotISI(QWidget, PlotBase):
    """
    widget to plot ISI (inter spike interval)
    """
    plotParamDefault = [
        ['plot_type', {
            'value': 'bar',
            'possible': ['bar', 'line']
        }],
        ['bin_width', {
            'value': 2.,
            'label': 'bin width (ms)'
        }],
        ['limit', {
            'value': 500.,
            'label': 'max limit (ms)'
        }],
    ]

    def __init__(
        self,
        parent=None,
        spike_times=None,
        sorted=None,
        colors=None,
        show_button=True,
        plotParams=None,
    ):
        QWidget.__init__(self, parent)
        PlotBase.__init__(self, plotParams=plotParams)

        self.colors = colors

        self.spikeSortingWin = self.parent()
        mainLayout = QVBoxLayout()
        self.setLayout(mainLayout)

        self.combo = QComboBox()
        mainLayout.addWidget(self.combo)
        self.connect(self.combo, SIGNAL('currentIndexChanged( int )'),
                     self.comboChanged)

        self.canvas = SimpleCanvasAndTool(orientation=Qt.Horizontal)
        self.fig = self.canvas.fig
        self.ax = self.fig.add_subplot(1, 1, 1)
        mainLayout.addWidget(self.canvas)

        if show_button:
            but = QPushButton('', parent=self.canvas.canvas)
            #~ but = QPushButton('',parent = self.canvas)
            but.setIcon(QIcon(':/configure.png'))
            but.setGeometry(10, 10, 30, 30)
            self.canvas.stackUnder(but)
            self.connect(but, SIGNAL('clicked()'), self.changePlotOptions)

        self.changeData(spike_times, sorted=sorted)

    def refresh(self):
        self.changeData(self.spike_times)

    def changeData(self, spike_times, sorted=None, colors=None):
        if spike_times is None: return
        self.spike_times = spike_times

        # sorted
        if sorted is not None:
            self.sorted = sorted
        if self.sorted is None:
            self.sorted = ones(waveforms.shape[0], dtype='i')
        # colors
        if colors is not None:
            self.colors = colors
        if self.colors is None:
            self.colors = {}
            cmap = get_cmap('jet', unique(self.sorted).size + 3)
            for i, c in enumerate(unique(self.sorted)):
                self.colors[c] = cmap(i + 2)

        # combobox
        self.combo.clear()
        self.allNeurons = unique(self.sorted)
        self.combo.addItems(['Neuron %d' % c for c in self.allNeurons])

    def comboChanged(self, ind):
        c = self.allNeurons[ind]
        self.ax.clear()

        width = self.plotParams['bin_width'] / 1000.
        limit = self.plotParams['limit'] / 1000.
        st = self.spike_times[c == self.sorted]
        #~ st.sort()
        y, x = numpy.histogram(numpy.diff(st),
                               bins=numpy.arange(0, limit, width))

        if self.plotParams['plot_type'] == 'bar':
            self.ax.bar(x[:-1] * 1000,
                        y,
                        width=width * 1000,
                        color=self.colors[c])
        elif self.plotParams['plot_type'] == 'line':
            self.ax.plot(x[:-1] * 1000, y, color=self.colors[c])

        self.ax.set_xlim(0, limit * 1000.)

        self.canvas.draw()
コード例 #5
0
class PlotCrossCorrelogram(QWidget , PlotBase):
    """
    widget to plot PlotCrossCorrelogram
    """
    plotParamDefault =  [ 
                                [ 'plot_type' , {'value' : 'line' , 'possible' : [ 'bar' , 'line']  }],
                                [ 'bin_width' , {'value' : 2.  , 'label' : 'bin width (ms)'}],
                                [ 'limit' , {'value' : 500.  , 'label' : 'max limit (ms)'}],
                                
                                [ 'exact' , {'value' :False  , 'label' : 'Compute exact crosscorrelogram'}],
                                [ 'max_spike' , {'value' :300  , 'label' : 'Otherwise bootstrap with'}],
                                
                        
                    ]
    
    def __init__(self , parent=None ,
                        
                        spike_times = None,
                        sorted = None,
                        colors = None,
                        
                        show_button = True,
                        plotParams = None,
                        
                        
                        ):
        QWidget.__init__(self,parent )
        PlotBase.__init__(self,plotParams = plotParams)

        
        self.colors = colors

        self.spikeSortingWin = self.parent()
        mainLayout = QVBoxLayout()
        self.setLayout(mainLayout)
        
        h = QHBoxLayout()
        mainLayout.addLayout(h)
        self.combo1 = QComboBox()
        h.addWidget( self.combo1 )
        self.connect( self.combo1, SIGNAL('currentIndexChanged( int )') , self.comboChanged )
        self.combo2 = QComboBox()
        h.addWidget( self.combo2 )
        self.connect( self.combo2, SIGNAL('currentIndexChanged( int )') , self.comboChanged )
        
        
        
        self.canvas = SimpleCanvasAndTool(orientation = Qt.Horizontal )
        self.fig = self.canvas.fig
        self.ax = self.fig.add_subplot(1,1,1)
        mainLayout.addWidget(self.canvas)
        
        if show_button:
            but = QPushButton('',self.canvas.canvas)
            #~ but = QPushButton('',parent = self.canvas)
            but.setIcon(QIcon(':/configure.png'))
            but.setGeometry(10,10,30,30)
            self.canvas.stackUnder(but)
            self.connect(but, SIGNAL('clicked()') , self.changePlotOptions)
        
        self.changeData(spike_times , sorted = sorted )
        
    
    def refresh(self):
        self.changeData(self.spike_times)
    
    def changeData(self, spike_times , sorted = None , colors = None):
        if spike_times is None : return
        self.spike_times = spike_times
        
        # sorted
        if sorted is not None:
            self.sorted = sorted
        if self.sorted is None:
            self.sorted = ones( waveforms.shape[0] , dtype = 'i')
        # colors
        if colors is not None:
            self.colors = colors
        if self.colors is None:
            self.colors = { }
            cmap = get_cmap('jet', unique(self.sorted).size+3)
            for i,c in enumerate(unique(self.sorted)):
                self.colors[c] = cmap(i+2)
        
        
        # combobox
        self.allNeurons = unique(self.sorted)
        self.combo1.clear()
        self.combo1.addItems( ['Neuron %d' %c for c in  self.allNeurons ])

        self.combo2.clear()
        self.combo2.addItems( ['Neuron %d' %c for c in  self.allNeurons ])
        
        

            
        
        

    def comboChanged(self, ind):
        c1 = self.allNeurons[self.combo1.currentIndex()]
        c2 = self.allNeurons[self.combo2.currentIndex()]
        
        self.ax.clear()

        width = self.plotParams['bin_width']/1000.
        limit = self.plotParams['limit']/1000.
        
        # corss correlogram
        
        t1 = self.spike_times[c1==self.sorted]
        t2 = self.spike_times[c2==self.sorted]
        
        if not(self.plotParams['exact']):
            
            max_spike = self.plotParams['max_spike']
            t1 = t1[unique(random.randint(0,high = t1.size, size = max_spike))]
            t2 = t2[unique(random.randint(0,high = t2.size, size = max_spike))]
        
        m1 = numpy.tile(t1[:,numpy.newaxis] , (1,t2.size) )
        m2 = numpy.tile(t2[numpy.newaxis,:] , (t1.size,1) )
        m = m2-m1
        m = m.flatten()
        #~ m = m.reshape(m.size)
        

        y,x = numpy.histogram(m, bins = numpy.arange(-limit,limit, width))
        
        if self.plotParams['plot_type'] == 'bar':
            self.ax.bar(x[:-1]*1000, y, width =width*1000)
        elif self.plotParams['plot_type'] == 'line':
            self.ax.plot(x[:-1]*1000, y )
        
        self.ax.set_xlim(-limit*1000., limit*1000.)


        
        self.canvas.draw()
コード例 #6
0
class PlotISI(QWidget , PlotBase):
    """
    widget to plot ISI (inter spike interval)
    """
    plotParamDefault =  [ 
                                [ 'plot_type' , {'value' : 'bar' , 'possible' : [ 'bar' , 'line']  }],
                                [ 'bin_width' , {'value' : 2.  , 'label' : 'bin width (ms)'}],
                                [ 'limit' , {'value' : 500.  , 'label' : 'max limit (ms)'}],
                        
                    ]
    
    def __init__(self , parent=None ,
                        
                        spike_times = None,
                        sorted = None,
                        colors = None,
                        
                        show_button = True,
                        plotParams = None,
                        
                        
                        ):
        QWidget.__init__(self,parent )
        PlotBase.__init__(self,plotParams = plotParams)

        
        self.colors = colors

        self.spikeSortingWin = self.parent()
        mainLayout = QVBoxLayout()
        self.setLayout(mainLayout)
        
        self.combo = QComboBox()
        mainLayout.addWidget( self.combo )
        self.connect( self.combo, SIGNAL('currentIndexChanged( int )') , self.comboChanged )
        
        self.canvas = SimpleCanvasAndTool(orientation = Qt.Horizontal )
        self.fig = self.canvas.fig
        self.ax = self.fig.add_subplot(1,1,1)
        mainLayout.addWidget(self.canvas)
        
        if show_button:
            but = QPushButton('',parent = self.canvas.canvas)
            #~ but = QPushButton('',parent = self.canvas)
            but.setIcon(QIcon(':/configure.png'))
            but.setGeometry(10,10,30,30)
            self.canvas.stackUnder(but)
            self.connect(but, SIGNAL('clicked()') , self.changePlotOptions)
        
        self.changeData(spike_times , sorted = sorted )
        
    
    def refresh(self):
        self.changeData(self.spike_times)
    
    def changeData(self, spike_times , sorted = None , colors = None):
        if spike_times is None : return
        self.spike_times = spike_times
        
        # sorted
        if sorted is not None:
            self.sorted = sorted
        if self.sorted is None:
            self.sorted = ones( waveforms.shape[0] , dtype = 'i')
        # colors
        if colors is not None:
            self.colors = colors
        if self.colors is None:
            self.colors = { }
            cmap = get_cmap('jet', unique(self.sorted).size+3)
            for i,c in enumerate(unique(self.sorted)):
                self.colors[c] = cmap(i+2)
        
        
        # combobox
        self.combo.clear()
        self.allNeurons = unique(self.sorted)
        self.combo.addItems( ['Neuron %d' %c for c in  self.allNeurons ])
        
            
        
        

    def comboChanged(self, ind):
        c = self.allNeurons[ind]
        self.ax.clear()

        width = self.plotParams['bin_width']/1000.
        limit = self.plotParams['limit']/1000.
        st = self.spike_times[c==self.sorted]
        #~ st.sort()
        y,x = numpy.histogram(numpy.diff(st), bins = numpy.arange(0,limit, width))
        
        if self.plotParams['plot_type'] == 'bar':
            self.ax.bar(x[:-1]*1000, y, width =width*1000, color = self.colors[c])
        elif self.plotParams['plot_type'] == 'line':
            self.ax.plot(x[:-1]*1000, y,  color = self.colors[c])
        
        self.ax.set_xlim(0, limit*1000.)


        
        self.canvas.draw()
コード例 #7
0
    def __init__(
        self,
        parent=None,
        metadata=None,
        Session=None,
        session=None,
        globalApplicationDict=None,
        id_respirationsignal=None,
    ):
        QDialog.__init__(self, parent)
        self.metadata = metadata
        self.session = Session()
        self.globalApplicationDict = globalApplicationDict
        self.id_respirationsignal = id_respirationsignal
        self.respiration = self.session.query(RespirationSignal).filter_by(
            id=id_respirationsignal).one()

        #FIXME: do not work:
        self.setModal(False)
        self.setWindowModality(Qt.NonModal)

        self.setWindowTitle(
            self.tr('OpenElectrophy respiration for %d' %
                    (self.respiration.id)))
        self.setWindowIcon(QIcon(':/respiration.png'))

        self.mainLayout = QVBoxLayout()
        self.setLayout(self.mainLayout)

        h = QHBoxLayout()
        self.mainLayout.addLayout(h)

        c = SimpleCanvasAndTool()
        h.addWidget(c, 3)
        self.canvas = c.canvas
        self.ax = self.canvas.fig.add_subplot(1, 1, 1)

        v = QVBoxLayout()
        h.addLayout(v, 2)

        but = QPushButton(QIcon(':/TODO.txt'), 'Auto detect')
        v.addWidget(but)
        self.connect(but, SIGNAL('clicked()'), self.newDetection)

        v.addSpacing(20)

        v.addWidget(QLabel('<b>Repiratory cycles</b>'))
        self.table = QTreeWidget()
        #~ self.table.setMinimumWidth(100)
        #~ self.table.setColumnWidth(0,80)
        v.addWidget(self.table)

        self.table.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.connect(self.table, SIGNAL('itemSelectionChanged()'),
                     self.newSelectionInTable)
        self.table.setContextMenuPolicy(Qt.CustomContextMenu)
        self.connect(self.table,
                     SIGNAL('customContextMenuRequested( const QPoint &)'),
                     self.contextMenuTable)

        self.mainLayout.addSpacing(20)

        buttonBox = QDialogButtonBox()

        but = QPushButton(QIcon(':/document-save.png'), 'Save to DB')
        buttonBox.addButton(but, QDialogButtonBox.ActionRole)
        self.connect(but, SIGNAL('clicked()'), self.save_to_db)

        but = QPushButton(QIcon(':/reload.png'), 'Reload from DB')
        buttonBox.addButton(but, QDialogButtonBox.ActionRole)
        self.connect(but, SIGNAL('clicked()'), self.reload_from_db)

        but = QPushButton(QIcon(':/window-close.png'), 'Quit')
        buttonBox.addButton(but, QDialogButtonBox.RejectRole)
        self.connect(but, SIGNAL('clicked()'), self.close)
        self.mainLayout.addWidget(buttonBox)

        if self.respiration.cycle_times is None:
            self.cycle_times = None
        else:
            self.cycle_times = self.respiration.cycle_times

        self.vlines = {}
        self.baseline = 0.
        self.refreshPlot()
        self.refreshTable()

        self.canvas.mpl_connect('pick_event', self.onPick)
        self.canvas.mpl_connect('button_release_event', self.releaseEvent)
        self.canvas.mpl_connect('motion_notify_event', self.motionEvent)
        #~ self.picked = None

        #~ self.lineSelection = None
        self.session.expunge_all()
コード例 #8
0
    def __init__(
        self,
        parent=None,
        metadata=None,
        Session=None,
        globalApplicationDict=None,
        id_analogsignal=None,
        tablename=None,
        mode="all signal",
    ):
        QDialog.__init__(self, parent)
        self.metadata = metadata
        self.session = Session()
        self.globalApplicationDict = globalApplicationDict

        self.anaSig = self.session.query(AnalogSignal).filter_by(id=id_analogsignal).one()
        self.mode = mode

        # FIXME: do not work:
        self.setModal(False)
        self.setWindowModality(Qt.NonModal)

        self.setWindowTitle(self.tr("OpenElectrophy Edit oscillation for %d" % (self.anaSig.id)))
        self.setWindowIcon(QIcon(":/oscillation.png"))

        self.mainLayout = QVBoxLayout()
        self.setLayout(self.mainLayout)

        self.tab = QTabWidget()
        self.mainLayout.addWidget(self.tab)

        if self.mode == "around epoch":
            fr = QFrame()
            self.tab.addTab(fr, "Epoch list")
            v1 = QVBoxLayout()
            fr.setLayout(v1)

            # ~ default_query = "SELECT id_epoch FROM epoch WHERE epoch.id_trial = %d "  % (self.elec.id_trial)
            # ~ self.queryBoxEpoch = QueryResultBox(table = 'epoch', field_list = Epoch.list_field, default_query = default_query )
            # ~ v1.addWidget(self.queryBoxEpoch)
            # ~ self.queryBoxEpoch.treeview_result.setSelectionMode(QAbstractItemView.SingleSelection)
            # ~ self.connect(self.queryBoxEpoch.treeview_result , SIGNAL('itemSelectionChanged()') , self.changeEpoch)

            query = "SELECT event.id \nFROM event \nWHERE event.id_segment = %s\n" % (self.anaSig.id_segment)
            self.queryEvent = QueryResultBox(
                metadata=self.metadata,
                session=self.session,
                globalApplicationDict=self.globalApplicationDict,
                table="event",
                orientation=Qt.Horizontal,
                query=query,
            )
            v1.addWidget(self.queryEvent, 2)
            self.queryEvent.tree.treeview.setSelectionMode(QAbstractItemView.SingleSelection)
            self.connect(self.queryEvent.tree.treeview, SIGNAL("clicked( QModelIndex )"), self.changeSelectedEvent)

            # ~ params = [
            # ~ ('t_start', {'value' : -1., }),
            # ~ ('t_stop', {'value' : 3., }),
            # ~ ]
            # ~ self.paramEvent = ParamWidget(params ,
            # ~ applicationdict = self.globalApplicationDict,
            # ~ keyformemory = 'linedetector/event_window' ,
            # ~ title = 'Choose the window',
            # ~ )
            # ~ v1.addWidget(self.paramEvent,0)
            v1.addSpacing(0)
            self.activeEvent = None

        fr = QFrame()
        self.tab.addTab(fr, "Oscillations")
        h = QHBoxLayout()
        fr.setLayout(h)

        # Scalogram
        v = QVBoxLayout()
        h.addLayout(v)
        self.paramMorlet = ParamWidget(
            morletParams,
            applicationdict=globalApplicationDict,
            keyformemory="linedetector/morlet",
            title="Parameters for scalogram",
        )
        v.addWidget(self.paramMorlet)
        hb = QHBoxLayout()
        v.addLayout(hb)
        hb.addStretch(0)
        but = QPushButton(QIcon(":/"), "Compute scalogram")
        self.connect(but, SIGNAL("clicked()"), self.computeScalogram)
        hb.addWidget(but)

        # detection zone
        v.addSpacing(20)
        self.paramDetectionZone = ParamWidget(
            detectionZoneParams,
            applicationdict=globalApplicationDict,
            keyformemory="linedetector/detection_zone",
            title="Detection zone",
        )
        v.addWidget(self.paramDetectionZone)
        self.connect(self.paramDetectionZone, SIGNAL("paramChanged( QString )"), self.plotDetectionZone)
        hb = QHBoxLayout()
        v.addLayout(hb)
        hb.addStretch(0)
        but = QPushButton(QIcon(":/"), "Redraw signal")
        self.connect(but, SIGNAL("clicked()"), self.redrawSignal)
        hb.addWidget(but)

        v.addStretch(0)

        # threshold
        v = QVBoxLayout()
        h.addLayout(v)
        self.paramThreshold = ParamWidget(
            thresholdParams,
            applicationdict=globalApplicationDict,
            keyformemory="linedetector/threshold",
            title="Threshold",
        )
        v.addWidget(self.paramThreshold)
        self.connect(self.paramThreshold, SIGNAL("paramChanged( QString )"), self.refreshThreshold)
        hb = QHBoxLayout()
        v.addLayout(hb)
        hb.addStretch(0)
        but = QPushButton(QIcon(":/"), "Detect maximas")
        self.connect(but, SIGNAL("clicked()"), self.detectMaximas)
        hb.addWidget(but)
        but = QPushButton(QIcon(":/"), "Compute lines")
        self.connect(but, SIGNAL("clicked()"), self.computeLines)
        hb.addWidget(but)

        # clean
        v.addSpacing(20)
        self.paramClean = ParamWidget(
            cleanParams, applicationdict=globalApplicationDict, keyformemory="linedetector/clean", title="Clean"
        )
        v.addWidget(self.paramClean)
        hb = QHBoxLayout()
        v.addLayout(hb)
        hb.addStretch(0)
        but = QPushButton(QIcon(":/"), "Clean list")
        hb.addWidget(but)
        self.connect(but, SIGNAL("clicked()"), self.cleanList)

        v.addSpacing(27)
        but = QPushButton(QIcon(":/"), "Compute all")
        v.addWidget(but)
        self.connect(but, SIGNAL("clicked()"), self.computeAll)

        v.addStretch(0)

        # center
        # ~ v = QVBoxLayout()
        # ~ h.addLayout(v)
        spv = QSplitter(Qt.Vertical)
        # ~ spv.setOpaqueResize(False)
        h.addWidget(spv, 10)

        self.treeviewOscillations = QTreeWidget()
        self.treeviewOscillations.setColumnCount(3)
        self.treeviewOscillations.setHeaderLabels(["oscillation", "time_max", "freq_max", "amplitude_max"])
        self.treeviewOscillations.setSelectionMode(QAbstractItemView.ExtendedSelection)
        spv.addWidget(self.treeviewOscillations)

        self.treeviewOscillations.setContextMenuPolicy(Qt.CustomContextMenu)
        self.connect(
            self.treeviewOscillations,
            SIGNAL("customContextMenuRequested( const QPoint &)"),
            self.contextMenuTreeviewOscillation,
        )
        self.connect(
            self.treeviewOscillations,
            SIGNAL("itemDoubleClicked(QTreeWidgetItem *, int)"),
            self.zoomOscillationOnDoubleClick,
        )
        self.connect(self.treeviewOscillations, SIGNAL("itemSelectionChanged()"), self.selectionOscillationChanged)

        # right side
        # ~ v = QHBoxLayout()
        # ~ h.addLayout(v)
        self.canvas = SimpleCanvasAndTool(orientation=Qt.Vertical)
        self.fig = self.canvas.fig
        spv.addWidget(self.canvas)

        # button
        buttonBox = QDialogButtonBox()

        but = QPushButton(QIcon(":/document-save.png"), "Save to DB (no delete)")
        buttonBox.addButton(but, QDialogButtonBox.ActionRole)
        self.connect(but, SIGNAL("clicked()"), self.save_to_db_no_delete)

        but = QPushButton(QIcon(":/document-save.png"), "Save to DB (delete old in interest zone)")
        buttonBox.addButton(but, QDialogButtonBox.ActionRole)
        self.connect(but, SIGNAL("clicked()"), self.save_to_db_and_delete)

        but = QPushButton(QIcon(":/reload.png"), "Reload from DB")
        buttonBox.addButton(but, QDialogButtonBox.ActionRole)
        self.connect(but, SIGNAL("clicked()"), self.reload_from_db_all)

        but = QPushButton(QIcon(":/reload.png"), "Reload from DB (only interest zone)")
        buttonBox.addButton(but, QDialogButtonBox.ActionRole)
        self.connect(but, SIGNAL("clicked()"), self.reload_from_db_only_zone)

        but = QPushButton(QIcon(":/window-close.png"), "Quit")
        buttonBox.addButton(but, QDialogButtonBox.RejectRole)
        self.connect(but, SIGNAL("clicked()"), self.close)
        self.mainLayout.addWidget(buttonBox)

        # context menu
        self.menu = QMenu()
        act = self.menu.addAction(self.tr("Delete"))
        self.connect(act, SIGNAL("triggered()"), self.deleteSelection)
        act = self.menu.addAction(self.tr("Recompute"))
        self.connect(act, SIGNAL("triggered()"), self.recomputeSelection)
        act = self.menu.addAction(self.tr("Clean"))
        self.connect(act, SIGNAL("triggered()"), self.cleanSelection)

        #
        self.lineDetector = LineDetector(self.anaSig)
        self.plotLineDetector = PlotLineDetector(figure=self.fig, lineDetector=self.lineDetector)

        self.checkParam()
コード例 #9
0
class OscillationDetection(QDialog):
    """
    Scroll area resazible for stacking matplotlib canvas
    
    """

    def __init__(
        self,
        parent=None,
        metadata=None,
        Session=None,
        globalApplicationDict=None,
        id_analogsignal=None,
        tablename=None,
        mode="all signal",
    ):
        QDialog.__init__(self, parent)
        self.metadata = metadata
        self.session = Session()
        self.globalApplicationDict = globalApplicationDict

        self.anaSig = self.session.query(AnalogSignal).filter_by(id=id_analogsignal).one()
        self.mode = mode

        # FIXME: do not work:
        self.setModal(False)
        self.setWindowModality(Qt.NonModal)

        self.setWindowTitle(self.tr("OpenElectrophy Edit oscillation for %d" % (self.anaSig.id)))
        self.setWindowIcon(QIcon(":/oscillation.png"))

        self.mainLayout = QVBoxLayout()
        self.setLayout(self.mainLayout)

        self.tab = QTabWidget()
        self.mainLayout.addWidget(self.tab)

        if self.mode == "around epoch":
            fr = QFrame()
            self.tab.addTab(fr, "Epoch list")
            v1 = QVBoxLayout()
            fr.setLayout(v1)

            # ~ default_query = "SELECT id_epoch FROM epoch WHERE epoch.id_trial = %d "  % (self.elec.id_trial)
            # ~ self.queryBoxEpoch = QueryResultBox(table = 'epoch', field_list = Epoch.list_field, default_query = default_query )
            # ~ v1.addWidget(self.queryBoxEpoch)
            # ~ self.queryBoxEpoch.treeview_result.setSelectionMode(QAbstractItemView.SingleSelection)
            # ~ self.connect(self.queryBoxEpoch.treeview_result , SIGNAL('itemSelectionChanged()') , self.changeEpoch)

            query = "SELECT event.id \nFROM event \nWHERE event.id_segment = %s\n" % (self.anaSig.id_segment)
            self.queryEvent = QueryResultBox(
                metadata=self.metadata,
                session=self.session,
                globalApplicationDict=self.globalApplicationDict,
                table="event",
                orientation=Qt.Horizontal,
                query=query,
            )
            v1.addWidget(self.queryEvent, 2)
            self.queryEvent.tree.treeview.setSelectionMode(QAbstractItemView.SingleSelection)
            self.connect(self.queryEvent.tree.treeview, SIGNAL("clicked( QModelIndex )"), self.changeSelectedEvent)

            # ~ params = [
            # ~ ('t_start', {'value' : -1., }),
            # ~ ('t_stop', {'value' : 3., }),
            # ~ ]
            # ~ self.paramEvent = ParamWidget(params ,
            # ~ applicationdict = self.globalApplicationDict,
            # ~ keyformemory = 'linedetector/event_window' ,
            # ~ title = 'Choose the window',
            # ~ )
            # ~ v1.addWidget(self.paramEvent,0)
            v1.addSpacing(0)
            self.activeEvent = None

        fr = QFrame()
        self.tab.addTab(fr, "Oscillations")
        h = QHBoxLayout()
        fr.setLayout(h)

        # Scalogram
        v = QVBoxLayout()
        h.addLayout(v)
        self.paramMorlet = ParamWidget(
            morletParams,
            applicationdict=globalApplicationDict,
            keyformemory="linedetector/morlet",
            title="Parameters for scalogram",
        )
        v.addWidget(self.paramMorlet)
        hb = QHBoxLayout()
        v.addLayout(hb)
        hb.addStretch(0)
        but = QPushButton(QIcon(":/"), "Compute scalogram")
        self.connect(but, SIGNAL("clicked()"), self.computeScalogram)
        hb.addWidget(but)

        # detection zone
        v.addSpacing(20)
        self.paramDetectionZone = ParamWidget(
            detectionZoneParams,
            applicationdict=globalApplicationDict,
            keyformemory="linedetector/detection_zone",
            title="Detection zone",
        )
        v.addWidget(self.paramDetectionZone)
        self.connect(self.paramDetectionZone, SIGNAL("paramChanged( QString )"), self.plotDetectionZone)
        hb = QHBoxLayout()
        v.addLayout(hb)
        hb.addStretch(0)
        but = QPushButton(QIcon(":/"), "Redraw signal")
        self.connect(but, SIGNAL("clicked()"), self.redrawSignal)
        hb.addWidget(but)

        v.addStretch(0)

        # threshold
        v = QVBoxLayout()
        h.addLayout(v)
        self.paramThreshold = ParamWidget(
            thresholdParams,
            applicationdict=globalApplicationDict,
            keyformemory="linedetector/threshold",
            title="Threshold",
        )
        v.addWidget(self.paramThreshold)
        self.connect(self.paramThreshold, SIGNAL("paramChanged( QString )"), self.refreshThreshold)
        hb = QHBoxLayout()
        v.addLayout(hb)
        hb.addStretch(0)
        but = QPushButton(QIcon(":/"), "Detect maximas")
        self.connect(but, SIGNAL("clicked()"), self.detectMaximas)
        hb.addWidget(but)
        but = QPushButton(QIcon(":/"), "Compute lines")
        self.connect(but, SIGNAL("clicked()"), self.computeLines)
        hb.addWidget(but)

        # clean
        v.addSpacing(20)
        self.paramClean = ParamWidget(
            cleanParams, applicationdict=globalApplicationDict, keyformemory="linedetector/clean", title="Clean"
        )
        v.addWidget(self.paramClean)
        hb = QHBoxLayout()
        v.addLayout(hb)
        hb.addStretch(0)
        but = QPushButton(QIcon(":/"), "Clean list")
        hb.addWidget(but)
        self.connect(but, SIGNAL("clicked()"), self.cleanList)

        v.addSpacing(27)
        but = QPushButton(QIcon(":/"), "Compute all")
        v.addWidget(but)
        self.connect(but, SIGNAL("clicked()"), self.computeAll)

        v.addStretch(0)

        # center
        # ~ v = QVBoxLayout()
        # ~ h.addLayout(v)
        spv = QSplitter(Qt.Vertical)
        # ~ spv.setOpaqueResize(False)
        h.addWidget(spv, 10)

        self.treeviewOscillations = QTreeWidget()
        self.treeviewOscillations.setColumnCount(3)
        self.treeviewOscillations.setHeaderLabels(["oscillation", "time_max", "freq_max", "amplitude_max"])
        self.treeviewOscillations.setSelectionMode(QAbstractItemView.ExtendedSelection)
        spv.addWidget(self.treeviewOscillations)

        self.treeviewOscillations.setContextMenuPolicy(Qt.CustomContextMenu)
        self.connect(
            self.treeviewOscillations,
            SIGNAL("customContextMenuRequested( const QPoint &)"),
            self.contextMenuTreeviewOscillation,
        )
        self.connect(
            self.treeviewOscillations,
            SIGNAL("itemDoubleClicked(QTreeWidgetItem *, int)"),
            self.zoomOscillationOnDoubleClick,
        )
        self.connect(self.treeviewOscillations, SIGNAL("itemSelectionChanged()"), self.selectionOscillationChanged)

        # right side
        # ~ v = QHBoxLayout()
        # ~ h.addLayout(v)
        self.canvas = SimpleCanvasAndTool(orientation=Qt.Vertical)
        self.fig = self.canvas.fig
        spv.addWidget(self.canvas)

        # button
        buttonBox = QDialogButtonBox()

        but = QPushButton(QIcon(":/document-save.png"), "Save to DB (no delete)")
        buttonBox.addButton(but, QDialogButtonBox.ActionRole)
        self.connect(but, SIGNAL("clicked()"), self.save_to_db_no_delete)

        but = QPushButton(QIcon(":/document-save.png"), "Save to DB (delete old in interest zone)")
        buttonBox.addButton(but, QDialogButtonBox.ActionRole)
        self.connect(but, SIGNAL("clicked()"), self.save_to_db_and_delete)

        but = QPushButton(QIcon(":/reload.png"), "Reload from DB")
        buttonBox.addButton(but, QDialogButtonBox.ActionRole)
        self.connect(but, SIGNAL("clicked()"), self.reload_from_db_all)

        but = QPushButton(QIcon(":/reload.png"), "Reload from DB (only interest zone)")
        buttonBox.addButton(but, QDialogButtonBox.ActionRole)
        self.connect(but, SIGNAL("clicked()"), self.reload_from_db_only_zone)

        but = QPushButton(QIcon(":/window-close.png"), "Quit")
        buttonBox.addButton(but, QDialogButtonBox.RejectRole)
        self.connect(but, SIGNAL("clicked()"), self.close)
        self.mainLayout.addWidget(buttonBox)

        # context menu
        self.menu = QMenu()
        act = self.menu.addAction(self.tr("Delete"))
        self.connect(act, SIGNAL("triggered()"), self.deleteSelection)
        act = self.menu.addAction(self.tr("Recompute"))
        self.connect(act, SIGNAL("triggered()"), self.recomputeSelection)
        act = self.menu.addAction(self.tr("Clean"))
        self.connect(act, SIGNAL("triggered()"), self.cleanSelection)

        #
        self.lineDetector = LineDetector(self.anaSig)
        self.plotLineDetector = PlotLineDetector(figure=self.fig, lineDetector=self.lineDetector)

        self.checkParam()

    def save_to_db(self, delete_old=False):

        t1, t2, f1, f2 = self.lineDetector.detection_zone
        if self.mode == "all signal" or self.mode == "around epoch":
            # delete old oscillations in database
            if delete_old:
                query = self.session.query(Oscillation)
                query = query.filter(Oscillation.id_analogsignal == self.anaSig.id)
                query = query.filter(Oscillation.freq_max >= f1).filter(Oscillation.freq_max <= f2)
                query = query.filter(Oscillation.time_max >= t1).filter(Oscillation.time_max <= t2)
                for osci in query.all():
                    self.session.delete(osci)
                self.session.commit()

            # create new ones
            for o, osci in enumerate(self.lineDetector.list_oscillation):
                # ~ if osci in self.session:
                # ~ self.session.expunge( osci )
                # ~ self.session.commit()
                # ~ osci.id = None
                # ~ osci.id_analogsignal = self.anaSig.id
                # ~ self.session.merge(osci)

                # ~ osci2 = osci.copy()
                # ~ osci2.id_analogsignal = self.anaSig.id
                # ~ self.session.add(osci2)
                self.anaSig._oscillations.append(osci.copy())
                self.session.commit()

    def save_to_db_no_delete(self):
        self.save_to_db(delete_old=False)

    def save_to_db_and_delete(self):
        self.save_to_db(delete_old=True)

    def reload_from_db(self, only_by_zone=True):

        t1, t2, f1, f2 = self.lineDetector.detection_zone
        if self.mode == "all signal" or self.mode == "around epoch":
            self.lineDetector.list_oscillation = []
            query = self.session.query(Oscillation)
            query = query.filter(Oscillation.id_analogsignal == self.anaSig.id)
            if only_by_zone:
                query = query.filter(Oscillation.freq_max >= f1).filter(Oscillation.freq_max <= f2)
                query = query.filter(Oscillation.time_max >= t1).filter(Oscillation.time_max <= t2)
            self.lineDetector.list_oscillation = [osci for osci in query.all()]

        self.refreshTreeview()
        self.plotLineDetector.plotOscillations()
        self.canvas.draw()

    def reload_from_db_all(self):
        self.reload_from_db(only_by_zone=False)

    def reload_from_db_only_zone(self):
        self.reload_from_db(only_by_zone=True)

    def changeSelectedEvent(self, index):
        # ~ print 'change', index.row()
        ev = index.internalPointer()
        if self.activeEvent is None:
            shift = ev.time
        else:
            shift = ev.time - self.activeEvent.time
        self.paramMorlet.update(
            {"t_start": self.paramMorlet["t_start"] + shift, "t_stop": self.paramMorlet["t_stop"] + shift}
        )
        self.paramDetectionZone.update(
            {"t1": self.paramDetectionZone["t1"] + shift, "t2": self.paramDetectionZone["t2"] + shift}
        )

        self.paramThreshold.update({"t1": self.paramThreshold["t1"] + shift, "t2": self.paramThreshold["t2"] + shift})
        self.plotLineDetector.clear()
        self.canvas.draw()
        self.checkParam()
        self.activeEvent = ev
        self.plotLineDetector.axMap.axvline(ev.time, color="c", linewidth=2)
        self.plotLineDetector.axSig.axvline(ev.time, color="c", linewidth=2)
        self.redrawSignal()
        self.computeScalogram()

    def checkParam(self):
        # get from UI
        self.lineDetector.update(**self.paramMorlet.get_dict())

        self.lineDetector.detection_zone = []
        for i, k in enumerate(["t1", "t2", "f1", "f2"]):
            self.lineDetector.detection_zone += [self.paramDetectionZone[k]]

        for k in ["manual_threshold", "abs_threshold", "std_relative_threshold"]:
            setattr(self.lineDetector, k, self.paramThreshold[k])
        self.lineDetector.reference_zone = []
        for i, k in enumerate(["t1", "t2", "f1", "f2"]):
            self.lineDetector.reference_zone += [self.paramThreshold[k]]

        self.lineDetector.update(**self.paramClean.get_dict())

        # check
        self.lineDetector.checkParam()

        # refresh UI
        for k in self.paramMorlet.get_dict():
            self.paramMorlet[k] = self.lineDetector.__dict__[k]
        for i, k in enumerate(["t1", "t2", "f1", "f2"]):
            self.paramDetectionZone[k] = self.lineDetector.detection_zone[i]
        for i, k in enumerate(["t1", "t2", "f1", "f2"]):
            self.paramThreshold[k] = self.lineDetector.reference_zone[i]
        enabled = not (self.paramThreshold["manual_threshold"])
        for i, k in enumerate(["t1", "t2", "f1", "f2"]):
            self.paramThreshold.params[k]["widget"].setEnabled(enabled)
        self.paramThreshold.params["abs_threshold"]["widget"].setEnabled(not (enabled))
        self.paramThreshold.params["std_relative_threshold"]["widget"].setEnabled(enabled)

    def computeScalogram(self):
        self.checkParam()
        self.lineDetector.computeTimeFreq()
        self.plotLineDetector.plotMap()
        self.canvas.draw()
        if self.mode == "around epoch" and self.activeEvent is not None:
            self.plotLineDetector.axMap.axvline(self.activeEvent.time, color="c", linewidth=2)
            # ~ self.plotLineDetector.axSig.axvline( self.activeEvent.time, color = 'c' , linewidth = 2)

    def plotDetectionZone(self, *name):
        self.checkParam()
        # ~ self.plotLineDetector.plotFilteredSig()
        self.plotLineDetector.plotDetectionZone()
        self.canvas.draw()

    def redrawSignal(self):
        self.checkParam()
        self.plotLineDetector.plotFilteredSig()
        self.plotLineDetector.plotDetectionZone()
        self.canvas.draw()
        if self.mode == "around epoch" and self.activeEvent is not None:
            # ~ self.plotLineDetector.axMap.axvline( self.activeEvent.time, color = 'c' , linewidth = 2)
            self.plotLineDetector.axSig.axvline(self.activeEvent.time, color="c", linewidth=2)

    def refreshThreshold(self, *name):
        self.checkParam()

        self.paramThreshold["abs_threshold"] = self.lineDetector.computeThreshold()
        self.plotLineDetector.plotReferenceZone()
        self.plotLineDetector.plotThreshold()
        self.canvas.draw()

    def detectMaximas(self):
        self.refreshThreshold()
        # ~ self.lineDetector.computeThreshold()
        self.lineDetector.detectMax()
        self.plotLineDetector.plotMax()
        self.canvas.draw()

    def computeLines(self):
        self.lineDetector.computeThreshold()
        self.lineDetector.detectLine()
        self.plotLineDetector.plotOscillations()
        self.canvas.draw()
        self.refreshTreeview()

    def cleanList(self):
        self.lineDetector.update(**self.paramClean.get_dict())
        self.lineDetector.cleanLine()
        self.plotLineDetector.plotOscillations()
        self.canvas.draw()
        self.refreshTreeview()

    def computeAll(self):
        self.computeScalogram()
        self.plotDetectionZone()
        self.redrawSignal()
        self.detectMaximas()
        self.computeLines()
        self.cleanList()
        self.refreshTreeview()
        # ~ print self.lineDetector.sampling_rate
        # ~ print self.plotLineDetector.lineDetector.sampling_rate

    def refreshTreeview(self):
        self.treeviewOscillations.clear()
        for o, osci in enumerate(self.lineDetector.list_oscillation):
            item = QTreeWidgetItem(
                ["oscillation %s" % o, str(osci.time_max), str(osci.freq_max), str(osci.amplitude_max)]
            )
            self.treeviewOscillations.addTopLevelItem(item)

    def contextMenuTreeviewOscillation(self, point):
        # ~ for item in  self.treeviewOscillations.selectedItems() :
        # ~ pos = self.treeviewOscillations.indexFromItem(item).row()

        self.menu.exec_(self.cursor().pos())

    def zoomOscillationOnDoubleClick(self, item):
        # push the current view to define home if stack is empty
        if self.canvas.toolbar._views.empty():
            self.canvas.toolbar.push_current()

        pos = self.treeviewOscillations.indexFromItem(item).row()
        osc = self.lineDetector.list_oscillation[pos]
        fmin = osc.freq_line.min()
        fmax = osc.freq_line.max()
        delta_f = max(10.0, (fmax - fmin) / 3.0)
        delta_t = (osc.time_stop - osc.time_start) / 2.0
        self.plotLineDetector.axMap.set_ylim(max(0.0, fmin - delta_f), fmax + delta_f)
        self.plotLineDetector.axMap.set_xlim(osc.time_start - delta_t, osc.time_stop + delta_t, emit=True)
        self.canvas.draw()

        # push the current view to add new view in the toolbar history
        self.canvas.toolbar.push_current()

    def selectionOscillationChanged(self):
        for l in self.plotLineDetector.lineOscillations1:
            l.set_linewidth(3)
            l.set_color("m")
        for l in self.plotLineDetector.lineOscillations2:
            l.set_linewidth(1)
            l.set_color("m")
        for item in self.treeviewOscillations.selectedItems():
            pos = self.treeviewOscillations.indexFromItem(item).row()
            self.plotLineDetector.lineOscillations1[pos].set_linewidth(4)
            self.plotLineDetector.lineOscillations1[pos].set_color("c")
            self.plotLineDetector.lineOscillations2[pos].set_linewidth(5)
            self.plotLineDetector.lineOscillations2[pos].set_color("c")
        self.canvas.draw()

    def deleteSelection(self):
        toremove = []
        for index in self.treeviewOscillations.selectedIndexes():
            if index.column() == 0:
                toremove.append(self.lineDetector.list_oscillation[index.row()])
        for r in toremove:
            self.lineDetector.list_oscillation.remove(r)
        self.plotLineDetector.plotOscillations()
        self.canvas.draw()
        self.refreshTreeview()

    def recomputeSelection(self):
        l = []
        for index in self.treeviewOscillations.selectedIndexes():
            l.append(index.row())

        self.lineDetector.recomputeSelection(l)
        self.plotLineDetector.plotOscillations()
        self.canvas.draw()
        self.refreshTreeview()

    def cleanSelection(self):
        self.lineDetector.update(**self.paramClean.get_dict())

        l = []
        for index in self.treeviewOscillations.selectedIndexes():
            l.append(index.row())
        self.lineDetector.cleanSelection(l)
        self.plotLineDetector.plotOscillations()
        self.canvas.draw()
        self.refreshTreeview()