Beispiel #1
0
    def gui(self):
        self.gui_reset()
        framerate = pg.SpinBox()

        if hasattr(g.win, 'framerate'):
            framerate.setValue(g.win.framerate)
        elif 'framerate' in g.settings.d.keys():
            framerate.setValue(g.settings['framerate'])

        framerate.setRange(0, 1000000)
        framerate.setDecimals(10)

        show = CheckBox()
        show.setChecked(True)

        #windows
        self.window_button = WindowSelector()

        #self.exportFolder = FolderSelector('*.txt')
        self.items.append({
            'name': 'window',
            'string': 'Select Window',
            'object': self.window_button
        })
        self.items.append({
            'name': 'framerate',
            'string': 'Frame Rate (Hz)',
            'object': framerate
        })
        self.items.append({'name': 'show', 'string': 'Show', 'object': show})
        super().gui()
Beispiel #2
0
class BatchOptions(QtWidgets.QDialog):
    def __init__(self, parent=None):
        super(BatchOptions, self).__init__(parent)

        self.s = g.settings['volumeSlider']

        self.slicesPerVolume = self.s['slicesPerVolume']
        self.baselineValue = self.s['baselineValue']
        self.f0Start = self.s['f0Start']
        self.f0End = self.s['f0End']
        self.f0VolStart = self.s['f0VolStart']
        self.f0VolEnd = self.s['f0VolEnd']
        self.multiplicationFactor = self.s['multiplicationFactor']
        self.currentDataType = self.s['currentDataType']
        self.newDataType = self.s['newDataType']
        self.inputArrayOrder = self.s['inputArrayOrder']
        self.displayArrayOrder = self.s['displayArrayOrder'] = 16
        self.theta = self.s['theta']
        self.shiftFactor = self.s['shiftFactor']
        self.trim_last_frame = self.s['trimLastFrame']

        self.subtractBaseline = False
        self.runDFF0 = False
        self.runMultiplication = False

        self.inputDirectory = ''

        #window geometry
        self.left = 300
        self.top = 300
        self.width = 300
        self.height = 200

        #labels
        self.label_slicesPerVolume = QtWidgets.QLabel("slices per volume:")
        self.label_theta = QtWidgets.QLabel("theta:")
        self.label_baselineValue = QtWidgets.QLabel('baseline Value:')
        self.label_f0Start = QtWidgets.QLabel('f0 Start:')
        self.label_f0End = QtWidgets.QLabel('f0 End:')
        self.label_f0VolStart = QtWidgets.QLabel('f0Vol Start:')
        self.label_f0VolEnd = QtWidgets.QLabel('f0Vol End:')
        self.label_multiplicationFactor = QtWidgets.QLabel(
            'multiplication Factor:')
        self.label_shiftFactor = QtWidgets.QLabel('shift Factor:')
        self.label_trim_last_frame = QtWidgets.QLabel('trim Last Frame:')
        self.label_inputDirectory = QtWidgets.QLabel('input directory:')

        self.label_subtractBaseline = QtWidgets.QLabel('subtract baseline:')
        self.label_runDFF0 = QtWidgets.QLabel('run DF/F0:')
        self.label_runMultiplication = QtWidgets.QLabel(
            'scale by multiplication factor:')

        #spinboxes/comboboxes
        self.volBox = QtWidgets.QSpinBox()
        self.volBox.setRange(0, 10000)
        self.volBox.setValue(self.slicesPerVolume)

        self.thetaBox = QtWidgets.QSpinBox()
        self.thetaBox.setRange(0, 360)
        self.thetaBox.setValue(self.theta)

        self.baselineBox = QtWidgets.QSpinBox()
        self.baselineBox.setRange(0, 100000)
        self.baselineBox.setValue(self.baselineValue)

        self.f0StartBox = QtWidgets.QSpinBox()
        self.f0StartBox.setRange(0, 100000)
        self.f0StartBox.setValue(self.f0Start)

        self.f0EndBox = QtWidgets.QSpinBox()
        self.f0EndBox.setRange(0, 100000)
        self.f0EndBox.setValue(self.f0End)

        self.f0VolStartBox = QtWidgets.QSpinBox()
        self.f0VolStartBox.setRange(0, 100000)
        self.f0VolStartBox.setValue(self.f0VolStart)

        self.f0VolEndBox = QtWidgets.QSpinBox()
        self.f0VolEndBox.setRange(0, 100000)
        self.f0VolEndBox.setValue(self.f0VolEnd)

        self.multiplicationFactorBox = QtWidgets.QSpinBox()
        self.multiplicationFactorBox.setRange(0, 100000)
        self.multiplicationFactorBox.setValue(self.multiplicationFactor)

        self.shiftFactorBox = QtWidgets.QSpinBox()
        self.shiftFactorBox.setRange(0, 100000)
        self.shiftFactorBox.setValue(self.shiftFactor)

        self.trim_last_frame_checkbox = CheckBox()
        self.trim_last_frame_checkbox.setChecked(self.trim_last_frame)

        self.subtractBaseline_checkbox = CheckBox()
        self.subtractBaseline_checkbox.setChecked(self.subtractBaseline)

        self.runDFF0_checkbox = CheckBox()
        self.runDFF0_checkbox.setChecked(self.runDFF0)

        self.runMultiplication_checkbox = CheckBox()
        self.runMultiplication_checkbox.setChecked(self.runMultiplication)

        self.inputDirectory_display = QtWidgets.QLabel(self.inputDirectory)

        #buttons
        self.button_setInputDirectory = QtWidgets.QPushButton("Set Folder")
        self.button_startBatch = QtWidgets.QPushButton("Go")

        #grid layout
        layout = QtWidgets.QGridLayout()
        layout.setSpacing(5)
        layout.addWidget(self.label_slicesPerVolume, 0, 0)
        layout.addWidget(self.volBox, 0, 1)
        layout.addWidget(self.label_theta, 1, 0)
        layout.addWidget(self.thetaBox, 1, 1)
        layout.addWidget(self.label_baselineValue, 2, 0)
        layout.addWidget(self.baselineBox, 2, 1)
        layout.addWidget(self.label_f0Start, 3, 0)
        layout.addWidget(self.f0StartBox, 3, 1)
        layout.addWidget(self.label_f0End, 4, 0)
        layout.addWidget(self.f0EndBox, 4, 1)
        layout.addWidget(self.label_f0VolStart, 5, 0)
        layout.addWidget(self.f0VolStartBox, 5, 1)
        layout.addWidget(self.label_f0VolEnd, 6, 0)
        layout.addWidget(self.f0VolEndBox, 6, 1)
        layout.addWidget(self.label_multiplicationFactor, 7, 0)
        layout.addWidget(self.multiplicationFactorBox, 7, 1)
        layout.addWidget(self.label_shiftFactor, 8, 0)
        layout.addWidget(self.shiftFactorBox, 8, 1)
        layout.addWidget(self.label_trim_last_frame, 9, 0)
        layout.addWidget(self.trim_last_frame_checkbox, 9, 1)

        layout.addWidget(self.label_subtractBaseline, 10, 0)
        layout.addWidget(self.subtractBaseline_checkbox, 10, 1)

        layout.addWidget(self.label_runDFF0, 11, 0)
        layout.addWidget(self.runDFF0_checkbox, 11, 1)
        layout.addWidget(self.label_runMultiplication, 12, 0)
        layout.addWidget(self.runMultiplication_checkbox, 12, 1)

        layout.addWidget(self.label_inputDirectory, 13, 0)
        layout.addWidget(self.inputDirectory_display, 13, 1)
        layout.addWidget(self.button_setInputDirectory, 13, 2)
        layout.addWidget(self.button_startBatch, 14, 2)

        self.setLayout(layout)
        self.setGeometry(self.left, self.top, self.width, self.height)

        #add window title
        self.setWindowTitle("Batch Options")

        #connect spinboxes/comboboxes
        self.volBox.valueChanged.connect(self.set_slicesPerVolume)
        self.thetaBox.valueChanged.connect(self.set_theta)
        self.baselineBox.valueChanged.connect(self.set_baselineValue)
        self.f0StartBox.valueChanged.connect(self.set_f0Start)
        self.f0EndBox.valueChanged.connect(self.set_f0End)
        self.f0VolStartBox.valueChanged.connect(self.set_f0VolStart)
        self.f0VolEndBox.valueChanged.connect(self.set_f0VolEnd)
        self.multiplicationFactorBox.valueChanged.connect(
            self.set_multiplicationFactor)
        self.shiftFactorBox.valueChanged.connect(self.set_shiftFactor)
        self.trim_last_frame_checkbox.stateChanged.connect(
            self.set_trim_last_frame)
        self.subtractBaseline_checkbox.stateChanged.connect(
            self.set_subtractBaseline)
        self.runDFF0_checkbox.stateChanged.connect(self.set_runDFF0)
        self.runMultiplication_checkbox.stateChanged.connect(
            self.set_runMultiplication)
        self.button_setInputDirectory.pressed.connect(
            lambda: self.setInput_button())
        self.button_startBatch.pressed.connect(lambda: self.start_button())
        return

    def set_slicesPerVolume(self, value):
        self.slicesPerVolume = value

    def set_baselineValue(self, value):
        self.baselineValue = value

    def set_f0Start(self, value):
        self.f0Start = value

    def set_f0End(self, value):
        self.f0End = value

    def set_f0VolStart(self, value):
        self.f0VolStart = value

    def set_f0VolEnd(self, value):
        self.f0VolEnd = value

    def set_multiplicationFactor(self, value):
        self.multiplicationFactor = value

    def set_theta(self, value):
        self.theta = value

    def set_shiftFactor(self, value):
        self.shiftFactor = value

    def set_trim_last_frame(self):
        self.trim_last_frame = self.trim_last_frame_checkbox.isChecked()

    def set_subtractBaseline(self):
        self.subtractBaseline = self.subtractBaseline_checkbox.isChecked()

    def set_runDFF0(self):
        self.runDFF0 = self.runDFF0_checkbox.isChecked()

    def set_runMultiplication(self):
        self.runMultiplication = self.runMultiplication_checkbox.isChecked()

    def setInput_button(self):
        self.inputDirectory = QtWidgets.QFileDialog.getExistingDirectory()
        self.inputDirectory_display.setText(
            '...\\' + os.path.basename(self.inputDirectory))
        return

    def start_button(self):
        paramDict = {
            'slicesPerVolume': self.slicesPerVolume,
            'theta': self.theta,
            'baselineValue': self.baselineValue,
            'f0Start': self.f0Start,
            'f0End': self.f0End,
            'f0VolStart': self.f0VolStart,
            'f0VolEnd': self.f0VolEnd,
            'multiplicationFactor': self.multiplicationFactor,
            'shiftFactor': self.shiftFactor,
            'trim_last_frame': self.trim_last_frame,
            'inputDirectory': self.inputDirectory,
            'subtractBaseline': self.subtractBaseline,
            'runDFF0': self.runDFF0,
            'runMultiplication': self.runMultiplication
        }

        self.hide()
        camVolumeSlider.batchProcess(paramDict)
        return

    def start(self):
        self.show()
