예제 #1
0
    def __init__(self, scrollAreaWidgetContents):
        QtGui.QWidget.__init__(self)
        self.setParent(scrollAreaWidgetContents)

        canvas = FigureCanvas(Figure((3.0, 2.0), dpi=100))
        canvas.setParent(self)
        toolbar = myNavigationToolbar(canvas, self)
        toolbar.disableButtons()
        temporal_toolbar = temporalNavigationToolbar(canvas, self)

        mainImage = QtGui.QLabel(self)
        mainImage.setText(_fromUtf8(""))
        mainImage.setPixmap(
            QtGui.QPixmap(
                _fromUtf8(":/newPrefix/images/fromHelyx/emptyFigure.png")))
        mainImage.setObjectName(_fromUtf8("mainImage"))

        plotLayout = QtGui.QVBoxLayout()
        plotLayout.addWidget(temporal_toolbar)
        plotLayout.addWidget(mainImage)
        plotLayout.addWidget(toolbar)

        self.setLayout(plotLayout)

        canvas.setMinimumSize(canvas.size())
예제 #2
0
    def __init__(self, scrollAreaWidgetContents, currentFolder):
        QtGui.QWidget.__init__(self)
        self.setParent(scrollAreaWidgetContents)

        canvas = FigureCanvas(Figure((3.0, 2.0), dpi=100))
        canvas.setParent(self)
        toolbar = myNavigationToolbar(canvas, self)
        toolbar.disableButtons()
        temporal_toolbar = temporalNavigationToolbar(canvas, self)

        mainImage = QtGui.QLabel(self)
        mainImage.setText(_fromUtf8(""))
        mainImage.setPixmap(
            QtGui.QPixmap(
                _fromUtf8(":/newPrefix/images/fromHelyx/emptyFigure.png")))
        mainImage.setObjectName(_fromUtf8("mainImage"))
        mainImage.setScaledContents(True)
        mainImage.setSizePolicy(QtGui.QSizePolicy.Ignored,
                                QtGui.QSizePolicy.Ignored)

        plotLayout = QtGui.QVBoxLayout()
        plotLayout.addWidget(temporal_toolbar)
        plotLayout.addWidget(mainImage, 1)
        plotLayout.addWidget(toolbar, 0, QtCore.Qt.AlignCenter)

        self.setLayout(plotLayout)
        self.lastPos = -1
        self.dirList = []
        self.currentFolder = currentFolder

        canvas.setMinimumSize(canvas.size())
예제 #3
0
    def __init__(self, scrollAreaWidgetContents, dataname):
        QtGui.QWidget.__init__(self)
        self.setParent(scrollAreaWidgetContents)
        fig = Figure((3.0, 2.0), dpi=100)
        canvas = FigureCanvas(fig)
        canvas.setParent(self)
        toolbar = myNavigationToolbar(canvas, self)
        temporal_toolbar = temporalNavigationToolbar(canvas, self)
        axes = fig.add_subplot(111)
        axes.autoscale(True)
        axes.set_yscale('log')
        axes.set_title(dataname)

        # place plot components in a layout
        plotLayout = QtGui.QVBoxLayout()
        plotLayout.addWidget(temporal_toolbar)
        plotLayout.addWidget(canvas)
        plotLayout.addWidget(toolbar)
        self.setLayout(plotLayout)

        canvas.setMinimumSize(canvas.size())

        self.name = dataname
        self.dirList = []
        self.dirType = 'Sampled Line'
        self.lastPos = -1
        self.colors = ['r', 'b', 'k', 'g', 'y', 'c']
        self.labels = ['_x', '_y', '_z']
예제 #4
0
    def __init__(self, scrollAreaWidgetContents, dataname, currentFolder):         
        QtGui.QWidget.__init__(self)
        self.setParent(scrollAreaWidgetContents)
        fig = Figure((3.0, 2.0), dpi=100)
        canvas = FigureCanvas(fig)
        canvas.setParent(self)
        toolbar = myNavigationToolbar(canvas, self)
        temporal_toolbar = temporalNavigationToolbar(canvas, self)
        axes = fig.add_subplot(111)
        axes.autoscale(True)
        axes.set_yscale('log')
        axes.set_title(dataname)
        
         # place plot components in a layout
        plotLayout = QtGui.QVBoxLayout()
        plotLayout.addWidget(temporal_toolbar)
        plotLayout.addWidget(canvas,1)
        plotLayout.addWidget(toolbar,0,QtCore.Qt.AlignCenter)
        self.setLayout(plotLayout)

        canvas.setMinimumSize(canvas.size())
        
        self.name = dataname
        self.dirList = []
        self.dirType = 'Sampled Line'
        self.lastPos = -1
        self.colors = ['r', 'b', 'k', 'g', 'y', 'c']
        self.labels = ['x','y','z']
        self.currentFolder = currentFolder
        filename = '%s/system/controlDict'%(self.currentFolder)
        parsedData = ParsedParameterFile(filename,createZipped=False)
        self.ifield=parsedData['functions'][dataname]['fields'][0]
        self.archifield = 'data_%s.xy'%self.ifield
예제 #5
0
    def __init__(self, scrollAreaWidgetContents, name):         
        QtGui.QWidget.__init__(self)
        self.setParent(scrollAreaWidgetContents)
        fig = Figure((3.0, 2.0), dpi=100)
        canvas = FigureCanvas(fig)
        canvas.setParent(self)
        toolbar = myNavigationToolbar(canvas, self)
        axes = fig.add_subplot(111)
        axes.autoscale(True)
        axes.set_title(name)
        axes.set_xlabel('Time [s]')
        axes.set_ylabel('T')

         # place plot components in a layout
        plotLayout = QtGui.QVBoxLayout()
        plotLayout.addWidget(canvas)
        plotLayout.addWidget(toolbar)
        self.setLayout(plotLayout)
        
        self.dataPlot = []
        self.dirList = []
        self.dirType = 'Tracers'
        self.lastPos = -1
        self.name = name
        self.colors = ['r', 'b', 'k', 'g', 'y', 'c']
        
        # prevent the canvas to shrink beyond a point
        #original size looks like a good minimum size
        canvas.setMinimumSize(canvas.size())
    def __init__(self, scrollAreaWidgetContents, currentFolder):         
        QtGui.QWidget.__init__(self)
        self.setParent(scrollAreaWidgetContents)
        
        canvas = FigureCanvas(Figure((3.0, 2.0), dpi=100))
        canvas.setParent(self)
        toolbar = myNavigationToolbar(canvas, self)
        toolbar.disableButtons()
        temporal_toolbar = temporalNavigationToolbar(canvas, self)

        mainImage = QtGui.QLabel(self)
        mainImage.setText(_fromUtf8(""))
        mainImage.setPixmap(QtGui.QPixmap(_fromUtf8(":/newPrefix/images/fromHelyx/emptyFigure.png")))
        mainImage.setObjectName(_fromUtf8("mainImage"))
        mainImage.setScaledContents(True)
        mainImage.setSizePolicy(QtGui.QSizePolicy.Ignored,QtGui.QSizePolicy.Ignored)


        plotLayout = QtGui.QVBoxLayout()
        plotLayout.addWidget(temporal_toolbar)
        plotLayout.addWidget(mainImage,1)
        plotLayout.addWidget(toolbar,0,QtCore.Qt.AlignCenter)
        
        self.setLayout(plotLayout)
        self.lastPos = -1
        self.dirList = []
        self.currentFolder = currentFolder

        canvas.setMinimumSize(canvas.size())
    def __init__(self, scrollAreaWidgetContents, dataname):         
        QtGui.QWidget.__init__(self)
        self.setParent(scrollAreaWidgetContents)
        fig = Figure((3.0, 2.0), dpi=100)
        canvas = FigureCanvas(fig)
        canvas.setParent(self)
        toolbar = myNavigationToolbar(canvas, self)
        temporal_toolbar = temporalNavigationToolbar(canvas, self)
        axes = fig.add_subplot(111)
        axes.autoscale(True)
        axes.set_yscale('log')
        axes.set_title(dataname)
        
         # place plot components in a layout
        plotLayout = QtGui.QVBoxLayout()
        plotLayout.addWidget(temporal_toolbar)
        plotLayout.addWidget(canvas)
        plotLayout.addWidget(toolbar)
        self.setLayout(plotLayout)

        canvas.setMinimumSize(canvas.size())
        
        self.name = dataname
        self.dirList = []
        self.dirType = 'Sampled Line'
        self.lastPos = -1
        self.colors = ['r', 'b', 'k', 'g', 'y', 'c']
        self.labels = ['_x','_y','_z']
예제 #8
0
    def __init__(self, scrollAreaWidgetContents, name):         
        QtGui.QWidget.__init__(self)
        self.setParent(scrollAreaWidgetContents)
        fig = Figure((3.0, 2.0), dpi=100)
        canvas = FigureCanvas(fig)
        canvas.setParent(self)
        toolbar = myNavigationToolbar(canvas, self)
        axes = fig.add_subplot(111)
        axes.autoscale(True)
        axes.set_yscale('log')
        axes.set_title(name)
        axes.set_xlabel('Time [s]')
        axes.set_ylabel('|R|')

         # place plot components in a layout
        plotLayout = QtGui.QVBoxLayout()
        plotLayout.addWidget(canvas)
        plotLayout.addWidget(toolbar)
        self.setLayout(plotLayout)
        
        self.dataPlot = []
        self.dirList = []
        self.dirType = 'Residuals'
        self.lastPos = -1
        self.name = name
        self.colors = ['r', 'b', 'k', 'g', 'y', 'c']
        
        # prevent the canvas to shrink beyond a point
        #original size looks like a good minimum size
        canvas.setMinimumSize(canvas.size())
예제 #9
0
def plot_file(fps, base_dir, string_graph_map):
    app = QtGui.QApplication('Bodysim')
    graph_map = ast.literal_eval(string_graph_map)

    # Find the length of the simulation by looking at trajectory results.
    start_frame = 1
    count = 0
    with open(base_dir + os.sep + 'Trajectory' + os.sep + graph_map.keys()[0] + '.csv') as f:
        iterF = iter(f)
        # Skip header
        next(iterF)
        line = next(iterF)
        start_frame = float(line.split(',')[0])
        count = sum(1 for line in iterF)

    frame = MainWindow(start_frame, count)

    for sensor in graph_map:
        layout_contents = frame.add_tab(sensor)
        for plugin in graph_map[sensor]:
            data = get_data(base_dir + os.sep + plugin + os.sep + sensor + '.csv')
            for variable_group in graph_map[sensor][plugin]:
                qfigWidget = QtGui.QWidget(layout_contents[1])
                fig = Figure((5.0, 4.0), dpi=100)
                canvas = FigureCanvas(fig)
                canvas.setParent(qfigWidget)
                toolbar = NavigationToolbar(canvas, qfigWidget)
                axes = fig.add_subplot(111)
                axes.set_title(plugin + ' ' + variable_group[2])
                yDatum = [data[variable[1]] for variable in graph_map[sensor][plugin][variable_group]]
                yLabels = [variable[0] for variable in graph_map[sensor][plugin][variable_group]]
                for i in range(len(yDatum)):
                    axes.plot(data[0], yDatum[i], label=yLabels[i])
                axes.grid(True)
                axes.legend()
                axes.autoscale(enable=False, axis='both')
                axes.set_xlabel(variable_group[0])
                axes.set_ylabel(variable_group[1])

                # Place plot components in a layout
                plotLayout = QtGui.QVBoxLayout()
                plotLayout.addWidget(canvas)
                plotLayout.addWidget(toolbar)
                qfigWidget.setLayout(plotLayout)
                frame.toolbars[fig] = toolbar
                frame.plots.append(axes)

                canvas.setMinimumSize(canvas.size())
                frame.bind_to_onclick_event(fig)
                layout_contents[0].addWidget(qfigWidget)

    frame.show()
    sys.exit(app.exec_())
    def __init__(self, scrollAreaWidgetContents):         
        QtGui.QWidget.__init__(self)
        self.setParent(scrollAreaWidgetContents)
        
        canvas = FigureCanvas(Figure((3.0, 2.0), dpi=100))
        canvas.setParent(self)
        toolbar = myNavigationToolbar(canvas, self)
        toolbar.disableButtons()
        temporal_toolbar = temporalNavigationToolbar(canvas, self)

        mainImage = QtGui.QLabel(self)
        mainImage.setText(_fromUtf8(""))
        mainImage.setPixmap(QtGui.QPixmap(_fromUtf8(":/newPrefix/images/fromHelyx/emptyFigure.png")))
        mainImage.setObjectName(_fromUtf8("mainImage"))

        plotLayout = QtGui.QVBoxLayout()
        plotLayout.addWidget(temporal_toolbar)
        plotLayout.addWidget(mainImage)
        plotLayout.addWidget(toolbar)
        
        self.setLayout(plotLayout)

        canvas.setMinimumSize(canvas.size())
예제 #11
0
qscrollLayout.setGeometry(QtCore.QRect(0, 0, 1000, 1000))

qscroll.setWidget(qscrollContents)
qscroll.setWidgetResizable(True)

for i in xrange(5):
    qfigWidget = QtGui.QWidget(qscrollContents)

    fig = Figure((5.0, 4.0), dpi=100)
    canvas = FigureCanvas(fig)
    canvas.setParent(qfigWidget)
    toolbar = NavigationToolbar(canvas, qfigWidget)
    axes = fig.add_subplot(111)
    axes.plot([1, 2, 3, 4])

    # place plot components in a layout
    plotLayout = QtGui.QVBoxLayout()
    plotLayout.addWidget(canvas)
    plotLayout.addWidget(toolbar)
    qfigWidget.setLayout(plotLayout)

    # prevent the canvas to shrink beyond a point
    # original size looks like a good minimum size
    canvas.setMinimumSize(canvas.size())

    qscrollLayout.addWidget(qfigWidget)
qscrollContents.setLayout(qscrollLayout)

qwidget.show()
exit(qapp.exec_())
class GUI(QtGui.QWidget):
    
    #-----------------------------------------------------------------------------------------------
    # INITIALIZATION OF THE WINDOW - DEFINE AND PLACE ALL THE WIDGETS
    #-----------------------------------------------------------------------------------------------

    def __init__(self):

        super(GUI, self).__init__()
        
        self.setWindowTitle('Seam Cells Analysis')
        self.scaleFactor = 4
        self.side = 'L'
        self.lbltxt = '"wheel" press: change side, currently %s\n"i" or "u" press: change cell sides'
        self.initUI()
        
    def initUI(self):
        
        # SET THE GEOMETRY
        
        mainWindow = QtGui.QVBoxLayout()
        mainWindow.setSpacing(15)
        
        fileBox = QtGui.QHBoxLayout()
        spaceBox1 = QtGui.QHBoxLayout()
        rawDataBox = QtGui.QHBoxLayout()
        spaceBox2 = QtGui.QHBoxLayout()
        straightBox = QtGui.QVBoxLayout()
        
        mainWindow.addLayout(fileBox)
        mainWindow.addLayout(spaceBox1)
        mainWindow.addLayout(rawDataBox)
        mainWindow.addLayout(spaceBox2)
        mainWindow.addLayout(straightBox)
        
        Col1 = QtGui.QGridLayout()
        Col2 = QtGui.QHBoxLayout()
        Col3 = QtGui.QVBoxLayout()
        Col4 = QtGui.QVBoxLayout()
        
        rawDataBox.addLayout(Col1)
        rawDataBox.addLayout(Col2)
        rawDataBox.addLayout(Col3)
        rawDataBox.addLayout(Col4)
        
        Raw1 = QtGui.QHBoxLayout()
        Raw2 = QtGui.QHBoxLayout()
        Raw3 = QtGui.QHBoxLayout()

        straightBox.addLayout(Raw1)
        straightBox.addLayout(Raw2)
        straightBox.addLayout(Raw3)

        self.setLayout(mainWindow)

        # DEFINE ALL WIDGETS AND BUTTONS
        
        loadBtn = QtGui.QPushButton('Load DataSet')
        saveBtn = QtGui.QPushButton('Save data (F12)')
        
        tpLbl = QtGui.QLabel('Timepoint:')
        slLbl = QtGui.QLabel('Slice:')
        hatchLbl = QtGui.QLabel('Hatching Time:')
        
        self.tp = QtGui.QSpinBox(self)
        self.tp.setValue(0)
        self.tp.setMaximum(100000)
        
        self.sl = QtGui.QSpinBox(self)
        self.sl.setValue(0)
        self.sl.setMaximum(100000)
        
        self.hatch = QtGui.QSpinBox(self)
        self.hatch.setValue(0)
        self.hatch.setMaximum(100000)
        
        self._488nmBtn = QtGui.QRadioButton('488nm')
        self._561nmBtn = QtGui.QRadioButton('561nm')
        self.CoolLEDBtn = QtGui.QRadioButton('CoolLED')
        
        automaticOutlineBtn = QtGui.QPushButton('Automatic Outline')
        straightenBtn = QtGui.QPushButton('Straighten images')
        
        self.sld1 = QtGui.QSlider(QtCore.Qt.Vertical, self)
        self.sld1.setMaximum(2**16-1)
        self.sld1.setValue(0)
        self.sld2 = QtGui.QSlider(QtCore.Qt.Vertical, self)
        self.sld2.setMaximum(2**16)
        self.sld2.setValue(2**16-1)

        self.fig1 = Figure((8.0, 8.0), dpi=100)
        self.fig1.subplots_adjust(left=0., right=1., top=1., bottom=0.)
        self.ax1 = self.fig1.add_subplot(111)
        self.canvas1 = FigureCanvas(self.fig1)
        self.canvas1.setFocusPolicy( QtCore.Qt.ClickFocus )
        self.canvas1.setFocus()
        self.canvas1.setFixedSize(QtCore.QSize(500,500)) ############################# change this value to set the figure size
        self.canvas1.setSizePolicy( QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding )

        self.cellTbl = QtGui.QTableWidget()

        self.sideLbl = QtGui.QLabel(self.lbltxt % self.side)
        autonameBtn = QtGui.QPushButton('Restore Automatic Cell Names')
        wrt2Btn = QtGui.QPushButton('Compute wrt-2 Expression')
        wrt2FullBtn = QtGui.QPushButton('Compute wrt-2 Expression on the raw data (SLOW!)')        
        
        self.fig2 = Figure((4.0, 2.0))        
        self.fig2.subplots_adjust(left=0., right=1., top=1., bottom=0.)
        self.ax2 = self.fig2.add_subplot(111)
        self.canvas2 = FigureCanvas(self.fig2)
        self.canvas2.setFocusPolicy( QtCore.Qt.StrongFocus )
        self.canvas2.setFocus()
        self.canvas2.setSizePolicy( QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding )

        self.fig3 = Figure((4.0, 2.0), dpi=100)
        self.fig3.subplots_adjust(left=0., right=1., top=1., bottom=0.)
        self.ax3 = self.fig3.add_subplot(111)
        self.canvas3 = FigureCanvas(self.fig3)
        self.canvas3.setFocusPolicy( QtCore.Qt.ClickFocus )

        self.canvas3.setFocus()
        self.canvas3.setSizePolicy( QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding )
        
        # PLACE ALL THE WIDGET ACCORDING TO THE GRIDS

        fileBox.addWidget(loadBtn)
        fileBox.addWidget(saveBtn)

        spaceBox1.addWidget(self.HLine())

        Col1.addWidget(tpLbl, 0, 0)#, 1, 1, Qt.AlignTop)
        Col1.addWidget(self.tp, 0, 1)#, 1, 1, Qt.AlignTop)
        Col1.addWidget(slLbl, 1, 0)#, 1, 1, Qt.AlignTop)
        Col1.addWidget(self.sl, 1, 1)#, 1, 1, Qt.AlignTop)
        Col1.addWidget(hatchLbl, 2, 0)#, 1, 1, Qt.AlignTop)
        Col1.addWidget(self.hatch, 2, 1)#, 1, 1, Qt.AlignTop)
        Col1.addWidget(self._488nmBtn, 3, 0 )
        Col1.addWidget(self._561nmBtn, 4, 0 )
        Col1.addWidget(self.CoolLEDBtn, 5, 0 )
        Col1.addWidget(automaticOutlineBtn, 6, 0 )        
        Col1.addWidget(straightenBtn, 7, 0 )
        
        Col2.addWidget(self.sld1)
        Col2.addWidget(self.sld2)
        Col2.addWidget(self.canvas1)
        
        Col3.addWidget(self.VLine())
        
        Col4.addWidget(self.cellTbl)

        spaceBox2.addWidget(self.HLine())

        Raw1.addWidget(self.sideLbl)
        Raw1.addWidget(autonameBtn)
        Raw1.addWidget(wrt2Btn)
        Raw1.addWidget(wrt2FullBtn)

        Raw2.addWidget(self.canvas2)
        
        Raw3.addWidget(self.canvas3)
        # Raw3.addWidget(QtGui.QDockWidget())

        self.setFocus()
        self.show()
        
        # BIND BUTTONS TO FUNCTIONS
        
        loadBtn.clicked.connect(self.selectWorm)
        saveBtn.clicked.connect(self.saveData)

        self.tp.valueChanged.connect(self.loadNewStack)
        self.sl.valueChanged.connect(self.updateAllCanvas)
        self.sld1.valueChanged.connect(self.updateAllCanvas)
        self.sld2.valueChanged.connect(self.updateAllCanvas)
        self.hatch.valueChanged.connect(self.updateTidxDataFrame)

        self._488nmBtn.toggled.connect(self.radioClicked)
        self._561nmBtn.toggled.connect(self.radioClicked)
        self.CoolLEDBtn.toggled.connect(self.radioClicked)

        automaticOutlineBtn.clicked.connect(self.automaticOutline)
        straightenBtn.clicked.connect(self.straightenWorm)
        autonameBtn.clicked.connect(self.automaticCellNames)

        self.fig1.canvas.mpl_connect('button_press_event',self.onMouseClickOnCanvas1)        
        self.fig2.canvas.mpl_connect('button_press_event',self.onMouseClickOnCanvas2)        
        self.fig1.canvas.mpl_connect('scroll_event',self.wheelEvent)        
        self.fig2.canvas.mpl_connect('scroll_event',self.wheelEvent)        
        self.fig3.canvas.mpl_connect('scroll_event',self.wheelEvent)        
        
    #-----------------------------------------------------------------------------------------------
    # FORMATTING THE WINDOW
    #-----------------------------------------------------------------------------------------------

    def center(self):
        
        qr = self.frameGeometry()
        cp = QtGui.QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())
        
    def HLine(self):
        
        toto = QtGui.QFrame()
        toto.setFrameShape(QtGui.QFrame.HLine)
        toto.setFrameShadow(QtGui.QFrame.Sunken)
        return toto

    def VLine(self):
        
        toto = QtGui.QFrame()
        toto.setFrameShape(QtGui.QFrame.VLine)
        toto.setFrameShadow(QtGui.QFrame.Sunken)
        return toto

    def heightForWidth(self, width):
        
        return width
    
    #-----------------------------------------------------------------------------------------------
    # BUTTON FUNCTIONS
    #-----------------------------------------------------------------------------------------------

    def selectWorm(self):

        self.pathDial = QtGui.QFileDialog.getExistingDirectory(self, 'Select a folder', 'Y:\\Images')
        self.worm = self.pathDial.split("\\")[-1]
        self.path = self.pathDial[:-len(self.worm)]
        
        self.setWindowTitle('Seam Cells Analysis - ' + self.pathDial)
        
        if 'downsized' not in self.worm:
            QtGui.QMessageBox.about(self,'Warning!','These are not downsized (512x512) images! Convert the images first!')
            return

        # print(path + worm + '\\z*.txt')
        self.fList = {}
        if os.path.isfile(self.path + self.worm + '\\z001_488nm.tif'):
            self.fList['488nm'] = glob.glob(self.path + self.worm + '\\z*488nm.tif')
            self.fList['488nm'].sort()
        if os.path.isfile(self.path + self.worm + '\\z001_561nm.tif'):
            self.fList['561nm'] = glob.glob(self.path + self.worm + '\\z*561nm.tif')
            self.fList['561nm'].sort()
        if os.path.isfile(self.path + self.worm + '\\z001_CoolLED.tif'):
            self.fList['CoolLED'] = glob.glob(self.path + self.worm + '\\z*CoolLED.tif')
            self.fList['CoolLED'].sort()

        self.fMetaList = glob.glob(self.path + self.worm + '\\z*.txt')
        
        self.channel = list(self.fList.keys())[0]
        self.tp.setMaximum(len(self.fList[self.channel])-1)
        
        if not os.path.isfile( self.path + '\\worm' + self.worm.split('_')[0] + '.pickle' ):

            create_worm( self.path, self.worm.split('_')[0], 40, len(self.fList[self.channel]) - self.hatch.value(), self.hatch.value()+1 )

        self.df = pickle.load( open(self.path + '\\worm' + self.worm.split('_')[0] + '.pickle','rb') )

        # if there are more timepoints, add the body rows to the dataframe
        if np.max(self.df.tidx)-np.min(self.df.tidx) < len(self.fMetaList):

            times = extract_times( self.path+'\\'+self.worm, -np.min(self.df.tidx) )[int(np.max(self.df.tidx)-np.min(self.df.tidx)+1):]
            df1 = pd.DataFrame( { 'rowtype': 'body',
                          'tidx': np.arange(np.max(self.df.tidx)+1,len(self.fMetaList)+np.min(self.df.tidx)),
                          'times': times,
                          'outline': np.nan,
                          'spline': np.nan} )

            df1.outline = df1.outline.astype(object)
            df1.spline = df1.spline.astype(object)
            for idx, row in df1.iterrows():    
                df1.outline.values[idx] = np.array([[np.nan,np.nan,np.nan]])
                df1.spline.values[idx] = np.array([[np.nan,np.nan,np.nan]])

            self.df = pd.concat([self.df,df1]).sort(['tidx','rowtype','cside','cXpos']).reset_index(drop=True)

        self.hatch.setValue(-np.min(self.df.tidx))
        self.tp.setValue( self.hatch.value() )

        self.loadNewStack()

        # self.pathDial.show()
        self.setFocus()

    def saveData(self):
        
        pickle.dump( self.df, open(self.path+'\\worm'+self.worm.split('_')[0]+'.pickle','wb'), protocol=2 )        
        
    def loadNewStack(self):
        
        # print(self.fList['gfp'][self.tp.value()])
        
        self.stacks = {}
        for key in self.fList.keys():
            self.stacks[key] = loadstack(self.fList[key][self.tp.value()])
        self.scaleFactor = 2048 / self.stacks[self.channel][0].shape[0]

        self.stacksStraight = {}
        self.straightFile = self.path+self.worm.split('_')[0]+'_straighten\\straight%.3d_%s.tif'%(self.tp.value()+1,self.channel)

        if os.path.isfile(self.straightFile):

            for key in self.fList.keys():
                self.stacksStraight[key] = loadstack(self.path+self.worm.split('_')[0]+'_straighten\\straight%.3d_%s.tif'%(self.tp.value()+1,key))
        # print(self.stacks.keys(), self.stacksStraight)
        self.sl.setMaximum(self.stacks[self.channel].shape[0]-1)

        self.setBCslidersMinMax()
        
        self.updateTable()
        self.updateAllCanvas()

    def updateAllCanvas(self):
        self.updateRadioBtn()
        self.updateCanvas1()
        self.updateCanvas2()
        self.updateCanvas3()
        
    def updateTidxDataFrame(self):
        
        times = extract_times(self.path+self.worm, self.hatch.value()+1)
        self.df.ix[self.df.rowtype=='body','tidx'] = np.arange(len(times))-self.hatch.value()
        self.df.ix[self.df.rowtype=='body','times'] = times

    def radioClicked(self):
        if self._488nmBtn.isChecked():
            if '488nm' in self.fList.keys():
                self.channel = '488nm'
            else:
                QtGui.QMessageBox.about(self, 'Warning', 'No 488nm channel!')
        elif self._561nmBtn.isChecked():
            if '561nm' in self.fList.keys():
                self.channel = '561nm'
            else:
                QtGui.QMessageBox.about(self, 'Warning', 'No 561nm channel!')
        elif self.CoolLEDBtn.isChecked():
            if 'CoolLED' in self.fList.keys():
                self.channel = 'CoolLED'
            else:
                QtGui.QMessageBox.about(self, 'Warning', 'No CoolLED channel!')
        self.setBCslidersMinMax()
        self.resetBC()
        self.setFocus()
        self.updateAllCanvas()

    def automaticOutline(self):
        
        tp = self.tp.value()
        sl = self.sl.value()
        
        rowmask = self.df['rowtype']=='body'
        outline = self.df.ix[ rowmask, 'outline' ].values
        spline = self.df.ix[ rowmask, 'spline' ].values
        
        for idx, o in enumerate( outline ):

            if len(o) == 2:
                
                stack = loadstack( self.fList['488nm'][idx] )
                
                # automatically create the outline
                outline[idx] = automatic_outline_michalis( stack, o, sl, idx )

                # create the spline interpolation
                spline[idx] = interp_spline( outline[idx] )

        # update the dataframe with the new outline and spline
        self.df.ix[ rowmask, 'outline' ] = outline
        self.df.ix[ rowmask, 'spline' ] = spline
        self.updateCanvas1()
    
    def straightenWorm(self):

        raw_worm = self.worm.split('_')[0]
        path = self.path+raw_worm
        if not os.path.exists(path):
            QtGui.QMessageBox.about(self, 'Warning! No raw data found in the standard directory. No straightening will be performed', 'Y:\\Images')
            return
        
        spline = []
        for idx in self.df.ix[ pd.notnull(self.df.spline)].index:
            spline.append( np.array( [ self.df.spline.values[idx][:,0]*self.scaleFactor,
                                    self.df.spline.values[idx][:,1]*self.scaleFactor,
                                    self.df.spline.values[idx][:,2] ] ).T )

        fList = {}
        if os.path.isfile(path + '\\z001_488nm.tif'):
            fList['488nm'] = glob.glob(path + '\\z*488nm.tif')
            fList['488nm'].sort()
        if os.path.isfile(path+'\\z001_561nm.tif'):
            fList['561nm'] = glob.glob(path + '\\z*561nm.tif')
            fList['561nm'].sort()
        if os.path.isfile(path + '\\z001_CoolLED.tif'):
            fList['CoolLED'] = glob.glob(path + '\\z*CoolLED.tif')
            fList['CoolLED'].sort()

