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 Simulate_mepp(BaseProcess_noPriorWindow): """ Simulate MEPP events in a noisy time trace Trace generated by linear summation of randomly occuring unitary events hF(t) (MEPPs) see Segal et al. Biophys J, 1985 h = time independent amplitude factor F(t) = nondimensional function of time hF(t) = h(exp(-t/dT) - exp(-t/dR)) dT = decay time constant rT = rise time constant time of MEPP addition drawn from exponential distribution (np.random.exponential()) amplitude of MEPP drawn from normal distribution (np.random.normal()) duration of MEPP drawn from normal distribution (np.random.normal()) """ def __init__(self): if g.settings[ 'mepp_simulator'] is None or 'decayTime' not in g.settings[ 'mepp_simulator']: s = dict() s['traceLength'] = 10000 s['meppAmplitude'] = 5 s['meppDuration'] = 1 s['startTime'] = 0 s['meanExp'] = 1000.0 s['baseline'] = 0.0 s['noiseSigma'] = 0.1 s['riseTime'] = 1.0 #s['riseTime_sigma'] = 0.01 s['decayTime'] = 10.0 #s['decayTime_sigma'] = 0.1 g.settings['mepp_simulator'] = s super().__init__() self.data = np.array([]) def gui(self): s = g.settings['mepp_simulator'] self.gui_reset() self.meppWindow = PlotWindow('Single MEPP (No noise)') self.traceWindow = PlotWindow('Time Trace') self.meppWindow.hide() self.traceWindow.hide() self.traceLength = SliderLabel(0) self.traceLength.setRange(0, 1000000) self.traceLength.setValue(s['traceLength']) self.startTime = SliderLabel(0) self.startTime.setRange(0, s['traceLength']) self.startTime.setValue(s['startTime']) self.meppDuration_slider = pg.SpinBox(int=True, step=1) self.meppDuration_slider.setValue(s['meppDuration']) self.meppDuration_sigma_slider = pg.SpinBox(int=True, step=1) self.meppDuration_sigma_slider.setValue(1) self.baseline_slider = pg.SpinBox(int=False, step=.01) self.baseline_slider.setValue(s['baseline']) self.noiseSigma_slider = pg.SpinBox(int=False, step=.01) self.noiseSigma_slider.setValue(s['noiseSigma']) self.meppAmplitude_slider = pg.SpinBox(int=False, step=.01) self.meppAmplitude_slider.setValue(s['meppAmplitude']) self.meppAmplitude_sigma_slider = pg.SpinBox(int=False, step=.01) self.meppAmplitude_sigma_slider.setValue(1.0) self.meppRiseTime_slider = pg.SpinBox(int=False, step=.01) self.meppRiseTime_slider.setValue(s['riseTime']) #self.meppRiseTime_sigma_slider = pg.SpinBox(int=False, step=.01) #self.meppRiseTime_sigma_slider.setValue(0.01) self.meppDecayTime_slider = pg.SpinBox(int=False, step=.01) self.meppDecayTime_slider.setValue(s['decayTime']) #self.meppDecayTime_sigma_slider = pg.SpinBox(int=False, step=.01) #self.meppDecayTime_sigma_slider.setValue(0.1) self.randommeppsAdded = False self.meanExp_slider = pg.SpinBox(int=False, step=.01) self.meanExp_slider.setValue(1000.0) self.plotHistoTimes = CheckBox() self.plotHistoTimes.setValue(False) self.exportTimes_button = QPushButton('Export times') self.exportTimes_button.pressed.connect(self.exportTimes) self.randommeppButton = QPushButton('Generate Trace') self.randommeppButton.pressed.connect(self.addRandommepps) self.plotmeppButton = QPushButton('Plot single MEPP') self.plotmeppButton.pressed.connect(self.plotSingleMEPP) self.items.append({ 'name': 'traceLength', 'string': 'Recording length', 'object': self.traceLength }) self.items.append({ 'name': 'startTime', 'string': 'Start time', 'object': self.startTime }) self.items.append({ 'name': 'meppDuration', 'string': 'MEPP duration (mean)', 'object': self.meppDuration_slider }) self.items.append({ 'name': 'meppDuration_sigma', 'string': 'MEPP duration (standard deviation)', 'object': self.meppDuration_sigma_slider }) self.items.append({ 'name': 'riseTime', 'string': 'MEPP rise time constant', 'object': self.meppRiseTime_slider }) #self.items.append({'name': 'riseTime_sigma','string':'MEPP rise time constant (standard deviation)','object':self.meppRiseTime_sigma_slider}) self.items.append({ 'name': 'decayTime', 'string': 'MEPP decay time constant', 'object': self.meppDecayTime_slider }) #self.items.append({'name': 'decayTime_sigma','string':'MEPP decay time constant (standard deviation)','object':self.meppDecayTime_sigma_slider}) self.items.append({ 'name': 'meppAmplitude', 'string': 'MEPP Amplitude (mean)', 'object': self.meppAmplitude_slider }) self.items.append({ 'name': 'meppAmplitude_sigma', 'string': 'MEPP Amplitude (standard deviation)', 'object': self.meppAmplitude_sigma_slider }) self.items.append({ 'name': 'meanExp', 'string': 'Mean of exponential distibution', 'object': self.meanExp_slider }) self.items.append({ 'name': 'baseline', 'string': 'Baseline', 'object': self.baseline_slider }) self.items.append({ 'name': 'noiseSigma', 'string': 'Noise Sigma', 'object': self.noiseSigma_slider }) self.items.append({ 'name': 'histoTimes', 'string': 'Plot histogram of mepp start times:', 'object': self.plotHistoTimes }) self.items.append({ 'name': 'random_mepp_Button', 'string': 'Click to add randomly distibuted mepps', 'object': self.randommeppButton }) self.items.append({ 'name': 'listTimes', 'string': 'Export list of mepp start times', 'object': self.exportTimes_button }) self.items.append({ 'name': 'plotMEPP', 'string': 'Plot single MEPP (without noise)', 'object': self.plotmeppButton }) super().gui() def __call__(self, keepSourceWindow=False): g.settings['mepp_simulator']['traceLength'] = self.getValue( 'traceLength') g.settings['mepp_simulator']['meppAmplitude'] = self.getValue( 'meppAmplitude') g.settings['mepp_simulator']['meppDuration'] = self.getValue( 'meppDuration') g.settings['mepp_simulator']['startTime'] = self.getValue('startTime') g.settings['mepp_simulator']['meanExp'] = self.getValue('meanExp') g.settings['mepp_simulator']['baseline'] = self.getValue('baseline') g.settings['mepp_simulator']['noiseSigma'] = self.getValue( 'noiseSigma') g.settings['mepp_simulator']['riseTime'] = self.getValue('riseTime') g.settings['mepp_simulator']['decayTime'] = self.getValue('decayTime') return def addMEPP(self, time, amplitude, duration, dT=10, rT=1): #using Segal et al. Biophys J, 1985 MINIATURE ENDPLATE POTENTIAL FREQUENCY AND AMPLITUDE DETERMINED BY AN EXTENSION OF CAMPBELL'S THEOREM #dT = decay time #rT = rise time ampList = [] for t in range(0, duration): ampList.append(amplitude * (math.exp(-t / dT) - math.exp(-t / rT))) #square event test #self.data[time:time+duration] = self.data[time:time+duration] + amplitude #add MEPP to trace self.data[time:time + duration] = self.data[time:time + duration] + np.array(ampList) def plotSingleMEPP(self): amp = self.getValue('meppAmplitude') duration = self.getValue('meppDuration') dT = self.getValue('decayTime') rT = self.getValue('riseTime') self.plotMEPP(amp, duration, dT=dT, rT=rT) def plotMEPP(self, amplitude, duration, dT=10, rT=1): ampList = [] for t in range(0, duration): ampList.append(amplitude * (math.exp(-t / dT) - math.exp(-t / rT))) #plot matplot #plt.figure(3) #plt.plot(range(0,duration),ampList) #plt.show() #plot pg self.meppWindow.update(ampList, [0, len(ampList)], [0, self.getValue('meppAmplitude')]) self.meppWindow.show() def addRandommepps(self): self.data = np.array([]) #generate noisy time trace n = int(self.getValue('traceLength')) self.data = np.random.normal(self.getValue('baseline'), self.getValue('noiseSigma'), n) #add MEPPS to trace mean = self.getValue('meanExp') meppsAdded = 0 meppsOutsideOfRange = 0 self.timesAdded = [] amp = self.getValue('meppAmplitude') duration = self.getValue('meppDuration') dT = self.getValue('decayTime') rT = self.getValue('riseTime') # add first mepp try: time = int((np.random.exponential(scale=mean, size=1) + self.getValue('startTime'))) #draw random amplitude randAmp = int( np.random.normal(amp, self.getValue('meppAmplitude_sigma'), 1)) #draw random duration randDuration = int( np.random.normal(duration, self.getValue('meppDuration_sigma'), 1)) # add MEPP self.addMEPP(time, randAmp, randDuration, dT=dT, rT=rT) #record time self.timesAdded.append(time) meppsAdded += 1 except BaseException as e: #print(e) #meppsOutsideOfRange += 1 #print('{} MEPPs added, {} MEPPs out of time range'.format(meppsAdded,meppsOutsideOfRange)) #print('1st MEPP outside of time range, aborting') pass # add mepp after each time selection untill end of stack # casting the exponential continous value as an int to select frame while time < self.getValue('traceLength') - self.getValue( 'meppDuration'): try: time = int((time + np.random.exponential(scale=mean, size=1))) #draw random amplitude randAmp = int( np.random.normal(amp, self.getValue('meppAmplitude_sigma'), 1)) #draw random duration randDuration = int( np.random.normal(duration, self.getValue('meppDuration_sigma'), 1)) # add MEPP self.addMEPP(time, randAmp, randDuration, dT=dT, rT=rT) #record time self.timesAdded.append(time) meppsAdded += 1 except BaseException as e: #print(e) meppsOutsideOfRange += 1 #print number of MEPPS added to console #print('{} MEPPs added, {} MEPPs out of time range'.format(meppsAdded,meppsOutsideOfRange)) if self.plotHistoTimes.isChecked(): plt.figure(1) plt.hist(self.timesAdded) plt.xlabel('Time MEPP added') plt.ylabel('Number of MEPPs added') plt.show() self.randommeppsAdded = True #print data to console #print(self.data) #plot data matplotlib #plt.figure(0) #plt.plot(self.data) #plt.show() #plot data pg self.traceWindow.update(self.data, [0, len(self.data)], [ self.getValue('baseline') - (3 * self.getValue('noiseSigma')), self.getValue('meppAmplitude') + (3 * self.getValue('meppAmplitude_sigma')) ]) self.traceWindow.show() return def exportTimes(self): if self.randommeppsAdded == False: g.alert('Add MEPPs first') return #set export path savePath, _ = QFileDialog.getSaveFileName(None, "Save file", "", "Text Files (*.csv)") #write file try: # opening the csv file in 'w+' mode file = open(savePath, 'w+', newline='') # writing the data into the file with file: write = csv.writer(file) write.writerows(map(lambda x: [x], self.timesAdded)) print('List of times saved to: {}'.format(savePath)) except BaseException as e: print(e) print('Export of times failed, printing times to console') print(self.timesAdded)
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
class Simulate_Puff(BaseProcess_noPriorWindow): """ Add a simulated puff to an image stack """ def __init__(self): super().__init__() self.currentWin = None self.currentROI = None self.data = None def get_init_settings_dict(self): s = dict() s['nFrames'] = 100 s['puffAmplitude'] = 5 s['x'] = 128 s['y'] = 128 s['startFrame'] = 100 s['sigma'] = 20 s['useROI'] = False s['meanExp'] = 5.0 s['nPuffs'] = 0 s['nSites'] = 10 s['meanDuration'] = 10 return s def gui(self): self.gui_reset() self.nFrames = pg.SpinBox(int=False, step=.01) #self.nFrames.setRange(0,10000) self.startFrame = SliderLabel(0) self.startFrame.setRange(0, 10000) self.puffAmplitude = pg.SpinBox(int=False, step=.01) self.puffAmplitude.setValue(1.0) self.sigma = SliderLabel(0) self.sigma.setRange(1, 1000) self.x = SliderLabel(0) self.x.setRange(1, 10000) self.y = SliderLabel(0) self.y.setRange(1, 10000) self.useROI = CheckBox() self.useFrame = CheckBox() self.active_window = WindowSelector() self.previewButton = QPushButton('Preview Puff') self.previewButton.pressed.connect(self.previewPuff) self.puffButton = QPushButton('Add Puff') self.puffButton.pressed.connect(self.addPuff) self.randomPuffsAdded = False self.nSites = 10 columnNames = ['time of puff', 'duration', 'site'] self.timesAdded = pd.DataFrame(columns=columnNames) self.siteNumber = int(0) self.nPuffs_slider = SliderLabel(0) self.nPuffs_slider.setRange(1, 1000) self.meanExp_slider = pg.SpinBox(int=False, step=.01) self.meanExp_slider.setValue(5.0) self.randomDuration = CheckBox() self.randomDuration.setValue(False) self.durationMean = 10.0 self.durationMean_box = pg.SpinBox(int=False, step=.01) self.durationMean_box.setRange(0, 10000) self.durationMean_box.setValue(self.durationMean) self.plotHistoTimes = CheckBox() self.plotHistoTimes.setValue(False) self.addPuffsSequentially = CheckBox() self.addPuffsSequentially.setValue(False) self.exportTimes_button = QPushButton('Export times') self.exportTimes_button.pressed.connect(self.exportTimes) self.randomPuffButton = QPushButton('Add Puffs to site') self.randomPuffButton.pressed.connect(self.addRandomPuffs) self.multipleRandomPuffButton = QPushButton('Add Puffs inside ROI') self.multipleRandomPuffButton.pressed.connect( self.addMultipleRandomPuffs) self.nSites_box = QSpinBox() self.nSites_box.setRange(0, 10000) self.nSites_box.setValue(self.nSites) self.items.append({ 'name': 'active_window', 'string': 'Select Window', 'object': self.active_window }) self.items.append({ 'name': 'nFrames', 'string': 'Duration (frames)', 'object': self.nFrames }) self.items.append({ 'name': 'randomDuration', 'string': 'Use exponentially distributed random duration', 'object': self.randomDuration }) self.items.append({ 'name': 'meanDuration', 'string': 'Mean duration', 'object': self.durationMean_box }) self.items.append({ 'name': 'startFrame', 'string': 'Start Frame', 'object': self.startFrame }) #self.items.append({'name': 'useCurrentFrame', 'string': 'Use Current Frame For Start', 'object': self.useFrame}) self.items.append({ 'name': 'puffAmplitude', 'string': 'Amplitude', 'object': self.puffAmplitude }) self.items.append({'name': 'x', 'string': 'x', 'object': self.x}) self.items.append({'name': 'y', 'string': 'y', 'object': self.y}) #self.items.append({'name': 'useROI', 'string': 'Use ROI for position', 'object': self.useROI}) self.items.append({ 'name': 'sigma', 'string': 'sigma', 'object': self.sigma }) self.items.append({ 'name': 'preview_Button', 'string': 'Click to preview Puff', 'object': self.previewButton }) self.items.append({ 'name': 'puff_Button', 'string': 'Click to add Puff', 'object': self.puffButton }) self.items.append({ 'name': 'blank', 'string': '---------- RANDOM PUFFS ---------------------------', 'object': None }) #self.items.append({'name': 'nPuffs', 'string': 'Number of puffs to add', 'object': self.nPuffs_slider}) self.items.append({ 'name': 'meanExp', 'string': 'Mean of exponential distibution of puff start times', 'object': self.meanExp_slider }) self.items.append({ 'name': 'puffsSequential', 'string': 'Wait until puff ends before adding next puff:', 'object': self.addPuffsSequentially }) self.items.append({ 'name': 'histoTimes', 'string': 'Plot histogram of puff start times:', 'object': self.plotHistoTimes }) self.items.append({ 'name': 'random_puff_Button', 'string': 'Click to add randomly distibuted puffs at one site', 'object': self.randomPuffButton }) self.items.append({ 'name': 'multipleRandom_puff_Button', 'string': 'Click to add randomly distibuted puffs at multiple sites', 'object': self.multipleRandomPuffButton }) self.items.append({ 'name': 'nSites', 'string': 'Number of Sites to add', 'object': self.nSites_box }) self.items.append({ 'name': 'blank', 'string': '---------- Export Puffs ---------------------------', 'object': None }) self.items.append({ 'name': 'listTimes', 'string': 'Export list of puff start times', 'object': self.exportTimes_button }) super().gui() def __call__(self): pass return def update(self): self.currentWin = self.getValue('active_window') #get image data self.data = np.array(deepcopy(self.currentWin.image)) self.dt, self.dy, self.dx = self.data.shape self.x.setRange(1, self.dx - 1) self.y.setRange(1, self.dy - 1) self.x.setValue(int((self.dx - 1) / 2)) self.y.setValue(int((self.dy - 1) / 2)) self.nFrames.setRange(0, self.dt) self.startFrame.setRange(0, self.dt - 1) self.sigma.setRange(1, int(self.dx / 7)) def addPuff(self, time=False, singleSite=True, x=None, y=None, duration=False): '''add synthetic blip to image stack''' #select window self.currentWin = self.getValue('active_window') if self.currentWin == None: g.alert('First select window') return #generate blip sigma = self.getValue('sigma') amp = self.getValue('puffAmplitude') if self.randomDuration.isChecked(): #get random duration if duration == False: duration = float( np.random.exponential(scale=self.getValue('meanDuration'), size=1)[0]) else: duration = self.getValue('nFrames') #scale puff amplitude to account for durations <1 frame if duration < 1: amp = amp * duration duration = ceil(duration) else: #round duration to nearest integer number of frames duration = ceil(duration) blip = generateBlip(sigma=sigma, amplitude=amp, duration=duration) blip_time, blip_x_size, blip_y_size = blip.shape x_size = int(blip_x_size / 2) y_size = int(blip_y_size / 2) #add blip to stack if time == False: t = self.getValue('startFrame') else: t = time if singleSite: x = self.getValue('x') y = self.getValue('y') tt = np.arange(t, t + duration, dtype=np.int) xx = np.arange(x - x_size - 1, x + x_size, dtype=np.int) yy = np.arange(y - y_size - 1, y + y_size, dtype=np.int) if time == False: try: self.data[np.ix_(tt, xx, yy)] = self.data[np.ix_(tt, xx, yy)] + blip except: g.alert( 'Error - Puff might be too large, too long or too close to edge' ) else: self.data[np.ix_(tt, xx, yy)] = self.data[np.ix_(tt, xx, yy)] + blip frame = self.currentWin.currentIndex self.currentWin.imageview.setImage(self.data) self.currentWin.image = self.data self.currentWin.setIndex(frame) print( 'Puff added at time: {}, x: {}, y: {} with duration: {}, sigma: {}, amplitude:{}' .format(t, x, y, duration, sigma, amp)) return def addRandomPuffs(self, singleSite=True, x=None, y=None): if self.getValue('active_window') == None: g.alert('First select window') return mean = self.getValue('meanExp') #nPuffs = self.getValue('nPuffs') puffsAdded = 0 puffsOutsideOfRange = 0 # add first puff try: if self.randomDuration.isChecked(): startTime = int( np.random.exponential(scale=mean, size=1) + self.getValue('startFrame')) duration = float( np.random.exponential(scale=self.getValue('meanDuration'), size=1)[0]) self.addPuff(time=startTime, singleSite=singleSite, x=x, y=y, duration=duration) else: startTime = int( np.random.exponential(scale=mean, size=1) + self.getValue('startFrame')) duration = self.getValue('nFrames') self.addPuff(time=startTime, singleSite=singleSite, x=x, y=y) if self.getValue('puffsSequential'): endTime = startTime + duration else: endTime = startTime except Exception as e: print(e) puffsOutsideOfRange += 1 print('{} puffs added, {} puffs out of range'.format( puffsAdded, puffsOutsideOfRange)) print('1st puff outside of range, aborting') return # add puff after each time selection untill end of stack # rounding the exponential continous value to an int to select frame while startTime < self.dt - self.getValue('nFrames'): try: startTime = int(endTime + np.random.exponential(scale=mean, size=1)) #if random duration if self.randomDuration.isChecked(): #print('original time: ', startTime) duration = np.random.exponential( scale=self.getValue('meanDuration'), size=1) startTime = startTime + ceil(duration) #print('time: ', startTime) #print('duration: ', duration) #add puff at time self.addPuff(time=startTime, singleSite=singleSite, x=x, y=y, duration=duration) #if sequental, add puff duration to time if self.getValue('puffsSequential'): endTime = startTime + duration else: endTime = startTime #else use duration from GUI else: startTime = startTime + self.getValue('nFrames') duration = self.getValue('nFrames') #add puff at time self.addPuff(time=startTime, singleSite=singleSite, x=x, y=y) #if sequental, add puff duration to time if self.getValue('puffsSequential'): endTime = startTime + duration else: endTime = startTime #update puff time log self.timesAdded = self.timesAdded.append( { 'time of puff': startTime, 'duration': duration, 'site': int(self.siteNumber) }, ignore_index=True) puffsAdded += 1 except: puffsOutsideOfRange += 1 print('{} puffs added, {} puffs out of range'.format( puffsAdded, puffsOutsideOfRange)) if self.plotHistoTimes.isChecked(): plt.hist(self.timesAdded) plt.xlabel('Time puff added (frames)') plt.ylabel('Number of puffs added') plt.show() self.randomPuffsAdded = True if singleSite: self.siteNumber += 1 return def addMultipleRandomPuffs(self): nSites = self.getValue('nSites') if self.currentWin == None: g.alert('First select window') return #select current ROI self.currentROI = self.currentWin.currentROI if self.currentWin.currentROI == None: g.alert('First draw an ROI') return bounds = self.currentROI.parentBounds() topLeft_x = bounds.topLeft().x() topLeft_y = bounds.topLeft().y() bottomRight_x = bounds.bottomRight().x() bottomRight_y = bounds.bottomRight().y() print('adding puffs to {} sites from {},{} to {},{}'.format( nSites, topLeft_x, topLeft_y, bottomRight_x, bottomRight_y)) sites = self.getRandomSites(topLeft_x, bottomRight_x, topLeft_y, bottomRight_y, nSites) for site in sites: print("Puff site: ", self.siteNumber) self.addRandomPuffs(singleSite=False, x=site[0], y=site[1]) self.siteNumber += 1 print('Finished adding sites') return def getRandomSites(self, xStart, xEnd, yStart, yEnd, qty, radius=0): import random rangeX = (xStart, xEnd) rangeY = (yStart, yEnd) deltas = set() for x in range(-radius, radius + 1): for y in range(-radius, radius + 1): if x * x + y * y <= radius * radius: deltas.add((x, y)) randPoints = [] excluded = set() i = 0 while i < qty: x = random.randrange(*rangeX) y = random.randrange(*rangeY) if (x, y) in excluded: continue randPoints.append((x, y)) i += 1 excluded.update((x + dx, y + dy) for (dx, dy) in deltas) return randPoints def exportTimes(self): if self.getValue('active_window') == None: g.alert('First select window') return if self.randomPuffsAdded == False: g.alert('Add puffs first') return #set export path savePath, _ = QFileDialog.getSaveFileName(None, "Save file", "", "Text Files (*.csv)") #write file self.timesAdded.to_csv(savePath) print('List of times saved to: {}'.format(savePath)) # #write file # try: # # opening the csv file in 'w+' mode # file = open(savePath, 'w+', newline ='') # # writing the data into the file # with file: # write = csv.writer(file) # write.writerows(map(lambda x: [x], self.timesAdded)) # print('List of times saved to: {}'.format(savePath)) # except BaseException as e: # print(e) # print('Export of times failed, printing times to console') # print(self.timesAdded) def previewPuff(self): '''preview blip to be added''' sigma = self.getValue('sigma') amp = self.getValue('puffAmplitude') if self.randomDuration.isChecked(): #get random duration duration = np.random.exponential( scale=self.getValue('meanDuration'), size=1) #scale puff amplitude to account for durations <1 frame or spread across 2 frames spread = ceil(duration) if spread < 2: amp = amp * (duration / spread) #round duration to nearest integer number of frames duration = ceil(duration) else: duration = self.getValue('nFrames') blip = generateBlip(sigma=sigma, amplitude=amp, duration=duration) Window(blip) return def generateBlip(sigma=1, amplitude=1, duration=1): sigma = int(sigma) width = sigma * 8 + 1 xorigin = sigma * 4 yorigin = sigma * 4 x = np.arange(width) y = np.arange(width) x = x[:, None] y = y[None, :] gaussian = amplitude * (np.exp(-(x - xorigin)**2 / (2. * sigma**2)) * np.exp(-(y - yorigin)**2 / (2. * sigma**2))) blip = np.repeat(gaussian[None, :, :], repeats=duration, axis=0) return blip
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
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 = []
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()
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