class Volume_Viewer(QtWidgets.QWidget):
    closeSignal = QtCore.Signal()

    def show_wo_focus(self):
        self.show()
        self.window.activateWindow()  # for Windows
        self.window.raise_()  # for MacOS

    def __init__(self, window=None, parent=None):
        super(Volume_Viewer,
              self).__init__(parent)  # Create window with ImageView widget
        g.m.volume_viewer = self
        window.lostFocusSignal.connect(self.hide)
        window.gainedFocusSignal.connect(self.show_wo_focus)
        self.window = window
        self.setWindowTitle('Light Sheet Volume View Controller')
        self.setWindowIcon(QtGui.QIcon(image_path('favicon.png')))
        self.setGeometry(QtCore.QRect(422, 35, 222, 86))
        self.layout = QtWidgets.QVBoxLayout()
        self.vol_shape = window.volume.shape
        mv, mz, mx, my = window.volume.shape
        self.currentAxisOrder = [0, 1, 2, 3]
        self.current_v_Index = 0
        self.current_z_Index = 0
        self.current_x_Index = 0
        self.current_y_Index = 0
        self.formlayout = QtWidgets.QFormLayout()
        self.formlayout.setLabelAlignment(QtCore.Qt.AlignRight)
        self.xzy_position_label = QtWidgets.QLabel('Z position')
        self.zSlider = SliderLabel(0)
        self.zSlider.setRange(0, mz - 1)
        self.zSlider.label.valueChanged.connect(self.zSlider_updated)
        self.zSlider.slider.mouseReleaseEvent = self.zSlider_release_event

        self.sideViewOn = CheckBox()
        self.sideViewOn.setChecked(False)
        self.sideViewOn.stateChanged.connect(self.sideViewOnClicked)

        self.sideViewSide = QtWidgets.QComboBox(self)
        self.sideViewSide.addItem("X")
        self.sideViewSide.addItem("Y")

        self.MaxProjButton = QtWidgets.QPushButton('Max Intenstiy Projection')
        self.MaxProjButton.pressed.connect(self.make_maxintensity)

        self.exportVolButton = QtWidgets.QPushButton('Export Volume')
        self.exportVolButton.pressed.connect(self.export_volume)

        self.formlayout.addRow(self.xzy_position_label, self.zSlider)
        self.formlayout.addRow('Side View On', self.sideViewOn)
        self.formlayout.addRow('Side View Side', self.sideViewSide)
        self.formlayout.addRow('', self.MaxProjButton)
        self.formlayout.addRow('', self.exportVolButton)

        self.layout.addWidget(self.zSlider)
        self.layout.addLayout(self.formlayout)
        self.setLayout(self.layout)
        self.setGeometry(QtCore.QRect(381, 43, 416, 110))
        self.show()

    def closeEvent(self, event):
        event.accept()  # let the window close

    def zSlider_updated(self, z_val):
        self.current_v_Index = self.window.currentIndex
        vol = self.window.volume
        testimage = np.squeeze(vol[self.current_v_Index, z_val, :, :])
        viewRect = self.window.imageview.view.targetRect()
        self.window.imageview.setImage(testimage, autoLevels=False)
        self.window.imageview.view.setRange(viewRect, padding=0)
        self.window.image = testimage

    def zSlider_release_event(self, ev):
        vol = self.window.volume
        if self.currentAxisOrder[1] == 1:  # 'z'
            self.current_z_Index = self.zSlider.value()
            image = np.squeeze(vol[:, self.current_z_Index, :, :])
        elif self.currentAxisOrder[1] == 2:  # 'x'
            self.current_x_Index = self.zSlider.value()
            image = np.squeeze(vol[:, self.current_x_Index, :, :])
        elif self.currentAxisOrder[1] == 3:  # 'y'
            self.current_y_Index = self.zSlider.value()
            image = np.squeeze(vol[:, self.current_y_Index, :, :])

        viewRect = self.window.imageview.view.viewRect()
        self.window.imageview.setImage(image, autoLevels=False)
        self.window.imageview.view.setRange(viewRect, padding=0)
        self.window.image = image
        if self.window.imageview.axes['t'] is not None:
            self.window.imageview.setCurrentIndex(self.current_v_Index)
        self.window.activateWindow()  # for Windows
        self.window.raise_()  # for MacOS
        QtWidgets.QSlider.mouseReleaseEvent(self.zSlider.slider, ev)

    def sideViewOnClicked(self, checked):
        self.current_v_Index = self.window.currentIndex
        vol = self.window.volume
        if checked == 2:  #checked=True
            assert self.currentAxisOrder == [0, 1, 2, 3]
            side = self.sideViewSide.currentText()
            if side == 'X':
                vol = vol.swapaxes(1, 2)
                self.currentAxisOrder = [0, 2, 1, 3]
                vol = vol.swapaxes(2, 3)
                self.currentAxisOrder = [0, 2, 3, 1]
            elif side == 'Y':
                vol = vol.swapaxes(1, 3)
                self.currentAxisOrder = [0, 3, 2, 1]
        else:  #checked=False
            if self.currentAxisOrder == [0, 3, 2, 1]:
                vol = vol.swapaxes(1, 3)
                self.currentAxisOrder = [0, 1, 2, 3]
            elif self.currentAxisOrder == [0, 2, 3, 1]:
                vol = vol.swapaxes(2, 3)
                vol = vol.swapaxes(1, 2)
                self.currentAxisOrder = [0, 1, 2, 3]
        if self.currentAxisOrder[1] == 1:  # 'z'
            idx = self.current_z_Index
            self.xzy_position_label.setText('Z position')
            self.zSlider.setRange(0, self.vol_shape[1] - 1)
        elif self.currentAxisOrder[1] == 2:  # 'x'
            idx = self.current_x_Index
            self.xzy_position_label.setText('X position')
            self.zSlider.setRange(0, self.vol_shape[2] - 1)
        elif self.currentAxisOrder[1] == 3:  # 'y'
            idx = self.current_y_Index
            self.xzy_position_label.setText('Y position')
            self.zSlider.setRange(0, self.vol_shape[3] - 1)
        image = np.squeeze(vol[:, idx, :, :])
        self.window.imageview.setImage(image, autoLevels=False)
        self.window.volume = vol
        self.window.imageview.setCurrentIndex(self.current_v_Index)
        self.zSlider.setValue(idx)

    def make_maxintensity(self):
        vol = self.window.volume
        new_vol = np.max(vol, 1)
        if self.currentAxisOrder[1] == 1:  # 'z'
            name = 'Max Z projection'
        elif self.currentAxisOrder[1] == 2:  # 'x'
            name = 'Max X projection'
        elif self.currentAxisOrder[1] == 3:  # 'y'
            name = 'Max Y projection'
        Window(new_vol, name=name)

    def export_volume(self):
        vol = self.window.volume
        export_path = QtWidgets.QFileDialog.getExistingDirectory(
            g.m, "Select a parent folder to save into.", expanduser("~"),
            QtWidgets.QFileDialog.ShowDirsOnly)
        export_path = os.path.join(export_path, 'light_sheet_vols')
        i = 0
        while os.path.isdir(export_path + str(i)):
            i += 1
        export_path = export_path + str(i)
        os.mkdir(export_path)
        for v in np.arange(len(vol)):
            A = vol[v]
            filename = os.path.join(export_path, str(v) + '.tiff')
            if len(A.shape) == 3:
                A = np.transpose(
                    A, (0, 2,
                        1))  # This keeps the x and the y the same as in FIJI
            elif len(A.shape) == 2:
                A = np.transpose(A, (1, 0))
            tifffile.imsave(filename, A)
Beispiel #4
0
class PuffMapper(BaseProcess_noPriorWindow):
    """
    puff heat map generator
    ------------------
    
    input:      csv file with one or more time traces (columns) 
    
    variables:  
    
    analysis:   
    
    output:     
    """
    def __init__(self):
        if g.settings['puffMapper'] is None or 'yExpand' not in g.settings['puffMapper']:
            s = dict()            
            s['nFrames'] = 1000           
            s['startFrame'] = 0 
            s['sortedByMax'] = False             
            s['xBin'] = 0 
            s['yExpand'] = 0                  
            
            g.settings['puffMapper'] = s
                   
        BaseProcess_noPriorWindow.__init__(self)
            
        

    def __call__(self, nFrames, startFrame, sortedByMax, xBin, yExpand, keepSourceWindow=False):
        '''
        '''

        #currently not saving parameter changes on call
        g.settings['puffMapper']['nFrames'] = nFrames         
        g.settings['puffMapper']['startFrame'] = startFrame   
        g.settings['puffMapper']['sortedByMax'] = sortedByMax  
        g.settings['puffMapper']['xBin'] = xBin  
        g.settings['puffMapper']['yExpand'] = yExpand         
        
        g.m.statusBar().showMessage("Starting puff mapper...")
        return



    def closeEvent(self, event):
        self.clearPlots()
        BaseProcess_noPriorWindow.closeEvent(self, event)
        return

    def gui(self):      
        self.filename = ''          
        self.gui_reset()        
        s=g.settings['puffMapper']  
        
        #buttons      
        self.plotChart_button = QPushButton('Create Line plot')
        self.plotChart_button.pressed.connect(self.plotData)  
                
        self.generateHeatmap_button = QPushButton('Create Heatmap')        
        self.generateHeatmap_button.pressed.connect(self.createHeatmap)  

                         
        #checkbox
        self.sorted_checkbox = CheckBox()
        self.sorted_checkbox.setChecked(s['sortedByMax'])

        #comboboxes
        self.xFunc_Box = pg.ComboBox()
        xFuncs = {'mean':np.mean, 'max':np.max, 'median':np.median}
        self.xFunc_Box.setItems(xFuncs)

        
        #spinboxes
        #Frames
        self.startFrame_Box = pg.SpinBox(int=True, step=1)
        self.startFrame_Box.setMinimum(0)
        self.startFrame_Box.setMaximum(1000000)  
        self.startFrame_Box.setValue(s['startFrame'])            
                
        self.nFrames_Box = pg.SpinBox(int=True, step=1)
        self.nFrames_Box.setMinimum(0)
        self.nFrames_Box.setMaximum(1000000)  
        self.nFrames_Box.setValue(s['nFrames'])          

        self.xBin_Box = pg.SpinBox(int=True, step=2)
        self.xBin_Box.setMinimum(1)
        self.xBin_Box.setMaximum(10000)  
        self.xBin_Box.setValue(s['xBin'])   

        self.yExpand_Box = pg.SpinBox(int=True, step=1)
        self.yExpand_Box.setMinimum(1)
        self.yExpand_Box.setMaximum(1000)  
        self.yExpand_Box.setValue(s['yExpand'])   


        #export file selector
        self.getFile = FileSelector()
        
        #connections
        self.getFile.valueChanged.connect(self.loadData)
           
        #################################################################
        #self.exportFolder = FolderSelector('*.txt')
        #MEPPS
        self.items.append({'name': 'blank1 ', 'string': '-------------   Parameters    ---------------', 'object': None}) 
        self.items.append({'name': 'startFrame', 'string': 'Set start frame ', 'object': self.startFrame_Box})          
        self.items.append({'name': 'nFrames', 'string': 'Set number of frames ', 'object': self.nFrames_Box}) 
        self.items.append({'name': 'xBin', 'string': 'Set x-axis binning number ', 'object': self.xBin_Box})  
        self.items.append({'name': 'xBinType', 'string': 'Set x-axis bin function ', 'object': self.xFunc_Box})  
        self.items.append({'name': 'yExpand', 'string': 'Set y-axis expansion value ', 'object': self.yExpand_Box})          
        self.items.append({'name': 'sortedByMax', 'string': 'Sorted by maximum', 'object': self.sorted_checkbox})         
        self.items.append({'name': 'blank ', 'string': '-------------------------------------------', 'object': None})           
        
        self.items.append({'name': 'filepath ', 'string': '', 'object': self.getFile})              

        self.items.append({'name': 'heatmap', 'string': '', 'object': self.generateHeatmap_button })            
        self.items.append({'name': 'lineplot', 'string': '', 'object': self.plotChart_button }) 

        
        super().gui()
        ######################################################################
        return



    def loadData(self):
        self.filename = self.getFile.value()
        self.data = pd.read_csv(self.filename, header=None, skiprows=1, index_col = 0)
        
        #drop extra x columns
        self.data = self.data[self.data.columns[::2]] 
        #drop columns with na values
        self.data = self.data.dropna(axis=1, how='all')        
        #set column names by number
        nCols = len(self.data.columns)
        colNames = list(range(0,nCols))
        self.data.columns = colNames
        #copy df and make one sorted by intensity
        self.dataSorted = self.data.copy()
        self.dataSorted = self.dataSorted.iloc[:, self.dataSorted.max().sort_values(ascending=False).index]

        #set nFrames max
        nRows = len(self.data)
        self.nFrames_Box.setMaximum(nRows)  
        self.nFrames_Box.setValue(nRows)  

        print('-------------------------------------')
        print('Data loaded (first 5 rows displayed):')
        print(self.data.head())
        print('-------------------------------------')



    def plotData(self):
        ### plot test result
        self.data.plot()
        plt.show()
        g.m.statusBar().showMessage('scatter plot created') 
        print('scatter plot created')    
        return

    def createHeatmap(self):
        ### create heatmap image
        if self.sorted_checkbox.isChecked():
            try:
                mapData = self.dataSorted.to_numpy()
            except:
                mapData = self.dataSorted.values
        else:
            try:
                mapData = self.data.to_numpy()
            except:
                mapData = self.data.values              
            

        nRows,nCols = mapData.shape
        print('original data has: {} columns, {} rows'.format(nRows, nCols))
        start = self.startFrame_Box.value()
        end = self.startFrame_Box.value() + self.nFrames_Box.value()
        
        if end > nRows:
            end = nRows

        #crop data
        img = mapData[start:end]
        
        #x binning
        img = groupedAvg(img,block_size=(self.xBin_Box.value(),1),func=self.xFunc_Box.value())

        #y expansion
        img = np.repeat(img,self.yExpand_Box.value(),axis=1)
        print('y-axis expanded by {}'.format(self.yExpand_Box.value()))
        
        #get new img shape
        nRows_img,nCols_img = img.shape
        print('displayed image has: {} columns, {} rows'.format(nRows_img, nCols_img))
      
        self.heatmapImg = Window(img,name='puff map')
        print('puff map created')
        return

    
    def clearPlots(self):
        try:
            plt.close('all')  
        except:
            pass
        return