#        print(25*self.scaleFactor)
        for key in list( fList.keys() ):
            straighten( path, fList[str(key)], spline )

        self.loadNewStack()
        self.updateCanvas2()
        self.canvas1.setFocus()
         
    def automaticCellNames(self):

        tidxNow = self.tp.value() - self.hatch.value()

        tidxNowMask = self.df.tidx == tidxNow
        cellMask = self.df.rowtype == 'cell'
        sideMask = self.df.cside == self.side

        # find the previous timepoint with labeled cells
        if np.sum( sideMask & (self.df.tidx < tidxNow) ) == 0:
            QtGui.QMessageBox.about(self, 'Warning', 'No cells are labeled in the %s side yet!' % self.side)
            return   
        else:
            tidxPrev = np.max( self.df.ix[ sideMask & ( self.df.tidx<tidxNow ), 'tidx' ] )
            # print(self.side, tidxPrev)
            tidxPrevMask = self.df['tidx'] == tidxPrev

        # filter the cells from the dataframe
        cellsNow = self.df[cellMask&tidxNowMask&sideMask]
        cellsPrev = self.df[cellMask&tidxPrevMask&sideMask]

        # find the relative positions and sort the cells
        wNowLen = np.max(cellsNow.cXpos)-np.min(cellsNow.cXpos)
        wPrevLen = np.max(cellsPrev.cXpos)-np.min(cellsPrev.cXpos)

        for idx in cellsNow.index:
            cellsNow.ix[idx,'relPos'] = ( cellsNow.ix[idx,'cXpos'] - np.min(cellsNow.cXpos) )/wNowLen
        for idx in cellsPrev.index:
            cellsPrev.ix[idx,'relPos'] = ( cellsPrev.ix[idx,'cXpos'] - np.min(cellsPrev.cXpos) )/wPrevLen

        cellsNow = cellsNow.sort(['relPos'])
        cellsPrev = cellsPrev.sort(['relPos'])

        # assign all the names according to closest cell in previous timepoint
        # if there are more cells now, two cells will have the same name
        for idx, cell in cellsNow.iterrows():
            closestCell = self.closestCell( cell, cellsPrev )
            cellsNow.ix[idx,'cname'] = closestCell.cname.values[0]

        # if more cells, a division happened.
        if len(cellsNow) > len(cellsPrev):
            # print('I am f****d...')

            # for each cell (but first the most left one), find the first one to the left
            for idx, cell in cellsNow.drop( np.min(cellsNow.index.values) ).iterrows():
                cellToTheLeft = cellsNow.ix[ idx - 1 ]

                # if it has the same name, a division happened
                if cellsNow.ix[idx,'cname'] == cellToTheLeft.cname:
                    cellsNow.ix[idx-1,'cname'] += 'a'
                    cellsNow.ix[idx,'cname'] += 'p'

        # update dataframe
        for idx, cell in cellsNow.iterrows():
            self.df.ix[idx,'cname'] = cell.cname

        # update canvas
        self.updateTable()
        self.updateCanvas2()

    #-----------------------------------------------------------------------------------------------
    # DEFAULT FUNCTION FOR KEY AND MOUSE PRESS ON WINDOW
    #-----------------------------------------------------------------------------------------------

    def keyPressEvent(self, event):
        
        # print(event.key())

        # change timepoint
        if event.key() == QtCore.Qt.Key_Right:
            self.changeSpaceTime( self.tp, +1 )

        if event.key() == QtCore.Qt.Key_Left:
            self.changeSpaceTime( self.tp, -1 )

        # change slice
        if event.key() == QtCore.Qt.Key_Up:
            self.changeSpaceTime( self.sl, +1 )
            
        if event.key() == QtCore.Qt.Key_Down:
            self.changeSpaceTime( self.sl, -1 )

        # change channel
        if event.key() == QtCore.Qt.Key_Space:
            currentidx = list(self.fList.keys()).index(self.channel) 
            nextidx = np.mod(currentidx+1,len(self.fList.keys()))
            self.channel = list(self.fList.keys())[nextidx]
            self.setBCslidersMinMax()
            self.resetBC()
            self.updateAllCanvas()
            
        # key press on straighten worm
        if self.canvas2.underMouse():
            self.onKeyPressOnCanvas2(event)
            
        self.setFocus()
        
    def wheelEvent(self,event):
        if any([ self.canvas1.underMouse(), self.canvas2.underMouse(), self.canvas3.underMouse() ]):
            step = event.step
        else:          
            step = event.delta()/abs(event.delta())
        self.sl.setValue( self.sl.value() + step) 

    #-----------------------------------------------------------------------------------------------
    # ADDITIONAL FUNCTIONS FOR KEY AND MOUSE PRESS ON CANVASES
    #-----------------------------------------------------------------------------------------------

    def onKeyPressOnCanvas2(self, event):

        # print(event.key())
        
        cellsname = [ QtCore.Qt.Key_A, QtCore.Qt.Key_B, QtCore.Qt.Key_C, QtCore.Qt.Key_1,
                      QtCore.Qt.Key_2, QtCore.Qt.Key_3, QtCore.Qt.Key_4, QtCore.Qt.Key_5,
                      QtCore.Qt.Key_6, QtCore.Qt.Key_T ]
        cellspos = [ QtCore.Qt.Key_Q, QtCore.Qt.Key_W ]

        # find the position of the cursor relative to the image in pixel
        imgshape = self.stacksStraight[self.channel][self.sl.value()].shape
        arimg = imgshape[1]/imgshape[0]
        canshape = self.canvas2.size()
        arcan = canshape.width()/canshape.height()
        cf = 1
        if arimg>arcan:
            cf = imgshape[1]/canshape.width()
            origin = ( canshape.height()*cf - imgshape[0] ) / 2.
            origin = np.array( [ 0, ( canshape.width()*cf - imgshape[1] ) / 2. ] )
        else:
            cf = imgshape[0]/canshape.height()
            origin = np.array( [ ( canshape.width()*cf - imgshape[1] ) / 2., 0 ] )
        refpos = self.canvas2.mapFromGlobal(QtGui.QCursor.pos())
        refpos = np.array([refpos.x(),refpos.y()])*cf - origin
        refpos = np.append(refpos,self.sl.value())

        # find the closest cell to the cursor
        bodymask = self.df['rowtype']=='body'
        cellmask = self.df['rowtype']=='cell'
        tpmask = self.df['tidx'] == (self.tp.value()-self.hatch.value())
        
        idx, cell = closer_cell( refpos, self.df[ cellmask & tpmask ], self.fMetaList[self.tp.value()] )

        if any( [ event.key() == cn for cn in cellsname ] ):
            self.df.ix[ idx, 'cname' ] = QtGui.QKeySequence(event.key()).toString().lower() + '.'

        elif any( [ event.key() == cp for cp in cellspos ] ):

            if event.key() == cellspos[0]:      self.df.ix[ idx, 'cname' ] += 'a'
            elif event.key() == cellspos[1]:    self.df.ix[ idx, 'cname' ] += 'p'
                
        elif event.key() == QtCore.Qt.Key_Backspace:
            
            self.df.ix[ idx, 'cname' ] = self.df.ix[ idx, 'cname' ][:-1]

        elif event.key() == QtCore.Qt.Key_I:
            
            sideLmask = self.df['cside']=='L'
            self.df.ix[ tpmask & cellmask & sideLmask,'cside'] = 'R'
            sideRmask = self.df['cside']=='R'
            self.df.ix[ tpmask & cellmask & sideRmask,'cside'] = 'L'

        elif event.key() == QtCore.Qt.Key_U:
            
            if self.df.ix[idx,'cside']=='L':    self.df.ix[ idx,'cside'] = 'R'
            elif self.df.ix[idx,'cside']=='R':  self.df.ix[ idx,'cside'] = 'L'
        
        self.df = self.df.sort(['tidx','rowtype','cside','cXpos']).reset_index(drop=True)
        self.updateTable()
        self.updateAllCanvas()
        
    def onMouseClickOnCanvas1(self, event):
        
        # print(event.button,event.xdata,event.ydata)
        
        tp = self.tp.value()
        sl = self.sl.value()
        
        rowmask = self.df['rowtype']=='body'
        outline = self.df.ix[ rowmask, 'outline' ].values
        spline = self.df.ix[ rowmask, 'spline' ].values

        x = event.xdata
        y = event.ydata

        # left button: add a point to the outline
        if event.button == 1:   
            
            if not np.all(np.isnan(outline[tp])):
                idx = find_closest_point( [ x, y ], outline[tp] )
            else:
                idx = 0                
            outline[tp] = np.insert( outline[tp], idx+1, [ x, y, sl ], axis=0 )
            
            # if the first line is still full of nan, remove it
            if np.all(np.isnan(outline[tp][0])):
                outline[tp] = np.delete(outline[tp],0,axis=0)
                                
        # right button: remove the closest point from the outline
        elif event.button == 3 and len(outline[tp]) > 0:
            
            idx = find_closest_point([x,y],outline[tp])
            if outline[tp].shape[0]!=1:
                outline[tp] = np.delete( outline[tp], idx, axis=0 )
            else:
                outline[tp] = np.array([[np.nan,np.nan,np.nan]])
                
        # update the dataframe with the new outline and spline
        spline[tp] = interp_spline( outline[tp] )
        self.df.ix[ rowmask, 'outline' ] = outline
        self.df.ix[ rowmask, 'spline' ] = spline
        self.updateCanvas1()
        self.setFocus()

    def onMouseClickOnCanvas2(self, event):
        
        refpos = np.array( [ event.xdata, event.ydata, self.sl.value() ] )  
        # print(refpos)
        bodymask = self.df['rowtype']=='body'
        cellmask = self.df['rowtype']=='cell'
        tpmask = self.df['tidx'] == (self.tp.value()-self.hatch.value())
        # print( 'mouse button pressed:', event.button, 'at pos:', refpos )
        if all( refpos[:-1] ) > 0:
            if event.button == 1:
    
                # create an empty cell: the only entries are tidx, times, xyzpos, side
                newcell = create_cell( refpos, self.df[ bodymask & tpmask ], self.side  )
                self.df = pd.concat( [ self.df, newcell ] )
                
            elif event.button == 3:

                if any( self.df[tpmask].rowtype == 'cell' ):
                    idx, cell = closer_cell( refpos, self.df[ cellmask & tpmask ], self.fMetaList[self.tp.value()] )
                    self.df = self.df.drop([idx])
            
            elif event.button == 2:
    
                if self.side == 'L': self.side = 'R'
                elif self.side == 'R': self.side = 'L'
                self.sideLbl.setText(self.lbltxt % self.side)

        self.df = self.df.sort(['tidx','rowtype','cside','cXpos']).reset_index(drop=True)
        self.updateCanvas2()
        self.updateTable()
        self.setFocus()
                
    #-----------------------------------------------------------------------------------------------
    # UTILS
    #-----------------------------------------------------------------------------------------------

    def updateRadioBtn(self):
        if self.channel == '488nm':
            self._488nmBtn.setChecked(True)
        elif self.channel == '561nm':
            self._561nmBtn.setChecked(True)
        elif self.channel == 'CoolLED':
            self.CoolLEDBtn.setChecked(True)
        self.setFocus()

    def setBCslidersMinMax(self):
        self.sld1.setMaximum(np.max(self.stacks[self.channel]))
        self.sld1.setMinimum(np.min(self.stacks[self.channel]))
        self.sld2.setMaximum(np.max(self.stacks[self.channel]))
        self.sld2.setMinimum(np.min(self.stacks[self.channel]))

    def resetBC(self):
        self.sld1.setValue(np.min(self.stacks[self.channel]))
        self.sld2.setValue(np.max(self.stacks[self.channel]))
        
    def updateCanvas1(self):
        
        rowmask = self.df['rowtype']=='body'
        tidxmask = self.df['tidx']==(self.tp.value()-self.hatch.value())
        
        # extract and rescale the outline and spline
        outline = np.copy( self.df.ix[ rowmask & tidxmask, 'outline' ].values[0] )
        spline = np.copy( self.df.ix[ rowmask & tidxmask, 'spline' ].values[0] )

        # plot the image
        self.ax1.cla()
        imgplot = self.ax1.imshow(self.stacks[self.channel][self.sl.value()], cmap = 'gray')
        
        # remove the white borders and plot outline and spline
        self.ax1.autoscale(False)
        self.ax1.axis('Off')
        self.fig1.subplots_adjust(left=0., right=1., top=1., bottom=0.)

        # change brightness and contrast
        self.sld1.setValue(np.min([self.sld1.value(),self.sld2.value()]))
        self.sld2.setValue(np.max([self.sld1.value(),self.sld2.value()]))
        imgplot.set_clim(self.sld1.value(), self.sld2.value())        

        # print(outline, spline)
        self.ax1.plot( outline[:,0], outline[:,1], 'o', color='red', ms=6, mew=1, alpha=.5, lw = 1 )
        self.ax1.plot( spline[:,0], spline[:,1], '-', color='yellow', lw = 1 )
        
        # redraw the canvas
        self.canvas1.draw()
        self.setFocus()

    def updateCanvas2(self):
        
        # plot the image
        self.ax2.cla()

        if not os.path.isfile(self.straightFile):
            self.fig2.clf()
            self.fig2.subplots_adjust(left=0., right=1., top=1., bottom=0.)
            self.ax2 = self.fig2.add_subplot(111)
            self.canvas2.draw()
            return
            
        imgplot = self.ax2.imshow(self.stacksStraight[self.channel][self.sl.value()], cmap = 'gray')
        imgplot.set_clim(self.sld1.value(), self.sld2.value())

        # remove the white borders
        self.ax2.autoscale(False)
        self.ax2.axis('Off')
        self.fig2.subplots_adjust(left=0., right=1., top=1., bottom=0.)
        
        # cell text on the image
        tpmask = self.df['tidx'] == (self.tp.value() - self.hatch.value())
        cellmask = self.df['rowtype'] == 'cell'

        for idx, cell in self.df[tpmask & cellmask].iterrows():

            if cell.cZpos == self.sl.value():
                clabel = str(cell.cname) + ' ' + str(cell.cside)
                self.ax2.text( cell.cXpos, cell.cYpos + 10, clabel, color='red', size='medium', alpha=.8,
                        rotation=90)
                self.ax2.plot( cell.cXpos, cell.cYpos, 'x', color='red', alpha = .8 )


        # redraw the canvas
        self.canvas2.draw()
        self.setFocus()

    def updateCanvas3(self):
        # print('updating canvas 3')
        
        tidxNow = self.tp.value() - self.hatch.value()

        tidxNowMask = self.df.tidx == tidxNow
        cellMask = self.df.rowtype == 'cell'
        sideMask = self.df.cside == self.side

        # find the previous timepoint with labeled cells
        if np.sum( sideMask & (self.df.tidx < tidxNow) ) == 0:
            self.fig3.clf()
            self.fig3.subplots_adjust(left=0., right=1., top=1., bottom=0.)
            self.ax3 = self.fig3.add_subplot(111)
            self.canvas3.draw()
            return   
        else:
            tidxPrev = np.max( self.df.ix[ sideMask & ( self.df.tidx<tidxNow ), 'tidx' ] )
            tidxPrevMask = self.df['tidx'] == tidxPrev

        # load images
        prevstacksStraight = {}
        for key in self.fList.keys():
            prevstacksStraight[key] = loadstack(self.path+self.worm.split('_')[0]+'_straighten\\straight%.3d_%s.tif'%(tidxPrev+self.hatch.value()+1,key))

        # plot the image
        self.ax3.cla()

        imgplot = self.ax3.imshow(prevstacksStraight[self.channel][self.sl.value()], cmap = 'gray')
        imgplot.set_clim(self.sld1.value(), self.sld2.value())

        # remove the white borders
        self.ax3.autoscale(False)
        self.ax3.axis('Off')
        self.fig3.subplots_adjust(left=0., right=1., top=1., bottom=0.)
        
        # cell text on the image
        for idx, cell in self.df[tidxPrevMask & cellMask].iterrows():

            if cell.cZpos == self.sl.value():
                clabel = str(cell.cname) + ' ' + str(cell.cside)
                self.ax3.text( cell.cXpos, cell.cYpos + 10, clabel, color='red', size='small', alpha=.8,
                        rotation=90)
                self.ax3.plot( cell.cXpos, cell.cYpos, 'x', color='red', alpha = .8 )

        # redraw the canvas
        self.canvas3.draw()
        self.setFocus()

    def closestCell(self,cell,clist):
        dist = np.abs( clist.relPos - cell.relPos )
        return clist[ dist == np.min(dist) ]
  
    def changeSpaceTime(self, whatToChange, increment):

        whatToChange.setValue( whatToChange.value() + increment )
        
    def rescaledImage(self, img):
        
        Nbig = img.shape[0]
        Nsmall = img.shape[0]/self.scaleFactor
        return img.reshape([Nsmall, Nbig/Nsmall, Nsmall, Nbig/Nsmall]).mean(3).mean(1)

    def updateTable(self):
        self.cellTbl.clear()

        tidxNow = self.tp.value() - self.hatch.value()

        tidxNowMask = self.df.tidx == tidxNow
        cellMask = self.df.rowtype == 'cell'

        cellsNow = self.df[cellMask&tidxNowMask]
        cellsPrev = pd.DataFrame({})
        if len(cellsNow) > 0:
	        sideMask = self.df.cside == cellsNow.cside.values[0]

	        # find the previous timepoint with labeled cells
	        if np.sum( sideMask & (self.df.tidx < tidxNow) ) == 0:
	        	cellsPrev = pd.DataFrame({})
	        else:
	            tidxPrev = np.max( self.df.ix[ sideMask & ( self.df.tidx<tidxNow ), 'tidx' ] )
	            tidxPrevMask = self.df['tidx'] == tidxPrev
	            cellsPrev = self.df[cellMask&tidxPrevMask]
	      
	        horHeaders = ['tidx','times','cell name','cell side','cellXpos','cellYpos','cellZpos','-',
	        				'tidx','times','cell name','cell side','cellXpos','cellYpos','cellZpos']
	        self.cellTbl.setColumnCount(len(horHeaders))
	        self.cellTbl.setRowCount(np.max([len(cellsNow),len(cellsPrev)]))        
	        self.cellTbl.setHorizontalHeaderLabels(horHeaders)
	        self.cellTbl.horizontalHeader().setResizeMode(QtGui.QHeaderView.ResizeToContents)
	        self.cellTbl.verticalHeader().setResizeMode(QtGui.QHeaderView.ResizeToContents)

	        row = 0
	        for idx, cell in cellsNow.iterrows():
	            self.cellTbl.setItem(row,0,QtGui.QTableWidgetItem(str(int(cell.tidx)),.0001))
	            self.cellTbl.setItem(row,1,QtGui.QTableWidgetItem(str('%.2f'%cell.times)))
	            self.cellTbl.setItem(row,2,QtGui.QTableWidgetItem(str(cell.cname)))
	            self.cellTbl.setItem(row,3,QtGui.QTableWidgetItem(cell.cside))
	            self.cellTbl.setItem(row,4,QtGui.QTableWidgetItem(str(int(cell.cXpos))))
	            self.cellTbl.setItem(row,5,QtGui.QTableWidgetItem(str(int(cell.cYpos))))
	            self.cellTbl.setItem(row,6,QtGui.QTableWidgetItem(str(int(cell.cZpos))))
	            row += 1

	        row = 0
	        for idx, cell in cellsPrev.iterrows():
	            self.cellTbl.setItem(row,8,QtGui.QTableWidgetItem(str(int(cell.tidx))))
	            self.cellTbl.setItem(row,9,QtGui.QTableWidgetItem(str('%.2f'%cell.times)))
	            self.cellTbl.setItem(row,10,QtGui.QTableWidgetItem(str(cell.cname)))
	            self.cellTbl.setItem(row,11,QtGui.QTableWidgetItem(cell.cside))
	            self.cellTbl.setItem(row,12,QtGui.QTableWidgetItem(str(int(cell.cXpos))))
	            self.cellTbl.setItem(row,13,QtGui.QTableWidgetItem(str(int(cell.cYpos))))
	            self.cellTbl.setItem(row,14,QtGui.QTableWidgetItem(str(int(cell.cZpos))))
	            row += 1
        
        self.setFocus()
예제 #13
0
    import sys

    app = QtGui.QApplication(sys.argv)
    imageViewer = ImageViewer()
    imageViewer.show()
    
    figure = plt.figure()
    figure.set_size_inches(11, 8.5)
    figure.patch.set_facecolor('white')
    plt.plot([1, 2, 3, 4], [1, 2, 3, 4], '-b')

    figure_canvas = FigureCanvasQTAgg(figure)
    figure_canvas.draw()
            
    size = figure_canvas.size()
    width, height = size.width(), size.height()
    print(width, height)
    print(figure_canvas.get_width_height())
    imgbuffer = figure_canvas.buffer_rgba()
    image = QtGui.QImage(imgbuffer, width, height,
                         QtGui.QImage.Format_ARGB32)
                         
    # Reference for the RGB to BGR swap:
    # http://sourceforge.net/p/matplotlib/mailman/message/5194542/
      
    image = QtGui.QImage.rgbSwapped(image)    
    imageViewer.load_image(image, 0)
    
    
    sys.exit(app.exec_())