Beispiel #5
0
class Synapse3D_batch(QtWidgets.QDialog):
    def __init__(self, parent = None):
        super(Synapse3D_batch, self).__init__(parent)
        #add window title
        self.setWindowTitle("Volume Slider GUI")
        
        self.pathName = ''

        self.eps  = clusterAnalysis.eps
        self.min_samples = clusterAnalysis.min_samples
        self.maxDistance = clusterAnalysis.maxDistance
        self.unitPerPixel = clusterAnalysis.unitPerPixel
        #self.multiThreadingFlag = clusterAnalysis.multiThreadingFlag
        self.displayFlag = clusterAnalysis.displayFlag
        
        self.clusterType = '3D'
        
        #window geometry
        self.left = 300
        self.top = 300
        self.width = 300
        self.height = 200

        #labels
        self.clusterTitle = QtWidgets.QLabel("----- Cluster Parameters -----") 
        self.label_eps = QtWidgets.QLabel("max distance between points:") 
        self.label_minSamples = QtWidgets.QLabel("minimum number of points:") 
        self.label_maxDistance = QtWidgets.QLabel("max distance between clusters:") 
        self.label_clustertype = QtWidgets.QLabel("clustering type:")        
        self.displayTitle = QtWidgets.QLabel("----- Display Parameters -----") 
        self.label_unitPerPixel = QtWidgets.QLabel("nanometers/pixel:") 
        #self.label_centroidSymbolSize = QtWidgets.QLabel("centroid symbol size:")  
        
        self.analysisTitle = QtWidgets.QLabel("----- Cluster Analysis -----") 
        self.label_analysis = QtWidgets.QLabel("Clusters to analyse: ")

        self.displayTitle = QtWidgets.QLabel("----- Display -----") 
        self.label_display = QtWidgets.QLabel("Plot results: ")         
        
        #self.multiThreadTitle = QtWidgets.QLabel("----- Multi-Threading -----") 
        #self.label_multiThread = QtWidgets.QLabel("Multi-Threading On: ")        
        
        #self.label_displayPlot = QtWidgets.QLabel("show plot")         

        #spinboxes
        self.epsBox = QtWidgets.QSpinBox()
        self.epsBox.setRange(0,10000)
        self.epsBox.setValue(self.eps)
        self.minSampleBox = QtWidgets.QSpinBox()    
        self.minSampleBox.setRange(0,10000)
        self.minSampleBox.setValue(self.min_samples)
        self.maxDistanceBox = QtWidgets.QSpinBox()    
        self.maxDistanceBox.setRange(0,10000)
        self.maxDistanceBox.setValue(self.maxDistance)    
        self.unitPerPixelBox = QtWidgets.QSpinBox()    
        self.unitPerPixelBox.setRange(0,1000)
        self.unitPerPixelBox.setValue(self.unitPerPixel)  
        #self.centroidSymbolSizeBox = QtWidgets.QSpinBox()    
        #self.centroidSymbolSizeBox.setRange(0,1000)
        #self.centroidSymbolSizeBox.setValue(self.centroidSymbolSize)          

        #combobox
        #self.analysis_Box = QtWidgets.QComboBox()
        #self.analysis_Box.addItems(["All Clusters", "Paired Clusters"])
        self.clustertype_Box = QtWidgets.QComboBox()
        self.clustertype_Box.addItems(["2D", "3D"])
        self.clustertype_Box.setCurrentText(self.clusterType)
        self.clustertype_Box.currentIndexChanged.connect(self.clusterTypeChange)
        
        #tickbox
        self.display_checkbox = CheckBox()
        self.display_checkbox.setChecked(self.displayFlag)
        self.display_checkbox.stateChanged.connect(self.displayClicked)
        #self.multiThread_checkbox = CheckBox()
        #self.multiThread_checkbox.setChecked(self.multiThreadingFlag)
        #self.multiThread_checkbox.stateChanged.connect(self.multiThreadClicked)

        #buttons
        self.button_getFolder = QtWidgets.QPushButton("Set Folder")
        self.button_start = QtWidgets.QPushButton("Start Batch Analysis")
        
        #grid layout
        layout = QtWidgets.QGridLayout()
        layout.setSpacing(5)
        layout.addWidget(self.clusterTitle, 0, 0, 1, 2)        
        layout.addWidget(self.label_eps, 1, 0)
        layout.addWidget(self.epsBox, 1, 1)       
        layout.addWidget(self.label_minSamples, 2, 0)        
        layout.addWidget(self.minSampleBox, 2, 1)     
        layout.addWidget(self.label_maxDistance, 3, 0)        
        layout.addWidget(self.maxDistanceBox, 3, 1)
        layout.addWidget(self.displayTitle, 4, 0, 1, 2)          
        layout.addWidget(self.label_unitPerPixel, 5, 0)  
        layout.addWidget(self.unitPerPixelBox, 5, 1)         
        layout.addWidget(self.label_clustertype, 6, 0) 
        layout.addWidget(self.clustertype_Box, 6, 1)
        layout.addWidget(self.displayTitle, 7, 0, 1, 2) 
        layout.addWidget(self.label_display, 8, 0)        
        layout.addWidget(self.display_checkbox, 8, 1)         
        layout.addWidget(self.button_getFolder, 9, 0)          
        layout.addWidget(self.button_start, 10, 0)         
        
        #layout.addWidget(self.label_centroidSymbolSize, 6, 0)  
        #layout.addWidget(self.centroidSymbolSizeBox, 6, 1) 
        
        #layout.addWidget(self.analysisTitle, 8, 0, 1, 2)  
        #layout.addWidget(self.label_analysis, 9, 0)  
        #layout.addWidget(self.analysis_Box, 9, 1)     
        
        #layout.addWidget(self.multiThreadTitle, 10, 0, 1, 2)  
        #layout.addWidget(self.label_multiThread, 11, 0)  
        #layout.addWidget(self.multiThread_checkbox, 11, 1)  
        

        
        self.setLayout(layout)
        self.setGeometry(self.left, self.top, self.width, self.height)

        #add window title
        self.setWindowTitle("Clustering Options")

        #connect spinboxes
        self.epsBox.valueChanged.connect(self.epsValueChange)
        self.minSampleBox.valueChanged.connect(self.minSampleChange) 
        self.maxDistanceBox.valueChanged.connect(self.maxDistanceChange)    
        self.unitPerPixelBox.valueChanged.connect(self.unitPerPixelChange) 
        #self.centroidSymbolSizeBox.valueChanged.connect(self.centroidSymbolSizeChange)  
        #connect combobox
        #self.analysis_Box.setCurrentIndex(0)
        #self.analysis_Box.currentIndexChanged.connect(self.analysisChange)         

        #connect buttons
        self.button_getFolder.clicked.connect(self.getSavePath)
        self.button_start.clicked.connect(self.run)

        
    def epsValueChange(self,value):
        self.epsBox = value
        clusterAnalysis.eps = self.epsBox
        return
    
    def minSampleChange(self,value):
        self.min_samples = value
        clusterAnalysis.min_samples = self.min_samples 
        return
        
    def maxDistanceChange(self,value):
        self.maxDistance = value
        clusterAnalysis.maxDistance = self.maxDistance
        return

    def unitPerPixelChange(self,value):
        self.unitPerPixel = value
        clusterAnalysis.unitPerPixel = self.unitPerPixel
        return
 
    def clusterTypeChange(self):
        self.clusterType = self.clustertype_Box.currentText
        clusterAnalysis.clusterType = self.clusterType
    
#    def centroidSymbolSizeChange(self,value):
#        self.centroidSymbolSize = value
#        self.viewer.centroidSymbolSize = self.centroidSymbolSize
#        return   
    
#    def analysisChange(self):
#        self.viewer.clusterAnaysisSelection = self.analysis_Box.currentText()
#        return
    
#    def multiThreadClicked(self):
#        self.viewer.multiThreadingFlag = self.multiThread_checkbox.isChecked()
#        return

    def getSavePath(self): 
        folder = QtWidgets.QFileDialog.getExistingDirectory(g.m, "Select batch folder.", os.path.expanduser("~"), QtWidgets.QFileDialog.ShowDirsOnly)
        self.pathName = folder
        return

    def run(self):
        if not os.path.exists(os.path.join(self.pathName,'results')):
            os.makedirs(os.path.join(self.pathName,'results'))
        clusterAnalysis.runBatch(self.pathName)
        return

    def displayClicked(self):
        clusterAnalysis.displayFlag = self.display_checkbox.isChecked()
        self.displayFlag = clusterAnalysis.displayFlag
        return

    def start(self):
        self.show()
        return
Beispiel #6
0
class Form2(QtWidgets.QDialog):
    def __init__(self, viewerInstance, parent=None):
        super(Form2, self).__init__(parent)
        self.batch = False
        self.viewer = viewerInstance
        self.fileName = self.viewer.getFileName()
        #print('loaded: ',self.fileName)
        self.s = g.settings['volumeSlider']

        self.arraySavePath = self.viewer.savePath
        self.arrayImportPath = "None"

        #window geometry
        windowGeometry(self, left=300, top=300, height=600, width=400)

        self.slicesPerVolume = self.s['slicesPerVolume']

        self.slicesDeletedPerVolume = self.s['slicesDeletedPerVolume']

        self.baselineValue = self.s['baselineValue']
        self.f0Start = self.s['f0Start']
        self.f0End = self.s['f0End']
        self.f0VolStart = self.s['f0VolStart']
        self.f0VolEnd = self.s['f0VolEnd']
        self.multiplicationFactor = self.s['multiplicationFactor']
        self.currentDataType = self.s['currentDataType']
        self.newDataType = self.s['newDataType']
        self.inputArrayOrder = self.s['inputArrayOrder']
        self.displayArrayOrder = self.s['displayArrayOrder'] = 16
        self.theta = self.s['theta']
        self.shiftFactor = self.s['shiftFactor']
        self.trim_last_frame = self.s['trimLastFrame']

        #spinboxes
        self.spinLabel1 = QtWidgets.QLabel("Slice #")
        self.SpinBox1 = QtWidgets.QSpinBox()
        self.SpinBox1.setRange(0, self.viewer.getNFrames())
        self.SpinBox1.setValue(0)

        self.spinLabel2 = QtWidgets.QLabel("# of slices per volume: ")
        self.SpinBox2 = QtWidgets.QSpinBox()
        self.SpinBox2.setRange(0, self.viewer.getNFrames())
        if self.slicesPerVolume < self.viewer.getNFrames():
            self.SpinBox2.setValue(self.slicesPerVolume)
        else:
            self.SpinBox2.setValue(1)

        self.spinLabel13 = QtWidgets.QLabel("# of slices removed per volume: ")
        self.SpinBox13 = QtWidgets.QSpinBox()
        self.SpinBox13.setRange(0, self.viewer.getNFrames())
        if self.slicesDeletedPerVolume < self.viewer.getNFrames():
            self.SpinBox13.setValue(self.slicesDeletedPerVolume)
        else:
            self.SpinBox13.setValue(0)

        self.spinLabel4 = QtWidgets.QLabel("baseline value: ")
        self.SpinBox4 = QtWidgets.QSpinBox()
        self.SpinBox4.setRange(0, self.viewer.getMaxPixel())
        if self.baselineValue < self.viewer.getMaxPixel():
            self.SpinBox4.setValue(self.baselineValue)
        else:
            self.SpinBox4.setValue(0)

        self.spinLabel6 = QtWidgets.QLabel("F0 start volume: ")
        self.SpinBox6 = QtWidgets.QSpinBox()
        self.SpinBox6.setRange(0, self.viewer.getNVols())
        if self.f0Start < self.viewer.getNVols():
            self.SpinBox6.setValue(self.f0Start)
        else:
            self.SpinBox6.setValue(0)

        self.spinLabel7 = QtWidgets.QLabel("F0 end volume: ")
        self.SpinBox7 = QtWidgets.QSpinBox()
        self.SpinBox7.setRange(0, self.viewer.getNVols())
        if self.f0End < self.viewer.getNVols():
            self.SpinBox7.setValue(self.f0End)
        else:
            self.SpinBox7.setValue(0)

        self.spinLabel8 = QtWidgets.QLabel("factor to multiply by: ")
        self.SpinBox8 = QtWidgets.QSpinBox()
        self.SpinBox8.setRange(0, 10000)
        self.SpinBox8.setValue(self.multiplicationFactor)

        self.spinLabel9 = QtWidgets.QLabel("theta: ")
        self.SpinBox9 = QtWidgets.QSpinBox()
        self.SpinBox9.setRange(0, 360)
        self.SpinBox9.setValue(self.theta)

        self.spinLabel10 = QtWidgets.QLabel("shift factor: ")
        self.SpinBox10 = QtWidgets.QSpinBox()
        self.SpinBox10.setRange(0, 100)
        self.SpinBox10.setValue(self.shiftFactor)

        self.SpinBox11 = QtWidgets.QSpinBox()
        self.SpinBox11.setRange(0, self.viewer.getNVols())
        if self.f0Start < self.viewer.getNVols():
            self.SpinBox11.setValue(self.f0VolStart)
        else:
            self.SpinBox6.setValue(0)

        self.SpinBox12 = QtWidgets.QSpinBox()
        self.SpinBox12.setRange(0, self.viewer.getNVols())
        if self.f0End <= self.viewer.getNVols():
            self.SpinBox12.setValue(self.f0VolEnd)
        else:
            self.SpinBox12.setValue(self.viewer.getNVols())

        #sliders
        self.slider1 = QtWidgets.QSlider(QtCore.Qt.Horizontal)
        setSliderUp(self.slider1,
                    minimum=0,
                    maximum=self.viewer.getNFrames(),
                    tickInterval=1,
                    singleStep=1,
                    value=0)

        #ComboBox
        self.dTypeSelectorBox = QtWidgets.QComboBox()
        self.dTypeSelectorBox.addItems([
            "float16", "float32", "float64", "int8", "int16", "int32", "int64"
        ])
        self.inputArraySelectorBox = QtWidgets.QComboBox()
        self.inputArraySelectorBox.addItems(self.viewer.getArrayKeys())
        self.inputArraySelectorBox.setCurrentIndex(4)
        self.inputArraySelectorBox.currentIndexChanged.connect(
            self.inputArraySelectionChange)

        self.displayArraySelectorBox = QtWidgets.QComboBox()
        self.displayArraySelectorBox.addItems(self.viewer.getArrayKeys())
        self.displayArraySelectorBox.setCurrentIndex(18)
        self.displayArraySelectorBox.currentIndexChanged.connect(
            self.displayArraySelectionChange)

        #buttons
        self.button1 = QtWidgets.QPushButton("Autolevel")
        self.button2 = QtWidgets.QPushButton("Set Slices")
        #self.button3 = QtWidgets.QPushButton("Average Volumes")
        self.button4 = QtWidgets.QPushButton("subtract baseline")
        self.button5 = QtWidgets.QPushButton("run DF/F0")
        self.button6 = QtWidgets.QPushButton("export to Window")
        self.button7 = QtWidgets.QPushButton("set data Type")
        self.button8 = QtWidgets.QPushButton("multiply")
        self.button9 = QtWidgets.QPushButton("export to array")

        self.button12 = QtWidgets.QPushButton("open 3D viewer")
        self.button13 = QtWidgets.QPushButton("close 3D viewer")

        self.button14 = QtWidgets.QPushButton("load new file")

        self.button15 = QtWidgets.QPushButton("Set overlay to current volume")

        #labels
        self.ratioVolStartLabel = QtWidgets.QLabel("ratio start volume: ")
        self.ratioVolEndLabel = QtWidgets.QLabel("ratio End volume: ")
        self.volumeLabel = QtWidgets.QLabel("# of volumes: ")
        self.volumeText = QtWidgets.QLabel("  ")

        self.currentVolumeLabel = QtWidgets.QLabel("current volume: ")
        self.currentVolumeText = QtWidgets.QLabel("0")

        self.shapeLabel = QtWidgets.QLabel("array shape: ")
        self.shapeText = QtWidgets.QLabel(str(self.viewer.getArrayShape()))

        self.dataTypeLabel = QtWidgets.QLabel("current data type: ")
        self.dataTypeText = QtWidgets.QLabel(str(self.viewer.getDataType()))
        self.dataTypeChangeLabel = QtWidgets.QLabel("new data type: ")

        self.inputArrayLabel = QtWidgets.QLabel("input array order: ")
        self.displayArrayLabel = QtWidgets.QLabel("display array order: ")

        self.arraySavePathLabel = QtWidgets.QLabel(str(self.arraySavePath))

        self.trim_last_frameLabel = QtWidgets.QLabel("Trim Last Frame: ")
        self.trim_last_frame_checkbox = CheckBox()
        self.trim_last_frame_checkbox.setChecked(self.trim_last_frame)
        self.trim_last_frame_checkbox.stateChanged.connect(
            self.trim_last_frameClicked)

        self.fileNameLabel = QtWidgets.QLabel("file name: ")
        self.fileNameText = QtWidgets.QLabel(str(self.fileName))

        #grid layout
        layout = QtWidgets.QGridLayout()
        layout.setSpacing(10)

        layout.addWidget(self.spinLabel1, 1, 0)
        layout.addWidget(self.SpinBox1, 1, 1)

        layout.addWidget(self.slider1, 2, 0, 2, 5)

        layout.addWidget(self.spinLabel2, 4, 0)
        layout.addWidget(self.SpinBox2, 4, 1)
        layout.addWidget(self.button2, 4, 4)

        layout.addWidget(self.spinLabel13, 4, 2)
        layout.addWidget(self.SpinBox13, 4, 3)

        layout.addWidget(self.spinLabel4, 6, 0)
        layout.addWidget(self.SpinBox4, 6, 1)
        layout.addWidget(self.button4, 6, 2)

        layout.addWidget(self.spinLabel6, 7, 0)
        layout.addWidget(self.SpinBox6, 7, 1)
        layout.addWidget(self.spinLabel7, 7, 2)
        layout.addWidget(self.SpinBox7, 7, 3)
        layout.addWidget(self.button5, 7, 4)

        layout.addWidget(self.ratioVolStartLabel, 8, 0)
        layout.addWidget(self.SpinBox11, 8, 1)
        layout.addWidget(self.ratioVolEndLabel, 8, 2)
        layout.addWidget(self.SpinBox12, 8, 3)

        layout.addWidget(self.volumeLabel, 9, 0)
        layout.addWidget(self.volumeText, 9, 1)

        layout.addWidget(self.currentVolumeLabel, 9, 2)
        layout.addWidget(self.currentVolumeText, 9, 3)

        layout.addWidget(self.shapeLabel, 10, 0)
        layout.addWidget(self.shapeText, 10, 1)

        layout.addWidget(self.spinLabel8, 11, 0)
        layout.addWidget(self.SpinBox8, 11, 1)
        layout.addWidget(self.button8, 11, 2)

        layout.addWidget(self.button15, 12, 0)

        layout.addWidget(self.dataTypeLabel, 13, 0)
        layout.addWidget(self.dataTypeText, 13, 1)
        layout.addWidget(self.dataTypeChangeLabel, 13, 2)
        layout.addWidget(self.dTypeSelectorBox, 13, 3)
        layout.addWidget(self.button7, 13, 4)

        layout.addWidget(self.button6, 15, 0)
        layout.addWidget(self.button1, 15, 4)
        layout.addWidget(self.button6, 15, 0)
        layout.addWidget(self.button1, 15, 4)
        layout.addWidget(self.button9, 16, 0)

        layout.addWidget(self.arraySavePathLabel, 16, 1, 1, 4)

        layout.addWidget(self.spinLabel9, 18, 0)
        layout.addWidget(self.SpinBox9, 18, 1)

        layout.addWidget(self.spinLabel10, 19, 0)
        layout.addWidget(self.SpinBox10, 19, 1)
        layout.addWidget(self.trim_last_frameLabel, 20, 0)
        layout.addWidget(self.trim_last_frame_checkbox, 20, 1)

        layout.addWidget(self.inputArrayLabel, 21, 0)
        layout.addWidget(self.inputArraySelectorBox, 21, 1)

        layout.addWidget(self.displayArrayLabel, 21, 2)
        layout.addWidget(self.displayArraySelectorBox, 21, 3)

        layout.addWidget(self.button12, 22, 0)
        layout.addWidget(self.button13, 22, 1)
        layout.addWidget(self.button14, 22, 2)

        layout.addWidget(self.fileNameLabel, 23, 0)
        layout.addWidget(self.fileNameText, 23, 1, 1, 4)

        self.setLayout(layout)
        self.setGeometry(self.left, self.top, self.width, self.height)

        #add window title
        self.setWindowTitle("Volume Slider GUI")

        #connect sliders & spinboxes
        self.slider1.valueChanged.connect(self.slider1ValueChange)
        self.SpinBox1.valueChanged.connect(self.spinBox1ValueChange)
        self.SpinBox9.valueChanged.connect(self.setTheta)
        self.SpinBox10.valueChanged.connect(self.setShiftFactor)

        #connect buttons
        self.button1.clicked.connect(self.autoLevel)
        self.button2.clicked.connect(self.updateVolumeValue)
        #self.button3.clicked.connect(self.averageByVol)
        self.button4.clicked.connect(self.subtractBaseline)
        self.button5.clicked.connect(self.ratioDFF0)
        self.button6.clicked.connect(self.exportToWindow)
        self.button7.clicked.connect(self.dTypeSelectionChange)
        self.button8.clicked.connect(self.multiplyByFactor)
        self.button9.clicked.connect(self.exportArray)
        self.button12.clicked.connect(self.startViewer)
        self.button13.clicked.connect(self.closeViewer)
        self.button14.clicked.connect(lambda: self.loadNewFile(''))
        self.button15.clicked.connect(self.setOverlay)

        return

    #volume changes with slider & spinbox
    def loadNewFile(self, fileName):
        if self.batch == False:
            fileName = QtWidgets.QFileDialog.getOpenFileName(
                self, 'Open File', os.path.expanduser("~/Desktop"),
                'tiff files (*.tif *.tiff)')
            fileName = str(fileName[0])

        A, _, _ = openTiff(fileName)
        self.viewer.updateVolumeSlider(A)
        self.viewer.displayWindow.imageview.setImage(A)
        self.setFileName(fileName)
        self.viewer.setFileName(fileName)
        return

    def slider1ValueChange(self, value):
        self.SpinBox1.setValue(value)
        return

    def spinBox1ValueChange(self, value):
        self.slider1.setValue(value)
        self.viewer.updateDisplay_sliceNumberChange(value)
        return

    def autoLevel(self):
        self.viewer.displayWindow.imageview.autoLevels()
        return

    def updateVolumeValue(self):
        self.slicesPerVolume = self.SpinBox2.value()
        noVols = int(self.viewer.getNFrames() / self.slicesPerVolume)
        self.framesToDelete = self.SpinBox13.value()
        self.viewer.updateVolsandFramesPerVol(
            noVols, self.slicesPerVolume, framesToDelete=self.framesToDelete)
        self.volumeText.setText(str(noVols))

        self.viewer.updateDisplay_volumeSizeChange()
        self.shapeText.setText(str(self.viewer.getArrayShape()))

        if (self.slicesPerVolume) % 2 == 0:
            self.SpinBox1.setRange(
                0, self.slicesPerVolume - 1 -
                self.framesToDelete)  #if even, display the last volume
            self.slider1.setMaximum(self.slicesPerVolume - 1 -
                                    self.framesToDelete)
        else:
            self.SpinBox1.setRange(
                0, self.slicesPerVolume - 2 -
                self.framesToDelete)  #else, don't display the last volume
            self.slider1.setMaximum(self.slicesPerVolume - 2 -
                                    self.framesToDelete)

        self.updateVolSpinBoxes()
        return

    def updateVolSpinBoxes(self):
        rangeValue = self.viewer.getNVols() - 1
        #self.SpinBox3.setRange(0,self.viewer.getNVols())
        self.SpinBox6.setRange(0, rangeValue)
        self.SpinBox7.setRange(0, rangeValue)
        self.SpinBox11.setRange(0, rangeValue)
        self.SpinBox12.setRange(0, rangeValue)
        self.SpinBox12.setValue(rangeValue)
        return

    def getBaseline(self):
        return self.SpinBox4.value()

    def getF0(self):
        return self.SpinBox6.value(), self.SpinBox7.value(
        ), self.SpinBox11.value(), self.SpinBox12.value()

    def subtractBaseline(self):
        self.viewer.subtractBaseline()
        return

    def ratioDFF0(self):
        self.viewer.ratioDFF0()
        return

    def exportToWindow(self):
        self.viewer.savePath = self.arraySavePath
        self.viewer.exportToWindow()
        return

    def dTypeSelectionChange(self):
        self.viewer.setDType(self.dTypeSelectorBox.currentText())
        self.dataTypeText = QtWidgets.QLabel(str(self.viewer.getDataType()))
        return

    def multiplyByFactor(self):
        self.viewer.multiplyByFactor(self.SpinBox8.value())
        return

    def exportArray(self):
        if self.viewer.B == []:
            print('first set number of frames per volume')
            g.m.statusBar().showMessage(
                "first set number of frames per volume")
            return
        self.arraySavePath = QtWidgets.QFileDialog.getSaveFileName(
            self, 'Save File', self.arraySavePath, 'Numpy array (*.npy)')
        self.arraySavePath = str(self.arraySavePath[0])
        self.viewer.savePath = self.arraySavePath
        self.arraySavePathLabel.setText(self.arraySavePath)
        self.viewer.exportArray()
        return

    def startViewer(self):
        self.saveSettings()
        self.viewer.startViewer()
        return

    def setOverlay(self):
        self.viewer.setOverlay()

    def closeViewer(self):
        self.viewer.closeViewer()
        return

    def setTheta(self):
        self.theta = self.SpinBox9.value()

    def setShiftFactor(self):
        self.shiftFactor = self.SpinBox10.value()

    def trim_last_frameClicked(self):
        self.trim_last_frame = self.trim_last_frame_checkbox.isChecked()

    def inputArraySelectionChange(self, value):
        self.viewer.setInputArrayOrder(
            self.inputArraySelectorBox.currentText())
        return

    def displayArraySelectionChange(self, value):
        self.viewer.setDisplayArrayOrder(
            self.displayArraySelectorBox.currentText())
        return

    def saveSettings(self):
        self.s['theta'] = self.theta
        self.s['slicesPerVolume'] = self.slicesPerVolume
        self.s['slicesDeletedPerVolume'] = self.slicesDeletedPerVolume
        self.s['baselineValue'] = self.baselineValue
        self.s['f0Start'] = self.f0Start
        self.s['f0End'] = self.f0End
        self.s['multiplicationFactor'] = self.multiplicationFactor
        self.s['currentDataType'] = self.currentDataType
        self.s['newDataType'] = self.newDataType
        self.s['shiftFactor'] = self.shiftFactor
        self.s['trimLastFrame'] = self.trim_last_frame
        self.s['f0VolStart'] = self.f0VolStart
        self.s['f0VolEnd'] = self.f0VolEnd

        g.settings['volumeSlider'] = self.s

        return

    def setFileName(self, fileName):
        self.fileName = fileName
        self.fileNameText.setText(self.fileName)

    def getFileName(self):
        return self.fileName

    def close(self):
        self.saveSettings()
        self.viewer.closeViewer()
        self.viewer.displayWindow.close()
        self.viewer.dialogbox.destroy()
        self.viewer.end()
        self.closeAllWindows()
        gc.collect()
        return

    def clearData(self):
        self.viewer.A = []
        self.viewer.B = []
    def gui(self):
        self.gui_reset()
        #w=g.win
        w = self.w
        width_units = QtWidgets.QDoubleSpinBox()

        width_pixels = QtWidgets.QSpinBox()
        width_units.setRange(.001, 1000000)
        width_pixels.setRange(1, self.width)

        font_size = QtWidgets.QSpinBox()

        unit = ComboBox()
        unit.addItem('micro')
        unit.addItem('nano')
        unit.addItem('pixels')

        orientation = ComboBox()
        orientation.addItem('horizontal')
        orientation.addItem('vertical')

        color = ComboBox()
        color.addItem("White")
        color.addItem("Black")

        background = ComboBox()
        background.addItem('None')
        background.addItem('Black')
        background.addItem('White')

        location = ComboBox()
        location.addItem('Lower Right')
        location.addItem('Lower Left')
        location.addItem('Top Right')
        location.addItem('Top Left')

        show = CheckBox()
        show_label = CheckBox()

        if hasattr(
                w, 'scaleBarLabel'
        ) and w.scaleBarLabel is not None:  #if the scaleBarLabel already exists
            props = w.scaleBarLabel.flika_properties
            width_units.setValue(props['width_units'])
            width_pixels.setValue(props['width_pixels'])
            unit.setCurrentIndex(color.findText(props['unit']))
            orientation.setCurrentIndex(color.findText(props['orientation']))
            font_size.setValue(props['font_size'])
            color.setCurrentIndex(color.findText(props['color']))
            background.setCurrentIndex(background.findText(
                props['background']))
            location.setCurrentIndex(location.findText(props['location']))
        else:
            font_size.setValue(12)
            width_pixels.setValue(int(w.view.width() / 8))
            width_units.setValue(1)

        show.setChecked(True)
        show_label.setChecked(True)

        self.items.append({'name': 'unit', 'string': 'Units', 'object': unit})
        self.items.append({
            'name': 'width_units',
            'string': 'Width of bar in [Units]',
            'object': width_units
        })
        self.items.append({
            'name': 'width_pixels',
            'string': 'Width of bar in pixels',
            'object': width_pixels
        })
        self.items.append({
            'name': 'font_size',
            'string': 'Font size',
            'object': font_size
        })
        self.items.append({
            'name': 'color',
            'string': 'Color',
            'object': color
        })
        self.items.append({
            'name': 'background',
            'string': 'Background',
            'object': background
        })
        self.items.append({
            'name': 'location',
            'string': 'Location',
            'object': location
        })
        self.items.append({
            'name': 'orientation',
            'string': 'Orientation',
            'object': orientation
        })
        self.items.append({'name': 'show', 'string': 'Show', 'object': show})
        self.items.append({
            'name': 'show_label',
            'string': 'Show label',
            'object': show_label
        })

        super().gui()
        self.preview()