예제 #14
0
class GUI(QtGui.QWidget):
    
    def __init__(self):

        super(GUI, self).__init__()
        
        self.setWindowTitle( 'Label Cells' )
        self.cellNames = ['1.p','4.a','1.pp','4.aa','1.ppa','1.ppp','4.aaa','4.aap','b_1','b_4']
        self.initUI()
        
    #-----------------------------------------------------------------------------------------------
    # INITIALIZATION OF THE WINDOW - DEFINE AND PLACE ALL THE WIDGETS
    #-----------------------------------------------------------------------------------------------

    def initUI(self):
        
        # SET THE GEOMETRY
        
        mainWindow = QtGui.QVBoxLayout()
        mainWindow.setSpacing(15)
        
        fileBox = QtGui.QHBoxLayout()
        spaceBox1 = QtGui.QHBoxLayout()
        rawDataBox = QtGui.QHBoxLayout()
        
        mainWindow.addLayout(fileBox)
        mainWindow.addLayout(spaceBox1)
        mainWindow.addLayout(rawDataBox)
        
        Col1 = QtGui.QGridLayout()
        Col2 = QtGui.QHBoxLayout()
        Col3 = QtGui.QVBoxLayout()
        
        rawDataBox.addLayout(Col1)
        rawDataBox.addLayout(Col2)
        rawDataBox.addLayout(Col3)
        
        self.setLayout(mainWindow)

        # DEFINE ALL WIDGETS AND BUTTONS
        
        loadBtn = QtGui.QPushButton('Load DataSet')
        saveBtn = QtGui.QPushButton('Save data (F12)')
        
        tpLbl = QtGui.QLabel('Relative Tp:')
        slLbl = QtGui.QLabel('Slice:')
        fNameLbl = QtGui.QLabel('File name:')
        
        self.tp = QtGui.QSpinBox(self)
        self.tp.setValue(0)
        self.tp.setMaximum(100000)

        self.sl = QtGui.QSpinBox(self)
        self.sl.setValue(0)
        self.sl.setMaximum(100000)

        self.fName = QtGui.QLabel('')
        
        self._488nmBtn = QtGui.QRadioButton('488nm')
        self._561nmBtn = QtGui.QRadioButton('561nm')
        self.CoolLEDBtn = QtGui.QRadioButton('CoolLED')
        
        self.sld1 = QtGui.QSlider(QtCore.Qt.Vertical, self)
        self.sld1.setMaximum(2**16-1)
        self.sld1.setValue(0)
        self.sld2 = QtGui.QSlider(QtCore.Qt.Vertical, self)
        self.sld2.setMaximum(2**16)
        self.sld2.setValue(2**16-1)

        self.fig1 = Figure((8.0, 8.0), dpi=100)
        self.fig1.subplots_adjust(left=0., right=1., top=1., bottom=0.)
        self.ax1 = self.fig1.add_subplot(111)
        self.canvas1 = FigureCanvas(self.fig1)
        self.canvas1.setFocusPolicy( QtCore.Qt.ClickFocus )
        self.canvas1.setFocus()
        self.canvas1.setFixedSize(QtCore.QSize(600,600))
        self.canvas1.setSizePolicy( QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding )

        self.cellTbl = QtGui.QTableWidget()

        self.fig2 = Figure((4.0, 4.0), dpi=100)
        self.fig2.subplots_adjust(left=0., right=1., top=1., bottom=0.)
        self.ax2 = self.fig2.add_subplot(111)
        self.canvas2 = FigureCanvas(self.fig2)
        self.canvas2.setFixedSize(QtCore.QSize(300,300))
        self.canvas2.setSizePolicy( QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding )

        # PLACE ALL THE WIDGET ACCORDING TO THE GRIDS

        fileBox.addWidget(loadBtn)
        fileBox.addWidget(saveBtn)

        spaceBox1.addWidget(self.HLine())

        Col1.addWidget(tpLbl, 0, 0)#, 1, 1, Qt.AlignTop)
        Col1.addWidget(self.tp, 0, 1)#, 1, 1, Qt.AlignTop)
        Col1.addWidget(slLbl, 1, 0)#, 1, 1, Qt.AlignTop)
        Col1.addWidget(self.sl, 1, 1)#, 1, 1, Qt.AlignTop)
        Col1.addWidget(fNameLbl, 2, 0)
        Col1.addWidget(self.fName, 2, 1)
        Col1.addWidget(self._488nmBtn, 3, 0 )
        Col1.addWidget(self._561nmBtn, 4, 0 )
        Col1.addWidget(self.CoolLEDBtn, 5, 0 )
        
        Col2.addWidget(self.sld1)
        Col2.addWidget(self.sld2)
        Col2.addWidget(self.canvas1)

        # Col3.addWidget(self.cellTbl)
        Col3.addWidget(self.canvas2)
        
        self.setFocus()

        self.show()
        
        # BIND BUTTONS TO FUNCTIONS
        
        loadBtn.clicked.connect(self.selectWorm)
        saveBtn.clicked.connect(self.saveData)

        self.checkNames = True
        self.tp.valueChanged.connect(self.changeTp)
        self.sl.valueChanged.connect(self.updateCanvas1)
        self.sld1.valueChanged.connect(self.updateBC)
        self.sld2.valueChanged.connect(self.updateBC)

        self._488nmBtn.toggled.connect(self.radio488Clicked)
        self._561nmBtn.toggled.connect(self.radio561Clicked)
        self.CoolLEDBtn.toggled.connect(self.radioCoolLEDClicked)

        self.fig1.canvas.mpl_connect('button_press_event',self.onMouseClickOnCanvas1)        
        self.fig1.canvas.mpl_connect('scroll_event',self.wheelEvent)        
        
    #-----------------------------------------------------------------------------------------------
    # FORMATTING THE WINDOW
    #-----------------------------------------------------------------------------------------------

    def HLine(self):
        
        toto = QtGui.QFrame()
        toto.setFrameShape(QtGui.QFrame.HLine)
        toto.setFrameShadow(QtGui.QFrame.Sunken)
        return toto

    #-----------------------------------------------------------------------------------------------
    # BUTTON FUNCTIONS
    #-----------------------------------------------------------------------------------------------

    def selectWorm(self):

        ### store the folders
        self.pathDial = QtGui.QFileDialog.getExistingDirectory(self, 'Select a folder', 'X:\\Simone\\160129_MCHERRY_HLH2GFP_onHB101')#'Y:\\Images')
        self.worm = self.pathDial.split("\\")[-1].split('_')[0]
        self.path = os.path.dirname( self.pathDial )
        self.setWindowTitle('Mark Cells - ' + self.pathDial)
        
        ### give error message if there is no CoolLED movie in the selected folder
        flist = glob.glob( self.pathDial + '\\*_movie.tif' )
        if len(flist)==0:#not os.path.isfile( os.path.join( self.pathDial, '*_movie.tif' ) ):
            QtGui.QMessageBox.about(self,'Warning!','There is no movie in this folder! Create a movie first!')
            return

        ### load parameters and times dataframes
        self.paramsDF = load_data_frame( self.path, self.worm + '_01params.pickle' )
        self.timesDF = load_data_frame( self.path, self.worm + '_01times.pickle' )
        self.gpDF = load_data_frame( self.path, self.worm + '_02gonadPos.pickle' )

        # extract some info
        self.compression = self.paramsDF.compression
        self.hatchingtidx = int( self.paramsDF.tidxHatch )

        ### find ecdysis timepoint

        ecd = np.loadtxt( open( os.path.join( self.path, 'skin.txt'), 'rb' ) )
        # load ecdysis data
        index = np.where( ecd[:,0] == float(self.worm[1:]) )
        mintp = np.min( [ i for i in ecd[index, 1:6][0][0] if i >= 0 ] )
        lethtidx = ecd[ index, 2:6 ][0][0] - 1
        tpL2 = self.timesDF.ix[ self.timesDF.tidxRel == lethtidx[0], 'timesRel' ].values[0]
        tpL1 = self.timesDF.ix[ self.timesDF.tidxRel == mintp, 'timesRel' ].values[0]

        # relative to hatching time
        self.tpHatch=tpL1

        ### if the cellPos pickle file already exists, load it, otherwise create a blank one
        if os.path.isfile( os.path.join(self.path, self.worm + '_04cellPos.pickle' ) ):
            self.cellPosDF = load_data_frame( self.path, self.worm + '_04cellPos.pickle' )
        
        else:
            self.cellPosDF = create_cell_pos( self.timesDF, self.cellNames )

        # detect available channels
        self.channels = []
        chns = ['CoolLED','488nm','561nm']
        for c in chns:

            if os.path.isfile( os.path.join( self.pathDial, c + '_movie.tif' ) ):

                self.channels.append(c)
        self.currentChannel = self.channels[0]

        ### detect size of the cropped images
        tp = np.min( self.gpDF.ix[ pd.notnull( self.gpDF.X ), 'tidx' ] )
        self.prevtp = tp-1
        tRow = self.timesDF.ix[ self.timesDF.tidxRel == tp ].squeeze()
        fileName = os.path.join( self.pathDial, tRow.fName + self.currentChannel + '.tif')
        firststack = load_stack( fileName )
        self.cropsize = firststack.shape[1]
        self.nslices = firststack.shape[0]

        ### load CoolLED movie
        if 'CoolLED' in self.channels:
            self.LEDmovie = load_stack( os.path.join( self.pathDial, 'CoolLED_movie.tif' ) )
        else:
            self.LEDmovie = load_stack( os.path.join( self.pathDial, self.currentChannel + '_movie.tif' ) )
        self.initializeCanvas1()
        self.initializeCanvas2()

        ### extract current cells already labeled
        self.currentCells = extract_current_cell_pos( self.cellPosDF, self.tp.value() )

        ### update the text of the fileName
        self.fName.setText( self.timesDF.ix[ self.timesDF.tidxRel == tp, 'fName' ].values[0])

        ### set the timepoint to the hatching time
        self.tp.setMinimum(np.min(self.timesDF.tidxRel))
        self.tp.setMaximum(np.max(self.timesDF.tidxRel))

        ### set the max slice number
        self.sl.setMaximum( self.nslices-1 )

        self.tp.setValue( tp )

        if self.currentChannel == 'CoolLED':
            self.CoolLEDBtn.setChecked(True)    # this uppdates the canvas1 once more
        elif self.currentChannel == '561nm':
            self._561nmBtn.setChecked(True)    # this uppdates the canvas1 once more
        elif self.currentChannel == '488nm':
            self._488nmBtn.setChecked(True)    # this uppdates the canvas1 once more

        # self.pathDial.show()
        self.setFocus()

    def loadNewStack(self):

        # print(self.fList['gfp'][self.tp.value()])
        tRow = self.timesDF.ix[ self.timesDF.tidxRel == self.tp.value() ].squeeze()

        ### update the text of the fileName
        self.fName.setText( self.timesDF.ix[ self.timesDF.tidxRel == self.tp.value(), 'fName' ].values[0])

        print( 'Loading... ', self.pathDial, tRow.fName )

        # calculate the max value of the previous stack
        try:
            prevmax = np.max( [ np.max(self.stacks[ch]) for ch in self.channels ] )
        # if it's the first time a stack is to be loaded (so if there is no previous stack), set it to zero
        except:
            prevmax = 0

        # load all the available stacks - this is the slowest part of the code!!!
        self.stacks = {}
        for ch in self.channels:
            fileName = os.path.join( self.pathDial, tRow.fName + ch + '.tif')
            if os.path.isfile( fileName ):
                # print(MultiImage('X:\\Simone\\160129_MCHERRY_HLH2GFP_onHB101\\C02_analyzedImages\\Z003_488nm.tif'))
                # print(fileName, MultiImage( fileName ))
                # self.stacks[ch] = MultiImage( fileName )
                self.stacks[ch] = load_stack( fileName )
            # if there are no files for the timepoint, create a blank image
            else:
                self.stacks[ch] = prevmax*np.ones((self.nslices,self.cropsize,self.cropsize))
                
        # if the BC bound are different, the BCsliderMinMax will automatically update canvas1. Otherwise, manually update it!
        self.setBCslidersMinMax()            

        self.updateCanvas1()    
        self.updateCanvas2()

    def changeTp( self ):

        # if it's the second time you are checking the same tp, don't do anything
        if self.checkNames:
            cellFine = self.checkConsistencyCellNames()
        else:
            return

        # before changing timepoint, print labeled cells and check if they are OK
        print( 'cells labeled:\n ', self.currentCells )

        ### extract current cells already labeled
        self.newCells = extract_current_cell_pos( self.cellPosDF, self.tp.value() )

        if cellFine:
            # if everything fine, load the new stack
            self.currentCells = self.newCells
            self.loadNewStack()
        else:
            # otherwise, go back to prev tp
            self.checkNames = False
            self.tp.setValue( self.prevtp )
            self.checkNames = True

        self.prevtp = self.tp.value()


    def saveData(self):
        
        if self.checkConsistencyCellNames():
            save_data_frame( self.cellPosDF, self.path, self.worm + '_04cellPos.pickle' )        
        else:
            QtGui.QMessageBox.about(self,'Warning!','There is a mistake in the cell labels!')
        self.setFocus()
        
    def radio488Clicked(self, enabled):
        # print('radio 488 clicked')

        if enabled:
            if '488nm' in self.channels:
                self.currentChannel = '488nm'
                self.setFocus()
                self.updateCanvas1()
            else:
                if self.currentChannel == 'CoolLED':
                    self.CoolLEDBtn.setChecked(True)    # this uppdates the canvas1 once more
                elif self.currentChannel == '561nm':
                    self._561nmBtn.setChecked(True)    # this uppdates the canvas1 once more
                QtGui.QMessageBox.about(self, 'Warning', 'No 488nm channel!')

    def radio561Clicked(self, enabled):
        # print('radio 561 clicked')

        if enabled:
            if '561nm' in self.channels:
                self.currentChannel = '561nm'
                self.setFocus()
                self.updateCanvas1()
            else:
                if self.currentChannel == 'CoolLED':
                    self.CoolLEDBtn.setChecked(True)    # this uppdates the canvas1 once more
                elif self.currentChannel == '488nm':
                    self._488nmBtn.setChecked(True)    # this uppdates the canvas1 once more
                QtGui.QMessageBox.about(self, 'Warning', 'No 561nm channel!')

    def radioCoolLEDClicked(self, enabled):
        # print('radio LED clicked')

        if enabled:
            if 'CoolLED' in self.channels:
                self.currentChannel = 'CoolLED'
                self.setFocus()
                self.updateCanvas1()
            else:
                if self.currentChannel == '561nm':
                    self._561nmBtn.setChecked(True)    # this uppdates the canvas1 once more
                elif self.currentChannel == '488nm':
                    self._488nmBtn.setChecked(True)    # this uppdates the canvas1 once more
                QtGui.QMessageBox.about(self, 'Warning', 'No CoolLED channel!')

    def updateBC(self):
        # change brightness and contrast
        self.imgplot1.set_clim( self.sld1.value(), self.sld2.value() )  
        self.canvas1.draw()

    #-----------------------------------------------------------------------------------------------
    # DEFAULT FUNCTION FOR KEY AND MOUSE PRESS ON WINDOW
    #-----------------------------------------------------------------------------------------------

    def keyPressEvent(self, event):
        
        # print(event.key())

        # change timepoint
        if event.key() == QtCore.Qt.Key_Right:
            self.changeSpaceTime( 'time', +1 )

        elif event.key() == QtCore.Qt.Key_Left:
            self.changeSpaceTime( 'time', -1 )

        # change slice
        elif event.key() == QtCore.Qt.Key_Up:
            self.changeSpaceTime( 'space', +1 )
            
        elif event.key() == QtCore.Qt.Key_Down:
            self.changeSpaceTime( 'space', -1 )

        elif event.key() == QtCore.Qt.Key_Space:
            idx = self.channels.index(self.currentChannel)
            if self.channels[ (idx+1)%len(self.channels) ] == 'CoolLED':
                self.CoolLEDBtn.setChecked(True)
            if self.channels[ (idx+1)%len(self.channels) ] == '488nm':
                self._488nmBtn.setChecked(True)
            if self.channels[ (idx+1)%len(self.channels) ] == '561nm':
                self._561nmBtn.setChecked(True)

        # key press on cropped image
        if self.canvas1.underMouse():
            self.onKeyPressOnCanvas1(event)
            
        self.setFocus()

    def wheelEvent(self,event):
        if self.canvas1.underMouse():
            step = event.step
        else:          
            step = event.delta()/abs(event.delta())
        self.sl.setValue( self.sl.value() + step) 

    #-----------------------------------------------------------------------------------------------
    # ADDITIONAL FUNCTIONS FOR KEY AND MOUSE PRESS ON CANVASES
    #-----------------------------------------------------------------------------------------------

    def onKeyPressOnCanvas1(self, event):
        
        motherCells = [ QtCore.Qt.Key_1, QtCore.Qt.Key_4, QtCore.Qt.Key_B ]
        daughterCells = [ QtCore.Qt.Key_A, QtCore.Qt.Key_P ]

        # find the position of the cursor relative to the image in pixel
        imgshape = self.stacks[self.currentChannel][self.sl.value()].shape
        canshape = self.canvas1.size()
        cf = imgshape[0]/canshape.width()
        refpos = self.canvas1.mapFromGlobal(QtGui.QCursor.pos())
        refpos = np.array([ int( refpos.x() * cf ), int( refpos.y() * cf )])
        refpos = np.append(refpos,self.sl.value())

        ### find the closest cell to the cursor
        idx = closer_cell( refpos.astype( np.uint16 ), self.currentCells )

        ### assign the name to the cell
        if any( [ event.key() == cn for cn in motherCells ] ):
            # if labeling bckg, add the 1 or 2 to the name
            if self.currentCells.ix[ idx, 'cname' ] == 'b_':
                self.currentCells.ix[ idx, 'cname' ] += QtGui.QKeySequence(event.key()).toString().lower()
            else:
                # if not, rename the cell from scratch
                if event.key() == QtCore.Qt.Key_B:
                    self.currentCells.ix[ idx, 'cname' ] = QtGui.QKeySequence(event.key()).toString().lower() + '_'
                else:
                    self.currentCells.ix[ idx, 'cname' ] = QtGui.QKeySequence(event.key()).toString().lower() + '.'

        # add the anterior/posterior to the cell name
        elif any( [ event.key() == cp for cp in daughterCells ] ):
            # don't do it if labeling background (bckg doesn't have a/p!)
            if self.currentCells.ix[ idx, 'cname' ] == 'b_':
                return
            else:
                self.currentCells.ix[ idx, 'cname' ] += QtGui.QKeySequence(event.key()).toString().lower()
        
        # remove the last entry of the name with backspace                
        elif event.key() == QtCore.Qt.Key_Backspace:
            self.currentCells.ix[ idx, 'cname' ] = self.currentCells.ix[ idx, 'cname' ][:-1]

        if ( event.key() != QtCore.Qt.Key_Left ) and ( event.key() != QtCore.Qt.Key_Right ) and ( event.key() != QtCore.Qt.Key_Up ) and ( event.key() != QtCore.Qt.Key_Down ):
            self.updateCanvas1()
        self.setFocus()

    def onMouseClickOnCanvas1(self, event):

        refpos = np.array( [ event.xdata, event.ydata, self.sl.value() ] )  

        if event.button == 1:

            # create an empty cell in the currentCells df: the only entries are tidx, xyzpos and cname
            newcell = create_single_cell_pos( refpos.astype(np.uint16), self.tp.value() )
            self.currentCells = pd.concat( [ self.currentCells, newcell ] )
            
        elif event.button == 3:

            if len( self.currentCells ) == 0:
                self.setFocus()
                return

            # remove a cell (the closest to the cursor at the moment of right-click)
            idx = closer_cell( refpos.astype(np.uint16), self.currentCells )
            self.currentCells = self.currentCells.drop( [ idx ] )

        self.currentCells = self.currentCells.reset_index(drop=True)
        
        self.updateCanvas1()
        self.setFocus()

    #-----------------------------------------------------------------------------------------------
    # UTILS
    #-----------------------------------------------------------------------------------------------

    def setBCslidersMinMax(self):
        self.sld1.setMaximum( np.max( [ np.max(self.stacks[ch]) for ch in self.channels ] ) )
        self.sld1.setMinimum(0)
        self.sld2.setMaximum (np.max( [ np.max(self.stacks[ch]) for ch in self.channels ] ) )
        self.sld2.setMinimum(0)

    def initializeCanvas1(self):
        # print('initializing canvas1')

        self.fig1.clf()
        self.fig1.subplots_adjust(left=0., right=1., top=1., bottom=0.)
        self.ax1 = self.fig1.add_subplot(111)
        self.canvas1.draw()

        # plot the first blank image with the right size
        self.ax1.cla()
        self.imgplot1 = self.ax1.imshow( np.zeros((self.cropsize,self.cropsize)), cmap = 'gray' )
        
        # remove the white borders
        self.ax1.autoscale(False)
        self.ax1.axis('Off')
        self.fig1.subplots_adjust(left=0., right=1., top=1., bottom=0.)

        # plot cell pos and name
        self.text1 = []
        self.points1 = []

        # redraw the canvas
        self.canvas1.draw()
        self.setFocus()
        
    def updateCanvas1(self):
        # print('updating canvas1')

        # plot the image
        self.imgplot1.set_data( self.stacks[self.currentChannel][self.sl.value()] )

        # change brightness and contrast
        self.imgplot1.set_clim( self.sld1.value(), self.sld2.value() )  
        
        # clear cell text and points
        # print(self.text1,self.points1)
        for text in self.text1:
            text.remove()
        self.text1 = []

        for points in self.points1:
            self.ax1.lines.remove(points)
        self.points1 = []

        # draw cell text and point
        for idx, cell in self.currentCells.iterrows():

            if cell.Z == self.sl.value():

                self.text1.append( self.ax1.text( cell.X, cell.Y + 18, cell.cname, color='red', size='medium', alpha=.8,
                        rotation=0 ) )
                self.points1.append( self.ax1.plot( cell.X, cell.Y, 'o', color='red', alpha = .8, mew = 0 )[0] )

        # redraw the canvas
        self.canvas1.draw()
        self.setFocus()

    def initializeCanvas2(self):
        # print('initializing canvas2')

        # plot the image
        self.ax2.cla()
        self.imgplot2 = self.ax2.imshow( np.zeros((512,512)), cmap = 'gray' )
        self.imgplot2.set_clim( np.min(self.LEDmovie), np.max(self.LEDmovie) )

        # remove the white borders and plot outline and spline
        self.ax2.autoscale(False)
        self.ax2.axis('Off')
        self.fig2.subplots_adjust(left=0., right=1., top=1., bottom=0.)

        # print gonad position
        gonadPos = [np.nan,np.nan]
        self.points2, = self.ax2.plot( gonadPos[0], gonadPos[1], 'o', color='red', ms=10, mew=0, alpha=.5, lw = 0 ) 

        # print time
        self.text2 = self.ax2.text( 5, 25, '--.--', color = 'red' )     

        # redraw the canvas
        self.canvas2.draw()
        self.setFocus()

    def updateCanvas2(self):
        # print('updating canvas2')
        # plot the image
        self.imgplot2.set_data( self.LEDmovie[ self.tp.value() + self.hatchingtidx ] )

        # print gonad position
        gonadPos = extract_pos( self.gpDF.ix[ self.gpDF.tidx == self.tp.value() ].squeeze() ) / self.compression
        if len( gonadPos.shape ) > 0:
            self.points2.set_xdata( gonadPos[0] ) 
            self.points2.set_ydata( gonadPos[1] ) 
            plt.draw()

        # print time
        # print(self.timesDF.ix[ self.timesDF.tidxRel == self.tp.value(), 'timesRel' ])
        self.text2.set_text( '%.2f' % ( self.timesDF.ix[ self.timesDF.tidxRel == self.tp.value(), 'timesRel' ].values[0] - self.tpHatch ) )

        # redraw the canvas
        self.canvas2.draw()
        self.setFocus()

    def checkConsistencyCellNames( self ):
        ### check consistency of cell names
        tp = self.prevtp

        # if no cells are labeled (currentCells df is empty), remove all labeled cells in the cellPosDF and return
        if len( self.currentCells ) == 0:
            newCellPosDF = update_cell_pos_DF( self.currentCells, self.cellPosDF, tp )
            correctCellNames = True

        if len( self.currentCells ) > 0:

            correctCellNames = check_cell_names( self.currentCells, self.cellNames )

            # if cells are not properly labeled, give a Warning
            if not correctCellNames:
                QtGui.QMessageBox.about(self,'Warning!','There is a mistake in the cell labels!')

            # else, update final cellPosDF and return OK
            else:
                newCellPosDF = update_cell_pos_DF( self.currentCells, self.cellPosDF, tp )
                self.cellPosDF = newCellPosDF

        return correctCellNames

    def changeSpaceTime(self, whatToChange, increment):

        if whatToChange == 'time':
            # if they are OK (and not going to negative times), change timepoint
            self.tp.setValue( self.tp.value() + increment )

        if whatToChange == 'space':
            self.sl.setValue( self.sl.value() + increment )
예제 #15
0
class Amoeba_Line_Graph():

    def __init__(self):
        """
        This class is for the plot on each of the parameter UIs.
        """
        #Generate plot
        x = []
        y = []
        self.fig = Figure(figsize=(8,4),dpi=72, facecolor=(1,1,1), edgecolor=(0,0,0))
        self.sub_plot = self.fig.add_subplot(111)
        self.sub_plot.xaxis_date()
        if AMOEBA_LINE_GRAPH_DEBUG:
            print "X = "
            print x
            print "Y = "
            print y
            print "Create "
            print self.sub_plot.plot
        self.sub_plot.plot(y,x,'b')
        self.sub_plot.set_xlabel('Time')
        self.fig.autofmt_xdate()
        #Create canvas for the plot
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setMinimumSize(self.canvas.size())

    def update(self,datay,datax):
        """
        This method updates the plot with the input data.
        :param datay: Y axis of the points to plot.
        :param datax: X axis of the points to plot.
        """
        if AMOEBA_LINE_GRAPH_DEBUG:
            print "Update sub plot"
            print "X = "
            print datax
            print "Y = "
            print datay
            print "Update "
            print self.sub_plot.plot
        # Clear the graph.
        self.clear_graph()
        self.sub_plot.plot(datax,datay,'b')
        self.sub_plot.set_visible(True)
        self.sub_plot.autoscale(True,"both")
        self.canvas.draw()
        
    def retrieve_graph(self):
        """
        This method returns the plot's widget.
        :return:
        """
        return self.canvas

    def clear_graph(self):
        """
        This method clears the graph.
        """
        y = []
        x = []
        self.sub_plot.clear()
        self.sub_plot.set_visible(True)
        self.sub_plot.autoscale(True,"both",False)
        self.sub_plot.plot(y,x,'b')
        self.canvas.draw()