class FFT_Chunker(BaseProcess_noPriorWindow):
    """
    fft chunk analysis
    ------------------
    
    input:      csv file with one or more time traces (columns) 
    
    variables:  chunk_size and time_step (s)
    
    analysis:   trace broken into chunks using chunk_size
                FFT analysis on each chunk using scipy.fft -> FFT_chunk
                power reported as abs(FFT_chunk)
                frequency calculated using scipy.fftfreq(chunk.size, time_step)
    
    output:     saves seperate results csv file for each trace in folder of input file 
                each results file has power and frequency results for every chunk (columns)
    """
    def __init__(self):
        if g.settings['fft_Chunker'] is None or 'closeplots' not in g.settings[
                'fft_Chunker']:
            s = dict()
            # s['timestep'] = 1
            # s['chunkSize'] = 128
            # s['plot'] = True

            s['chunkSize'] = 128
            s['timestep'] = 1
            s['numFrames'] = None
            s['numChunks'] = None
            s['baseline_start'] = 0
            s['baseline_stop'] = 2
            s['puff1_start'] = 0
            s['puff1_stop'] = 0
            s['puff2_start'] = 0
            s['puff2_stop'] = 0
            s['puff3_start'] = 0
            s['puff3_stop'] = 0
            s['puff4_start'] = 0
            s['puff4_stop'] = 0
            s['filepath'] = None
            s['run'] = None
            s['plot'] = True
            s['closeplots'] = None

            g.settings['fft_Chunker'] = s

        BaseProcess_noPriorWindow.__init__(self)