예제 #16
0
class GUI(QtGui.QWidget):
    def __init__(self):

        super(GUI, self).__init__()

        self.setWindowTitle('Label Cells')
        self.cellNames = [
            '1.p', '4.a', '1.pp', '4.aa', '1.ppa', '1.ppp', '4.aaa', '4.aap',
            'b_1', 'b_4'
        ]
        self.initUI()

    #-----------------------------------------------------------------------------------------------
    # INITIALIZATION OF THE WINDOW - DEFINE AND PLACE ALL THE WIDGETS
    #-----------------------------------------------------------------------------------------------

    def initUI(self):

        # SET THE GEOMETRY

        mainWindow = QtGui.QVBoxLayout()
        mainWindow.setSpacing(15)

        fileBox = QtGui.QHBoxLayout()
        spaceBox1 = QtGui.QHBoxLayout()
        rawDataBox = QtGui.QHBoxLayout()

        mainWindow.addLayout(fileBox)
        mainWindow.addLayout(spaceBox1)
        mainWindow.addLayout(rawDataBox)

        Col1 = QtGui.QGridLayout()
        Col2 = QtGui.QHBoxLayout()
        Col3 = QtGui.QVBoxLayout()

        rawDataBox.addLayout(Col1)
        rawDataBox.addLayout(Col2)
        rawDataBox.addLayout(Col3)

        self.setLayout(mainWindow)

        # DEFINE ALL WIDGETS AND BUTTONS

        loadBtn = QtGui.QPushButton('Load DataSet')
        saveBtn = QtGui.QPushButton('Save data (F12)')

        tpLbl = QtGui.QLabel('Relative Tp:')
        slLbl = QtGui.QLabel('Slice:')
        fNameLbl = QtGui.QLabel('File name:')

        self.tp = QtGui.QSpinBox(self)
        self.tp.setValue(0)
        self.tp.setMaximum(100000)

        self.sl = QtGui.QSpinBox(self)
        self.sl.setValue(0)
        self.sl.setMaximum(100000)

        self.fName = QtGui.QLabel('')

        self._488nmBtn = QtGui.QRadioButton('488nm')
        self._561nmBtn = QtGui.QRadioButton('561nm')
        self.CoolLEDBtn = QtGui.QRadioButton('CoolLED')

        self.sld1 = QtGui.QSlider(QtCore.Qt.Vertical, self)
        self.sld1.setMaximum(2**16 - 1)
        self.sld1.setValue(0)
        self.sld2 = QtGui.QSlider(QtCore.Qt.Vertical, self)
        self.sld2.setMaximum(2**16)
        self.sld2.setValue(2**16 - 1)

        self.fig1 = Figure((8.0, 8.0), dpi=100)
        self.fig1.subplots_adjust(left=0., right=1., top=1., bottom=0.)
        self.ax1 = self.fig1.add_subplot(111)
        self.canvas1 = FigureCanvas(self.fig1)
        self.canvas1.setFocusPolicy(QtCore.Qt.ClickFocus)
        self.canvas1.setFocus()
        self.canvas1.setFixedSize(QtCore.QSize(600, 600))
        self.canvas1.setSizePolicy(QtGui.QSizePolicy.Expanding,
                                   QtGui.QSizePolicy.Expanding)

        self.cellTbl = QtGui.QTableWidget()

        self.fig2 = Figure((4.0, 4.0), dpi=100)
        self.fig2.subplots_adjust(left=0., right=1., top=1., bottom=0.)
        self.ax2 = self.fig2.add_subplot(111)
        self.canvas2 = FigureCanvas(self.fig2)
        self.canvas2.setFixedSize(QtCore.QSize(300, 300))
        self.canvas2.setSizePolicy(QtGui.QSizePolicy.Expanding,
                                   QtGui.QSizePolicy.Expanding)

        # self.cellNamesBox=QtGui.QMenu(self.canvas1)
        # actn = []
        # for cname in self.cellNames:
        #     actn.append( QtGui.QAction(cname, self.cellNamesBox) )
        #     self.cellNamesBox.addAction(actn[-1])
        #     actn[-1].triggered.connect( lambda item = cname : self.actionFunct(cname) )

        self.cellNamesBox = QtGui.QMenu(self.canvas1)

        ### define all actions (can be done better!!!)
        actn1p = QtGui.QAction('1.p', self.cellNamesBox)
        self.cellNamesBox.addAction(actn1p)
        actn1p.triggered.connect(lambda item='1.p': self.actionFunct1p('1.p'))

        actn1pp = QtGui.QAction('1.pp', self.cellNamesBox)
        self.cellNamesBox.addAction(actn1pp)
        actn1pp.triggered.connect(
            lambda item='1.pp': self.actionFunct1pp('1.pp'))

        actn1ppp = QtGui.QAction('1.ppp', self.cellNamesBox)
        self.cellNamesBox.addAction(actn1ppp)
        actn1ppp.triggered.connect(
            lambda item='1.ppp': self.actionFunct1ppp('1.ppp'))

        actn1ppa = QtGui.QAction('1.ppa', self.cellNamesBox)
        self.cellNamesBox.addAction(actn1ppa)
        actn1ppa.triggered.connect(
            lambda item='1.ppa': self.actionFunct1ppa('1.ppa'))

        actn4a = QtGui.QAction('4.a', self.cellNamesBox)
        self.cellNamesBox.addAction(actn4a)
        actn4a.triggered.connect(lambda item='4.a': self.actionFunct4a('4.a'))

        actn4aa = QtGui.QAction('4.aa', self.cellNamesBox)
        self.cellNamesBox.addAction(actn4aa)
        actn4aa.triggered.connect(
            lambda item='4.aa': self.actionFunct4aa('4.aa'))

        actn4aaa = QtGui.QAction('4.aaa', self.cellNamesBox)
        self.cellNamesBox.addAction(actn4aaa)
        actn4aaa.triggered.connect(
            lambda item='4.aaa': self.actionFunct4aaa('4.aaa'))

        actn4aap = QtGui.QAction('4.aap', self.cellNamesBox)
        self.cellNamesBox.addAction(actn4aap)
        actn4aap.triggered.connect(
            lambda item='4.aap': self.actionFunct4aap('4.aap'))

        actnb1 = QtGui.QAction('b_1', self.cellNamesBox)
        self.cellNamesBox.addAction(actnb1)
        actnb1.triggered.connect(lambda item='b_1': self.actionFunctb1('b_1'))

        actnb4 = QtGui.QAction('b_4', self.cellNamesBox)
        self.cellNamesBox.addAction(actnb4)
        actnb4.triggered.connect(lambda item='b_4': self.actionFunctb4('b_4'))
        ### END OF THE UGLY PART :)

        self.cellNamesBox.installEventFilter(self)
        self.canvas1.installEventFilter(self)
        self.cellNamesBox.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.cellNamesBox.connect(
            self.cellNamesBox,
            QtCore.SIGNAL("customContextMenuRequested(QPoint)"),
            self.leftClicked)

        # PLACE ALL THE WIDGET ACCORDING TO THE GRIDS

        fileBox.addWidget(loadBtn)
        fileBox.addWidget(saveBtn)

        spaceBox1.addWidget(self.HLine())

        Col1.addWidget(tpLbl, 0, 0)  #, 1, 1, Qt.AlignTop)
        Col1.addWidget(self.tp, 0, 1)  #, 1, 1, Qt.AlignTop)
        Col1.addWidget(slLbl, 1, 0)  #, 1, 1, Qt.AlignTop)
        Col1.addWidget(self.sl, 1, 1)  #, 1, 1, Qt.AlignTop)
        Col1.addWidget(fNameLbl, 2, 0)
        Col1.addWidget(self.fName, 2, 1)
        Col1.addWidget(self._488nmBtn, 3, 0)
        Col1.addWidget(self._561nmBtn, 4, 0)
        Col1.addWidget(self.CoolLEDBtn, 5, 0)

        Col2.addWidget(self.sld1)
        Col2.addWidget(self.sld2)
        Col2.addWidget(self.canvas1)

        # Col3.addWidget(self.cellTbl)
        # Col3.addWidget(self.cellNamesBox)
        Col3.addWidget(self.canvas2)

        self.setFocus()

        self.show()

        # BIND BUTTONS TO FUNCTIONS

        loadBtn.clicked.connect(self.selectWorm)
        saveBtn.clicked.connect(self.saveData)

        self.checkNames = True
        self.tp.valueChanged.connect(self.changeTp)
        self.sl.valueChanged.connect(self.updateCanvas1)
        self.sld1.valueChanged.connect(self.updateBC)
        self.sld2.valueChanged.connect(self.updateBC)

        self._488nmBtn.toggled.connect(self.radio488Clicked)
        self._561nmBtn.toggled.connect(self.radio561Clicked)
        self.CoolLEDBtn.toggled.connect(self.radioCoolLEDClicked)

        self.fig1.canvas.mpl_connect('scroll_event', self.wheelEvent)

    #-----------------------------------------------------------------------------------------------
    # FORMATTING THE WINDOW
    #-----------------------------------------------------------------------------------------------

    def HLine(self):

        toto = QtGui.QFrame()
        toto.setFrameShape(QtGui.QFrame.HLine)
        toto.setFrameShadow(QtGui.QFrame.Sunken)
        return toto

    #-----------------------------------------------------------------------------------------------
    # ACTION FUNCTIONS in THE POPUP MENU
    #-----------------------------------------------------------------------------------------------

    def changeName(self, item):
        idx = len(self.currentCells.cname) - 1
        self.currentCells.ix[idx, 'cname'] = str(item)
        self.currentCells = self.currentCells.reset_index(drop=True)

        self.updateCanvas1()
        self.setFocus()

    def actionFunct1p(self, item):
        self.changeName(item)

    def actionFunct1pp(self, item):
        self.changeName(item)

    def actionFunct1ppp(self, item):
        self.changeName(item)

    def actionFunct1ppa(self, item):
        self.changeName(item)

    def actionFunct4a(self, item):
        self.changeName(item)

    def actionFunct4aa(self, item):
        self.changeName(item)

    def actionFunct4aaa(self, item):
        self.changeName(item)

    def actionFunct4aap(self, item):
        self.changeName(item)

    def actionFunctb1(self, item):
        self.changeName(item)

    def actionFunctb4(self, item):
        self.changeName(item)

    def eventFilter(self, widget, event):
        # print( 'eventFilter', widget, event)
        if widget == self.canvas1 and isinstance(
                event,
                QtGui.QMouseEvent) and event.buttons() & QtCore.Qt.LeftButton:
            self.leftClicked(event.pos())
            return True
        if widget == self.canvas1 and isinstance(
                event,
                QtGui.QMouseEvent) and event.buttons() & QtCore.Qt.RightButton:
            self.rightClicked(event.pos())
            return True
        return False

    def leftClicked(self, QPos):
        refpos = np.array([
            int(QPos.x() / 600. * 512.),
            int(QPos.y() / 600. * 512.),
            self.sl.value()
        ])
        # print(refpos)

        # create an empty cell in the currentCells df: the only entries are tidx, xyzpos and cname
        newcell = create_single_cell_pos(refpos.astype(np.uint16),
                                         self.tp.value())
        self.currentCells = pd.concat([self.currentCells, newcell])

        self.currentCells = self.currentCells.reset_index(drop=True)

        self.updateCanvas1()

        parentPosition = self.canvas1.mapToGlobal(QtCore.QPoint(0, 0))
        # print('leftClicked', QPos, parentPosition)
        menuPosition = parentPosition + QPos

        self.cellNamesBox.move(menuPosition)
        self.cellNamesBox.show()
        self.setFocus()

    def rightClicked(self, QPos):
        refpos = np.array(
            [QPos.x() / 600. * 512.,
             QPos.y() / 600. * 512.,
             self.sl.value()])
        # print(refpos)

        if len(self.currentCells) == 0:
            self.setFocus()
            return

        # remove a cell (the closest to the cursor at the moment of right-click)
        idx = closer_cell(refpos.astype(np.uint16), self.currentCells)
        self.currentCells = self.currentCells.drop([idx])
        self.currentCells = self.currentCells.reset_index(drop=True)

        self.updateCanvas1()
        self.setFocus()

    #-----------------------------------------------------------------------------------------------
    # BUTTON FUNCTIONS
    #-----------------------------------------------------------------------------------------------

    def selectWorm(self):

        ### store the folders
        self.pathDial = QtGui.QFileDialog.getExistingDirectory(
            self, 'Select a folder',
            'X:/Simone/160129_MCHERRY_HLH2GFP_onHB101')  #'Y:\\Images')
        self.worm = self.pathDial.split("/")[-1].split('_')[0]
        self.path = os.path.dirname(self.pathDial)
        self.setWindowTitle('Label cells - ' + self.pathDial.split("/")[-2] +
                            ' - ' + self.pathDial.split("/")[-1][:3])

        ### give error message if there is no CoolLED movie in the selected folder
        flist = glob.glob(self.pathDial + '/*_movie.tif')
        if len(
                flist
        ) == 0:  #not os.path.isfile( os.path.join( self.pathDial, '*_movie.tif' ) ):
            QtGui.QMessageBox.about(
                self, 'Warning!',
                'There is no movie in this folder! Create a movie first!')
            return

        ### load parameters and times dataframes
        self.paramsDF = load_data_frame_pandas(self.path,
                                               self.worm + '_01params.pickle')
        self.timesDF = load_data_frame_pandas(self.path,
                                              self.worm + '_01times.pickle')
        self.gpDF = load_data_frame_pandas(self.path,
                                           self.worm + '_02gonadPos.pickle')

        # extract some info
        self.compression = self.paramsDF.compression
        self.hatchingtidx = int(self.paramsDF.tidxHatch)

        ### if the cellPos pickle file already exists, load it, otherwise create a blank one
        if os.path.isfile(
                os.path.join(self.path, self.worm + '_04cellPos.pickle')):
            self.cellPosDF = load_data_frame_pandas(
                self.path, self.worm + '_04cellPos.pickle')

        else:
            self.cellPosDF = create_cell_pos(self.timesDF, self.cellNames)

        # detect available channels
        self.channels = []
        chns = ['CoolLED', '488nm', '561nm']
        for c in chns:

            if os.path.isfile(os.path.join(self.pathDial, c + '_movie.tif')):

                self.channels.append(c)
        self.currentChannel = self.channels[0]

        ### detect size of the cropped images
        tp = np.min(self.gpDF.ix[pd.notnull(self.gpDF.X), 'tidx'])
        self.prevtp = tp - 1
        tRow = self.timesDF.ix[self.timesDF.tidxRel == tp].squeeze()
        fileName = os.path.join(self.pathDial,
                                tRow.fName + self.currentChannel + '.tif')
        firststack = load_stack(fileName)
        self.cropsize = firststack.shape[1]
        self.nslices = firststack.shape[0]

        ### load CoolLED movie
        if 'CoolLED' in self.channels:
            self.LEDmovie = load_stack(
                os.path.join(self.pathDial, 'CoolLED_movie.tif'))
        else:
            self.LEDmovie = load_stack(
                os.path.join(self.pathDial,
                             self.currentChannel + '_movie.tif'))
        self.initializeCanvas1()
        self.initializeCanvas2()

        ### extract current cells already labeled
        self.currentCells = extract_current_cell_pos(self.cellPosDF,
                                                     self.tp.value())

        ### update the text of the fileName
        self.fName.setText(self.timesDF.ix[self.timesDF.tidxRel == tp,
                                           'fName'].values[0])

        ### set the timepoint to the hatching time
        self.tp.setMinimum(np.min(self.timesDF.tidxRel))
        self.tp.setMaximum(np.max(self.timesDF.tidxRel))

        ### set the max slice number
        self.sl.setMaximum(self.nslices - 1)

        self.tp.setValue(tp)

        if self.currentChannel == 'CoolLED':
            self.CoolLEDBtn.setChecked(
                True)  # this uppdates the canvas1 once more
        elif self.currentChannel == '561nm':
            self._561nmBtn.setChecked(
                True)  # this uppdates the canvas1 once more
        elif self.currentChannel == '488nm':
            self._488nmBtn.setChecked(
                True)  # this uppdates the canvas1 once more

        # self.pathDial.show()
        self.setFocus()

    def loadNewStack(self):

        # print(self.fList['gfp'][self.tp.value()])
        tRow = self.timesDF.ix[self.timesDF.tidxRel ==
                               self.tp.value()].squeeze()

        ### update the text of the fileName
        self.fName.setText(
            self.timesDF.ix[self.timesDF.tidxRel == self.tp.value(),
                            'fName'].values[0])

        print('Loading... ', self.pathDial, tRow.fName)

        # calculate the max value of the previous stack
        try:
            prevmax = np.max([np.max(self.stacks[ch]) for ch in self.channels])
        # if it's the first time a stack is to be loaded (so if there is no previous stack), set it to zero
        except:
            prevmax = 0

        # load all the available stacks - this is the slowest part of the code!!!
        self.stacks = {}
        for ch in self.channels:
            fileName = os.path.join(self.pathDial, tRow.fName + ch + '.tif')
            if os.path.isfile(fileName):
                # print(MultiImage('X:\\Simone\\160129_MCHERRY_HLH2GFP_onHB101\\C02_analyzedImages\\Z003_488nm.tif'))
                # print(fileName, MultiImage( fileName ))
                # self.stacks[ch] = MultiImage( fileName )
                self.stacks[ch] = load_stack(fileName)
            # if there are no files for the timepoint, create a blank image
            else:
                self.stacks[ch] = prevmax * np.ones(
                    (self.nslices, self.cropsize, self.cropsize))

        # if the BC bound are different, the BCsliderMinMax will automatically update canvas1. Otherwise, manually update it!
        self.setBCslidersMinMax()

        self.updateCanvas1()
        self.updateCanvas2()

    def changeTp(self):

        # if it's the second time you are checking the same tp, don't do anything
        if self.checkNames:
            cellFine = self.checkConsistencyCellNames()
        else:
            return

        # before changing timepoint, print labeled cells and check if they are OK
        print('cells labeled:\n ', self.currentCells)

        ### extract current cells already labeled
        self.newCells = extract_current_cell_pos(self.cellPosDF,
                                                 self.tp.value())

        if cellFine:
            # if everything fine, load the new stack
            self.currentCells = self.newCells
            self.loadNewStack()
        else:
            # otherwise, go back to prev tp
            self.checkNames = False
            self.tp.setValue(self.prevtp)
            self.checkNames = True

        self.prevtp = self.tp.value()

    def saveData(self):

        if self.checkConsistencyCellNames():
            save_data_frame(self.cellPosDF, self.path,
                            self.worm + '_04cellPos.pickle')
        else:
            QtGui.QMessageBox.about(self, 'Warning!',
                                    'There is a mistake in the cell labels!')
        self.setFocus()

    def radio488Clicked(self, enabled):
        # print('radio 488 clicked')

        if enabled:
            if '488nm' in self.channels:
                self.currentChannel = '488nm'
                self.setFocus()
                self.updateCanvas1()
            else:
                if self.currentChannel == 'CoolLED':
                    self.CoolLEDBtn.setChecked(
                        True)  # this uppdates the canvas1 once more
                elif self.currentChannel == '561nm':
                    self._561nmBtn.setChecked(
                        True)  # this uppdates the canvas1 once more
                QtGui.QMessageBox.about(self, 'Warning', 'No 488nm channel!')

    def radio561Clicked(self, enabled):
        # print('radio 561 clicked')

        if enabled:
            if '561nm' in self.channels:
                self.currentChannel = '561nm'
                self.setFocus()
                self.updateCanvas1()
            else:
                if self.currentChannel == 'CoolLED':
                    self.CoolLEDBtn.setChecked(
                        True)  # this uppdates the canvas1 once more
                elif self.currentChannel == '488nm':
                    self._488nmBtn.setChecked(
                        True)  # this uppdates the canvas1 once more
                QtGui.QMessageBox.about(self, 'Warning', 'No 561nm channel!')

    def radioCoolLEDClicked(self, enabled):
        # print('radio LED clicked')

        if enabled:
            if 'CoolLED' in self.channels:
                self.currentChannel = 'CoolLED'
                self.setFocus()
                self.updateCanvas1()
            else:
                if self.currentChannel == '561nm':
                    self._561nmBtn.setChecked(
                        True)  # this uppdates the canvas1 once more
                elif self.currentChannel == '488nm':
                    self._488nmBtn.setChecked(
                        True)  # this uppdates the canvas1 once more
                QtGui.QMessageBox.about(self, 'Warning', 'No CoolLED channel!')

    def updateBC(self):
        # change brightness and contrast
        self.imgplot1.set_clim(self.sld1.value(), self.sld2.value())
        self.canvas1.draw()

    #-----------------------------------------------------------------------------------------------
    # DEFAULT FUNCTION FOR KEY AND MOUSE PRESS ON WINDOW
    #-----------------------------------------------------------------------------------------------

    def keyPressEvent(self, event):

        # print(event.key())

        # change timepoint
        if event.key() == QtCore.Qt.Key_Right:
            self.changeSpaceTime('time', +1)

        elif event.key() == QtCore.Qt.Key_Left:
            self.changeSpaceTime('time', -1)

        # change slice
        elif event.key() == QtCore.Qt.Key_Up:
            self.changeSpaceTime('space', +1)

        elif event.key() == QtCore.Qt.Key_Down:
            self.changeSpaceTime('space', -1)

        elif event.key() == QtCore.Qt.Key_PageDown:
            idx = self.channels.index(self.currentChannel)
            if self.channels[(idx + 1) % len(self.channels)] == 'CoolLED':
                self.CoolLEDBtn.setChecked(True)
            if self.channels[(idx + 1) % len(self.channels)] == '488nm':
                self._488nmBtn.setChecked(True)
            if self.channels[(idx + 1) % len(self.channels)] == '561nm':
                self._561nmBtn.setChecked(True)
        elif event.key() == QtCore.Qt.Key_PageUp:
            idx = self.channels.index(self.currentChannel)
            if self.channels[(idx - 1) % len(self.channels)] == 'CoolLED':
                self.CoolLEDBtn.setChecked(True)
            if self.channels[(idx - 1) % len(self.channels)] == '488nm':
                self._488nmBtn.setChecked(True)
            if self.channels[(idx - 1) % len(self.channels)] == '561nm':
                self._561nmBtn.setChecked(True)

        # key press on cropped image
        if self.canvas1.underMouse():
            self.onKeyPressOnCanvas1(event)

        self.setFocus()

    def wheelEvent(self, event):
        if self.canvas1.underMouse():
            step = event.step
        else:
            step = event.delta() / abs(event.delta())
        self.sl.setValue(self.sl.value() + step)

    #-----------------------------------------------------------------------------------------------
    # ADDITIONAL FUNCTIONS FOR KEY AND MOUSE PRESS ON CANVASES
    #-----------------------------------------------------------------------------------------------

    def onKeyPressOnCanvas1(self, event):

        motherCells = [QtCore.Qt.Key_1, QtCore.Qt.Key_4, QtCore.Qt.Key_B]
        daughterCells = [QtCore.Qt.Key_A, QtCore.Qt.Key_P]

        # find the position of the cursor relative to the image in pixel
        imgshape = self.stacks[self.currentChannel][self.sl.value()].shape
        canshape = self.canvas1.size()
        cf = imgshape[0] / canshape.width()
        refpos = self.canvas1.mapFromGlobal(QtGui.QCursor.pos())
        refpos = np.array([int(refpos.x() * cf), int(refpos.y() * cf)])
        refpos = np.append(refpos, self.sl.value())

        ### find the closest cell to the cursor
        idx = closer_cell(refpos.astype(np.uint16), self.currentCells)

        ### assign the name to the cell
        if any([event.key() == cn for cn in motherCells]):
            # if labeling bckg, add the 1 or 2 to the name
            if self.currentCells.ix[idx, 'cname'] == 'b_':
                self.currentCells.ix[idx, 'cname'] += QtGui.QKeySequence(
                    event.key()).toString().lower()
            else:
                # if not, rename the cell from scratch
                if event.key() == QtCore.Qt.Key_B:
                    self.currentCells.ix[idx, 'cname'] = QtGui.QKeySequence(
                        event.key()).toString().lower() + '_'
                else:
                    self.currentCells.ix[idx, 'cname'] = QtGui.QKeySequence(
                        event.key()).toString().lower() + '.'

        # add the anterior/posterior to the cell name
        elif any([event.key() == cp for cp in daughterCells]):
            # don't do it if labeling background (bckg doesn't have a/p!)
            if self.currentCells.ix[idx, 'cname'] == 'b_':
                return
            else:
                self.currentCells.ix[idx, 'cname'] += QtGui.QKeySequence(
                    event.key()).toString().lower()

        # remove the last entry of the name with backspace
        elif event.key() == QtCore.Qt.Key_Backspace:
            self.currentCells.ix[idx,
                                 'cname'] = self.currentCells.ix[idx,
                                                                 'cname'][:-1]

        if (event.key() != QtCore.Qt.Key_Left) and (
                event.key() != QtCore.Qt.Key_Right) and (
                    event.key() != QtCore.Qt.Key_Up) and (event.key() !=
                                                          QtCore.Qt.Key_Down):
            self.updateCanvas1()
        self.setFocus()

    #-----------------------------------------------------------------------------------------------
    # UTILS
    #-----------------------------------------------------------------------------------------------

    def setBCslidersMinMax(self):
        self.sld1.setMaximum(
            np.max([np.max(self.stacks[ch]) for ch in self.channels]))
        self.sld1.setMinimum(0)
        self.sld2.setMaximum(
            np.max([np.max(self.stacks[ch]) for ch in self.channels]))
        self.sld2.setMinimum(0)

    def initializeCanvas1(self):
        # print('initializing canvas1')

        self.fig1.clf()
        self.fig1.subplots_adjust(left=0., right=1., top=1., bottom=0.)
        self.ax1 = self.fig1.add_subplot(111)
        self.canvas1.draw()

        # plot the first blank image with the right size
        self.ax1.cla()
        self.imgplot1 = self.ax1.imshow(np.zeros(
            (self.cropsize, self.cropsize)),
                                        cmap='gray')

        # remove the white borders
        self.ax1.autoscale(False)
        self.ax1.axis('Off')
        self.fig1.subplots_adjust(left=0., right=1., top=1., bottom=0.)

        # plot cell pos and name
        self.text1 = []
        self.points1 = []

        # redraw the canvas
        self.canvas1.draw()
        self.setFocus()

    def updateCanvas1(self):
        # print('updating canvas1')

        # plot the image
        self.imgplot1.set_data(
            self.stacks[self.currentChannel][self.sl.value()])

        # change brightness and contrast
        self.imgplot1.set_clim(self.sld1.value(), self.sld2.value())

        # clear cell text and points
        # print(self.text1,self.points1)
        for text in self.text1:
            text.remove()
        self.text1 = []

        for points in self.points1:
            self.ax1.lines.remove(points)
        self.points1 = []

        # draw cell text and point
        for idx, cell in self.currentCells.iterrows():

            if cell.Z == self.sl.value():

                self.text1.append(
                    self.ax1.text(cell.X,
                                  cell.Y + 18,
                                  cell.cname,
                                  color='orange',
                                  fontsize=10,
                                  alpha=.7,
                                  rotation=0))
                self.points1.append(
                    self.ax1.plot(cell.X,
                                  cell.Y,
                                  'o',
                                  color='orange',
                                  alpha=.7,
                                  mew=0,
                                  ms=6)[0])

        # redraw the canvas
        self.canvas1.draw()
        self.setFocus()

    def initializeCanvas2(self):
        # print('initializing canvas2')

        # plot the image
        self.ax2.cla()
        self.imgplot2 = self.ax2.imshow(np.zeros((512, 512)), cmap='gray')
        self.imgplot2.set_clim(np.min(self.LEDmovie), np.max(self.LEDmovie))

        # remove the white borders and plot outline and spline
        self.ax2.autoscale(False)
        self.ax2.axis('Off')
        self.fig2.subplots_adjust(left=0., right=1., top=1., bottom=0.)

        # print gonad position
        gonadPos = [np.nan, np.nan]
        self.points2, = self.ax2.plot(gonadPos[0],
                                      gonadPos[1],
                                      'o',
                                      color='blue',
                                      ms=10,
                                      mew=0,
                                      alpha=.5,
                                      lw=0)

        # print time
        self.text2 = self.ax2.text(5, 25, '--.--', color='white')

        # redraw the canvas
        self.canvas2.draw()
        self.setFocus()

    def updateCanvas2(self):
        # print('updating canvas2')
        # plot the image
        self.imgplot2.set_data(self.LEDmovie[self.tp.value() +
                                             self.hatchingtidx])

        # print gonad position
        gonadPos = extract_pos(self.gpDF.ix[
            self.gpDF.tidx == self.tp.value()].squeeze()) / self.compression
        if len(gonadPos.shape) > 0:
            self.points2.set_xdata(gonadPos[0])
            self.points2.set_ydata(gonadPos[1])
            plt.draw()

        # print time
        # print time
        ### find ecdysis timepoint
        ecd = np.loadtxt(open(os.path.join(self.path, 'skin.txt'), 'rb'))
        # load ecdysis data
        index = np.where(ecd[:, 0] == float(self.worm[1:]))
        mintp = np.min([i for i in ecd[index, 1:6][0][0] if i >= 0])
        lethtidx = ecd[index, 1:6][0][0]
        lethtidx = lethtidx[lethtidx >= 0]
        tpL2 = self.timesDF.ix[self.timesDF.tidxRel == (lethtidx[1] - mintp),
                               'timesRel'].values[0]
        # print(self.timesDF.ix[ self.timesDF.tidxRel == self.tp.value(), 'timesRel' ])
        self.text2.set_text(
            '%.2f' % (self.timesDF.ix[self.timesDF.tidxRel == self.tp.value(),
                                      'timesRel'].values[0] - tpL2))

        # redraw the canvas
        self.canvas2.draw()
        self.setFocus()

    def checkConsistencyCellNames(self):
        ### check consistency of cell names
        tp = self.prevtp

        # if no cells are labeled (currentCells df is empty), remove all labeled cells in the cellPosDF and return
        if len(self.currentCells) == 0:
            newCellPosDF = update_cell_pos_DF(self.currentCells,
                                              self.cellPosDF, tp)
            correctCellNames = True

        if len(self.currentCells) > 0:

            correctCellNames = check_cell_names(self.currentCells,
                                                self.cellNames)

            # if cells are not properly labeled, give a Warning
            if not correctCellNames:
                QtGui.QMessageBox.about(
                    self, 'Warning!', 'There is a mistake in the cell labels!')

            # else, update final cellPosDF and return OK
            else:
                newCellPosDF = update_cell_pos_DF(self.currentCells,
                                                  self.cellPosDF, tp)
                self.cellPosDF = newCellPosDF

        return correctCellNames

    def changeSpaceTime(self, whatToChange, increment):

        if whatToChange == 'time':
            # if they are OK (and not going to negative times), change timepoint
            self.tp.setValue(self.tp.value() + increment)

        if whatToChange == 'space':
            self.sl.setValue(self.sl.value() + increment)
예제 #17
0
class GUI(QtGui.QWidget):
    def __init__(self):

        super(GUI, self).__init__()

        self.setWindowTitle('Label Cells')
        self.cellNames = [
            '1.p', '4.a', '1.pp', '4.aa', '1.ppa', '1.ppp', '4.aaa', '4.aap',
            'b_1', 'b_4'
        ]
        self.initUI()

    #-----------------------------------------------------------------------------------------------
    # INITIALIZATION OF THE WINDOW - DEFINE AND PLACE ALL THE WIDGETS
    #-----------------------------------------------------------------------------------------------

    def initUI(self):

        # SET THE GEOMETRY

        mainWindow = QtGui.QVBoxLayout()
        mainWindow.setSpacing(15)

        fileBox = QtGui.QHBoxLayout()
        spaceBox1 = QtGui.QHBoxLayout()
        rawDataBox = QtGui.QHBoxLayout()

        mainWindow.addLayout(fileBox)
        mainWindow.addLayout(spaceBox1)
        mainWindow.addLayout(rawDataBox)

        Col1 = QtGui.QGridLayout()
        Col2 = QtGui.QHBoxLayout()
        Col3 = QtGui.QVBoxLayout()

        rawDataBox.addLayout(Col1)
        rawDataBox.addLayout(Col2)
        rawDataBox.addLayout(Col3)

        self.setLayout(mainWindow)

        # DEFINE ALL WIDGETS AND BUTTONS

        loadBtn = QtGui.QPushButton('Load DataSet')
        saveBtn = QtGui.QPushButton('Save data (F12)')

        tpLbl = QtGui.QLabel('Relative Tp:')
        slLbl = QtGui.QLabel('Slice:')
        fNameLbl = QtGui.QLabel('File name:')

        self.tp = QtGui.QSpinBox(self)
        self.tp.setValue(0)
        self.tp.setMaximum(100000)

        self.sl = QtGui.QSpinBox(self)
        self.sl.setValue(0)
        self.sl.setMaximum(100000)

        self.fName = QtGui.QLabel('')

        self._488nmBtn = QtGui.QRadioButton('488nm')
        self._561nmBtn = QtGui.QRadioButton('561nm')
        self.CoolLEDBtn = QtGui.QRadioButton('CoolLED')

        self.sld1 = QtGui.QSlider(QtCore.Qt.Vertical, self)
        self.sld1.setMaximum(2**16 - 1)
        self.sld1.setValue(0)
        self.sld2 = QtGui.QSlider(QtCore.Qt.Vertical, self)
        self.sld2.setMaximum(2**16)
        self.sld2.setValue(2**16 - 1)

        self.fig1 = Figure((8.0, 8.0), dpi=100)
        self.fig1.subplots_adjust(left=0., right=1., top=1., bottom=0.)
        self.ax1 = self.fig1.add_subplot(111)
        self.canvas1 = FigureCanvas(self.fig1)
        self.canvas1.setFocusPolicy(QtCore.Qt.ClickFocus)
        self.canvas1.setFocus()
        self.canvas1.setFixedSize(QtCore.QSize(600, 600))
        self.canvas1.setSizePolicy(QtGui.QSizePolicy.Expanding,
                                   QtGui.QSizePolicy.Expanding)

        self.cellTbl = QtGui.QTableWidget()

        self.fig2 = Figure((4.0, 4.0), dpi=100)
        self.fig2.subplots_adjust(left=0., right=1., top=1., bottom=0.)
        self.ax2 = self.fig2.add_subplot(111)
        self.canvas2 = FigureCanvas(self.fig2)
        self.canvas2.setFixedSize(QtCore.QSize(300, 300))
        self.canvas2.setSizePolicy(QtGui.QSizePolicy.Expanding,
                                   QtGui.QSizePolicy.Expanding)

        # PLACE ALL THE WIDGET ACCORDING TO THE GRIDS

        fileBox.addWidget(loadBtn)
        fileBox.addWidget(saveBtn)

        spaceBox1.addWidget(self.HLine())

        Col1.addWidget(tpLbl, 0, 0)  #, 1, 1, Qt.AlignTop)
        Col1.addWidget(self.tp, 0, 1)  #, 1, 1, Qt.AlignTop)
        Col1.addWidget(slLbl, 1, 0)  #, 1, 1, Qt.AlignTop)
        Col1.addWidget(self.sl, 1, 1)  #, 1, 1, Qt.AlignTop)
        Col1.addWidget(fNameLbl, 2, 0)
        Col1.addWidget(self.fName, 2, 1)
        Col1.addWidget(self._488nmBtn, 3, 0)
        Col1.addWidget(self._561nmBtn, 4, 0)
        Col1.addWidget(self.CoolLEDBtn, 5, 0)

        Col2.addWidget(self.sld1)
        Col2.addWidget(self.sld2)
        Col2.addWidget(self.canvas1)

        Col3.addWidget(self.cellTbl)
        Col3.addWidget(self.canvas2)

        self.setFocus()
        self.show()

        # BIND BUTTONS TO FUNCTIONS

        loadBtn.clicked.connect(self.selectWorm)
        saveBtn.clicked.connect(self.saveData)

        self.tp.valueChanged.connect(self.loadNewStack)
        self.sl.valueChanged.connect(self.updateAllCanvas)
        self.sld1.valueChanged.connect(self.updateAllCanvas)
        self.sld2.valueChanged.connect(self.updateAllCanvas)

        self._488nmBtn.toggled.connect(self.radioClicked)
        self._561nmBtn.toggled.connect(self.radioClicked)
        self.CoolLEDBtn.toggled.connect(self.radioClicked)

        self.fig1.canvas.mpl_connect('button_press_event',
                                     self.onMouseClickOnCanvas1)
        self.fig1.canvas.mpl_connect('scroll_event', self.wheelEvent)

    #-----------------------------------------------------------------------------------------------
    # FORMATTING THE WINDOW
    #-----------------------------------------------------------------------------------------------

    def center(self):

        qr = self.frameGeometry()
        cp = QtGui.QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def HLine(self):

        toto = QtGui.QFrame()
        toto.setFrameShape(QtGui.QFrame.HLine)
        toto.setFrameShadow(QtGui.QFrame.Sunken)
        return toto

    def VLine(self):

        toto = QtGui.QFrame()
        toto.setFrameShape(QtGui.QFrame.VLine)
        toto.setFrameShadow(QtGui.QFrame.Sunken)
        return toto

    def heightForWidth(self, width):

        return width

    #-----------------------------------------------------------------------------------------------
    # BUTTON FUNCTIONS
    #-----------------------------------------------------------------------------------------------

    def selectWorm(self):

        ### store the folders
        self.pathDial = QtGui.QFileDialog.getExistingDirectory(
            self, 'Select a folder', 'Y:\\Images')
        self.worm = self.pathDial.split("\\")[-1].split('_')[0]
        self.path = os.path.dirname(self.pathDial)
        self.setWindowTitle('Mark Cells - ' + self.pathDial)

        ### give error message if there is no CoolLED movie in the selected folder
        if not os.path.isfile(os.path.join(self.pathDial,
                                           'CoolLED_movie.tif')):
            QtGui.QMessageBox.about(
                self, 'Warning!',
                'There is no movie in this folder! Create a movie first!')
            return

        ### load parameters and times dataframes
        self.paramsDF = load_data_frame(self.path,
                                        self.worm + '_01params.pickle')
        self.timesDF = load_data_frame(self.path,
                                       self.worm + '_01times.pickle')
        self.gpDF = load_data_frame(self.path,
                                    self.worm + '_02gonadPos.pickle')

        # extract some info
        self.compression = self.paramsDF.compression
        self.hatchingtidx = int(self.paramsDF.tidxHatch)

        ### if the cellPos pickle file already exists, load it, otherwise create a blank one
        if os.path.isfile(
                os.path.join(self.path, self.worm + '_04cellPos.pickle')):
            self.cellPosDF = load_data_frame(self.path,
                                             self.worm + '_04cellPos.pickle')

        else:
            self.cellPosDF = create_cell_pos(self.timesDF, self.cellNames)

        ### load all movies (without timestamps, we will add it later on)
        self.LEDmovie = load_stack(
            os.path.join(self.pathDial, 'CoolLED_movie.tif'))

        ### set the timepoint to the hatching time
        self.tp.setMinimum(np.min(self.timesDF.tidxRel))
        self.tp.setMaximum(np.max(self.timesDF.tidxRel))
        self.tp.setValue(0)

        ### extract current cells already labeled
        self.currentCells = extract_current_cell_pos(self.cellPosDF,
                                                     self.tp.value())

        # detect available channels
        self.channels = []
        chns = ['CoolLED', '488nm', '561nm']
        for c in chns:

            if os.path.isfile(os.path.join(self.pathDial, c + '_movie.tif')):

                self.channels.append(c)
        self.currentChannel = self.channels[0]

        ### update the text of the fileName
        self.fName.setText(
            self.timesDF.ix[self.timesDF.tidxRel == self.tp.value(),
                            'fName'].values[0])

        self.loadNewStack()

        # self.pathDial.show()
        self.updateAllCanvas()
        self.setFocus()

    def loadNewStack(self):

        # print(self.fList['gfp'][self.tp.value()])
        tRow = self.timesDF.ix[self.timesDF.tidxRel ==
                               self.tp.value()].squeeze()

        print('Loading... ', self.pathDial, tRow.fName)

        # load all the available stacks
        self.stacks = {}
        for ch in self.channels:
            fileName = os.path.join(self.pathDial, tRow.fName + ch + '.tif')
            if os.path.isfile(fileName):
                self.stacks[ch] = load_stack(fileName)

        if len(self.stacks.keys()) > 0:
            # print(self.stacks.keys(), self.stacksStraight)
            self.sl.setMaximum(self.stacks[self.currentChannel].shape[0] - 1)

            self.setBCslidersMinMax()

        ### update the text of the fileName
        self.fName.setText(
            self.timesDF.ix[self.timesDF.tidxRel == self.tp.value(),
                            'fName'].values[0])

        ### extract current cells already labeled
        self.currentCells = extract_current_cell_pos(self.cellPosDF,
                                                     self.tp.value())

        # self.updateTable()
        self.updateAllCanvas()

    def saveData(self):

        if self.checkConsistencyCellNames():
            save_data_frame(self.cellPosDF, self.path,
                            self.worm + '_04cellPos.pickle')
        else:
            QtGui.QMessageBox.about(self, 'Warning!',
                                    'There is a mistake in the cell labels!')
        self.setFocus()

    def updateAllCanvas(self):
        self.updateRadioBtn()
        self.updateCanvas1()
        self.updateCanvas2()

    def radioClicked(self):
        if self._488nmBtn.isChecked():
            if '488nm' in self.channels:
                self.currentChannel = '488nm'
            else:
                QtGui.QMessageBox.about(self, 'Warning', 'No 488nm channel!')
        elif self._561nmBtn.isChecked():
            if '561nm' in self.channels:
                self.currentChannel = '561nm'
            else:
                QtGui.QMessageBox.about(self, 'Warning', 'No 561nm channel!')
        elif self.CoolLEDBtn.isChecked():
            if 'CoolLED' in self.channels:
                self.currentChannel = 'CoolLED'
            else:
                QtGui.QMessageBox.about(self, 'Warning', 'No CoolLED channel!')
        self.setBCslidersMinMax()
        self.resetBC()
        self.setFocus()
        self.updateAllCanvas()

    #-----------------------------------------------------------------------------------------------
    # DEFAULT FUNCTION FOR KEY AND MOUSE PRESS ON WINDOW
    #-----------------------------------------------------------------------------------------------

    def keyPressEvent(self, event):

        # print(event.key())

        # change timepoint
        if event.key() == QtCore.Qt.Key_Right:
            self.changeSpaceTime('time', +1)

        elif event.key() == QtCore.Qt.Key_Left:
            self.changeSpaceTime('time', -1)

        # change slice
        elif event.key() == QtCore.Qt.Key_Up:
            self.changeSpaceTime('space', +1)

        elif event.key() == QtCore.Qt.Key_Down:
            self.changeSpaceTime('space', -1)

        # key press on cropped image
        if self.canvas1.underMouse():
            self.onKeyPressOnCanvas1(event)

        self.setFocus()

    def wheelEvent(self, event):
        if self.canvas1.underMouse():
            step = event.step
        else:
            step = event.delta() / abs(event.delta())
        self.sl.setValue(self.sl.value() + step)

    #-----------------------------------------------------------------------------------------------
    # ADDITIONAL FUNCTIONS FOR KEY AND MOUSE PRESS ON CANVASES
    #-----------------------------------------------------------------------------------------------

    def onKeyPressOnCanvas1(self, event):

        motherCells = [QtCore.Qt.Key_1, QtCore.Qt.Key_4, QtCore.Qt.Key_B]
        daughterCells = [QtCore.Qt.Key_A, QtCore.Qt.Key_P]

        # find the position of the cursor relative to the image in pixel
        imgshape = self.stacks[self.currentChannel][self.sl.value()].shape
        canshape = self.canvas1.size()
        cf = imgshape[0] / canshape.width()
        refpos = self.canvas1.mapFromGlobal(QtGui.QCursor.pos())
        refpos = np.array([int(refpos.x() * cf), int(refpos.y() * cf)])
        refpos = np.append(refpos, self.sl.value())

        ### find the closest cell to the cursor
        idx = closer_cell(refpos.astype(np.uint16), self.currentCells)

        ### assign the name to the cell
        if any([event.key() == cn for cn in motherCells]):
            # if labeling bckg, add the 1 or 2 to the name
            if self.currentCells.ix[idx, 'cname'] == 'b_':
                self.currentCells.ix[idx, 'cname'] += QtGui.QKeySequence(
                    event.key()).toString().lower()
            else:
                # if not, rename the cell from scratch
                if event.key() == QtCore.Qt.Key_B:
                    self.currentCells.ix[idx, 'cname'] = QtGui.QKeySequence(
                        event.key()).toString().lower() + '_'
                else:
                    self.currentCells.ix[idx, 'cname'] = QtGui.QKeySequence(
                        event.key()).toString().lower() + '.'

        # add the anterior/posterior to the cell name
        elif any([event.key() == cp for cp in daughterCells]):
            # don't do it if labeling background (bckg doesn't have a/p!)
            if self.currentCells.ix[idx, 'cname'] == 'b_':
                return
            else:
                self.currentCells.ix[idx, 'cname'] += QtGui.QKeySequence(
                    event.key()).toString().lower()

        # remove the last entry of the name with backspace
        elif event.key() == QtCore.Qt.Key_Backspace:
            self.currentCells.ix[idx,
                                 'cname'] = self.currentCells.ix[idx,
                                                                 'cname'][:-1]

        self.updateCanvas1()
        self.setFocus()

    def onMouseClickOnCanvas1(self, event):

        refpos = np.array([event.xdata, event.ydata, self.sl.value()])

        if event.button == 1:

            # create an empty cell in the currentCells df: the only entries are tidx, xyzpos and cname
            newcell = create_single_cell_pos(refpos.astype(np.uint16),
                                             self.tp.value())
            self.currentCells = pd.concat([self.currentCells, newcell])

        elif event.button == 3:

            # remove a cell (the closest to the cursor at the moment of right-click)
            idx = closer_cell(refpos.astype(np.uint16), self.currentCells)
            self.currentCells = self.currentCells.drop([idx])

        self.currentCells = self.currentCells.reset_index(drop=True)

        self.updateCanvas1()
        self.setFocus()

    #-----------------------------------------------------------------------------------------------
    # UTILS
    #-----------------------------------------------------------------------------------------------

    def updateRadioBtn(self):
        if self.currentChannel == '488nm':
            self._488nmBtn.setChecked(True)
        elif self.currentChannel == '561nm':
            self._561nmBtn.setChecked(True)
        elif self.currentChannel == 'CoolLED':
            self.CoolLEDBtn.setChecked(True)
        self.setFocus()

    def setBCslidersMinMax(self):
        self.sld1.setMaximum(np.max(self.stacks[self.currentChannel]))
        self.sld1.setMinimum(np.min(self.stacks[self.currentChannel]))
        self.sld2.setMaximum(np.max(self.stacks[self.currentChannel]))
        self.sld2.setMinimum(np.min(self.stacks[self.currentChannel]))

    def resetBC(self):
        self.sld1.setValue(np.min(self.stacks[self.currentChannel]))
        self.sld2.setValue(np.max(self.stacks[self.currentChannel]))

    def updateCanvas1(self):

        self.fig1.clf()
        self.fig1.subplots_adjust(left=0., right=1., top=1., bottom=0.)
        self.ax1 = self.fig1.add_subplot(111)
        self.canvas1.draw()

        if len(self.stacks.keys()) == 0:
            # if no images are found, leave the canvas empty
            return

        # plot the image
        self.ax1.cla()
        imgplot = self.ax1.imshow(
            self.stacks[self.currentChannel][self.sl.value()], cmap='gray')

        # remove the white borders and plot outline and spline
        self.ax1.autoscale(False)
        self.ax1.axis('Off')
        self.fig1.subplots_adjust(left=0., right=1., top=1., bottom=0.)

        # cell text on the image
        for idx, cell in self.currentCells.iterrows():

            if cell.Z == self.sl.value():

                self.ax1.text(cell.X,
                              cell.Y + 18,
                              cell.cname,
                              color='red',
                              size='medium',
                              alpha=.8,
                              rotation=0)
                self.ax1.plot(cell.X,
                              cell.Y,
                              'o',
                              color='red',
                              alpha=.8,
                              mew=0)

        # change brightness and contrast
        self.sld1.setValue(np.min([self.sld1.value(), self.sld2.value()]))
        self.sld2.setValue(np.max([self.sld1.value(), self.sld2.value()]))
        imgplot.set_clim(self.sld1.value(), self.sld2.value())

        # redraw the canvas
        self.canvas1.draw()
        self.setFocus()

    def updateCanvas2(self):

        # plot the image
        self.ax2.cla()
        imgplot = self.ax2.imshow(self.LEDmovie[self.tp.value() +
                                                self.hatchingtidx],
                                  cmap='gray')

        # remove the white borders and plot outline and spline
        self.ax2.autoscale(False)
        self.ax2.axis('Off')
        self.fig2.subplots_adjust(left=0., right=1., top=1., bottom=0.)

        # print gonad position
        gonadPos = extract_pos(self.gpDF.ix[
            self.gpDF.tidx == self.tp.value()].squeeze()) / self.compression
        self.ax2.plot(gonadPos[0],
                      gonadPos[1],
                      'o',
                      color='red',
                      ms=10,
                      mew=0,
                      alpha=.5,
                      lw=0)

        # print time
        # print(self.timesDF.ix[ self.timesDF.tidxRel == self.tp.value(), 'timesRel' ])
        self.ax2.text(5,
                      25,
                      '%.2f' %
                      self.timesDF.ix[self.timesDF.tidxRel == self.tp.value(),
                                      'timesRel'].values[0],
                      color='red')

        # redraw the canvas
        self.canvas2.draw()
        self.setFocus()

    def checkConsistencyCellNames(self):
        ### check consistency of cell names
        tp = self.tp.value()

        # if no cells are labeled (currentCells df is empty), remove all labeled cells in the cellPosDF and return
        if len(self.currentCells) == 0:
            newCellPosDF = update_cell_pos_DF(self.currentCells,
                                              self.cellPosDF, tp)
            correctCellNames = True

        if len(self.currentCells) > 0:

            correctCellNames = check_cell_names(self.currentCells,
                                                self.cellNames)

            # if cells are not properly labeled, give a Warning
            if not correctCellNames:
                QtGui.QMessageBox.about(
                    self, 'Warning!', 'There is a mistake in the cell labels!')

            # else, update final cellPosDF and return OK
            else:
                newCellPosDF = update_cell_pos_DF(self.currentCells,
                                                  self.cellPosDF, tp)
                self.cellPosDF = newCellPosDF

        return correctCellNames

    def changeSpaceTime(self, whatToChange, increment):

        if whatToChange == 'time':

            # before changinf timepoint, print labeled cells and check if they are OK
            print(self.currentCells)

            # if they are OK (and not going to negative times), change timepoint
            if self.checkConsistencyCellNames() and (self.tp.value() +
                                                     increment) >= 0:
                self.tp.setValue(self.tp.value() + increment)

        if whatToChange == 'space':
            self.sl.setValue(self.sl.value() + increment)
예제 #18
0
class main(QMainWindow):

    #Definimos variables globales
    lista = []
    lstlst = []
    a = []
    number_axe_1 = 0
    number_axe_2 = 0
    cwd = os.getcwd()
    dirs = os.listdir(cwd)

    #Creamos el constructor de la clase
    def __init__(self):
        QMainWindow.__init__(self)

        #Cargamos el archivo que contiene la interfáz gráfica
        uic.loadUi("main.ui", self)

        #Configuramos tamaño mínimo y máximo
        self.setMinimumSize(863, 640)
        self.setMaximumSize(863, 640)

        #Configuramos la fuente
        qfont = QFont("Arial", 12)
        self.setFont(qfont)

        #Centramos la ventana en la pantalla
        qr = self.frameGeometry()
        cp = QtGui.QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

        #Definimos el área de dibujo
        grid = QtGui.QGridLayout()
        self.frame_figure.setLayout(grid)
        self.figure = matplotlib.figure.Figure()
        self.canvas = FigureCanvas(self.figure)
        grid.addWidget(self.canvas)

        #Desactivamos los botones btn_select_file, btn_plot_data, btn_save_figure
        self.btn_select_file.setEnabled(False)
        self.btn_plot_data.setEnabled(False)
        self.btn_save_figure.setEnabled(False)

        #Asociamos los eventos (Funciones) a los botones del sistema
        self.btn_show_files.clicked.connect(self.show_files)
        self.btn_select_file.clicked.connect(self.select_file)
        self.btn_plot_data.clicked.connect(self.show_plot)
        self.btn_save_figure.clicked.connect(self.save_figure)
        self.btn_restart.clicked.connect(self.restart)

    #Función show_files
    def show_files(self):
        """
        La función show_files hace un análisis de los archivos que se encuentren en el directorio actual,
        haciendo un filtro con la extención de cada archivo y guardando en lista[] los archivos cuya
        extención sea .txt o .csv, posteriormente muestra en un área de texto dicha lista.
        """
        #Declaramos variables locales
        n = 0

        #Deshabilitamos el botón btn_show_files y habilitamos el botón btn_select_file
        self.btn_show_files.setEnabled(False)
        self.btn_select_file.setEnabled(True)

        #Creamos el ciclo que se encarga de analizar la extensión de los archivos y almacenarlos en la lista
        for i in self.dirs:
            if ".csv" in i or ".txt" in i:
                self.lista.append(i)

        #Creamos una condición preventiva que se ejecutará en caso de que el directorio no contenga archivos válidos
        if (len(self.lista) == 0):

            #Mostramos un mensaje de alerta indicando de que no hay archivos válidos
            QMessageBox.warning(
                self, "File Error",
                "Ha ocurrido un error, No hay archivos disponibles!!!")

            # Deshabilitamos el botón btn_select_files y habilitamos el botón btn_show_file
            self.btn_select_file.setEnabled(False)
            self.btn_show_files.setEnabled(True)

        #Creamos la condición para el caso de que si hayan archivos
        else:
            text = (
                "                                            ARCHIVOS DISPONIBLES\n"
                "----------------------------------------------------------------------------------------------------------\n"
            )
            #Mostramos los archivos disponibles en un área de texto
            for i in self.lista:
                n = n + 1
                text += (str(n) + "." + i + "\t\t")
                self.area_text.setText(text)

    #Función select_files
    def select_file(self):
        """
        La función select_files permite seleccionar de la lista de archivos disponibles un archivo,
        además se encarga de crear las estructuras de datos necesarias para almacenarlas en memoria local
        y de corregir posibles errores en los datos
        """
        #Definimos variables locales
        error = []
        indiceserror = []
        filaserror = []

        #Deshabilitamos el botón btn_select_file y habilitamos el botón btn_plot_data
        self.btn_select_file.setEnabled(False)
        self.btn_plot_data.setEnabled(True)

        #Solicitamos al usuario que ingrese el índice del archivo a ser cargado, la variable number_file almacena
        #dicho índice, mientras la variable ok almacena el estado de la solicitud
        number_file, ok = QInputDialog.getInt(
            self, "Select File", "Ingrese el número del archivo a procesar")

        #Verificamos que la variable ok contenga un dato exitoso, esto es, verdadero
        if ok:

            #Verificamos que el número ingresado por el usuario corresponda al índice de un archivo
            if number_file in range(1, len(self.lista) + 1):

                #Guardamos en la variable file el nombre del archivo
                file = self.lista[number_file - 1]

                #Abrimos el archivo
                openf = open(file)

                #Mostramos en el campo de texto file_loaded_text el nombre del archivo cargado
                self.file_loaded.setText("Se ha abierto el archivo " +
                                         openf.name)

                #Creamos la variable route que contiene la ruta absoluta del archivo
                route = self.cwd + "/" + openf.name

                #Mostramos en el campo de texto dir_file_loaded la ruta
                self.dir_file_loaded.setText(route)

                #Procesamos el archivo cargado eliminando comas y puntoycomas que se encuentren en los archivos
                for line in openf:

                    #Realizamos los procedimientos necesarios en caso de que el archivo sea txt
                    if ".txt" in file:
                        if "," in line:
                            temp_list = line.split(",")
                        if ";" in line:
                            temp_list = line.split(";")

                        #Agregamos los datos a la lista lstlst
                        self.lstlst.append(temp_list)

                    # Realizamos los procedimientos necesarios en caso de que el archivo sea csv
                    if ".csv" in file:
                        temp_list = line.split(";")

                        # Agregamos los datos a la lista lstlst
                        self.lstlst.append(temp_list)

                #Procesamos la lista lstlst eliminando posibles errores
                for i in self.lstlst:
                    for j in i:

                        #Intentamos convertir los datos de la lista en números reales
                        try:
                            j = float(j)

                        #Capturamos cualquier posible error en el proceso de conversión y obtenemos el índice del error
                        except ValueError:
                            error.append(j)
                            indiceserror.append(i.index(j))
                            filaserror.append(self.lstlst.index(i))

                #Eliminamos de lstlst los datos que contengan errores
                for i in range(0, len(error)):
                    self.lstlst[filaserror[i]].remove(error[i])
                    self.lstlst[filaserror[i]].insert(indiceserror[i], None)

            #Mostramos una alerta en caso de que el usuario ingrese un número que no corresponde aun índice
            else:
                QMessageBox.warning(
                    self, "Select File Error",
                    "Ha ocurrido un error, verifique los datos ingresados!!!")

                #Habilitamos el botón btn_select_file y deshabilitamos el botón btn_plot_data
                self.btn_select_file.setEnabled(True)
                self.btn_plot_data.setEnabled(False)

        #Procesamos un posible error en la entrada de datos, esto es, ok es falso
        else:
            QMessageBox.warning(
                self, "Select File Error",
                "Ha ocurrido un error, verifique los datos ingresados!!!")

            #Habilitamos el botón btn_select_file y deshabilitamos el botón btn_plot_data
            self.btn_select_file.setEnabled(True)
            self.btn_plot_data.setEnabled(False)

    #Función show_plot
    def show_plot(self):
        """
        La funcíón show_plot es la encargada de mostar la gráfica de los datos, para realizar dicha tarea, primero
        se muestran las columnas disponibles para la comparación (lo que llamarémos ejes), cada eje corresponde a una
        columna del archivo, además permite al usuario seleccionar dos de dichos ejes para realizar la comparación,
        separa los datos en listas y por último grafica dicha información,
        """
        #Definimos variables locales
        primereje = []
        segundoeje = []
        op = 0
        e = "eje "
        n = 0
        text_eje_x = "     "
        text_eje_y = "     "

        #Deshabilitamos el botón btn_plot_data y habilitamos el botón btn_save_figure
        self.btn_plot_data.setEnabled(False)
        self.btn_save_figure.setEnabled(True)

        #Contamos el número de ejes
        temp_list = self.lstlst[1]

        #Agregamos los ejes dispobibles a la lista a
        for i in range(1, len(temp_list) + 1):
            op += 1
            self.a.append(e + str(op))
        text = (
            "                                            EJES DISPONIBLES\n"
            "----------------------------------------------------------------------------------------------------------\n"
        )

        #Mostramos los ejes disponibles en un área de texto
        for i in self.a:
            n = n + 1
            text += (str(n) + ".  " + i + " \t\t ")
            self.area_text.setText(text)

        #Solicitamos al usuario que ingrese el primer eje a graficar (La solicitud se realiza mientras
        #los datos ingresados sean erroneos)
        while (True):

            #Solicitamos el primer eje a graficar, la variable global number_axe_1 contiene el número del eje,
            #la variable ok contiene información sobre el éxito de la solicitud
            self.number_axe_1, ok = QInputDialog.getInt(
                self, "Select Axe",
                "Ingrese el número del primer eje a graficar")

            #Definimos las instrucciones correspondientes al éxito de la solicitud
            if ok:

                #Verificamos que el número ingresado corresponda a un índice de eje, en caso de que sea cierto
                #salimos del ciclo while
                if self.number_axe_1 in range(1, len(self.a) + 1):
                    break

                #Procesamos el posible error de que el dato ingresado sea erroneo
                else:
                    QMessageBox.warning(
                        self, "Select Axe Error",
                        "Ha ocurrido un error, verifique los datos ingresados!!!"
                    )

            #Procesamos un posible error en caso de que la solicitud no se realice con éxito
            else:
                QMessageBox.warning(
                    self, "Select Axe Error",
                    "Ha ocurrido un error, verifique los datos ingresados!!!")

        #Solicitamos al usuario que ingrese el segundo eje a graficar (La solicitud se realiza mientras
        #los datos ingresados sean erroneos)
        while (True):

            #Solicitamos el segundo eje a graficar, la variable global number_axe_2 contiene el número del eje,
            #la variable ok contiene información sobre el éxito de la solicitud
            self.number_axe_2, ok = QInputDialog.getInt(
                self, "Select Axe",
                "Ingrese el número del segundo eje a graficar")

            #Definimos las instrucciones correspondientes al éxito de la solicitud
            if ok:

                #Verificamos que el número ingresado corresponda a un índice de eje
                if self.number_axe_2 in range(1, len(self.a) + 1):

                    #Comprobamos que el número ingresado para el segundo eje sea diferente del número ingresado
                    #para el primer eje, si la condición se cumple salimos del while
                    if (self.number_axe_1 != self.number_axe_2):
                        break

                    #Procesamos el posible error de que el dato ingresado sea igual al primero
                    else:
                        QMessageBox.warning(
                            self, "Select Axe Error",
                            "Ha ocurrido un error, Debe seleccionar un eje diferente!!"
                        )

                #Procesamos el posible error de que el dato ingresado sea erroneo
                else:
                    QMessageBox.warning(
                        self, "Select Axe Error",
                        "Ha ocurrido un error, verifique los datos ingresados!!!"
                    )

            #Procesamos un posible error en caso de que la solicitud no se realice con éxito
            else:
                QMessageBox.warning(
                    self, "Select Axe Error",
                    "Ha ocurrido un error, verifique los datos ingresados!!!")

        #Agregamos los datos de los ejes a comparar en dos listas
        for i in self.lstlst:
            primereje.append(i[self.number_axe_1 - 1])
            segundoeje.append(i[self.number_axe_2 - 1])

        #Agregamos los datos de los ejes a comparar en dos cadenas
        for i in range(len(primereje)):
            text_eje_x += (primereje[i]) + "\n     "
        for i in range(len(segundoeje)):
            text_eje_y += (segundoeje[i]) + "\n     "

        #Mostramos en las áreas de texto data_eje_x y data_eje_y las cadenas que contienen los datos
        self.data_eje_x.setText(text_eje_x)
        self.data_eje_y.setText(text_eje_y)

        #Preparamos la figura para mostrar la gráfica
        self.figure.clf()
        ax = self.figure.add_subplot(111)

        #Mostramos la gráfica de los datos
        ax.plot(primereje, segundoeje, 'r.-')

        #Agregamos un título a la gráfica
        ax.set_title(self.a[self.number_axe_2 - 1] + " vs " +
                     self.a[self.number_axe_1 - 1])

        #Mostramos los datos
        self.canvas.draw()

    #Función save_figure
    def save_figure(self):
        """
        La función save_figure contiene las instrucciones necesarias para almacenar una imagen en formato png
        de la gráfica mostrada
        """
        #Deshabilitamos el botón btn_save_figure
        self.btn_save_figure.setEnabled(False)

        #Obtenemos el tamaño de la gráfica
        size = self.canvas.size()

        #Obtenemos el ancho y el alto de la imagen en las variables width y height
        width, height = size.width(), size.height()

        #Creamos la imagen a guardar
        im = QImage(self.canvas.buffer_rgba(), width, height,
                    QImage.Format_ARGB32)

        #Guardamos la imagen en formato png
        im.save(
            str(self.a[self.number_axe_2 - 1] + self.a[self.number_axe_1 - 1] +
                ".png"))

        #Informamos que la imagen ha sido guardad con éxito
        QMessageBox.information(self, "Save Figure Success",
                                "La gráfica ha sido guardada!!!")

        #Mostramos en el campo de texto dir_img_shown la dirección de la imagen guardada
        dir_image_save = self.cwd + "/" + str(self.a[self.number_axe_2 - 1] +
                                              self.a[self.number_axe_1 - 1] +
                                              ".png")
        self.dir_img_shown.setText(dir_image_save)

    #Función restart
    def restart(self):
        """
        La función restart contiene el conjunto de instrucciones necesarias para preparar el sistema
        con el fin repetir el proceso de graficación de imágenes, se encarga de llevar a sus estados iniciales
        todas las variables globales utilizadas, limpiar los campos y áreas de texto y limpiar el área de graficado
        """
        #Restauramos las variables globales
        self.lista = []
        self.lstlst = []
        self.a = []
        self.number_axe_1 = 0
        self.number_axe_2 = 0

        #Limpiamos campos y áreas de texto
        self.data_eje_x.setText("")
        self.data_eje_y.setText("")
        self.file_loaded.setText("")
        self.dir_file_loaded.setText("")
        self.dir_img_shown.setText("")
        self.area_text.setText("")

        #Habilitamos el botón btn_show_files y deshabilitamos el botón btn_save_figure
        self.btn_show_files.setEnabled(True)
        self.btn_save_figure.setEnabled(False)

        #Reseteamos el área de graficado
        self.figure.clf()
        ax = self.figure.add_subplot(111)
        ax.plot(0, 0)
        self.canvas.draw()

    #Función closeEvent
    def closeEvent(self, QCloseEvent):
        """
        La función closeEvent contiene las instrucciones a ser seguidas al momento de cerrar la aplicación
        """
        #Preguntamos al usuario si realmente quiere salir de la aplicación
        result = QMessageBox.question(
            self, "Salir...", "¿Seguro que quieres cerrar la aplicación?",
            QMessageBox.Yes | QMessageBox.No)

        #Cerramos la aplicación en caso de respuesta afirmatica
        if result == QMessageBox.Yes:
            QCloseEvent.accept()

        #Ignoramos el evento en caso de que la respuesta sea negativa
        else:
            QCloseEvent.ignore()