#chunkSize , timestep , numFrames, numChunks, blank2, blank3, baseline_start , baseline_stop, puff1_start ,puff1_stop, puff2_start, puff2_stop, puff3_start , puff3_stop, puff4_start , puff4_stop, filepath , run, plot, closeplots

    def __call__(self):
        '''
        reset saved parameters
        '''

        #currently not saving parameter changes on call - using updateParms()
        self.clearPlots()
        self.updateParams()
        return

    def updateParams(self):
        g.settings['fft_Chunker']['chunkSize'] = self.chunkSize_Box.value()
        g.settings['fft_Chunker']['timestep'] = self.timestep_Box.value()
        # g.settings['fft_Chunker']['baseline_start'] = baseline_start
        # g.settings['fft_Chunker']['baseline_stop'] = baseline_stop
        # g.settings['fft_Chunker']['puff1_start'] = puff1_start
        # g.settings['fft_Chunker']['puff1_stop'] = puff1_stop
        # g.settings['fft_Chunker']['puff2_start'] = puff2_start
        # g.settings['fft_Chunker']['puff2_stop'] = puff2_stop
        # g.settings['fft_Chunker']['puff3_start'] = puff3_start
        # g.settings['fft_Chunker']['puff3_stop'] = puff3_stop
        # g.settings['fft_Chunker']['puff4_start'] = puff4_start
        # g.settings['fft_Chunker']['puff4_stop'] = puff4_stop
        # g.settings['fft_Chunker']['filepath'] = filepath
        g.settings['fft_Chunker']['plot'] = self.plot_checkbox.isChecked()

        return

    def closeEvent(self, event):
        self.clearPlots()
        BaseProcess_noPriorWindow.closeEvent(self, event)
        return

    def gui(self):

        self.filename = ''

        self.gui_reset()
        s = g.settings['fft_Chunker']

        #buttons
        self.runAnalysis_button = QPushButton('Run Analysis')
        self.runAnalysis_button.pressed.connect(self.runAnalysis)
        self.setSavename_button = QPushButton('Set SaveName')
        self.setSavename_button.pressed.connect(self.setSavename)

        self.closePlots_button = QPushButton('Close plots')
        self.closePlots_button.pressed.connect(self.clearPlots)

        #checkbox
        self.plot_checkbox = CheckBox()
        self.plot_checkbox.setChecked(s['plot'])

        #label
        self.numFrames_label = QLabel()
        self.numFrames_label.setText('No file selected')
        self.numChunks_label = QLabel()
        self.numChunks_label.setText('No file selected')
        self.savename_label = QLabel()
        self.savename_label.setText('')
        #self.setExportFolder_button = FolderSelector('*.csv')

        #spinboxes
        #MEPPS
        self.chunkSize_Box = pg.SpinBox(int=True, step=1)
        self.chunkSize_Box.setMinimum(0)
        self.chunkSize_Box.setMaximum(1000000)
        self.chunkSize_Box.setValue(s['chunkSize'])

        self.timestep_Box = pg.SpinBox(int=False, step=0.01)
        self.timestep_Box.setMinimum(0)
        self.timestep_Box.setMaximum(1000000)
        self.timestep_Box.setValue(s['timestep'])

        self.baseline_start = pg.SpinBox(int=True, step=1)
        self.baseline_start.setMinimum(1)
        self.baseline_start.setMaximum(1000000)
        self.baseline_start.setValue(1)

        self.baseline_stop = pg.SpinBox(int=True, step=1)
        self.baseline_stop.setMinimum(0)
        self.baseline_stop.setMaximum(1000000)
        self.baseline_stop.setValue(0)

        self.puff1_start = pg.SpinBox(int=True, step=1)
        self.puff1_start.setMinimum(1)
        self.puff1_start.setMaximum(1000000)
        self.puff1_start.setValue(1)

        self.puff1_stop = pg.SpinBox(int=True, step=1)
        self.puff1_stop.setMinimum(0)
        self.puff1_stop.setMaximum(1000000)
        self.puff1_stop.setValue(0)

        self.puff2_start = pg.SpinBox(int=True, step=1)
        self.puff2_start.setMinimum(1)
        self.puff2_start.setMaximum(1000000)
        self.puff2_start.setValue(1)

        self.puff2_stop = pg.SpinBox(int=True, step=1)
        self.puff2_stop.setMinimum(0)
        self.puff2_stop.setMaximum(1000000)
        self.puff2_stop.setValue(0)

        self.puff3_start = pg.SpinBox(int=True, step=1)
        self.puff3_start.setMinimum(1)
        self.puff3_start.setMaximum(1000000)
        self.puff3_start.setValue(1)

        self.puff3_stop = pg.SpinBox(int=True, step=1)
        self.puff3_stop.setMinimum(0)
        self.puff3_stop.setMaximum(1000000)
        self.puff3_stop.setValue(0)

        self.puff4_start = pg.SpinBox(int=True, step=1)
        self.puff4_start.setMinimum(1)
        self.puff4_start.setMaximum(1000000)
        self.puff4_start.setValue(1)

        self.puff4_stop = pg.SpinBox(int=True, step=1)
        self.puff4_stop.setMinimum(0)
        self.puff4_stop.setMaximum(1000000)
        self.puff4_stop.setValue(0)

        #export file selector
        self.getFile = FileSelector()

        #connections
        self.chunkSize_Box.valueChanged.connect(self.chunkSizeUpdate)
        self.getFile.valueChanged.connect(self.loadData)

        #################################################################
        #self.exportFolder = FolderSelector('*.txt')
        #MEPPS
        self.items.append({
            'name': 'blank1 ',
            'string': '-------------   Parameters    ---------------',
            'object': None
        })
        self.items.append({
            'name': 'chunksize ',
            'string': 'Set chunk size ',
            'object': self.chunkSize_Box
        })
        self.items.append({
            'name': 'timestep ',
            'string': 'Set timestep: ',
            'object': self.timestep_Box
        })
        self.items.append({
            'name': 'numFrames',
            'string': 'Number of frames in trace: ',
            'object': self.numFrames_label
        })
        self.items.append({
            'name': 'numChunks',
            'string': 'Number of chunks: ',
            'object': self.numChunks_label
        })
        self.items.append({
            'name': 'blank2 ',
            'string': '-------------    Averaging     ---------------',
            'object': None
        })
        self.items.append({
            'name': 'blank3 ',
            'string': '--  If  stop = 0 the group will be ignored  --',
            'object': None
        })
        self.items.append({
            'name': 'baseline_start ',
            'string': 'Baseline start: ',
            'object': self.baseline_start
        })
        self.items.append({
            'name': 'baseline_stop',
            'string': 'Baseline stop: ',
            'object': self.baseline_stop
        })
        self.items.append({
            'name': 'puff1_start ',
            'string': 'Puff Range 1 start: ',
            'object': self.puff1_start
        })
        self.items.append({
            'name': 'puff1_stop',
            'string': 'Puff Range 1 stop: ',
            'object': self.puff1_stop
        })
        self.items.append({
            'name': 'puff2_start ',
            'string': 'Puff Range 2 start: ',
            'object': self.puff2_start
        })
        self.items.append({
            'name': 'puff2_stop',
            'string': 'Puff Range 2 stop: ',
            'object': self.puff2_stop
        })
        self.items.append({
            'name': 'puff3_start ',
            'string': 'Puff Range 3 start: ',
            'object': self.puff3_start
        })
        self.items.append({
            'name': 'puff3_stop',
            'string': 'Puff Range 3 stop: ',
            'object': self.puff3_stop
        })
        self.items.append({
            'name': 'puff4_start ',
            'string': 'Puff Range 4 start: ',
            'object': self.puff4_start
        })
        self.items.append({
            'name': 'puff4_stop',
            'string': 'Puff Range 4 stop: ',
            'object': self.puff4_stop
        })
        self.items.append({
            'name': 'blank ',
            'string': '-------------------------------------------',
            'object': None
        })
        self.items.append({
            'name': 'filepath ',
            'string': '',
            'object': self.getFile
        })
        self.items.append({
            'name': 'plot',
            'string': 'Plot results',
            'object': self.plot_checkbox
        })
        self.items.append({
            'name': 'saveName_label',
            'string': 'Save Name (if blank, input filename used): ',
            'object': self.savename_label
        })
        self.items.append({
            'name': 'saveName',
            'string': '',
            'object': self.setSavename_button
        })
        #self.items.append({'name': 'setPath ', 'string': '', 'object': self.setExportFolder_button })
        self.items.append({
            'name': 'run',
            'string': '',
            'object': self.runAnalysis_button
        })
        self.items.append({
            'name': 'closeplots',
            'string': '',
            'object': self.closePlots_button
        })

        super().gui()
        ######################################################################
        return

    def chunkSizeUpdate(self):
        if self.filename == '':
            return

        else:
            self.numChunks = float(self.nFrames / self.chunkSize_Box.value())
            self.numChunks_label.setText(str(self.numChunks))
            maxChunks = int(self.numChunks) + 1
            self.baseline_start.setMaximum(maxChunks)
            self.baseline_stop.setMaximum(maxChunks)
            self.puff1_start.setMaximum(maxChunks)
            self.puff1_stop.setMaximum(maxChunks)
            self.puff2_start.setMaximum(maxChunks)
            self.puff2_stop.setMaximum(maxChunks)
            self.puff3_start.setMaximum(maxChunks)
            self.puff3_stop.setMaximum(maxChunks)
            self.puff4_start.setMaximum(maxChunks)
            self.puff4_stop.setMaximum(maxChunks)

        return

    def frameLengthUpdate(self):
        if self.filename == '':
            return
        else:
            self.nFrames = len(self.data[0].values)
            self.numFrames_label.setText(str(self.nFrames))
            self.chunkSizeUpdate()
        return

    def loadData(self):
        self.filename = self.getFile.value()
        self.data = pd.read_csv(self.filename,
                                header=None,
                                skiprows=1,
                                index_col=0)

        #drop extra x columns
        self.data = self.data[self.data.columns[::2]]
        #drop columns with na values
        self.data = self.data.dropna(axis=1, how='all')
        #set column names by number
        nCols = len(self.data.columns)
        colNames = list(range(0, nCols))
        self.data.columns = colNames
        #update
        self.frameLengthUpdate()

        print('-------------------------------------')
        print('Data loaded (first 5 rows displayed):')
        print(self.data.head())
        print('-------------------------------------')

    def setSavename(self):

        text, ok = QInputDialog.getText(None, 'SaveName Dialog',
                                        'Enter save name:')

        if ok:

            fft_Chunker.savename_label.setText(str(text))
        return

    def plotData(self):
        ### plot test result
        result_data = self.result_dict[0]  # just results for 1st trace
        numChunks = int(len(list(result_data.keys())) / 3)
        if numChunks > 40:
            g.alert(
                'More than 40 plots would be generated - aborting plotting')
            return

        for i in range(1, numChunks + 1):
            print('Plotting chunk {}'.format(str(i)))
            plt.figure(i)
            plt.subplot(211)
            plt.plot(result_data['chunk_{}'.format(str(i))])
            plt.xlabel("frame")
            plt.ylabel("DF/F0")
            plt.ylim(ymin=self.minTime, ymax=self.maxTime)

            plt.subplot(212)
            x = result_data['frequency_{}'.format(str(i))]
            y = result_data['power_{}'.format(str(i))]

            plt.scatter(x, y, s=8, c='blue')
            #plt.plot(result_data['frequency_{}'.format(str(i))],result_data['power_{}'.format(str(i))])
            plt.title("FFT analysis - chunk {}".format(str(i)))
            plt.xlabel("frequency")
            plt.ylabel("power")

            #add average line
            #y_mean = [np.mean(y)]*len(x)
            #plt.plot(x,y_mean, label='Mean', color='red')

            #plt.xscale('log')
            plt.yscale('log')
            #plt.xlim(xmin= 0.0001, xmax=self.X_max)
            plt.ylim(ymin=self.Y_min, ymax=self.Y_max)

            plt.show()

        return

    def plotAverages(self):
        #plot averaged chunks
        self.fig, (ax1, ax2, ax3, ax4, ax5) = plt.subplots(1,
                                                           5,
                                                           sharex=True,
                                                           sharey=True)
        self.fig.suptitle('Averaged chunks')
        ax1.semilogy(self.baseline_FreqAverage, self.baseline_PowerAverage)
        ax2.semilogy(self.puff1_FreqAverage, self.puff1_PowerAverage)
        ax3.semilogy(self.puff2_FreqAverage, self.puff2_PowerAverage)
        ax4.semilogy(self.puff3_FreqAverage, self.puff3_PowerAverage)
        ax5.semilogy(self.puff4_FreqAverage, self.puff4_PowerAverage)

        ax1.set_title('Baseline')
        ax2.set_title('Puff group 1')
        ax3.set_title('Puff group 2')
        ax4.set_title('Puff group 3')
        ax5.set_title('Puff group 4')

        plt.show()
        return

    def clearPlots(self):
        try:
            plt.close('all')
        except:
            pass
        return

    def makeAverage(self):
        self.averageResults_dict = {}

        for key in self.result_dict:
            result_data = self.result_dict[key]

            self.baseline_PowerAverage = []
            self.puff1_PowerAverage = []
            self.puff2_PowerAverage = []
            self.puff3_PowerAverage = []
            self.puff4_PowerAverage = []
            self.baseline_FreqAverage = []
            self.puff1_FreqAverage = []
            self.puff2_FreqAverage = []
            self.puff3_FreqAverage = []
            self.puff4_FreqAverage = []

            self.average_dict = {}

            def getAverage(start, end):
                powerList = []
                frequencyList = []

                print('Averaging Group {} - {}'.format(start, end))

                for i in range(start, end):
                    print('power_{}'.format(str(i)), )
                    #print(result_data['power_{}'.format(str(i))])
                    print('frequency_{}'.format(str(i)), )
                    #print(result_data['frequency_{}'.format(str(i))])
                    powerList.append(result_data['power_{}'.format(str(i))])
                    frequencyList.append(result_data['frequency_{}'.format(
                        str(i))])
                power = np.mean(powerList, axis=0)
                frequency = np.mean(frequencyList, axis=0)
                print('power mean'.format(str(i)), )
                print(power)
                print('log10 power mean'.format(str(i)), )
                print(np.log10(power))
                print('frequency mean'.format(str(i)), )
                print(frequency)
                print('log10 frequency mean'.format(str(i)), )
                print(np.log10(frequency))
                print('------------')
                return power, frequency

            base_start = self.baseline_start.value()
            base_stop = self.baseline_stop.value()
            puff1_start = self.puff1_start.value()
            puff1_stop = self.puff1_stop.value()
            puff2_start = self.puff2_start.value()
            puff2_stop = self.puff2_stop.value()
            puff3_start = self.puff3_start.value()
            puff3_stop = self.puff3_stop.value()
            puff4_start = self.puff4_start.value()
            puff4_stop = self.puff4_stop.value()

            #get average group settings
            if base_stop > 0 and base_stop >= base_start:
                self.baseline_PowerAverage, self.baseline_FreqAverage = getAverage(
                    base_start, base_stop)
                self.average_dict.update({
                    'baseline_PowerAverage':
                    self.baseline_PowerAverage,
                    'baseline_FreqAverage':
                    self.baseline_FreqAverage
                })

            if puff1_stop > 0 and puff1_stop >= puff1_start:
                self.puff1_PowerAverage, self.puff1_FreqAverage = getAverage(
                    puff1_start, puff1_stop)
                self.average_dict.update({
                    'puff1_PowerAverage':
                    self.puff1_PowerAverage,
                    'puff1_FreqAverage':
                    self.puff1_FreqAverage
                })

            if puff2_stop > 0 and puff2_stop >= puff2_start:
                self.puff2_PowerAverage, self.puff2_FreqAverage = getAverage(
                    puff2_start, puff2_stop)
                self.average_dict.update({
                    'puff2_PowerAverage':
                    self.puff2_PowerAverage,
                    'puff2_FreqAverage':
                    self.puff2_FreqAverage
                })

            if puff3_stop > 0 and puff3_stop >= puff3_start:
                self.puff3_PowerAverage, self.puff3_FreqAverage = getAverage(
                    puff3_start, puff3_stop)
                self.average_dict.update({
                    'puff3_PowerAverage':
                    self.puff3_PowerAverage,
                    'puff3_FreqAverage':
                    self.puff3_FreqAverage
                })

            if puff4_stop > 0 and puff4_stop >= puff4_start:
                self.puff4_PowerAverage, self.puff4_FreqAverage = getAverage(
                    puff4_start, puff4_stop)
                self.average_dict.update({
                    'puff4_PowerAverage':
                    self.puff4_PowerAverage,
                    'puff4_FreqAverage':
                    self.puff4_FreqAverage
                })

        self.averageResults_dict.update(
            {'AverageResult_{}'.format(str(key)): self.average_dict})
        return

    def exportAverage(self):
        for key in self.averageResults_dict:
            self.average_DF = pd.DataFrame.from_dict(
                data=self.averageResults_dict[key])
            savePath = os.path.dirname(self.filename)
            if self.savename_label.text() == '':
                saveName = os.path.join(
                    savePath, 'FFT_Chunker_Batch_{}_{}.csv'.format(
                        self.timeStr, str(key)))
            else:
                saveName = os.path.join(
                    savePath, '{}_{}.csv'.format(self.savename_label.text(),
                                                 str(key)))
            #self.average_DF.to_csv(saveName)

            #take logs
            logDF = pd.DataFrame(np.log10(self.average_DF),
                                 index=self.average_DF.index,
                                 columns=self.average_DF.columns)
            logDF.to_csv(saveName)
            print('average file saved')
        return

    def exportResult(self):
        savePath = os.path.dirname(self.filename)
        toAverage = []

        for key in self.result_dict:
            if self.savename_label.text() == '':
                saveName = os.path.join(
                    savePath, 'FFT_Chunker_Batch_{}_Trace_{}.csv'.format(
                        self.timeStr, str(key)))
            else:
                saveName = os.path.join(
                    savePath,
                    '{}_Trace_{}.csv'.format(self.savename_label.text(),
                                             str(key)))

            #self.result_dict[key].to_csv(saveName)

            #takeLogs
            logDF = pd.DataFrame(np.log10(self.result_dict[key]),
                                 index=self.result_dict[key].index,
                                 columns=self.result_dict[key].columns)
            logDF.to_csv(saveName)

            print('File {} saved'.format(saveName))
            g.m.statusBar().showMessage('File {} saved'.format(saveName))
            toAverage.append(self.result_dict[key])

        #if multiple ROI traces - take average of results and export as seperate file
        if len(self.result_dict) > 1:
            if self.savename_label.text() == '':
                saveName = os.path.join(
                    savePath, 'FFT_Chunker_Batch_{}_AveragedTraces.csv'.format(
                        self.timeStr))
            else:
                saveName = os.path.join(
                    savePath,
                    '{}_AveragedTraces.csv'.format(self.savename_label.text()))

            averagedDF = pd.concat(toAverage).groupby(level=0).mean()

            #remove extraneous columns for Ian
            freqCols = [c for c in averagedDF.columns if 'frequency' in c]
            powerCols = [c for c in averagedDF.columns if 'power' in c]
            #chunkCols = [c for c in averagedDF.columns  if 'chunk' in c]

            cols = [freqCols[0]] + powerCols

            averagedDF = averagedDF[cols]

            #take logs
            #logsDF = averagedDF.applymap(math.log10)
            logsDF = pd.DataFrame(np.log10(averagedDF),
                                  index=averagedDF.index,
                                  columns=averagedDF.columns)

            #print averaged traces df
            print('-----------------------------------------------')
            print('Averaged Traces DF')
            print(logsDF.head())
            print('-----------------------------------------------')
            logsDF.to_csv(saveName)
            print('Averaged ROI File {} saved'.format(saveName))
            g.m.statusBar().showMessage(
                'Averaged ROI File {} saved'.format(saveName))
        return

    def runAnalysis(self):
        chunk_size = self.chunkSize_Box.value()
        timestep = self.timestep_Box.value()
        self.timeStr = time.strftime("%Y%m%d-%H%M%S")

        if self.filename == '':
            print('File not loaded!')
            g.m.statusBar().showMessage('File not loaded!')
            return
        else:
            self.clearPlots()

            #import trace/traces
            columns = list(self.data)

            #initiate result dict (for multiple traces)
            self.result_dict = {}

            #fft analysis
            for i in columns:
                # analyse each column
                result, self.X_min, self.X_max, self.Y_min, self.Y_max, self.minTime, self.maxTime = (
                    fft_chunks(self.data[i].values, chunk_size, timestep))

                # add to self.result_dict
                self.result_dict.update({i: result})
                print('Trace {} analysed, {} chunks processed'.format(
                    str(i), str((len(self.data[i].values) / chunk_size))))

            #export results
            self.exportResult()

            #generate averages for groups
            self.makeAverage()
            self.exportAverage()

            #plots
            if self.plot_checkbox.isChecked():
                self.plotData()
                self.plotAverages()