예제 #19
0
class Amoeba_Line_Graph():
    def __init__(self):
        """
        This class is for the plot on each of the parameter UIs.
        """
        #Generate plot
        x = []
        y = []
        self.fig = Figure(figsize=(8, 4),
                          dpi=72,
                          facecolor=(1, 1, 1),
                          edgecolor=(0, 0, 0))
        self.sub_plot = self.fig.add_subplot(111)
        self.sub_plot.xaxis_date()
        if AMOEBA_LINE_GRAPH_DEBUG:
            print "X = "
            print x
            print "Y = "
            print y
            print "Create "
            print self.sub_plot.plot
        self.sub_plot.plot(y, x, 'b')
        self.sub_plot.set_xlabel('Time')
        self.fig.autofmt_xdate()
        #Create canvas for the plot
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setMinimumSize(self.canvas.size())

    def update(self, datay, datax):
        """
        This method updates the plot with the input data.
        :param datay: Y axis of the points to plot.
        :param datax: X axis of the points to plot.
        """
        if AMOEBA_LINE_GRAPH_DEBUG:
            print "Update sub plot"
            print "X = "
            print datax
            print "Y = "
            print datay
            print "Update "
            print self.sub_plot.plot
        # Clear the graph.
        self.clear_graph()
        self.sub_plot.plot(datax, datay, 'b')
        self.sub_plot.set_visible(True)
        self.sub_plot.autoscale(True, "both")
        self.canvas.draw()

    def retrieve_graph(self):
        """
        This method returns the plot's widget.
        :return:
        """
        return self.canvas

    def clear_graph(self):
        """
        This method clears the graph.
        """
        y = []
        x = []
        self.sub_plot.clear()
        self.sub_plot.set_visible(True)
        self.sub_plot.autoscale(True, "both", False)
        self.sub_plot.plot(y, x, 'b')
        self.canvas.draw()
예제 #20
0
    def __init__(self, parent=None): #========================================
        super(ImageViewer, self).__init__(parent)
        
        self.scaleFactor = 0
        self.scaleStep = 1.2
        self.pan = False
        
        #---- image container Set Up ----
        
        self.imageLabel = QtGui.QLabel()
        self.imageLabel.setBackgroundRole(QtGui.QPalette.Base)
        self.imageLabel.setSizePolicy(QtGui.QSizePolicy.Ignored,
                                      QtGui.QSizePolicy.Ignored)
        self.imageLabel.setScaledContents(True)
        self.imageLabel.installEventFilter(self)
        
        self.imageLabel.setFrameStyle(QtGui.QFrame.Panel | QtGui.QFrame.Raised)
        self.imageLabel.setLineWidth(2)
        self.imageLabel.setMidLineWidth(1)        
        
        #---- Scroll Area Set Up ----
        
        self.scrollArea = QtGui.QScrollArea(self)
        self.scrollArea.setWidget(self.imageLabel)
        self.scrollArea.setAlignment(QtCore.Qt.AlignCenter)
                
        #---- Grid Set Up ----
                
        grid = QtGui.QGridLayout()
               
        grid.addWidget(self.scrollArea, 0, 0)
                
        grid.setSpacing(10)
        grid.setContentsMargins(0, 0, 0, 0) # (Left,Top, Right, Bottom)
        
        self.setLayout(grid)
        self.setWindowTitle("Image Viewer")
              
        #---- Create Initial Image with Matplotlib ----
        
        # http://stackoverflow.com/questions/17676373/
        # python-matplotlib-pyqt-copy-image-to-clipboard
        
        # http://stackoverflow.com/questions/21939658/
        # matplotlib-render-into-buffer-access-pixel-data
        
        figure = plt.figure()
        figure.patch.set_facecolor('white')

        figure_canvas = FigureCanvasQTAgg(figure)
        figure_canvas.draw()
                
        size = figure_canvas.size()
        width, height = size.width(), size.height()
        
        imgbuffer = figure_canvas.buffer_rgba()
        image = QtGui.QImage(imgbuffer, width, height,
                             QtGui.QImage.Format_ARGB32)
                             
        # Reference for the RGB to BGR swap:
        # http://sourceforge.net/p/matplotlib/mailman/message/5194542/
          
        image = QtGui.QImage.rgbSwapped(image)
        
        self.load_image(image, 0)
예제 #21
0
class GUI(QtGui.QDialog):
    def __init__(self):
        super(GUI, self).__init__()
        # Pola pomocnicze do obsługi pętli
        self._generator = None
        self._timerId = None
        
        # Właściwe pola klasy
        self.serial = serial.Serial()
        self.data = np.array([[], [], []])
        self.frames = 0;
        self.last_frame = 0;
        self.frames_lost = 0;
        self.window = 100  # Szerokość okna rysowanego sygnału
        
        # Ustawienia ramki
        self.frame_length = 30;  # Długość ramki z danymi
        self.frame_markers = np.array([int('A5', 16), int('5a', 16)])
        self.buffer = bytearray(self.frame_length - len(self.frame_markers))
        
        # Elementy okna
        self.figure = plt.figure()
        self.canvas = FigureCanvas(self.figure)
        self.canvas.setMinimumSize(self.canvas.size())
                                   
        self.serial_line = QtGui.QLineEdit(self)
        self.serial_line.setText('COM9')
        self.serial_line.setAlignment(QtCore.Qt.AlignCenter)
        self.serial_line.setMaxLength(30)
        
        self.serial_line_label = QtGui.QLabel("Port")
        self.serial_line_label.setAlignment(QtCore.Qt.AlignCenter)
        
        self.lost_frames_count = QtGui.QLineEdit(self)
        self.lost_frames_count.setText('0%')
        self.lost_frames_count.setAlignment(QtCore.Qt.AlignCenter)
        self.lost_frames_count.setMaxLength(30)
        
        self.lost_frames_label = QtGui.QLabel("Frames lost")
        self.lost_frames_label.setAlignment(QtCore.Qt.AlignCenter)
        
        self.start_button = self.createButton("Start", self.start)
        self.stop_button = self.createButton("Stop", self.stop)
        self.stop_button.setEnabled(False)
        
        self.info_line = QtGui.QLineEdit(self)
        self.info_line.setReadOnly(True)
        self.info_line.setAlignment(QtCore.Qt.AlignCenter)
        self.info_line.setMaxLength(30)
        self.info_line.setText('INFO')
        
        self.setWindowTitle('Signal Reader v.1.0')
        # Układanie layout'u
        layout = QtGui.QGridLayout()
        layout.setSizeConstraint(QtGui.QLayout.SetFixedSize)
        layout
        layout.addWidget(self.canvas, 0, 0, 1, 2)
        layout.addWidget(self.serial_line_label, 1, 0, 1, 2)
        layout.addWidget(self.serial_line, 2, 0, 1, 2)
        layout.addWidget(self.start_button, 3, 0, 1, 1)
        layout.addWidget(self.stop_button, 3, 1, 1, 1)
        layout.addWidget(self.lost_frames_label, 4, 0, 1, 2)
        layout.addWidget(self.lost_frames_count, 5, 0, 1, 2)
        layout.addWidget(self.info_line, 6, 0, 1, 2)
        self.setLayout(layout)
        self.setFigures()
    
    def setFigures(self):
        self.channel1 = self.figure.add_subplot(3, 1, 1)
        self.channel1.hold(True)
        self.channel1_data, = self.channel1.plot(np.zeros(self.window))
        plt.ylim([0, 4096])
        plt.title('Channel 1')
        plt.grid()
        plt.tight_layout(pad = 0.4, w_pad = 0.5, h_pad = 1.0)
        
        self.channel2 = self.figure.add_subplot(3, 1, 2)
        self.channel2.hold(True)
        self.channel2_data, = self.channel2.plot(np.zeros(self.window))
        plt.ylim([0, 4096])
        plt.title('Channel 2')
        plt.grid()
        plt.tight_layout(pad = 0.4, w_pad = 0.5, h_pad = 1.0)
        
        self.channel3 = self.figure.add_subplot(3, 1, 3)
        self.channel3.hold(True)
        self.channel3_data, = self.channel3.plot(np.zeros(self.window))
        plt.ylim([0, 4096])
        plt.title('Channel 3')
        plt.grid()
        plt.tight_layout(pad = 0.4, w_pad = 0.5, h_pad = 1.0)
        
        plt.ion()
        
    def start(self):
        # Aktywancja/deazktywacja przycisków
        self.start_button.setEnabled(False)
        self.stop_button.setEnabled(True)
        self.port = str(self.serial_line.text())  # Zapisuje nazwę portu
        if self._timerId is not None:
            self.killTimer(self._timerId)
        self.serial_line.setReadOnly(True)  # Ustawia pole z portem na niezmienialne
        self._generator = self.readData()  # Wchodzi do pętli wczytywania danych
        self._timerId = self.startTimer(0)
        
    def stop(self):
        # Aktywancja/deazktywacja przycisków
        self.start_button.setEnabled(True)
        self.stop_button.setEnabled(False)
        if self._timerId is not None:
            self.killTimer(self._timerId)
        self._generator = None
        self._timerId = None
        self.serial_line.setReadOnly(False)
        if(self.serial.isOpen()):
            self.serial.close()
            self.info_line.setText('STOP')
            
    def readData(self):
        ''' Metoda do czytania dancyh z podanego portu. '''
        try:
            self.serial = serial.Serial(self.port)  # Otwiera port
            self.info_line.setText('Reading data...')  # Zmienia napis
            while (True):
                input = self.serial.read()  # Czyta 1 bajt
                # Sprawdzenie czy jest starszym bajtem znacznika
                if(int.from_bytes(input, byteorder = 'big') == self.frame_markers[0]):
                    # Czytanie kolejnego 1 bajtu
                    input = self.serial.read()
                    # Sprawdzenie czy następny jest młodszym bajtem znacznika
                    if(int.from_bytes(input, byteorder = 'big') == self.frame_markers[1]):
                        # Jeśli tak to znaczy, że mamy ramkę
                        self.frames += 1
                        # Wczytujemy do struktury buffer (która jest tablicą
                        # bajtów) 28 bajtów (bo taki został ustalony jej rozmiar)
                        self.serial.readinto(self.buffer)
                        # Zamiana tablicy bajtów na macierz liczb całkowitych
                        self.buffer = np.array(self.buffer, dtype = np.int32);
                        self.parseData()
                        self.plot()
                        self.buffer = bytearray(self.frame_length - 2)
                    yield
        except serial.SerialException as ex:
            self.info_line.setText('Can\'t open the serial port!')
            
    def parseData(self):
        ''' Metoda analizująca pobraną ramkę z danymi. '''
        if(self.last_frame == 0):
            self.last_frame = self.buffer[0] * 256 + self.buffer[1]
        else:
            frame = self.buffer[0] * 256 + self.buffer[1]
            if(frame - 1 != self.last_frame):
                self.frames_lost += 1
            self.last_frame = frame
            
        self.lost_frames_count.setText(str(round(self.frames_lost / self.frames * 100, 2)) + '%')
            
        # Sprawdzanie sumy kontrolnej
        checksum = self.buffer[-2] * 256 + self.buffer[-1]
        sum = np.sum(self.buffer[:-2])
        #-----------------------------------------------------------------------
        # Tutaj w warunku ustawić sum == checksum
        #-----------------------------------------------------------------------
        if(True):
            self.buffer = self.buffer[2:-2].reshape((-1, 2))
            self.buffer[:, 0] *= 256
            self.buffer = np.sum(self.buffer, 1)
            self.buffer = self.buffer.reshape((-1, 3)).T
            self.data = np.hstack((self.data, self.buffer))
            
    def plot(self):
        if(self.data.shape[1] >= self.window):
            self.data = self.data[:, -self.window:]
            self.channel1_data.set_ydata(self.data[0])
            self.channel2_data.set_ydata(self.data[1])
            self.channel3_data.set_ydata(self.data[2])
            self.canvas.draw()
        
    def timerEvent(self, event):
        if self._generator is None:
            return
        try:
            next(self._generator)
        except StopIteration:
            self.stop()
            
    def closeEvent(self, event):
        self.stop()
        event.accept()
        
    def createButton(self, text, member):
        button = Button(text)
        button.clicked.connect(member)
        return button
예제 #22
0
class GUI(QtGui.QWidget):
    
    def __init__(self):

        super(GUI, self).__init__()
        
        self.setWindowTitle( 'AP-DV Analaysis' )
        self.lbltxt = '"wheel" press: change side, currently %s\n"i" or "u" press: change cell sides'
        self.initUI()
        
    #-----------------------------------------------------------------------------------------------
    # INITIALIZATION OF THE WINDOW - DEFINE AND PLACE ALL THE WIDGETS
    #-----------------------------------------------------------------------------------------------

    def initUI(self):
        
        # SET THE GEOMETRY
        
        mainWindow = QtGui.QVBoxLayout()
        mainWindow.setSpacing(15)
        
        fileBox = QtGui.QHBoxLayout()
        spaceBox1 = QtGui.QHBoxLayout()
        rawDataBox = QtGui.QHBoxLayout()
        
        mainWindow.addLayout(fileBox)
        mainWindow.addLayout(spaceBox1)
        mainWindow.addLayout(rawDataBox)
        
        Col1 = QtGui.QGridLayout()
        Col2 = QtGui.QHBoxLayout()
        
        rawDataBox.addLayout(Col1)
        rawDataBox.addLayout(Col2)
        
        self.setLayout(mainWindow)

        # DEFINE ALL WIDGETS AND BUTTONS
        
        loadBtn = QtGui.QPushButton('Load DataSet')
        saveBtn = QtGui.QPushButton('Save data (F12)')
        
        tpLbl = QtGui.QLabel('Relative Tp:')
        fNameLbl = QtGui.QLabel('File name:')
        
        self.tp = QtGui.QSpinBox(self)
        self.tp.setValue(0)
        self.tp.setMinimum(-100000)
        self.tp.setMaximum(100000)

        self.fName = QtGui.QLabel('')
        
        self._488nmBtn = QtGui.QRadioButton('488nm')
        self._561nmBtn = QtGui.QRadioButton('561nm')
        self.CoolLEDBtn = QtGui.QRadioButton('CoolLED')
        
        self.sld1 = QtGui.QSlider(QtCore.Qt.Vertical, self)
        self.sld1.setMaximum(2**16-1)
        self.sld1.setValue(0)
        self.sld2 = QtGui.QSlider(QtCore.Qt.Vertical, self)
        self.sld2.setMaximum(2**16)
        self.sld2.setValue(2**16-1)

        self.fig1 = Figure((8.0, 8.0), dpi=100)
        self.fig1.subplots_adjust(left=0., right=1., top=1., bottom=0.)
        self.ax1 = self.fig1.add_subplot(111)
        self.canvas1 = FigureCanvas(self.fig1)
        self.canvas1.setFocusPolicy( QtCore.Qt.ClickFocus )
        self.canvas1.setFocus()
        self.canvas1.setFixedSize(QtCore.QSize(600,600))
        self.canvas1.setSizePolicy( QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding )

        # PLACE ALL THE WIDGET ACCORDING TO THE GRIDS

        fileBox.addWidget(loadBtn)
        fileBox.addWidget(saveBtn)

        spaceBox1.addWidget(self.HLine())

        Col1.addWidget(tpLbl, 0, 0)#, 1, 1, Qt.AlignTop)
        Col1.addWidget(self.tp, 0, 1)#, 1, 1, Qt.AlignTop)
        Col1.addWidget(fNameLbl, 1, 0)#, 1, 1, Qt.AlignTop)
        Col1.addWidget(self.fName, 1, 1)#, 1, 1, Qt.AlignTop)
        Col1.addWidget(self._488nmBtn, 2, 0 )
        Col1.addWidget(self._561nmBtn, 3, 0 )
        Col1.addWidget(self.CoolLEDBtn, 4, 0 )
        
        Col2.addWidget(self.sld1)
        Col2.addWidget(self.sld2)
        Col2.addWidget(self.canvas1)
        
        self.setFocus()
        self.show()
        
        # BIND BUTTONS TO FUNCTIONS
        
        loadBtn.clicked.connect(self.selectWorm)
        saveBtn.clicked.connect(self.saveData)

        self.tp.valueChanged.connect(self.updateAllCanvas)
        self.sld1.valueChanged.connect(self.updateAllCanvas)
        self.sld2.valueChanged.connect(self.updateAllCanvas)

        self._488nmBtn.toggled.connect(self.radioClicked)
        self._561nmBtn.toggled.connect(self.radioClicked)
        self.CoolLEDBtn.toggled.connect(self.radioClicked)

        self.fig1.canvas.mpl_connect('button_press_event',self.onMouseClickOnCanvas1)        
        self.fig1.canvas.mpl_connect('scroll_event',self.wheelEvent)        
        
    #-----------------------------------------------------------------------------------------------
    # FORMATTING THE WINDOW
    #-----------------------------------------------------------------------------------------------

    def center(self):
        
        qr = self.frameGeometry()
        cp = QtGui.QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())
        
    def HLine(self):
        
        toto = QtGui.QFrame()
        toto.setFrameShape(QtGui.QFrame.HLine)
        toto.setFrameShadow(QtGui.QFrame.Sunken)
        return toto

    def VLine(self):
        
        toto = QtGui.QFrame()
        toto.setFrameShape(QtGui.QFrame.VLine)
        toto.setFrameShadow(QtGui.QFrame.Sunken)
        return toto

    def heightForWidth(self, width):
        
        return width
    
    #-----------------------------------------------------------------------------------------------
    # BUTTON FUNCTIONS
    #-----------------------------------------------------------------------------------------------

    def selectWorm(self):

        ### store the folders
        self.pathDial = QtGui.QFileDialog.getExistingDirectory(self, 'Select a folder', 'X:\\Simone\\160226_lag2YFP_histmCherry')
        self.worm = self.pathDial.split("\\")[-1].split('_')[0]
        self.path = os.path.dirname( self.pathDial )
        self.setWindowTitle('Body Length Analysis - ' + self.pathDial)

        ### give error message if there is no CoolLED movie in the selected folder
        if not os.path.isfile( os.path.join( self.pathDial, 'CoolLED_movie.tif' ) ):
            QtGui.QMessageBox.about(self,'Warning!','There is no movie in this folder! Create a movie first!')
            return

        ### load all movies (without timestamps, we will add it later on)
        self.channels = {}
        
        if os.path.isfile( os.path.join( self.pathDial, '488nm_movie.tif' ) ):
            self.channels['488nm'] = load_stack( os.path.join( self.pathDial, '488nm_movie.tif') )
        
        if os.path.isfile( os.path.join( self.pathDial, '561nm_movie.tif') ):
            self.channels['561nm'] = load_stack( os.path.join( self.pathDial, '561nm_movie.tif') )
        
        if os.path.isfile( os.path.join( self.pathDial, 'CoolLED_movie.tif' ) ):
            self.channels['CoolLED'] = load_stack( os.path.join( self.pathDial, 'CoolLED_movie.tif' ) )

        self.currentChannel = 'CoolLED'
        
        ### load parameters and times dataframes
        self.paramsDF = load_data_frame( self.path, self.worm + '_01params.pickle' )
        self.timesDF = load_data_frame( self.path, self.worm + '_01times.pickle' )
        self.gpDF = load_data_frame( self.path, self.worm + '_02gonadPos.pickle' )
        self.cellPosDF = load_data_frame( self.path, self.worm + '_04cellPos.pickle' )
        
        # extract some info
        self.compression = self.paramsDF.compression
        self.hatchingtidx = int( self.paramsDF.tidxHatch )

        ### if the AP pickle file already exists, load it, otherwise create a blank one
        if os.path.isfile( os.path.join(self.path, self.worm + '_08apdvPos.pickle' ) ):
            self.apdvPosDF = load_data_frame( self.path, self.worm + '_08apdvPos.pickle' )
        
        else:
            self.apdvPosDF = create_apdv_pos( self.timesDF )

        ### extract current cells already labeled
        self.currentPos = extract_current_apdv_pos( self.apdvPosDF, first_tidx_pos_all_cells( self.cellPosDF ) )
        print(self.currentPos)

        ### set the timepoint to the hatching time
        self.tp.setMinimum(np.min(self.timesDF.tidxRel))
        self.tp.setMaximum(np.max(self.timesDF.tidxRel))
        self.tp.setValue( first_tidx_pos_all_cells( self.cellPosDF ) )

        ### update the text of the fileName
        self.fName.setText(self.timesDF.ix[self.timesDF.tidxRel == self.tp.value(), 'fName'].values[0])

        self.setFocus()

    def saveData(self):

        save_data_frame( self.apdvPosDF, self.path, self.worm + '_08apdvPos.pickle' )
        
    def updateAllCanvas(self):

        self.updateRadioBtn()
        self.updateCanvas1()
        
    def radioClicked(self):

        if self._488nmBtn.isChecked():
            if '488nm' in self.channels.keys():
                self.currentChannel = '488nm'
            else:
                QtGui.QMessageBox.about(self, 'Warning', 'No 488nm channel!')

        elif self._561nmBtn.isChecked():
            if '561nm' in self.channels.keys():
                self.currentChannel = '561nm'
            else:
                QtGui.QMessageBox.about(self, 'Warning', 'No 561nm channel!')

        elif self.CoolLEDBtn.isChecked():
            if 'CoolLED' in self.channels.keys():
                self.currentChannel = 'CoolLED'
            else:
                QtGui.QMessageBox.about(self, 'Warning', 'No CoolLED channel!')

        self.setBCslidersMinMax()
        self.resetBC()
        self.setFocus()
        self.updateAllCanvas()

    def keyPressEvent(self, event):
        
        # key press on cropped image
        if self.canvas1.underMouse():
            self.onKeyPressOnCanvas1(event)
            
        self.setFocus()

    #-----------------------------------------------------------------------------------------------
    # DEFAULT FUNCTION FOR KEY AND MOUSE PRESS ON WINDOW
    #-----------------------------------------------------------------------------------------------

    def wheelEvent(self,event):

        if self.canvas1.underMouse():
            step = event.step
        
        else:          
            step = event.delta()/abs(event.delta())

        ### update daytaframe with previously labeled cells
        newapdvDF = update_apdv_pos_DF( self.currentPos, self.apdvPosDF, self.tp.value() )
        self.apdvPosDF = newapdvDF
        print(self.currentPos) # print previously labeled positions

        ### extract current cells already labeled
        self.currentPos = extract_current_apdv_pos( self.apdvPosDF, self.tp.value() + step )

        self.tp.setValue( self.tp.value() + step ) 

        self.fName.setText( self.timesDF.ix[ self.timesDF.tidxRel == self.tp.value(), 'fName' ].values[0] )

    #-----------------------------------------------------------------------------------------------
    # ADDITIONAL FUNCTIONS FOR KEY AND MOUSE PRESS ON CANVASES
    #-----------------------------------------------------------------------------------------------

    def onKeyPressOnCanvas1(self, event):
        
        posNameList = [ QtCore.Qt.Key_A, QtCore.Qt.Key_P, QtCore.Qt.Key_D ]

        # find the position of the cursor relative to the image in pixel
        imgshape = self.channels[self.currentChannel][0].shape
        canshape = self.canvas1.size()
        cf = imgshape[0]/canshape.width()
        refpos = self.canvas1.mapFromGlobal(QtGui.QCursor.pos())
        refpos = np.array([ int( refpos.x() * cf ), int( refpos.y() * cf )]) * self.compression

        ### find the closest cell to the cursor
        idx = closer_2Dpos( refpos.astype( np.uint16 ), self.currentPos )

        ### assign the name to the cell
        if any( [ event.key() == cn for cn in posNameList ] ):

            self.currentPos.ix[ idx, 'pname' ] = QtGui.QKeySequence(event.key()).toString().lower()

        self.updateCanvas1()
        self.setFocus()

    def onMouseClickOnCanvas1(self, event):
        
        refpos = np.array( [ event.xdata, event.ydata ] ) * self.compression 

        if event.button == 1:

            # create an empty cell in the currentCells df: the only entries are tidx, xyzpos and cname
            newpos = create_single_apdv_pos( refpos.astype(np.uint16), self.tp.value() )
            self.currentPos = pd.concat( [ self.currentPos, newpos ] )
            
        elif event.button == 3:

            # remove a cell (the closest to the cursor at the moment of right-click)
            idx = closer_2Dpos( refpos.astype(np.uint16), self.currentPos )
            self.currentPos = self.currentPos.drop( [ idx ] )

        self.currentPos = self.currentPos.reset_index(drop=True)
        
        self.updateCanvas1()
        self.setFocus()

    #-----------------------------------------------------------------------------------------------
    # UTILS
    #-----------------------------------------------------------------------------------------------

    def updateRadioBtn(self):
        if self.currentChannel == '488nm':
            self._488nmBtn.setChecked(True)
        elif self.currentChannel == '561nm':
            self._561nmBtn.setChecked(True)
        elif self.currentChannel == 'CoolLED':
            self.CoolLEDBtn.setChecked(True)
        self.setFocus()

    def setBCslidersMinMax(self):
        self.sld1.setMaximum(np.max(self.channels[self.currentChannel]))
        self.sld1.setMinimum(np.min(self.channels[self.currentChannel]))
        self.sld2.setMaximum(np.max(self.channels[self.currentChannel]))
        self.sld2.setMinimum(np.min(self.channels[self.currentChannel]))

    def resetBC(self):
        self.sld1.setValue(np.min(self.channels[self.currentChannel]))
        self.sld2.setValue(np.max(self.channels[self.currentChannel]))
        
    def updateCanvas1(self):
        
        # plot the image
        self.ax1.cla()
        imgplot = self.ax1.imshow( self.channels[self.currentChannel][self.tp.value() + self.hatchingtidx], cmap = 'gray' )
        
        # remove the white borders and plot outline and spline
        self.ax1.autoscale(False)
        self.ax1.axis('Off')
        self.fig1.subplots_adjust(left=0., right=1., top=1., bottom=0.)

        # change brightness and contrast
        self.sld1.setValue(np.min([self.sld1.value(),self.sld2.value()]))
        self.sld2.setValue(np.max([self.sld1.value(),self.sld2.value()]))
        imgplot.set_clim(self.sld1.value(), self.sld2.value())  

        # print gonad position
        gonadPos = extract_pos( self.gpDF.ix[ self.gpDF.tidx == self.tp.value() ].squeeze() ) / self.compression
        if len( gonadPos.shape ) > 0:
            self.ax1.plot( gonadPos[0], gonadPos[1], 'o', color='red', ms=10, mew=0, alpha=.5, lw = 0 ) 

        # pritn apdv pos
        for idx, pos in self.currentPos.iterrows():
            p = extract_pos( pos ) / self.compression

            self.ax1.plot( p[0], p[1], 'o', color='red', ms=10, mew=0, alpha=.8, lw = 0 ) 
            self.ax1.text( p[0], p[1] + 20, pos.pname, color='red', size='medium', alpha=.8,
                    rotation=0 )

        # print time
        # print(self.timesDF.ix[ self.timesDF.tidxRel == self.tp.value(), 'timesRel' ])
        self.ax1.text( 5, 15, '%.2f' % self.timesDF.ix[ self.timesDF.tidxRel == self.tp.value(), 'timesRel' ].values[0], color = 'red' )     

        # redraw the canvas
        self.canvas1.draw()
        self.setFocus()
예제 #23
0
class FilterDesignDialog(QtGui.QDialog):
    """A dialog to apply Takanami's AR picking method to a selected piece of a
    seismic signal.

    Attributes:
        document: Current opened document containing a seismic record.
        seismic_event: A seismic event to be refined by using Takanami method.
            If no event is provided, then a new seismic event will be created
            by using the estimated arrival time after clicking on 'Accept'
    """

    def __init__(self, stream, trace_list=None, parent=None):
        super(FilterDesignDialog, self).__init__(parent)

        # Calc max. frequency
        traces = stream.traces if not trace_list else trace_list
        self.max_freq = max([trace.fs for trace in traces])

        self._init_ui()
        self.load_settings()
        # Initial draw
        w, h_db, angles = self._retrieve_filter_plot_data()
        self._module_data = self.module_axes.plot(w, h_db, 'b')[0]
        self._phase_data = self.phase_axes.plot(w, angles, 'g')[0]
        self.module_axes.set_ylim([-60,10])
        self.phase_axes.set_ylim([min(angles), max(angles)])
        self.canvas.draw_idle()

        self.start_point_spinbox.valueChanged.connect(self.on_freq_min_changed)
        self.end_point_spinbox.valueChanged.connect(self.on_freq_max_changed)
        self.start_point_spinbox.valueChanged.connect(self._draw_filter_response)
        self.end_point_spinbox.valueChanged.connect(self._draw_filter_response)
        self.number_coefficient_spinbox.valueChanged.connect(self._draw_filter_response)
        self.zeroPhaseCheckBox.toggled.connect(self._draw_filter_response)
        self.button_box.accepted.connect(self.accept)
        self.button_box.rejected.connect(self.reject)
        self.button_box.clicked.connect(self.on_click)

    def _init_ui(self):
        self.setWindowTitle("Filter Design (Butterworth-Bandpass Filter)")
        self.fig, _ = plt.subplots(1, 1, sharex=True)
        # Set up filter axes
        self.module_axes = self.fig.axes[0]
        self.phase_axes = self.module_axes.twinx()
        self.module_axes.set_title('Digital filter frequency response (Butterworth-Bandpass filter)')
        self.module_axes.set_xlabel('Frequency [Hz]')
        self.module_axes.set_ylabel('Amplitude [dB]', color='b')
        self.module_axes.axis('tight')
        self.module_axes.grid(which='both', axis='both')
        self.phase_axes.set_ylabel('Angle (radians)', color='g')
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setMinimumSize(self.canvas.size())
        self.canvas.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Policy.Expanding,
                                                    QtGui.QSizePolicy.Policy.Expanding))
        self.toolBarNavigation = navigationtoolbar.NavigationToolBar(self.canvas, self)
        self.group_box = QtGui.QGroupBox(self)
        self.group_box2 = QtGui.QGroupBox(self)
        self.group_box3 = QtGui.QGroupBox(self)
        self.group_box4 = QtGui.QGroupBox(self)
        self.group_box.setTitle("")
        self.group_box2.setTitle("")
        self.group_box3.setTitle("Parameters")
        self.start_point_label = QtGui.QLabel("Lower cutoff frequency (Hz): ")
        self.start_point_label.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Policy.Maximum,
                                                               QtGui.QSizePolicy.Policy.Preferred))

        self.start_point_spinbox = QtGui.QDoubleSpinBox(self.group_box)
        self.start_point_spinbox.setMinimum(1.0)
        self.start_point_spinbox.setSingleStep(1.00)
        self.start_point_spinbox.setAccelerated(True)
        self.start_point_spinbox.setMaximum(self.max_freq * 0.5)
        self.end_point_label = QtGui.QLabel("Higher cutoff frequency (Hz):")
        self.end_point_label.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Policy.Maximum,
                                                               QtGui.QSizePolicy.Policy.Preferred))
        self.end_point_spinbox = QtGui.QDoubleSpinBox(self.group_box4)
        self.end_point_spinbox.setMinimum(1.0)
        self.end_point_spinbox.setSingleStep(1.00)
        self.end_point_spinbox.setAccelerated(True)
        self.end_point_spinbox.setMaximum(self.max_freq * 0.5)
        self.end_point_spinbox.setValue(5.0)
        #######################################################################

        self.number_coefficient_label = QtGui.QLabel("Order: ")
        self.number_coefficient_label2 = QtGui.QLabel("")
        self.number_coefficient_label.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Policy.Maximum,
                                                               QtGui.QSizePolicy.Policy.Preferred))
        self.number_coefficient_label2.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Policy.Maximum,
                                                               QtGui.QSizePolicy.Policy.Preferred))
        self.number_coefficient_spinbox = QtGui.QSpinBox(self.group_box3)
        self.number_coefficient_spinbox.adjustSize()
        self.number_coefficient_spinbox.setMinimum(1)
        self.number_coefficient_spinbox.setSingleStep(1)
        self.number_coefficient_spinbox.setAccelerated(True)
        self.zeroPhaseCheckBox = QtGui.QCheckBox("Zero phase filtering", self.group_box2)
        self.zeroPhaseCheckBox.setChecked(True)

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

        self.group_box_layout = QtGui.QHBoxLayout(self.group_box)
        self.group_box_layout.setContentsMargins(9, 9, 9, 9)
        self.group_box_layout.setSpacing(12)
        self.group_box_layout.addWidget(self.start_point_label)
        self.group_box_layout.addWidget(self.start_point_spinbox)
        self.group_box4_layout = QtGui.QHBoxLayout(self.group_box4)
        self.group_box4_layout.setContentsMargins(9, 9, 9, 9)
        self.group_box4_layout.setSpacing(12)
        self.group_box4_layout.addWidget(self.end_point_label)
        self.group_box4_layout.addWidget(self.end_point_spinbox)
        #####################################################################
        self.group_box2_layout = QtGui.QHBoxLayout(self.group_box2)
        self.group_box2_layout.setContentsMargins(9, 9, 9, 9)
        self.group_box2_layout.setSpacing(12)
        self.group_box2_layout.addWidget(self.zeroPhaseCheckBox)
        ###################################################################
        self.group_box3_layout = QtGui.QHBoxLayout(self.group_box3)
        self.group_box3_layout.setContentsMargins(9, 9, 9, 9)
        self.group_box3_layout.setSpacing(12)
        self.group_box3_layout.addWidget(self.number_coefficient_label)
        self.group_box3_layout.addWidget(self.number_coefficient_spinbox)
        self.group_box3_layout.addWidget(self.number_coefficient_label2)
        #####################################################################
        self.button_box = QtGui.QDialogButtonBox(self)
        self.button_box.setOrientation(QtCore.Qt.Horizontal)
        self.button_box.setStandardButtons(QtGui.QDialogButtonBox.Apply |
                                           QtGui.QDialogButtonBox.Cancel |
                                           QtGui.QDialogButtonBox.Ok)
        self.layout = QtGui.QVBoxLayout(self)
        self.layout.setContentsMargins(9, 9, 9, 9)
        self.layout.setSpacing(6)
        self.layout.addWidget(self.toolBarNavigation)
        self.layout.addWidget(self.canvas)
        self.layout.addWidget(self.group_box3)
        self.layout.addWidget(self.group_box)
        self.layout.addWidget(self.group_box4)
        #self.layout.addWidget(self.group_box2)
        self.layout.addWidget(self.zeroPhaseCheckBox)
        self.layout.addWidget(self.button_box)

    def on_freq_min_changed(self, value):
        self.end_point_spinbox.setMinimum(value + 1.0)

    def on_freq_max_changed(self, value):
        self.start_point_spinbox.setMaximum(value - 1.0)

    def on_click(self, button):
        if self.button_box.standardButton(button) == QtGui.QDialogButtonBox.Ok:
            self.save_settings()
        if self.button_box.standardButton(button) == QtGui.QDialogButtonBox.Apply:
            self._draw_filter_response()

    def save_settings(self):
        """Save settings to persistent storage."""
        settings = QtCore.QSettings(_organization, _application_name)
        settings.beginGroup("filterdesign_settings")
        #self.default_margin = int(float(settings.value('filterdesign_margin', 5.0)) *
                             #self.record.fs)
        settings.setValue('freq_min', self.start_point_spinbox.value())
        settings.setValue('freq_max', self.end_point_spinbox.value())
        settings.setValue('coef_number', self.number_coefficient_spinbox.value())
        settings.setValue('zero_phase', self.zeroPhaseCheckBox.isChecked())
        settings.endGroup()

    def load_settings(self):
        """Loads settings from persistent storage."""
        settings = QtCore.QSettings(_organization, _application_name)
        settings.beginGroup("filterdesign_settings")
        self.start_point_spinbox.setValue(float(settings.value('freq_min', 0.0)))
        self.end_point_spinbox.setValue(float(settings.value('freq_max', self.max_freq * 0.5)))
        self.number_coefficient_spinbox.setValue(int(settings.value('coef_number', 1)))
        self.zeroPhaseCheckBox.setChecked(bool(settings.value('zero_phase', True)))
        settings.endGroup()

    def _butter_bandpass(self, lowcut, highcut, fs, order=5):
        nyq = 0.5 * fs
        low = lowcut / nyq
        high = highcut / nyq
        b, a = butter(order, [low, high], btype='band')
        return b, a

    def _retrieve_filter_plot_data(self):
        b, a = self._butter_bandpass(self.start_point_spinbox.value(), self.end_point_spinbox.value(), self.max_freq, order=self.number_coefficient_spinbox.value())
        #w, h = freqz(b, a)
        w, h = freqz(b, a,1024)
        angles = np.unwrap(np.angle(h))
        #return (self.max_freq * 0.5 / np.pi) * w, 20 * np.log10(abs(h)), angles
        f= (self.max_freq/2)*(w/np.pi)
        return f, 20 * np.log10(abs(h)), angles

    def _draw_filter_response(self, *args, **kwargs):
        w, h_db, angles = self._retrieve_filter_plot_data()
        self._module_data.set_xdata(w)
        self._module_data.set_ydata(h_db)
        self._phase_data.set_xdata(w)
        self._phase_data.set_ydata(angles)
        self.phase_axes.set_ylim([min(angles), max(angles)])
        self.canvas.draw_idle()
예제 #24
0
class GUI(QtGui.QWidget):
    
    def __init__(self):

        super(GUI, self).__init__()
        
        self.setWindowTitle( 'Label Cells' )
        self.cellNames = ['1.p','4.a','1.pp','4.aa','1.ppa','1.ppp','4.aaa','4.aap','b_1','b_4']
        self.initUI()
        
    #-----------------------------------------------------------------------------------------------
    # INITIALIZATION OF THE WINDOW - DEFINE AND PLACE ALL THE WIDGETS
    #-----------------------------------------------------------------------------------------------

    def initUI(self):
        
        # SET THE GEOMETRY
        
        mainWindow = QtGui.QVBoxLayout()
        mainWindow.setSpacing(15)
        
        fileBox = QtGui.QHBoxLayout()
        spaceBox1 = QtGui.QHBoxLayout()
        rawDataBox = QtGui.QHBoxLayout()
        
        mainWindow.addLayout(fileBox)
        mainWindow.addLayout(spaceBox1)
        mainWindow.addLayout(rawDataBox)
        
        Col1 = QtGui.QGridLayout()
        Col2 = QtGui.QHBoxLayout()
        Col3 = QtGui.QVBoxLayout()
        
        rawDataBox.addLayout(Col1)
        rawDataBox.addLayout(Col2)
        rawDataBox.addLayout(Col3)
        
        self.setLayout(mainWindow)

        # DEFINE ALL WIDGETS AND BUTTONS
        
        loadBtn = QtGui.QPushButton('Load DataSet')
        saveBtn = QtGui.QPushButton('Save data (F12)')
        
        tpLbl = QtGui.QLabel('Relative Tp:')
        slLbl = QtGui.QLabel('Slice:')
        fNameLbl = QtGui.QLabel('File name:')
        
        self.tp = QtGui.QSpinBox(self)
        self.tp.setValue(0)
        self.tp.setMaximum(100000)

        self.sl = QtGui.QSpinBox(self)
        self.sl.setValue(0)
        self.sl.setMaximum(100000)

        self.fName = QtGui.QLabel('')
        
        self._488nmBtn = QtGui.QRadioButton('488nm')
        self._561nmBtn = QtGui.QRadioButton('561nm')
        self.CoolLEDBtn = QtGui.QRadioButton('CoolLED')
        
        self.sld1 = QtGui.QSlider(QtCore.Qt.Vertical, self)
        self.sld1.setMaximum(2**16-1)
        self.sld1.setValue(0)
        self.sld2 = QtGui.QSlider(QtCore.Qt.Vertical, self)
        self.sld2.setMaximum(2**16)
        self.sld2.setValue(2**16-1)

        self.fig1 = Figure((8.0, 8.0), dpi=100)
        self.fig1.subplots_adjust(left=0., right=1., top=1., bottom=0.)
        self.ax1 = self.fig1.add_subplot(111)
        self.canvas1 = FigureCanvas(self.fig1)
        self.canvas1.setFocusPolicy( QtCore.Qt.ClickFocus )
        self.canvas1.setFocus()
        self.canvas1.setFixedSize(QtCore.QSize(600,600))
        self.canvas1.setSizePolicy( QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding )

        self.cellTbl = QtGui.QTableWidget()

        self.fig2 = Figure((4.0, 4.0), dpi=100)
        self.fig2.subplots_adjust(left=0., right=1., top=1., bottom=0.)
        self.ax2 = self.fig2.add_subplot(111)
        self.canvas2 = FigureCanvas(self.fig2)
        self.canvas2.setFixedSize(QtCore.QSize(300,300))
        self.canvas2.setSizePolicy( QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding )

        # PLACE ALL THE WIDGET ACCORDING TO THE GRIDS

        fileBox.addWidget(loadBtn)
        fileBox.addWidget(saveBtn)

        spaceBox1.addWidget(self.HLine())

        Col1.addWidget(tpLbl, 0, 0)#, 1, 1, Qt.AlignTop)
        Col1.addWidget(self.tp, 0, 1)#, 1, 1, Qt.AlignTop)
        Col1.addWidget(slLbl, 1, 0)#, 1, 1, Qt.AlignTop)
        Col1.addWidget(self.sl, 1, 1)#, 1, 1, Qt.AlignTop)
        Col1.addWidget(fNameLbl, 2, 0)
        Col1.addWidget(self.fName, 2, 1)
        Col1.addWidget(self._488nmBtn, 3, 0 )
        Col1.addWidget(self._561nmBtn, 4, 0 )
        Col1.addWidget(self.CoolLEDBtn, 5, 0 )
        
        Col2.addWidget(self.sld1)
        Col2.addWidget(self.sld2)
        Col2.addWidget(self.canvas1)

        Col3.addWidget(self.cellTbl)
        Col3.addWidget(self.canvas2)
        
        self.setFocus()
        self.show()
        
        # BIND BUTTONS TO FUNCTIONS
        
        loadBtn.clicked.connect(self.selectWorm)
        saveBtn.clicked.connect(self.saveData)

        self.tp.valueChanged.connect(self.loadNewStack)
        self.sl.valueChanged.connect(self.updateAllCanvas)
        self.sld1.valueChanged.connect(self.updateAllCanvas)
        self.sld2.valueChanged.connect(self.updateAllCanvas)

        self._488nmBtn.toggled.connect(self.radioClicked)
        self._561nmBtn.toggled.connect(self.radioClicked)
        self.CoolLEDBtn.toggled.connect(self.radioClicked)

        self.fig1.canvas.mpl_connect('button_press_event',self.onMouseClickOnCanvas1)        
        self.fig1.canvas.mpl_connect('scroll_event',self.wheelEvent)        
        
    #-----------------------------------------------------------------------------------------------
    # FORMATTING THE WINDOW
    #-----------------------------------------------------------------------------------------------

    def center(self):
        
        qr = self.frameGeometry()
        cp = QtGui.QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())
        
    def HLine(self):
        
        toto = QtGui.QFrame()
        toto.setFrameShape(QtGui.QFrame.HLine)
        toto.setFrameShadow(QtGui.QFrame.Sunken)
        return toto

    def VLine(self):
        
        toto = QtGui.QFrame()
        toto.setFrameShape(QtGui.QFrame.VLine)
        toto.setFrameShadow(QtGui.QFrame.Sunken)
        return toto

    def heightForWidth(self, width):
        
        return width
    
    #-----------------------------------------------------------------------------------------------
    # BUTTON FUNCTIONS
    #-----------------------------------------------------------------------------------------------

    def selectWorm(self):

        ### store the folders
        self.pathDial = QtGui.QFileDialog.getExistingDirectory(self, 'Select a folder', 'Y:\\Images')
        self.worm = self.pathDial.split("\\")[-1].split('_')[0]
        self.path = os.path.dirname( self.pathDial )
        self.setWindowTitle('Mark Cells - ' + self.pathDial)
        
        ### give error message if there is no CoolLED movie in the selected folder
        if not os.path.isfile( os.path.join( self.pathDial, 'CoolLED_movie.tif' ) ):
            QtGui.QMessageBox.about(self,'Warning!','There is no movie in this folder! Create a movie first!')
            return

        ### load parameters and times dataframes
        self.paramsDF = load_data_frame( self.path, self.worm + '_01params.pickle' )
        self.timesDF = load_data_frame( self.path, self.worm + '_01times.pickle' )
        self.gpDF = load_data_frame( self.path, self.worm + '_02gonadPos.pickle' )

        # extract some info
        self.compression = self.paramsDF.compression
        self.hatchingtidx = int( self.paramsDF.tidxHatch )

        ### if the cellPos pickle file already exists, load it, otherwise create a blank one
        if os.path.isfile( os.path.join(self.path, self.worm + '_04cellPos.pickle' ) ):
            self.cellPosDF = load_data_frame( self.path, self.worm + '_04cellPos.pickle' )
        
        else:
            self.cellPosDF = create_cell_pos( self.timesDF, self.cellNames )

        ### load all movies (without timestamps, we will add it later on)
        self.LEDmovie = load_stack( os.path.join( self.pathDial, 'CoolLED_movie.tif' ) )

        ### set the timepoint to the hatching time
        self.tp.setMinimum(np.min(self.timesDF.tidxRel))
        self.tp.setMaximum(np.max(self.timesDF.tidxRel))
        self.tp.setValue( 0 )

        ### extract current cells already labeled
        self.currentCells = extract_current_cell_pos( self.cellPosDF, self.tp.value() )

        # detect available channels
        self.channels = []
        chns = ['CoolLED','488nm','561nm']
        for c in chns:

            if os.path.isfile( os.path.join( self.pathDial, c + '_movie.tif' ) ):

                self.channels.append(c)
        self.currentChannel = self.channels[0]

        ### update the text of the fileName
        self.fName.setText( self.timesDF.ix[ self.timesDF.tidxRel == self.tp.value(), 'fName' ].values[0])
        
        self.loadNewStack()

        # self.pathDial.show()
        self.updateAllCanvas()
        self.setFocus()

    def loadNewStack(self):

        # print(self.fList['gfp'][self.tp.value()])
        tRow = self.timesDF.ix[ self.timesDF.tidxRel == self.tp.value() ].squeeze()

        print( 'Loading... ', self.pathDial, tRow.fName )

        # load all the available stacks
        self.stacks = {}
        for ch in self.channels:
            fileName = os.path.join( self.pathDial, tRow.fName + ch + '.tif')
            if os.path.isfile( fileName ):
                self.stacks[ch] = load_stack( fileName )

        if len( self.stacks.keys() ) > 0:
            # print(self.stacks.keys(), self.stacksStraight)
            self.sl.setMaximum(self.stacks[self.currentChannel].shape[0]-1)

            self.setBCslidersMinMax()
        
        ### update the text of the fileName
        self.fName.setText( self.timesDF.ix[ self.timesDF.tidxRel == self.tp.value(), 'fName' ].values[0])

        ### extract current cells already labeled
        self.currentCells = extract_current_cell_pos( self.cellPosDF, self.tp.value() )

        # self.updateTable()
        self.updateAllCanvas()

    def saveData(self):
        
        if self.checkConsistencyCellNames():
            save_data_frame( self.cellPosDF, self.path, self.worm + '_04cellPos.pickle' )        
        else:
            QtGui.QMessageBox.about(self,'Warning!','There is a mistake in the cell labels!')
        self.setFocus()
        
    def updateAllCanvas(self):
        self.updateRadioBtn()
        self.updateCanvas1()
        self.updateCanvas2()
        
    def radioClicked(self):
        if self._488nmBtn.isChecked():
            if '488nm' in self.channels:
                self.currentChannel = '488nm'
            else:
                QtGui.QMessageBox.about(self, 'Warning', 'No 488nm channel!')
        elif self._561nmBtn.isChecked():
            if '561nm' in self.channels:
                self.currentChannel = '561nm'
            else:
                QtGui.QMessageBox.about(self, 'Warning', 'No 561nm channel!')
        elif self.CoolLEDBtn.isChecked():
            if 'CoolLED' in self.channels:
                self.currentChannel = 'CoolLED'
            else:
                QtGui.QMessageBox.about(self, 'Warning', 'No CoolLED channel!')
        self.setBCslidersMinMax()
        self.resetBC()
        self.setFocus()
        self.updateAllCanvas()

    #-----------------------------------------------------------------------------------------------
    # DEFAULT FUNCTION FOR KEY AND MOUSE PRESS ON WINDOW
    #-----------------------------------------------------------------------------------------------

    def keyPressEvent(self, event):
        
        # print(event.key())

        # change timepoint
        if event.key() == QtCore.Qt.Key_Right:
            self.changeSpaceTime( 'time', +1 )

        elif event.key() == QtCore.Qt.Key_Left:
            self.changeSpaceTime( 'time', -1 )

        # change slice
        elif event.key() == QtCore.Qt.Key_Up:
            self.changeSpaceTime( 'space', +1 )
            
        elif event.key() == QtCore.Qt.Key_Down:
            self.changeSpaceTime( 'space', -1 )

        # key press on cropped image
        if self.canvas1.underMouse():
            self.onKeyPressOnCanvas1(event)
            
        self.setFocus()

    def wheelEvent(self,event):
        if self.canvas1.underMouse():
            step = event.step
        else:          
            step = event.delta()/abs(event.delta())
        self.sl.setValue( self.sl.value() + step) 

    #-----------------------------------------------------------------------------------------------
    # ADDITIONAL FUNCTIONS FOR KEY AND MOUSE PRESS ON CANVASES
    #-----------------------------------------------------------------------------------------------

    def onKeyPressOnCanvas1(self, event):
        
        motherCells = [ QtCore.Qt.Key_1, QtCore.Qt.Key_4, QtCore.Qt.Key_B ]
        daughterCells = [ QtCore.Qt.Key_A, QtCore.Qt.Key_P ]

        # find the position of the cursor relative to the image in pixel
        imgshape = self.stacks[self.currentChannel][self.sl.value()].shape
        canshape = self.canvas1.size()
        cf = imgshape[0]/canshape.width()
        refpos = self.canvas1.mapFromGlobal(QtGui.QCursor.pos())
        refpos = np.array([ int( refpos.x() * cf ), int( refpos.y() * cf )])
        refpos = np.append(refpos,self.sl.value())

        ### find the closest cell to the cursor
        idx = closer_cell( refpos.astype( np.uint16 ), self.currentCells )

        ### assign the name to the cell
        if any( [ event.key() == cn for cn in motherCells ] ):
            # if labeling bckg, add the 1 or 2 to the name
            if self.currentCells.ix[ idx, 'cname' ] == 'b_':
                self.currentCells.ix[ idx, 'cname' ] += QtGui.QKeySequence(event.key()).toString().lower()
            else:
                # if not, rename the cell from scratch
                if event.key() == QtCore.Qt.Key_B:
                    self.currentCells.ix[ idx, 'cname' ] = QtGui.QKeySequence(event.key()).toString().lower() + '_'
                else:
                    self.currentCells.ix[ idx, 'cname' ] = QtGui.QKeySequence(event.key()).toString().lower() + '.'

        # add the anterior/posterior to the cell name
        elif any( [ event.key() == cp for cp in daughterCells ] ):
            # don't do it if labeling background (bckg doesn't have a/p!)
            if self.currentCells.ix[ idx, 'cname' ] == 'b_':
                return
            else:
                self.currentCells.ix[ idx, 'cname' ] += QtGui.QKeySequence(event.key()).toString().lower()
        
        # remove the last entry of the name with backspace                
        elif event.key() == QtCore.Qt.Key_Backspace:
            self.currentCells.ix[ idx, 'cname' ] = self.currentCells.ix[ idx, 'cname' ][:-1]

        self.updateCanvas1()
        self.setFocus()

    def onMouseClickOnCanvas1(self, event):

        refpos = np.array( [ event.xdata, event.ydata, self.sl.value() ] )  

        if event.button == 1:

            # create an empty cell in the currentCells df: the only entries are tidx, xyzpos and cname
            newcell = create_single_cell_pos( refpos.astype(np.uint16), self.tp.value() )
            self.currentCells = pd.concat( [ self.currentCells, newcell ] )
            
        elif event.button == 3:

            # remove a cell (the closest to the cursor at the moment of right-click)
            idx = closer_cell( refpos.astype(np.uint16), self.currentCells )
            self.currentCells = self.currentCells.drop( [ idx ] )

        self.currentCells = self.currentCells.reset_index(drop=True)
        
        self.updateCanvas1()
        self.setFocus()

    #-----------------------------------------------------------------------------------------------
    # UTILS
    #-----------------------------------------------------------------------------------------------

    def updateRadioBtn(self):
        if self.currentChannel == '488nm':
            self._488nmBtn.setChecked(True)
        elif self.currentChannel == '561nm':
            self._561nmBtn.setChecked(True)
        elif self.currentChannel == 'CoolLED':
            self.CoolLEDBtn.setChecked(True)
        self.setFocus()

    def setBCslidersMinMax(self):
        self.sld1.setMaximum(np.max(self.stacks[self.currentChannel]))
        self.sld1.setMinimum(np.min(self.stacks[self.currentChannel]))
        self.sld2.setMaximum(np.max(self.stacks[self.currentChannel]))
        self.sld2.setMinimum(np.min(self.stacks[self.currentChannel]))

    def resetBC(self):
        self.sld1.setValue(np.min(self.stacks[self.currentChannel]))
        self.sld2.setValue(np.max(self.stacks[self.currentChannel]))
        
    def updateCanvas1(self):

        self.fig1.clf()
        self.fig1.subplots_adjust(left=0., right=1., top=1., bottom=0.)
        self.ax1 = self.fig1.add_subplot(111)
        self.canvas1.draw()

        if len( self.stacks.keys() ) == 0:
            # if no images are found, leave the canvas empty
            return

        # plot the image
        self.ax1.cla()
        imgplot = self.ax1.imshow( self.stacks[self.currentChannel][self.sl.value()], cmap = 'gray' )
        
        # remove the white borders and plot outline and spline
        self.ax1.autoscale(False)
        self.ax1.axis('Off')
        self.fig1.subplots_adjust(left=0., right=1., top=1., bottom=0.)

        # cell text on the image
        for idx, cell in self.currentCells.iterrows():

            if cell.Z == self.sl.value():

                self.ax1.text( cell.X, cell.Y + 18, cell.cname, color='red', size='medium', alpha=.8,
                        rotation=0 )
                self.ax1.plot( cell.X, cell.Y, 'o', color='red', alpha = .8, mew = 0 )

        # change brightness and contrast
        self.sld1.setValue(np.min([self.sld1.value(),self.sld2.value()]))
        self.sld2.setValue(np.max([self.sld1.value(),self.sld2.value()]))
        imgplot.set_clim(self.sld1.value(), self.sld2.value())  

        # redraw the canvas
        self.canvas1.draw()
        self.setFocus()

    def updateCanvas2(self):
        
        # plot the image
        self.ax2.cla()
        imgplot = self.ax2.imshow( self.LEDmovie[ self.tp.value() + self.hatchingtidx ], cmap = 'gray' )
        
        # remove the white borders and plot outline and spline
        self.ax2.autoscale(False)
        self.ax2.axis('Off')
        self.fig2.subplots_adjust(left=0., right=1., top=1., bottom=0.)

        # print gonad position
        gonadPos = extract_pos( self.gpDF.ix[ self.gpDF.tidx == self.tp.value() ].squeeze() ) / self.compression
        self.ax2.plot( gonadPos[0], gonadPos[1], 'o', color='red', ms=10, mew=0, alpha=.5, lw = 0 )      

        # print time
        # print(self.timesDF.ix[ self.timesDF.tidxRel == self.tp.value(), 'timesRel' ])
        self.ax2.text( 5, 25, '%.2f' % self.timesDF.ix[ self.timesDF.tidxRel == self.tp.value(), 'timesRel' ].values[0], color = 'red' )     

        # redraw the canvas
        self.canvas2.draw()
        self.setFocus()

    def checkConsistencyCellNames( self ):
        ### check consistency of cell names
        tp = self.tp.value()

        # if no cells are labeled (currentCells df is empty), remove all labeled cells in the cellPosDF and return
        if len( self.currentCells ) == 0:
            newCellPosDF = update_cell_pos_DF( self.currentCells, self.cellPosDF, tp )
            correctCellNames = True

        if len( self.currentCells ) > 0:

            correctCellNames = check_cell_names( self.currentCells, self.cellNames )

            # if cells are not properly labeled, give a Warning
            if not correctCellNames:
                QtGui.QMessageBox.about(self,'Warning!','There is a mistake in the cell labels!')

            # else, update final cellPosDF and return OK
            else:
                newCellPosDF = update_cell_pos_DF( self.currentCells, self.cellPosDF, tp )
                self.cellPosDF = newCellPosDF

        return correctCellNames

    def changeSpaceTime(self, whatToChange, increment):


        if whatToChange == 'time':

            # before changinf timepoint, print labeled cells and check if they are OK
            print( self.currentCells )

            # if they are OK (and not going to negative times), change timepoint
            if self.checkConsistencyCellNames() and ( self.tp.value() + increment ) >= 0 :
                self.tp.setValue( self.tp.value() + increment )

        if whatToChange == 'space':
            self.sl.setValue( self.sl.value() + increment )