Beispiel #9
0
class RoiExtras(BaseProcess_noPriorWindow):
    """
    Extends ROI menu features
    """
    def __init__(self):
        BaseProcess_noPriorWindow.__init__(self)

        self.currentWin = None
        self.currentROI = None
        self.displayStarted = False
        self.data = None
        self.img = None

        self.startScale = -3
        self.endScale = 50
        self.n = 50

        self.frame = 0
        self.ROIwindowExists = False
        self.ROI_ID = 0

    def __call__(self):
        '''
        
        '''
        self.closeAction()
        return

    def closeAction(self):
        self.currentWin = None
        self.currentROI = None
        self.displayStarted = False
        self.data = None
        self.img = None
        self.ROIwindowExists = False
        try:
            self.currentROI.sigRegionChanged.disconnect()
        except:
            pass
        try:
            self.currentWin.sigTimeChanged.disconnect()
        except:
            pass
        try:
            self.ROIwindow.close()
        except:
            pass

        try:
            self.histoWindow.close()
        except:
            pass

    def closeEvent(self, event):
        self.closeAction()
        #BaseProcess_noPriorWindow.closeEvent(self, event)
        event.accept()

    def gui(self):
        self.gui_reset()
        self.active_window = WindowSelector()

        self.startButton = QPushButton('Start')
        self.startButton.pressed.connect(self.start)

        self.autoscaleX = CheckBox()
        self.autoscaleY = CheckBox()

        self.autoscaleX.setChecked(True)
        self.autoscaleY.setChecked(True)

        self.autoscaleX.stateChanged.connect(self.updateX)
        self.autoscaleY.stateChanged.connect(self.updateY)

        self.items.append({
            'name': 'active_window',
            'string': 'Select Window',
            'object': self.active_window
        })
        self.items.append({
            'name': 'autoScaleX',
            'string': 'Autoscale Histogram X-axis',
            'object': self.autoscaleX
        })
        self.items.append({
            'name': 'autoScaleY',
            'string': 'Autoscale Histogram Y-axis',
            'object': self.autoscaleY
        })
        self.items.append({
            'name': 'start_button',
            'string': 'Click to select current ROI',
            'object': self.startButton
        })

        super().gui()

    def start(self):
        #select window
        self.currentWin = self.getValue('active_window')
        if self.currentWin == None:
            g.alert('First select window')
            return

        #disconnect previous ROI (if exists)
        try:
            self.currentROI.sigRegionChanged.disconnect()
        except:
            pass

        #disconnect previous time update (if exists)
        try:
            self.currentWin.sigTimeChanged.disconnect(self.update)
        except:
            pass

        try:
            self.ROIwindow.close()
        except:
            pass

        try:
            self.histoWindow.close()
        except:
            pass

        #select current ROI
        self.currentROI = self.currentWin.currentROI

        if self.currentWin.currentROI == None:
            g.alert('First draw an ROI')
            return

        #set updates
        self.currentROI.sigRegionChanged.connect(self.update)
        self.currentWin.sigTimeChanged.connect(self.update)
        self.currentWin.imageview.scene.sigMouseClicked.connect(self.update)

        #start plotting
        self.startPlot()
        self.displayStarted = True

        #get stack data
        self.data = np.array(deepcopy(self.currentWin.image))

        #get histo range from whole stack
        self.startScale = np.min(self.data)
        self.endScale = np.max(self.data)

        self.update()

    def update(self):
        if self.currentROI != self.currentWin.currentROI:
            self.currentROI = self.currentWin.currentROI
            self.currentROI.sigRegionChanged.connect(self.update)
            self.currentROI.sigClicked.connect(self.update)

        #get frame index
        self.frame = self.currentWin.currentIndex
        #get roi region
        self.selected = self.currentROI.getArrayRegion(
            self.data[self.frame], self.currentWin.imageview.getImageItem())
        #print(self.selected)

        #get roi mask (needed for freehand roi which returns square array)
        mask = self.currentROI.getMask()
        #reset indices to cropped roi
        mask_norm = (mask[0] - min(mask[0]), mask[1] - min(mask[1]))
        #invert mask
        invertMask = np.ones_like(self.selected, dtype=bool)
        invertMask[mask_norm] = False
        #select region within roi boundary
        self.selected[invertMask] = 0  #using 0 for now, np.nan is slow

        #count number of pixels
        n_pixels = (self.selected > 0).sum()

        #update plot
        self.histoWindow.update(self.selected,
                                start=self.startScale,
                                end=self.endScale,
                                n=self.n,
                                n_pixels=n_pixels)
        #update roi window
        try:
            self.ROIwindow.imageview.setImage(self.selected)
        except:
            self.ROIwindow = Window(self.selected, name='ROI')
            self.ROIwindowExists = True

    def updateX(self):
        try:
            self.histoWindow.autoscaleX = self.autoscaleX.isChecked()
        except:
            pass

    def updateY(self):
        try:
            self.histoWindow.autoscaleY = self.autoscaleY.isChecked()
        except:
            pass

    def startPlot(self):
        self.histoWindow = HistoWindow()
        self.histoWindow.show()