예제 #25
0
class TakanamiDialog(QtGui.QDialog):
    """A dialog to apply Takanami's AR picking method to a selected piece of a
    seismic signal.

    Attributes:
        document: Current opened document containing a seismic record.
        seismic_event: A seismic event to be refined by using Takanami method.
            If no event is provided, then a new seismic event will be created
            by using the estimated arrival time after clicking on 'Accept'
    """
    def __init__(self,
                 document,
                 t_start=None,
                 t_end=None,
                 seismic_event=None,
                 parent=None):
        super(TakanamiDialog, self).__init__(parent)

        self.document = document
        self.record = self.document.record

        self.load_settings()

        self.seismic_event = seismic_event
        self._start = t_start
        self._end = t_end

        if self.seismic_event is not None:
            self.event_time = self.seismic_event.time
            if self._start is None:
                self._start = max(0, self.event_time - self.default_margin)
            if self._end is None:
                self._end = min(
                    len(self.record.signal) - 1,
                    self.event_time + self.default_margin)
        else:
            if self._start is None or self._end is None:
                raise ValueError("t_start and t_end values not specified")
            else:
                self._start = max(0, int(t_start * self.record.fs))
                self._end = min(
                    len(self.record.signal) - 1, int(t_end * self.record.fs))
                self.event_time = self._start + int(
                    (self._end - self._start) / 2)

        if not 0 <= self._start < self._end:
            raise ValueError("Invalid t_start value")
        if not self._start < self._end < len(self.record.signal):
            raise ValueError("Invalid t_end value")
        if (self._end - self._start) < (MINIMUM_MARGIN_IN_SECS *
                                        self.record.fs):
            raise ValueError("Distance between t_start and t_end must be"
                             " at least of %g seconds" %
                             MINIMUM_MARGIN_IN_SECS)
        if not self._start < self.event_time < self._end:
            raise ValueError(
                "Event time must be a value between t-start and t_end")

        self._init_ui()

        self.button_box.accepted.connect(self.accept)
        self.button_box.rejected.connect(self.reject)
        self.button_box.clicked.connect(self.on_click)
        self.start_point_spinbox.timeChanged.connect(
            self.on_start_point_changed)
        self.end_point_spinbox.timeChanged.connect(self.on_end_point_changed)

    def _init_ui(self):
        self.setWindowTitle("Takanami's Autoregressive Method")
        self.fig, _ = plt.subplots(2, 1, sharex=True)
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setMinimumSize(self.canvas.size())
        self.canvas.setSizePolicy(
            QtGui.QSizePolicy(QtGui.QSizePolicy.Policy.Expanding,
                              QtGui.QSizePolicy.Policy.Expanding))
        self.toolBarNavigation = navigationtoolbar.NavigationToolBar(
            self.canvas, self)
        self.position_label = QtGui.QLabel(
            "Estimated Arrival Time: 00 h 00 m 00.000 s")
        self.group_box = QtGui.QGroupBox(self)
        self.group_box.setTitle("Limits")
        self.start_point_label = QtGui.QLabel("Start point:")
        self.start_point_label.setSizePolicy(
            QtGui.QSizePolicy(QtGui.QSizePolicy.Policy.Maximum,
                              QtGui.QSizePolicy.Policy.Preferred))
        self.start_point_spinbox = QtGui.QTimeEdit(self.group_box)
        self.start_point_spinbox.setDisplayFormat("hh 'h' mm 'm' ss.zzz 's'")
        self.end_point_label = QtGui.QLabel("End point:")
        self.end_point_label.setSizePolicy(
            QtGui.QSizePolicy(QtGui.QSizePolicy.Policy.Maximum,
                              QtGui.QSizePolicy.Policy.Preferred))
        self.end_point_spinbox = QtGui.QTimeEdit(self.group_box)
        self.end_point_spinbox.setDisplayFormat("hh 'h' mm 'm' ss.zzz 's'")
        self.group_box_layout = QtGui.QHBoxLayout(self.group_box)
        self.group_box_layout.setContentsMargins(9, 9, 9, 9)
        self.group_box_layout.setSpacing(12)
        self.group_box_layout.addWidget(self.start_point_label)
        self.group_box_layout.addWidget(self.start_point_spinbox)
        self.group_box_layout.addWidget(self.end_point_label)
        self.group_box_layout.addWidget(self.end_point_spinbox)
        self.button_box = QtGui.QDialogButtonBox(self)
        self.button_box.setOrientation(QtCore.Qt.Horizontal)
        self.button_box.setStandardButtons(QtGui.QDialogButtonBox.Apply
                                           | QtGui.QDialogButtonBox.Cancel
                                           | QtGui.QDialogButtonBox.Ok)
        self.layout = QtGui.QVBoxLayout(self)
        self.layout.setContentsMargins(9, 9, 9, 9)
        self.layout.setSpacing(6)
        self.layout.addWidget(self.toolBarNavigation)
        self.layout.addWidget(self.canvas)
        self.layout.addWidget(self.position_label)
        self.layout.addWidget(self.group_box)
        self.layout.addWidget(self.button_box)

        # set spinboxes's initial values and limits
        max_time_in_msecs = int(
            ((len(self.record.signal) - 1) * 1000) / self.record.fs)
        start_time_in_msecs = int((self._start * 1000.0) / self.record.fs)
        end_time_in_msecs = int((self._end * 1000.0) / self.record.fs)
        self.start_point_spinbox.setTime(
            QtCore.QTime().addMSecs(start_time_in_msecs))
        self.end_point_spinbox.setTime(
            QtCore.QTime().addMSecs(end_time_in_msecs))
        self.start_point_spinbox.setMinimumTime(QtCore.QTime().addMSecs(0))
        self.end_point_spinbox.setMinimumTime(
            QtCore.QTime().addMSecs(start_time_in_msecs +
                                    MINIMUM_MARGIN_IN_SECS * 1000))
        self.start_point_spinbox.setMaximumTime(
            QtCore.QTime().addMSecs(end_time_in_msecs -
                                    MINIMUM_MARGIN_IN_SECS * 1000))
        self.end_point_spinbox.setMaximumTime(
            QtCore.QTime().addMSecs(max_time_in_msecs))

    def on_click(self, button):
        if self.button_box.standardButton(button) == QtGui.QDialogButtonBox.Ok:
            self.save_event()
        if self.button_box.standardButton(
                button) == QtGui.QDialogButtonBox.Apply:
            self.do_takanami()

    def on_start_point_changed(self, value):
        time_in_msecs = QtCore.QTime().msecsTo(value)
        t_start = int(max(0, (time_in_msecs / 1000.0) * self.record.fs))
        if self._start != t_start:
            self._start = t_start
            self.end_point_spinbox.setMinimumTime(
                QtCore.QTime().addMSecs(time_in_msecs +
                                        MINIMUM_MARGIN_IN_SECS * 1000))

    def on_end_point_changed(self, value):
        time_in_msecs = QtCore.QTime().msecsTo(value)
        t_end = int(
            min(len(self.record.signal),
                ((time_in_msecs / 1000.0) * self.record.fs)))
        if self._end != t_end:
            self._end = t_end
            self.start_point_spinbox.setMaximumTime(
                QtCore.QTime().addMSecs(time_in_msecs -
                                        MINIMUM_MARGIN_IN_SECS * 1000))

    def on_position_estimated(self, time, aic, n0_aic):
        self.event_time = time
        time_in_msecs = QtCore.QTime().addMSecs(
            (self.event_time * 1000.0) / self.record.fs)
        self.position_label.setText(
            "Estimated Arrival Time: %s" %
            time_in_msecs.toString("hh 'h' mm 'm' ss.zzz 's'"))
        # Plot estimated arrival time
        m_event = rc.Event(self.record, time, aic=aic, n0_aic=n0_aic)
        m_event.plot_aic(show_envelope=True, num=self.fig.number)
        self.fig.canvas.draw_idle()

    def load_settings(self):
        """Loads settings from persistent storage."""
        settings = QtCore.QSettings(_organization, _application_name)
        settings.beginGroup("takanami_settings")
        self.default_margin = int(
            float(settings.value('takanami_margin', 5.0)) * self.record.fs)
        settings.endGroup()

    def save_event(self):
        """"""
        if self.seismic_event is not None:
            if self.seismic_event.time != self.event_time:
                self.document.editEvent(self.seismic_event,
                                        time=self.event_time,
                                        method=rc.method_takanami,
                                        mode=rc.mode_automatic,
                                        status=rc.status_reported)
        else:
            self.document.createEvent(self.event_time,
                                      method=rc.method_takanami,
                                      mode=rc.mode_automatic,
                                      status=rc.status_reported)

    def do_takanami(self):
        self._task = TakanamiTask(self.record, self._start, self._end)
        self._task.position_estimated.connect(self.on_position_estimated)
        self.wait_dialog = processingdialog.ProcessingDialog(
            label_text="Applying Takanami's AR method...")
        self.wait_dialog.setWindowTitle("Event detection")
        return self.wait_dialog.run(self._task)

    def exec_(self, *args, **kwargs):
        return_code = self.do_takanami()
        if return_code == QtGui.QDialog.Accepted:
            return QtGui.QDialog.exec_(self, *args, **kwargs)
예제 #26
0
class MatplotWidget(QWidget):
    """
        Class to plot data inside a QWidget
    """
    def __init__(self, parent=None, toolbar=False):
        """
        """
        super(MatplotWidget, self).__init__(parent)

        self.figure, self.axes = plt.subplots(nrows=1, ncols=1)
        self.canvas = FigureCanvasQTAgg(self.figure)

        self.figure.subplots_adjust(right=0.85)
        self.figure.subplots_adjust(left=0.1)
        self.figure.subplots_adjust(bottom=0.3)

        self.axes1 = self.axes.twinx()
        self.axes1.set_ylabel('quality')

        self.axes.locator_params(nbins=5)
        self.axes1.locator_params(nbins=5)

        self.vbox = QVBoxLayout(self)

        if toolbar:
            self.toolbar = NavigationToolbar(self.canvas, self)
            self.vbox.addWidget(self.toolbar)

        self.vbox.addWidget(self.canvas)

    def set_data(self, data, qi=False, min_size=False):
        """
            draw data to canvas

        Args:
            data (sensor) : sensor containing data
            qi (bool): if true plot quality
            min_size (bool): force to set min size to chart
        """

        self.figure.suptitle(data.name, fontsize=12)
        self.axes.set_ylabel(data.unit, fontsize=12)
        self.axes.set_xlabel('')

        ax = data.plot(quality=qi, axis=self.axes, qaxis=self.axes1)

        n = 5
        ticks = ax.xaxis.get_ticklocs()
        ticklabels = [l.get_text() for l in ax.xaxis.get_ticklabels()]
        ax.xaxis.set_ticks(ticks[::n])
        ax.xaxis.set_ticklabels(ticklabels[::n])

        if min_size:
            size = self.canvas.size()
            size.setHeight(size.height() / 2)

            self.canvas.setMinimumSize(size)

    def set_multiple_data(self, data, qi=False):
        """
            Plot multiple data source to chart

        Args:
            data (list): list of sensor to plot
            qi (bool): if true plot quality
        """

        colors = ['b', 'g', 'm', 'lime', 'orange', 'gray', 'salmon', 'tomato']

        ax = None
        labels = []
        for idx, evt in enumerate(data):
            if len(evt.ts) == 0:
                continue
            color = colors[idx % len(colors)]
            ax = evt.plot(quality=qi,
                          data_color=color,
                          axis=self.axes,
                          qaxis=self.axes1)
            labels.append(evt.name)

        lines, _ = ax.get_legend_handles_labels()

        ax.legend(lines, labels, loc='best')

        plt.legend(loc="upper left",
                   bbox_to_anchor=[0, 1],
                   ncol=2,
                   shadow=True,
                   title="Legend",
                   fancybox=True)

        if not ax:
            n = 5
            ticks = ax.xaxis.get_ticklocs()
            ticklabels = [l.get_text() for l in ax.xaxis.get_ticklabels()]
            ax.xaxis.set_ticks(ticks[::n])
            ax.xaxis.set_ticklabels(ticklabels[::n])
예제 #27
0
def plot_file(fps, base_dir, string_graph_map):
    app = QtGui.QApplication('Bodysim')
    graph_map = ast.literal_eval(string_graph_map)

    # Find the length of the simulation by looking at trajectory results.
    start_frame = 1
    count = 0
    with open(base_dir + os.sep + 'Trajectory' + os.sep + graph_map.keys()[0] +
              '.csv') as f:
        iterF = iter(f)
        # Skip header
        next(iterF)
        line = next(iterF)
        start_frame = float(line.split(',')[0])
        count = sum(1 for line in iterF)

    frame = MainWindow(start_frame, count)

    for sensor in graph_map:
        layout_contents = frame.add_tab(sensor)
        for plugin in graph_map[sensor]:
            data = get_data(base_dir + os.sep + plugin + os.sep + sensor +
                            '.csv')
            for variable_group in graph_map[sensor][plugin]:
                qfigWidget = QtGui.QWidget(layout_contents[1])
                fig = Figure((5.0, 4.0), dpi=100)
                canvas = FigureCanvas(fig)
                canvas.setParent(qfigWidget)
                toolbar = NavigationToolbar(canvas, qfigWidget)
                axes = fig.add_subplot(111)
                axes.set_title(plugin + ' ' + variable_group[2])
                yDatum = [
                    data[variable[1]]
                    for variable in graph_map[sensor][plugin][variable_group]
                ]
                yLabels = [
                    variable[0]
                    for variable in graph_map[sensor][plugin][variable_group]
                ]
                for i in range(len(yDatum)):
                    axes.plot(data[0], yDatum[i], label=yLabels[i])
                axes.grid(True)
                axes.legend()
                axes.autoscale(enable=False, axis='both')
                axes.set_xlabel(variable_group[0])
                axes.set_ylabel(variable_group[1])

                # Place plot components in a layout
                plotLayout = QtGui.QVBoxLayout()
                plotLayout.addWidget(canvas)
                plotLayout.addWidget(toolbar)
                qfigWidget.setLayout(plotLayout)
                frame.toolbars[fig] = toolbar
                frame.plots.append(axes)

                canvas.setMinimumSize(canvas.size())
                frame.bind_to_onclick_event(fig)
                layout_contents[0].addWidget(qfigWidget)

    frame.show()
    sys.exit(app.exec_())
예제 #28
0
class TakanamiDialog(QtGui.QDialog):
    """A dialog to apply Takanami's AR picking method to a selected piece of a
    seismic signal.

    Attributes:
        document: Current opened document containing a seismic record.
        seismic_event: A seismic event to be refined by using Takanami method.
            If no event is provided, then a new seismic event will be created
            by using the estimated arrival time after clicking on 'Accept'
    """

    def __init__(self, document, t_start=None, t_end=None, seismic_event=None, parent=None):
        super(TakanamiDialog, self).__init__(parent)

        self.document = document
        self.record = self.document.record

        self.load_settings()

        self.seismic_event = seismic_event
        self._start = t_start
        self._end = t_end

        if self.seismic_event is not None:
            self.event_time = self.seismic_event.stime
            if self._start is None:
                self._start = max(0, self.event_time - self.default_margin)
            if self._end is None:
                self._end = min(len(self.record.signal) - 1, self.event_time + self.default_margin)
        else:
            if self._start is None or self._end is None:
                raise ValueError("t_start and t_end values not specified")
            else:
                self._start = max(0, int(t_start * self.record.fs))
                self._end = min(len(self.record.signal) - 1, int(t_end * self.record.fs))
                self.event_time = self._start + int((self._end - self._start) / 2)

        if not 0 <= self._start < self._end:
            raise ValueError("Invalid t_start value")
        if not self._start < self._end < len(self.record.signal):
            raise ValueError("Invalid t_end value")
        if (self._end - self._start) < (MINIMUM_MARGIN_IN_SECS * self.record.fs):
            raise ValueError("Distance between t_start and t_end must be"
                             " at least of %g seconds" % MINIMUM_MARGIN_IN_SECS)
        if not self._start < self.event_time < self._end:
            raise ValueError("Event time must be a value between t-start and t_end")

        self._init_ui()

        self.button_box.accepted.connect(self.accept)
        self.button_box.rejected.connect(self.reject)
        self.button_box.clicked.connect(self.on_click)
        self.start_point_spinbox.timeChanged.connect(self.on_start_point_changed)
        self.end_point_spinbox.timeChanged.connect(self.on_end_point_changed)

    def _init_ui(self):
        self.setWindowTitle("Takanami's Autoregressive Method")
        self.fig, _ = plt.subplots(2, 1, sharex=True)
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setMinimumSize(self.canvas.size())
        self.canvas.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Policy.Expanding,
                                                    QtGui.QSizePolicy.Policy.Expanding))
        self.toolBarNavigation = navigationtoolbar.NavigationToolBar(self.canvas, self)
        self.position_label = QtGui.QLabel("Estimated Arrival Time: 00 h 00 m 00.000 s")
        self.group_box = QtGui.QGroupBox(self)
        self.group_box.setTitle("Limits")
        self.start_point_label = QtGui.QLabel("Start point:")
        self.start_point_label.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Policy.Maximum,
                                                               QtGui.QSizePolicy.Policy.Preferred))
        self.start_point_spinbox = QtGui.QTimeEdit(self.group_box)
        self.start_point_spinbox.setDisplayFormat("hh 'h' mm 'm' ss.zzz 's'")
        self.end_point_label = QtGui.QLabel("End point:")
        self.end_point_label.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Policy.Maximum,
                                                               QtGui.QSizePolicy.Policy.Preferred))
        self.end_point_spinbox = QtGui.QTimeEdit(self.group_box)
        self.end_point_spinbox.setDisplayFormat("hh 'h' mm 'm' ss.zzz 's'")
        self.group_box_layout = QtGui.QHBoxLayout(self.group_box)
        self.group_box_layout.setContentsMargins(9, 9, 9, 9)
        self.group_box_layout.setSpacing(12)
        self.group_box_layout.addWidget(self.start_point_label)
        self.group_box_layout.addWidget(self.start_point_spinbox)
        self.group_box_layout.addWidget(self.end_point_label)
        self.group_box_layout.addWidget(self.end_point_spinbox)
        self.button_box = QtGui.QDialogButtonBox(self)
        self.button_box.setOrientation(QtCore.Qt.Horizontal)
        self.button_box.setStandardButtons(QtGui.QDialogButtonBox.Apply |
                                           QtGui.QDialogButtonBox.Cancel |
                                           QtGui.QDialogButtonBox.Ok)
        self.layout = QtGui.QVBoxLayout(self)
        self.layout.setContentsMargins(9, 9, 9, 9)
        self.layout.setSpacing(6)
        self.layout.addWidget(self.toolBarNavigation)
        self.layout.addWidget(self.canvas)
        self.layout.addWidget(self.position_label)
        self.layout.addWidget(self.group_box)
        self.layout.addWidget(self.button_box)

        # set spinboxes's initial values and limits
        max_time_in_msecs = int(((len(self.record.signal) - 1) * 1000) / self.record.fs)
        start_time_in_msecs = int((self._start * 1000.0) / self.record.fs)
        end_time_in_msecs = int((self._end * 1000.0) / self.record.fs)
        self.start_point_spinbox.setTime(QtCore.QTime().addMSecs(start_time_in_msecs))
        self.end_point_spinbox.setTime(QtCore.QTime().addMSecs(end_time_in_msecs))
        self.start_point_spinbox.setMinimumTime(QtCore.QTime().addMSecs(0))
        self.end_point_spinbox.setMinimumTime(QtCore.QTime().addMSecs(start_time_in_msecs + MINIMUM_MARGIN_IN_SECS * 1000))
        self.start_point_spinbox.setMaximumTime(QtCore.QTime().addMSecs(end_time_in_msecs - MINIMUM_MARGIN_IN_SECS * 1000))
        self.end_point_spinbox.setMaximumTime(QtCore.QTime().addMSecs(max_time_in_msecs))

    def on_click(self, button):
        if self.button_box.standardButton(button) == QtGui.QDialogButtonBox.Ok:
            self.save_event()
        if self.button_box.standardButton(button) == QtGui.QDialogButtonBox.Apply:
            self.do_takanami()

    def on_start_point_changed(self, value):
        time_in_msecs = QtCore.QTime().msecsTo(value)
        t_start = int(max(0, (time_in_msecs / 1000.0) *
                          self.record.fs))
        if self._start != t_start:
            self._start = t_start
            self.end_point_spinbox.setMinimumTime(QtCore.QTime().
                                                  addMSecs(time_in_msecs + MINIMUM_MARGIN_IN_SECS * 1000))

    def on_end_point_changed(self, value):
        time_in_msecs = QtCore.QTime().msecsTo(value)
        t_end = int(min(len(self.record.signal),
                        ((time_in_msecs / 1000.0) *
                         self.record.fs)))
        if self._end != t_end:
            self._end = t_end
            self.start_point_spinbox.setMaximumTime(QtCore.QTime().
                                                    addMSecs(time_in_msecs - MINIMUM_MARGIN_IN_SECS * 1000))

    def on_position_estimated(self, time, aic, n0_aic):
        self.event_time = time
        time_in_secs = self.event_time / self.record.fs
        self.position_label.setText("Estimated Arrival Time: {}".format(
            clt.float_secs_2_string_date(time_in_secs, starttime=self.record.starttime)))
        # Plot estimated arrival time
        m_event = rc.ApasvoEvent(self.record, time, aic=aic, n0_aic=n0_aic)
        m_event.plot_aic(show_envelope=True, num=self.fig.number)
        self.fig.canvas.draw_idle()

    def load_settings(self):
        """Loads settings from persistent storage."""
        settings = QtCore.QSettings(_organization, _application_name)
        settings.beginGroup("takanami_settings")
        self.default_margin = int(float(settings.value('takanami_margin', 5.0)) *
                             self.record.fs)
        settings.endGroup()

    def save_event(self):
        """"""
        if self.seismic_event is not None:
            if self.seismic_event.stime != self.event_time:
                self.document.editEvent(self.seismic_event,
                                        stime=self.event_time,
                                        method=rc.method_takanami,
                                        evaluation_mode=rc.mode_automatic,
                                        evaluation_status=rc.status_preliminary)
        else:
            self.document.createEvent(self.event_time,
                                      method=rc.method_takanami,
                                      evaluation_mode=rc.mode_automatic,
                                      evaluation_status=rc.status_preliminary)

    def do_takanami(self):
        self._task = TakanamiTask(self.record, self._start, self._end)
        self._task.position_estimated.connect(self.on_position_estimated)
        self.wait_dialog = processingdialog.ProcessingDialog(label_text="Applying Takanami's AR method...")
        self.wait_dialog.setWindowTitle("Event detection")
        return self.wait_dialog.run(self._task)

    def exec_(self, *args, **kwargs):
        return_code = self.do_takanami()
        if return_code == QtGui.QDialog.Accepted:
            return QtGui.QDialog.exec_(self, *args, **kwargs)
예제 #29
0
qscrollLayout.setGeometry(QtCore.QRect(0, 0, 1000, 1000))

qscroll.setWidget(qscrollContents)
qscroll.setWidgetResizable(True)

for i in xrange(5):
  qfigWidget = QtGui.QWidget(qscrollContents)

  fig = Figure((5.0, 4.0), dpi=100)
  canvas = FigureCanvas(fig)
  canvas.setParent(qfigWidget)
  toolbar = NavigationToolbar(canvas, qfigWidget)
  axes = fig.add_subplot(111)
  axes.plot([1,2,3,4])

  # place plot components in a layout
  plotLayout = QtGui.QVBoxLayout()
  plotLayout.addWidget(canvas)
  plotLayout.addWidget(toolbar)
  qfigWidget.setLayout(plotLayout)

  # prevent the canvas to shrink beyond a point
  # original size looks like a good minimum size
  canvas.setMinimumSize(canvas.size())

  qscrollLayout.addWidget(qfigWidget)
qscrollContents.setLayout(qscrollLayout)

qwidget.show()
exit(qapp.exec_())