class Form2(QtWidgets.QDialog):
    def __init__(self, parent = None):
        super(Form2, self).__init__(parent)

        self.arraySavePath = camVolumeSlider.savePath
        self.arrayImportPath = "None"

        #window geometry
        self.left = 300
        self.top = 300
        self.width = 600
        self.height = 400

        self.theta = 45
        self.shiftFactor = 1
        self.trim_last_frame = False

        #spinboxes
        self.spinLabel1 = QtWidgets.QLabel("Slice #")
        self.SpinBox1 = QtWidgets.QSpinBox()
        self.SpinBox1.setRange(0,camVolumeSlider.getNFrames())
        self.SpinBox1.setValue(0)

        self.spinLabel2 = QtWidgets.QLabel("# of slices per volume: ")
        self.SpinBox2 = QtWidgets.QSpinBox()
        self.SpinBox2.setRange(0,camVolumeSlider.getNFrames())
        self.SpinBox2.setValue(camVolumeSlider.getNFrames())

        self.spinLabel4 = QtWidgets.QLabel("baseline value: ")
        self.SpinBox4 = QtWidgets.QSpinBox()
        self.SpinBox4.setRange(0,camVolumeSlider.getMaxPixel())
        self.SpinBox4.setValue(0)

        self.spinLabel6 = QtWidgets.QLabel("F0 start volume: ")
        self.SpinBox6 = QtWidgets.QSpinBox()
        self.SpinBox6.setRange(0,camVolumeSlider.getNVols())
        self.SpinBox6.setValue(0)

        self.spinLabel7 = QtWidgets.QLabel("F0 end volume: ")
        self.SpinBox7 = QtWidgets.QSpinBox()
        self.SpinBox7.setRange(0,camVolumeSlider.getNVols())
        self.SpinBox7.setValue(0)

        self.spinLabel8 = QtWidgets.QLabel("factor to multiply by: ")
        self.SpinBox8 = QtWidgets.QSpinBox()
        self.SpinBox8.setRange(0,10000)
        self.SpinBox8.setValue(100)

        self.spinLabel9 = QtWidgets.QLabel("theta: ")
        self.SpinBox9 = QtWidgets.QSpinBox()
        self.SpinBox9.setRange(0,360)
        self.SpinBox9.setValue(self.theta)

        self.spinLabel10 = QtWidgets.QLabel("shift factor: ")
        self.SpinBox10 = QtWidgets.QSpinBox()
        self.SpinBox10.setRange(0,100)
        self.SpinBox10.setValue(self.shiftFactor)


        #sliders
        self.slider1 = QtWidgets.QSlider(QtCore.Qt.Horizontal)
        self.slider1.setFocusPolicy(QtCore.Qt.StrongFocus)
        self.slider1.setTickPosition(QtWidgets.QSlider.TicksBothSides)
        self.slider1.setMinimum(0)
        self.slider1.setMaximum(camVolumeSlider.getNFrames())
        self.slider1.setTickInterval(1)
        self.slider1.setSingleStep(1)

        #ComboBox
        self.dTypeSelectorBox = QtWidgets.QComboBox()
        self.dTypeSelectorBox.addItems(["float16", "float32", "float64","int8","int16","int32","int64"])
        self.inputArraySelectorBox = QtWidgets.QComboBox()
        self.inputArraySelectorBox.addItems(camVolumeSlider.getArrayKeys())
        self.inputArraySelectorBox.setCurrentIndex(4)
        self.inputArraySelectorBox.currentIndexChanged.connect(self.inputArraySelectionChange)

        self.displayArraySelectorBox = QtWidgets.QComboBox()
        self.displayArraySelectorBox.addItems(camVolumeSlider.getArrayKeys())
        self.displayArraySelectorBox.setCurrentIndex(18)
        self.displayArraySelectorBox.currentIndexChanged.connect(self.displayArraySelectionChange)

        #buttons
        self.button1 = QtWidgets.QPushButton("Autolevel")
        self.button2 = QtWidgets.QPushButton("Set Slices")
        #self.button3 = QtWidgets.QPushButton("Average Volumes")
        self.button4 = QtWidgets.QPushButton("subtract baseline")
        self.button5 = QtWidgets.QPushButton("run DF/F0")
        self.button6 = QtWidgets.QPushButton("export to Window")
        self.button7 = QtWidgets.QPushButton("set data Type")
        self.button8 = QtWidgets.QPushButton("multiply")
        self.button9 = QtWidgets.QPushButton("export to array")        

        self.button12 = QtWidgets.QPushButton("open 3D viewer")
        self.button13 = QtWidgets.QPushButton("close 3D viewer")

        #labels
        self.volumeLabel = QtWidgets.QLabel("# of volumes: ")
        self.volumeText = QtWidgets.QLabel("  ")

        self.shapeLabel = QtWidgets.QLabel("array shape: ")
        self.shapeText = QtWidgets.QLabel(str(camVolumeSlider.getArrayShape()))

        self.dataTypeLabel = QtWidgets.QLabel("current data type: ")
        self.dataTypeText = QtWidgets.QLabel(str(camVolumeSlider.getDataType()))
        self.dataTypeChangeLabel = QtWidgets.QLabel("new data type: ")

        self.inputArrayLabel = QtWidgets.QLabel("input array order: ")
        self.displayArrayLabel = QtWidgets.QLabel("display array order: ")

        self.arraySavePathLabel = QtWidgets.QLabel(str(self.arraySavePath))

        self.trim_last_frameLabel = QtWidgets.QLabel("Trim Last Frame: ")
        self.trim_last_frame_checkbox = CheckBox()
        self.trim_last_frame_checkbox.setChecked(self.trim_last_frame)
        self.trim_last_frame_checkbox.stateChanged.connect(self.trim_last_frameClicked)


        #grid layout
        layout = QtWidgets.QGridLayout()
        layout.setSpacing(10)

        layout.addWidget(self.spinLabel1, 1, 0)
        layout.addWidget(self.SpinBox1, 1, 1)

        layout.addWidget(self.slider1, 2, 0, 2, 5)

        layout.addWidget(self.spinLabel2, 4, 0)
        layout.addWidget(self.SpinBox2, 4, 1)
        layout.addWidget(self.button2, 4, 2)

        layout.addWidget(self.spinLabel4, 6, 0)
        layout.addWidget(self.SpinBox4, 6, 1)
        layout.addWidget(self.button4, 6, 2)

        layout.addWidget(self.spinLabel6, 7, 0)
        layout.addWidget(self.SpinBox6, 7, 1)
        layout.addWidget(self.spinLabel7, 7, 2)
        layout.addWidget(self.SpinBox7, 7, 3)
        layout.addWidget(self.button5, 7, 4)

        layout.addWidget(self.volumeLabel, 8, 0)
        layout.addWidget(self.volumeText, 8, 1)
        layout.addWidget(self.shapeLabel, 9, 0)
        layout.addWidget(self.shapeText, 9, 1)

        layout.addWidget(self.spinLabel8, 10, 0)
        layout.addWidget(self.SpinBox8, 10, 1)
        layout.addWidget(self.button8, 10, 2)

        layout.addWidget(self.dataTypeLabel, 11, 0)
        layout.addWidget(self.dataTypeText, 11, 1)
        layout.addWidget(self.dataTypeChangeLabel, 11, 2)
        layout.addWidget(self.dTypeSelectorBox, 11,3)
        layout.addWidget(self.button7, 11, 4)

        layout.addWidget(self.button6, 13, 0)
        layout.addWidget(self.button1, 13, 4)
        layout.addWidget(self.button6, 13, 0)
        layout.addWidget(self.button1, 13, 4)
        layout.addWidget(self.button9, 14, 0)
        layout.addWidget(self.arraySavePathLabel, 14, 1, 1, 4)      
        
        
        layout.addWidget(self.spinLabel9, 16, 0)
        layout.addWidget(self.SpinBox9, 16, 1)

        layout.addWidget(self.spinLabel10, 17, 0)
        layout.addWidget(self.SpinBox10, 17, 1)
        layout.addWidget(self.trim_last_frameLabel, 18, 0)
        layout.addWidget(self.trim_last_frame_checkbox, 18, 1)

        layout.addWidget(self.inputArrayLabel, 19, 0)
        layout.addWidget(self.inputArraySelectorBox, 19, 1)

        layout.addWidget(self.displayArrayLabel, 19, 2)
        layout.addWidget(self.displayArraySelectorBox, 19, 3)

        layout.addWidget(self.button12, 20, 0)
        layout.addWidget(self.button13, 20, 1)


        self.setLayout(layout)
        self.setGeometry(self.left, self.top, self.width, self.height)

        #add window title
        self.setWindowTitle("Volume Slider GUI")

        #connect sliders & spinboxes
        self.slider1.valueChanged.connect(self.slider1ValueChange)
        self.SpinBox1.valueChanged.connect(self.spinBox1ValueChange)
        self.SpinBox9.valueChanged.connect(self.setTheta)
        self.SpinBox10.valueChanged.connect(self.setShiftFactor)

        #connect buttons
        self.button1.clicked.connect(self.autoLevel)
        self.button2.clicked.connect(self.updateVolumeValue)
        #self.button3.clicked.connect(self.averageByVol)
        self.button4.clicked.connect(self.subtractBaseline)
        self.button5.clicked.connect(self.ratioDFF0)
        self.button6.clicked.connect(self.exportToWindow)
        self.button7.clicked.connect(self.dTypeSelectionChange)
        self.button8.clicked.connect(self.multiplyByFactor)
        self.button9.clicked.connect(self.exportArray)            
        self.button12.clicked.connect(self.startViewer)
        self.button13.clicked.connect(self.closeViewer)

        return

     #volume changes with slider & spinbox
    def slider1ValueChange(self, value):
        self.SpinBox1.setValue(value)
        return

    def spinBox1ValueChange(self, value):
        self.slider1.setValue(value)
        camVolumeSlider.updateDisplay_sliceNumberChange(value)
        return

    def autoLevel(self):
        camVolumeSlider.displayWindow.imageview.autoLevels()
        return

    def updateVolumeValue(self):
        value = self.SpinBox2.value()
        noVols = int(camVolumeSlider.getNFrames()/value)
        camVolumeSlider.updateVolsandFramesPerVol(noVols, value)
        self.volumeText.setText(str(noVols))

        camVolumeSlider.updateDisplay_volumeSizeChange()
        self.shapeText.setText(str(camVolumeSlider.getArrayShape()))

        if (value)%2 == 0:
            self.SpinBox1.setRange(0,value-1) #if even, display the last volume
            self.slider1.setMaximum(value-1)
        else:
            self.SpinBox1.setRange(0,value-2) #else, don't display the last volume
            self.slider1.setMaximum(value-2)

        self.updateVolSpinBoxes()
        return

    def updateVolSpinBoxes(self):
        #self.SpinBox3.setRange(0,camVolumeSlider.getNVols())

        self.SpinBox6.setRange(0,camVolumeSlider.getNVols())
        self.SpinBox7.setRange(0,camVolumeSlider.getNVols())
        return

    def getBaseline(self):
        return self.SpinBox4.value()

    def getF0(self):
        return self.SpinBox6.value(), self.SpinBox7.value()

    def subtractBaseline(self):
        camVolumeSlider.subtractBaseline()
        return

    def ratioDFF0(self):
        camVolumeSlider.ratioDFF0()
        return

    def exportToWindow(self):
        camVolumeSlider.savePath = self.arraySavePath
        camVolumeSlider.exportToWindow()
        return

    def dTypeSelectionChange(self):
        camVolumeSlider.setDType(self.dTypeSelectorBox.currentText())
        self.dataTypeText = QtWidgets.QLabel(str(camVolumeSlider.getDataType()))
        return

    def multiplyByFactor(self):
        camVolumeSlider.multiplyByFactor(self.SpinBox8.value())
        return

    def exportArray(self):
        self.arraySavePath = QtWidgets.QFileDialog.getSaveFileName(self, 'Save File', self.arraySavePath, 'Numpy array (*.npy)')
        self.arraySavePath = str(self.arraySavePath[0])
        camVolumeSlider.savePath = self.arraySavePath
        self.arraySavePathLabel.setText(self.arraySavePath)
        camVolumeSlider.exportArray()
        return

    def startViewer(self):
        camVolumeSlider.startViewer()
        return

    def closeViewer(self):
        camVolumeSlider.closeViewer()
        return

    def setTheta(self):
        self.theta = self.SpinBox9.value()

    def setShiftFactor(self):
        self.shiftFactor = self.SpinBox10.value()

    def trim_last_frameClicked(self):
        self.trim_last_frame = self.trim_last_frame_checkbox.isChecked()

    def inputArraySelectionChange(self, value):
        camVolumeSlider.setInputArrayOrder(self.inputArraySelectorBox.currentText())
        return

    def displayArraySelectionChange(self, value):
        camVolumeSlider.setDisplayArrayOrder(self.displayArraySelectorBox.currentText())
        return

    def close(self):
        camVolumeSlider.closeViewer()
        camVolumeSlider.displayWindow.close()
        camVolumeSlider.dialogbox.destroy()
        camVolumeSlider.end()
        self.closeAllWindows()
        return