From cea70f3dd87c479dd42fe33dffdefbd20b9004f6 Mon Sep 17 00:00:00 2001 From: "LAKESIDE\\LindaT18" Date: Fri, 23 Aug 2019 10:39:30 -0700 Subject: [PATCH 01/63] fix viewbox error --- PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py index a5196c8..ba71f52 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py @@ -606,7 +606,7 @@ def plot_intensity_sums(self): scale = pg.ScaleBar(size=2,suffix='um') scale.setParentItem(self.ui.intensity_sums_viewBox.view) scale.anchor((1, 1), (1, 1), offset=(-30, -30)) - self.ui.intensity_sums_viewbox.view.sigRangeChanged.connect(lambda: updateDelay(scale, 10)) + self.ui.intensity_sums_viewBox.view.sigRangeChanged.connect(lambda: updateDelay(scale, 10)) except Exception as e: self.ui.result_textBrowser2.append(str(e)) From 5dd9f3778b617180133642958ba168da9b914ebe Mon Sep 17 00:00:00 2001 From: "LAKESIDE\\LindaT18" Date: Fri, 23 Aug 2019 16:46:33 -0700 Subject: [PATCH 02/63] added csv handling, added ref/inpath/outpath data options --- .../PLQE_analysis/column_selection_gui.ui | 104 ++++++++++++++++++ PythonGUI_apps/PLQE_analysis/plqe_analysis.py | 51 ++++++++- 2 files changed, 150 insertions(+), 5 deletions(-) create mode 100644 PythonGUI_apps/PLQE_analysis/column_selection_gui.ui diff --git a/PythonGUI_apps/PLQE_analysis/column_selection_gui.ui b/PythonGUI_apps/PLQE_analysis/column_selection_gui.ui new file mode 100644 index 0000000..63baac3 --- /dev/null +++ b/PythonGUI_apps/PLQE_analysis/column_selection_gui.ui @@ -0,0 +1,104 @@ + + + MainWindow + + + + 0 + 0 + 800 + 600 + + + + Select number of columns + + + + + + + Data preview + + + + + + + + Select data columns + + + + + + + + Ref + + + + + + + Inpath + + + + + + + Outpath + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + Done + + + + + + + + + + + + + + 0 + 0 + 800 + 31 + + + + + + + + diff --git a/PythonGUI_apps/PLQE_analysis/plqe_analysis.py b/PythonGUI_apps/PLQE_analysis/plqe_analysis.py index a560746..b03a005 100644 --- a/PythonGUI_apps/PLQE_analysis/plqe_analysis.py +++ b/PythonGUI_apps/PLQE_analysis/plqe_analysis.py @@ -5,7 +5,7 @@ from pyqtgraph import exporters from pyqtgraph.Qt import QtCore, QtGui, QtWidgets import matplotlib.pyplot as plt - +import pandas as pd import numpy as np import time @@ -69,14 +69,28 @@ def open_data_file(self): """ Open data file """ try: self.filename = QtWidgets.QFileDialog.getOpenFileName(self) - self.data = np.loadtxt(self.filename[0], delimiter = '\t', skiprows = 1) + #self.data = np.loadtxt(self.filename[0], delimiter = '\t', skiprows = 1) + if ".txt" in self.filename[0]: + self.data = np.loadtxt(self.filename[0], delimiter = '\t', skiprows = 1) + elif ".csv" in self.filename[0]: + self.data = np.loadtxt(self.filename[0], delimiter = ',', skiprows = 1) + self.cs_window = ColSelectionWindow(self.data) + self.cs_window.col_selection_signal.connect(self.open_with_col_selection) self.nm = np.copy(self.data[:,0]) - self.ref_data = np.copy(self.data[:,1]) - self.inpath_data = np.copy(self.data[:,2]) - self.outpath_data = np.copy(self.data[:,3]) + #self.ref_data = np.copy(self.data[:,1]) + #self.inpath_data = np.copy(self.data[:,2]) + #self.outpath_data = np.copy(self.data[:,3]) except Exception as err: print(format(err)) + def open_with_col_selection(self): + ref_data_col = self.cs_window.ui.ref_spinBox.value() - 1 #subtract since spinboxes refer to column num and not index + inpath_data_col = self.cs_window.ui.inpath_spinBox.value() - 1 + outpath_data_col = self.cs_window.ui.outpath_spinBox.value() - 1 + self.ref_data = np.copy(self.data[:,ref_data_col]) + self.inpath_data = np.copy(self.data[:,inpath_data_col]) + self.outpath_data = np.copy(self.data[:,outpath_data_col]) + def update_laser_spinBoxes(self): """ Update laser spinboxes based on line rois """ self.laser_start, self.laser_stop = self.laser_region.getRegion() @@ -158,6 +172,33 @@ def calculate_plqe(self): def clear(self): self.plot.clear() +"""Table view GUI""" +ui_file_path = (base_path / "column_selection_gui.ui").resolve() +col_selection_WindowTemplate, col_selection_TemplateBaseClass = pg.Qt.loadUiType(ui_file_path) + +class ColSelectionWindow(col_selection_TemplateBaseClass): + + col_selection_signal = QtCore.pyqtSignal() #signal to help with pass info back to MainWindow + + def __init__(self, data): + col_selection_TemplateBaseClass.__init__(self) + # Create the param window + self.ui = col_selection_WindowTemplate() + self.ui.setupUi(self) + self.ui.done_pushButton.clicked.connect(self.done) + + self.table_widget = pg.TableWidget() + self.ui.data_preview_groupBox.layout().addWidget(self.table_widget) + + self.table_widget.setData(data) + + self.setWindowFlag(QtCore.Qt.WindowCloseButtonHint, False) + self.show() + + def done(self): + self.col_selection_signal.emit() + self.close() + """Run the Main Window""" def run(): win = MainWindow() From 6dbf4e3d46e2e026c2cffa48acebdbc49d79d999 Mon Sep 17 00:00:00 2001 From: "LAKESIDE\\LindaT18" Date: Fri, 23 Aug 2019 16:58:24 -0700 Subject: [PATCH 03/63] disable col selection auto close --- PythonGUI_apps/PLQE_analysis/column_selection_gui.ui | 3 +++ PythonGUI_apps/PLQE_analysis/plqe_analysis.py | 8 ++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/PythonGUI_apps/PLQE_analysis/column_selection_gui.ui b/PythonGUI_apps/PLQE_analysis/column_selection_gui.ui index 63baac3..c20125c 100644 --- a/PythonGUI_apps/PLQE_analysis/column_selection_gui.ui +++ b/PythonGUI_apps/PLQE_analysis/column_selection_gui.ui @@ -80,6 +80,9 @@ + + + diff --git a/PythonGUI_apps/PLQE_analysis/plqe_analysis.py b/PythonGUI_apps/PLQE_analysis/plqe_analysis.py index b03a005..96e3b96 100644 --- a/PythonGUI_apps/PLQE_analysis/plqe_analysis.py +++ b/PythonGUI_apps/PLQE_analysis/plqe_analysis.py @@ -192,12 +192,16 @@ def __init__(self, data): self.table_widget.setData(data) - self.setWindowFlag(QtCore.Qt.WindowCloseButtonHint, False) + #self.setWindowFlag(QtCore.Qt.WindowCloseButtonHint, False) self.show() def done(self): self.col_selection_signal.emit() - self.close() + self.ui.textBrowser.setText("Data successfully loaded.") + #self.close() + + def closeEvent(self, event): + self.col_selection_signal.emit() """Run the Main Window""" def run(): From 28cbe559bb8cca3e1750e11d50a91ae9f23ae7eb Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Mon, 26 Aug 2019 13:54:13 -0700 Subject: [PATCH 04/63] fix loading files for single spec as saved from microscope app, added 'space' delim to fix it --- .../Spectrum_analysis/Spectra_plot_fit.py | 1458 +++++++++-------- 1 file changed, 734 insertions(+), 724 deletions(-) diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py index ba71f52..626bce0 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py @@ -21,9 +21,9 @@ import customplotting.mscope as cpm # local modules try: - from Spectra_fit_funcs import Spectra_Fit, Single_Gaussian, Single_Lorentzian, Double_Gaussian, Multi_Gaussian + from Spectra_fit_funcs import Spectra_Fit, Single_Gaussian, Single_Lorentzian, Double_Gaussian, Multi_Gaussian except: - from Spectrum_analysis.Spectra_fit_funcs import Spectra_Fit, Single_Gaussian, Single_Lorentzian, Double_Gaussian, Multi_Gaussian + from Spectrum_analysis.Spectra_fit_funcs import Spectra_Fit, Single_Gaussian, Single_Lorentzian, Double_Gaussian, Multi_Gaussian """Recylce params for plotting""" @@ -46,714 +46,724 @@ WindowTemplate, TemplateBaseClass = pg.Qt.loadUiType(uiFile) def updateDelay(scale, time): - """ Hack fix for scalebar inaccuracy""" - QtCore.QTimer.singleShot(time, scale.updateBar) + """ Hack fix for scalebar inaccuracy""" + QtCore.QTimer.singleShot(time, scale.updateBar) class MainWindow(TemplateBaseClass): - - def __init__(self): - pg.setConfigOption('imageAxisOrder', 'row-major') - super(TemplateBaseClass, self).__init__() - - # Create the main window - self.ui = WindowTemplate() - self.ui.setupUi(self) - - # self.ui.fitFunc_comboBox.addItems(["Single Gaussian","Single Lorentzian", "Double Gaussian", "Multiple Gaussians"]) + + def __init__(self): + pg.setConfigOption('imageAxisOrder', 'row-major') + super(TemplateBaseClass, self).__init__() + + # Create the main window + self.ui = WindowTemplate() + self.ui.setupUi(self) + + # self.ui.fitFunc_comboBox.addItems(["Single Gaussian","Single Lorentzian", "Double Gaussian", "Multiple Gaussians"]) # self.ui.actionExit.triggered.connect(self.close_application) - - ##setup ui signals - self.ui.importSpec_pushButton.clicked.connect(self.open_file) - self.ui.importBck_pushButton.clicked.connect(self.open_bck_file) - self.ui.importWLRef_pushButton.clicked.connect(self.open_wlref_file) - - self.ui.load_spectra_scan_pushButton.clicked.connect(self.open_spectra_scan_file) - self.ui.load_bck_file_pushButton.clicked.connect(self.open_spectra_bck_file) - self.ui.load_fitted_scan_pushButton.clicked.connect(self.open_fit_scan_file) - - self.ui.plot_pushButton.clicked.connect(self.plot) - self.ui.plot_fit_scan_pushButton.clicked.connect(self.plot_fit_scan) - self.ui.plot_raw_scan_pushButton.clicked.connect(self.plot_raw_scan) - self.ui.plot_intensity_sums_pushButton.clicked.connect(self.plot_intensity_sums) - - self.ui.fit_pushButton.clicked.connect(self.fit_and_plot) - self.ui.fit_scan_pushButton.clicked.connect(self.fit_and_plot_scan) - # self.ui.config_fit_params_pushButton.clicked.connect(self.configure_fit_params) - self.ui.clear_pushButton.clicked.connect(self.clear_plot) - self.ui.export_single_figure_pushButton.clicked.connect(self.pub_ready_plot_export) - self.ui.export_scan_figure_pushButton.clicked.connect(self.pub_ready_plot_export) - - self.ui.import_pkl_pushButton.clicked.connect(self.open_pkl_file) - self.ui.data_txt_pushButton.clicked.connect(self.pkl_data_to_txt) - self.ui.scan_params_txt_pushButton.clicked.connect(self.pkl_params_to_txt) - - self.ui.pkl_to_h5_pushButton.clicked.connect(self.pkl_to_h5) - - self.ui.tabWidget.currentChanged.connect(self.switch_overall_tab) - self.ui.fitFunc_comboBox.currentTextChanged.connect(self.switch_bounds_and_guess_tab) - self.ui.adjust_param_checkBox.stateChanged.connect(self.switch_adjust_param) - - self.ui.export_data_pushButton.clicked.connect(self.export_data) - self.ui.clear_export_data_pushButton.clicked.connect(self.clear_export_data) - - # for i in reversed(range(self.ui.bounds_groupBox.layout().count())): - # self.ui.bounds_groupBox.layout().itemAt(i).widget().deleteLater() - #self.ui.single_bounds_page.layout().addWidget(QtWidgets.QPushButton("test")) - - self.file = None - self.bck_file = None - self.wlref_file = None - self.x = None - self.y = None - self.out = None # output file after fitting - - # Peak parameters if adjust params is selected - self.center_min = None - self.center_max = None - - #variables accounting for data received from FLIM analysis - self.opened_from_flim = False #switched to True in FLIM_plot when "analyze lifetime" clicked - self.sum_data_from_flim = [] - - #container for data to append to txt file - self.data_list = [] - - self.show() - - """ Open Single Spectrum files """ - def open_file(self): - try: - self.single_spec_filename = QtWidgets.QFileDialog.getOpenFileName(self) - try: - self.file = np.loadtxt(self.single_spec_filename[0], skiprows = 16, delimiter='\t') - except: - self.file = np.genfromtxt(self.single_spec_filename[0], skip_header=1, skip_footer=3, delimiter='\t') - self.opened_from_flim = False - except: - pass - - def open_bck_file(self): - try: - filename = QtWidgets.QFileDialog.getOpenFileName(self) - try: - self.bck_file = np.loadtxt(filename[0], skiprows = 16, delimiter='\t') - except: - self.bck_file = np.genfromtxt(filename[0], skip_header=1, skip_footer=3, delimiter='\t') - except Exception as e: - self.ui.result_textBrowser.append(str(e)) - pass - - def open_wlref_file(self): - try: - filename = QtWidgets.QFileDialog.getOpenFileName(self) - try: - self.wlref_file = np.loadtxt(filename[0], skiprows = 16, delimiter='\t') - except: - self.wlref_file = np.genfromtxt(filename[0], skip_header=1, skip_footer=3, delimiter='\t') - except: - pass - - """Open Scan Files""" - def open_spectra_scan_file(self): - try: - filename = QtWidgets.QFileDialog.getOpenFileName(self, filter="Scan files (*.pkl *.h5)") - if ".pkl" in filename[0]: - self.spec_scan_file = pickle.load(open(filename[0], 'rb')) - self.scan_file_type = "pkl" - elif ".h5" in filename[0]: - self.spec_scan_file = h5py.File(filename[0], 'r') - self.scan_file_type = "h5" - self.get_data_params() - self.ui.result_textBrowser2.append("Done Loading - Spectra Scan File") - except Exception as e: - self.ui.result_textBrowser2.append(str(e)) - pass - - def open_spectra_bck_file(self): - try: - filename = QtWidgets.QFileDialog.getOpenFileName(self) - self.bck_file = np.loadtxt(filename[0])#, skiprows=1, delimiter=None) - self.ui.result_textBrowser2.append("Done Loading - Background File") - except Exception as e: - self.ui.result_textBrowser2.append(str(e)) - pass - - def open_fit_scan_file(self): - try: - filename = QtWidgets.QFileDialog.getOpenFileName(self) - self.fit_scan_file = pickle.load(open(filename[0], 'rb')) - self.ui.result_textBrowser2.append("Done Loading - Scan Fit File") - except Exception as e: - self.ui.result_textBrowser2.append(str(e)) - pass - - def open_pkl_file(self): - """ Open pkl file to convert to txt """ - try: - self.pkl_to_convert = QtWidgets.QFileDialog.getOpenFileName(self) - except: - pass - - def switch_overall_tab(self): - """ Enable/disable fit settings on right depending on current tab """ - if self.ui.tabWidget.currentIndex() == 0: - self.ui.fitting_settings_groupBox.setEnabled(True) - self.ui.fit_pushButton.setEnabled(True) - self.ui.fit_scan_pushButton.setEnabled(True) - self.ui.scan_fit_settings_groupBox.setEnabled(False) - elif self.ui.tabWidget.currentIndex() == 1: - self.ui.fitting_settings_groupBox.setEnabled(False) - self.ui.fit_pushButton.setEnabled(False) - self.ui.fit_scan_pushButton.setEnabled(True) - self.ui.scan_fit_settings_groupBox.setEnabled(True) - elif self.ui.tabWidget.currentIndex() == 2: - self.ui.fitting_settings_groupBox.setEnabled(False) - self.ui.fit_pushButton.setEnabled(False) - self.ui.fit_scan_pushButton.setEnabled(False) - self.ui.scan_fit_settings_groupBox.setEnabled(False) - - """ Single spectrum functions """ - def switch_bounds_and_guess_tab(self): - """ Show the appropriate bounds and initial guess params based on fit function """ - fit_func = self.ui.fitFunc_comboBox.currentText() - if fit_func == "Single Gaussian" or fit_func == "Single Lorentzian": - self.ui.n_label.setEnabled(False) - self.ui.n_spinBox.setEnabled(False) - self.ui.bounds_stackedWidget.setCurrentIndex(0) - self.ui.guess_stackedWidget.setCurrentIndex(0) - self.ui.plot_components_checkBox.setEnabled(False) - self.ui.n_spinBox.setValue(1) - elif fit_func == "Double Gaussian": - self.ui.n_label.setEnabled(False) - self.ui.n_spinBox.setEnabled(False) - self.ui.bounds_stackedWidget.setCurrentIndex(1) - self.ui.guess_stackedWidget.setCurrentIndex(1) - self.ui.plot_components_checkBox.setEnabled(True) - self.ui.n_spinBox.setValue(2) - elif fit_func == "Triple Gaussian": - self.ui.n_label.setEnabled(False) - self.ui.n_spinBox.setEnabled(False) - self.ui.bounds_stackedWidget.setCurrentIndex(2) - self.ui.guess_stackedWidget.setCurrentIndex(2) - self.ui.plot_components_checkBox.setEnabled(True) - self.ui.n_spinBox.setValue(3) - - def switch_adjust_param(self): - """ Enable bounds and initial guess only when adjust parameters is checked """ - checked = self.ui.adjust_param_checkBox.isChecked() - self.ui.bounds_groupBox.setEnabled(checked) - self.ui.guess_groupBox.setEnabled(checked) - - def check_loaded_files(self): - """ - Check if 'subtract background' or 'white light correction' is checked - and if required files have been loaded. - """ - if self.ui.subtract_bck_radioButton.isChecked() and self.bck_file is None: - self.ui.result_textBrowser.setText("You need to load a background file.") - elif self.wlref_file is not None and self.ui.WLRef_checkBox.isChecked() == False: - self.ui.result_textBrowser.setText("You need to check the White Light Correction option!") - elif self.wlref_file is None and self.ui.WLRef_checkBox.isChecked(): - self.ui.result_textBrowser.setText("You need to load a White Light Ref file.") - else: - return True - - def plot(self): - try: - if self.opened_from_flim: - flim_data = self.sum_data_from_flim.T - interp = interpolate.interp1d(flim_data[:,0], flim_data[:,1]) - x_range = [flim_data[:,0][0], flim_data[:,0][-1]] - xnew = np.linspace(x_range[0], x_range[1], 100 ) - ynew = interp(xnew) - self.file = np.zeros((xnew.shape[0], 2)) - self.file[:,0] = xnew - self.file[:,1] = ynew - self.x = xnew - self.y = ynew - - elif self.file is None: #elif - self.ui.result_textBrowser.setText("You need to load a data file.") - else: - self.x = self.file[:,0] - self.y = self.file[:,1] - - if self.check_loaded_files == True: #check the following conditions if all required files have been provided - if self.ui.subtract_bck_radioButton.isChecked() == True and self.ui.WLRef_checkBox.isChecked() == False: - bck_y = self.bck_file[:,1] - self.y = self.y - bck_y - elif self.ui.subtract_bck_radioButton.isChecked() == False and self.ui.WLRef_checkBox.isChecked() == True: - wlref_y = self.wlref_file[:,1] - self.y = (self.y)/wlref_y - - elif self.ui.subtract_bck_radioButton.isChecked() == True and self.ui.WLRef_checkBox.isChecked() == True: - bck_y = self.bck_file[:,1] - wlref_y = self.wlref_file[:,1] - self.y = (self.y-bck_y)/wlref_y - - - if self.ui.norm_checkBox.isChecked(): - self.normalize() - - self.ui.plot.plot(self.x, self.y, clear=self.clear_check(), pen='r') - - except Exception as err: - pass - self.ui.plot.setLabel('left', 'Intensity', units='a.u.') - self.ui.plot.setLabel('bottom', 'Wavelength (nm)') - - def normalize(self): - self.y = (self.y) / np.amax(self.y) - - def clear_plot(self): - self.ui.plot.clear() - self.ui.result_textBrowser.clear() - - def clear_check(self): - if self.ui.clear_checkBox.isChecked() == True: - return True - elif self.ui.clear_checkBox.isChecked() == False: - return False - - def fit_and_plot(self): - fit_func = self.ui.fitFunc_comboBox.currentText() - - try: - self.plot() - if self.opened_from_flim: - self.file = np.zeros((self.x.shape[0], 2)) - self.file[:,0] = self.x - self.file[:,1] = self.y - - if self.ui.plot_without_bck_radioButton.isChecked(): #if plot w/o bck, create dummy bck_file - self.bck_file = np.zeros(shape=(self.file.shape[0], 2)) - self.bck_file[:,0] = self.file[:,0] + + ##setup ui signals + self.ui.importSpec_pushButton.clicked.connect(self.open_file) + self.ui.importBck_pushButton.clicked.connect(self.open_bck_file) + self.ui.importWLRef_pushButton.clicked.connect(self.open_wlref_file) + + self.ui.load_spectra_scan_pushButton.clicked.connect(self.open_spectra_scan_file) + self.ui.load_bck_file_pushButton.clicked.connect(self.open_spectra_bck_file) + self.ui.load_fitted_scan_pushButton.clicked.connect(self.open_fit_scan_file) + + self.ui.plot_pushButton.clicked.connect(self.plot) + self.ui.plot_fit_scan_pushButton.clicked.connect(self.plot_fit_scan) + self.ui.plot_raw_scan_pushButton.clicked.connect(self.plot_raw_scan) + self.ui.plot_intensity_sums_pushButton.clicked.connect(self.plot_intensity_sums) + + self.ui.fit_pushButton.clicked.connect(self.fit_and_plot) + self.ui.fit_scan_pushButton.clicked.connect(self.fit_and_plot_scan) + # self.ui.config_fit_params_pushButton.clicked.connect(self.configure_fit_params) + self.ui.clear_pushButton.clicked.connect(self.clear_plot) + self.ui.export_single_figure_pushButton.clicked.connect(self.pub_ready_plot_export) + self.ui.export_scan_figure_pushButton.clicked.connect(self.pub_ready_plot_export) + + self.ui.import_pkl_pushButton.clicked.connect(self.open_pkl_file) + self.ui.data_txt_pushButton.clicked.connect(self.pkl_data_to_txt) + self.ui.scan_params_txt_pushButton.clicked.connect(self.pkl_params_to_txt) + + self.ui.pkl_to_h5_pushButton.clicked.connect(self.pkl_to_h5) + + self.ui.tabWidget.currentChanged.connect(self.switch_overall_tab) + self.ui.fitFunc_comboBox.currentTextChanged.connect(self.switch_bounds_and_guess_tab) + self.ui.adjust_param_checkBox.stateChanged.connect(self.switch_adjust_param) + + self.ui.export_data_pushButton.clicked.connect(self.export_data) + self.ui.clear_export_data_pushButton.clicked.connect(self.clear_export_data) + + # for i in reversed(range(self.ui.bounds_groupBox.layout().count())): + # self.ui.bounds_groupBox.layout().itemAt(i).widget().deleteLater() + #self.ui.single_bounds_page.layout().addWidget(QtWidgets.QPushButton("test")) + + self.file = None + self.bck_file = None + self.wlref_file = None + self.x = None + self.y = None + self.out = None # output file after fitting + + # Peak parameters if adjust params is selected + self.center_min = None + self.center_max = None + + #variables accounting for data received from FLIM analysis + self.opened_from_flim = False #switched to True in FLIM_plot when "analyze lifetime" clicked + self.sum_data_from_flim = [] + + #container for data to append to txt file + self.data_list = [] + + self.show() + + """ Open Single Spectrum files """ + def open_file(self): + try: + self.single_spec_filename = QtWidgets.QFileDialog.getOpenFileName(self) + try: + try: + self.file = np.loadtxt(self.single_spec_filename[0], skiprows = 1, delimiter=" ") + except: + np.loadtxt(self.single_spec_filename[0], skiprows = 16, delimiter='\t') + except: + self.file = np.genfromtxt(self.single_spec_filename[0], skip_header=1, skip_footer=3, delimiter='\t') + self.opened_from_flim = False + except: + pass + + def open_bck_file(self): + try: + filename = QtWidgets.QFileDialog.getOpenFileName(self) + try: + try: + self.bck_file = np.loadtxt(filename[0], skiprows=1, delimiter=" ") + except: + self.bck_file = np.loadtxt(filename[0], skiprows = 16, delimiter='\t') + except: + self.bck_file = np.genfromtxt(filename[0], skip_header=1, skip_footer=3, delimiter='\t') + except Exception as e: + self.ui.result_textBrowser.append(str(e)) + pass + + def open_wlref_file(self): + try: + filename = QtWidgets.QFileDialog.getOpenFileName(self) + try: + try: + self.wlref_file = np.loadtxt(filename[0], skiprows=1, delimiter= " ") + except: + self.wlref_file = np.loadtxt(filename[0], skiprows = 16, delimiter='\t') + except: + self.wlref_file = np.genfromtxt(filename[0], skip_header=1, skip_footer=3, delimiter='\t') + except: + pass + + """Open Scan Files""" + def open_spectra_scan_file(self): + try: + filename = QtWidgets.QFileDialog.getOpenFileName(self, filter="Scan files (*.pkl *.h5)") + if ".pkl" in filename[0]: + self.spec_scan_file = pickle.load(open(filename[0], 'rb')) + self.scan_file_type = "pkl" + elif ".h5" in filename[0]: + self.spec_scan_file = h5py.File(filename[0], 'r') + self.scan_file_type = "h5" + self.get_data_params() + self.ui.result_textBrowser2.append("Done Loading - Spectra Scan File") + except Exception as e: + self.ui.result_textBrowser2.append(str(e)) + pass + + def open_spectra_bck_file(self): + try: + filename = QtWidgets.QFileDialog.getOpenFileName(self) + self.bck_file = np.loadtxt(filename[0])#, skiprows=1, delimiter=None) + self.ui.result_textBrowser2.append("Done Loading - Background File") + except Exception as e: + self.ui.result_textBrowser2.append(str(e)) + pass + + def open_fit_scan_file(self): + try: + filename = QtWidgets.QFileDialog.getOpenFileName(self) + self.fit_scan_file = pickle.load(open(filename[0], 'rb')) + self.ui.result_textBrowser2.append("Done Loading - Scan Fit File") + except Exception as e: + self.ui.result_textBrowser2.append(str(e)) + pass + + def open_pkl_file(self): + """ Open pkl file to convert to txt """ + try: + self.pkl_to_convert = QtWidgets.QFileDialog.getOpenFileName(self) + except: + pass + + def switch_overall_tab(self): + """ Enable/disable fit settings on right depending on current tab """ + if self.ui.tabWidget.currentIndex() == 0: + self.ui.fitting_settings_groupBox.setEnabled(True) + self.ui.fit_pushButton.setEnabled(True) + self.ui.fit_scan_pushButton.setEnabled(True) + self.ui.scan_fit_settings_groupBox.setEnabled(False) + elif self.ui.tabWidget.currentIndex() == 1: + self.ui.fitting_settings_groupBox.setEnabled(False) + self.ui.fit_pushButton.setEnabled(False) + self.ui.fit_scan_pushButton.setEnabled(True) + self.ui.scan_fit_settings_groupBox.setEnabled(True) + elif self.ui.tabWidget.currentIndex() == 2: + self.ui.fitting_settings_groupBox.setEnabled(False) + self.ui.fit_pushButton.setEnabled(False) + self.ui.fit_scan_pushButton.setEnabled(False) + self.ui.scan_fit_settings_groupBox.setEnabled(False) + + """ Single spectrum functions """ + def switch_bounds_and_guess_tab(self): + """ Show the appropriate bounds and initial guess params based on fit function """ + fit_func = self.ui.fitFunc_comboBox.currentText() + if fit_func == "Single Gaussian" or fit_func == "Single Lorentzian": + self.ui.n_label.setEnabled(False) + self.ui.n_spinBox.setEnabled(False) + self.ui.bounds_stackedWidget.setCurrentIndex(0) + self.ui.guess_stackedWidget.setCurrentIndex(0) + self.ui.plot_components_checkBox.setEnabled(False) + self.ui.n_spinBox.setValue(1) + elif fit_func == "Double Gaussian": + self.ui.n_label.setEnabled(False) + self.ui.n_spinBox.setEnabled(False) + self.ui.bounds_stackedWidget.setCurrentIndex(1) + self.ui.guess_stackedWidget.setCurrentIndex(1) + self.ui.plot_components_checkBox.setEnabled(True) + self.ui.n_spinBox.setValue(2) + elif fit_func == "Triple Gaussian": + self.ui.n_label.setEnabled(False) + self.ui.n_spinBox.setEnabled(False) + self.ui.bounds_stackedWidget.setCurrentIndex(2) + self.ui.guess_stackedWidget.setCurrentIndex(2) + self.ui.plot_components_checkBox.setEnabled(True) + self.ui.n_spinBox.setValue(3) + + def switch_adjust_param(self): + """ Enable bounds and initial guess only when adjust parameters is checked """ + checked = self.ui.adjust_param_checkBox.isChecked() + self.ui.bounds_groupBox.setEnabled(checked) + self.ui.guess_groupBox.setEnabled(checked) + + def check_loaded_files(self): + """ + Check if 'subtract background' or 'white light correction' is checked + and if required files have been loaded. + """ + if self.ui.subtract_bck_radioButton.isChecked() and self.bck_file is None: + self.ui.result_textBrowser.setText("You need to load a background file.") + elif self.wlref_file is not None and self.ui.WLRef_checkBox.isChecked() == False: + self.ui.result_textBrowser.setText("You need to check the White Light Correction option!") + elif self.wlref_file is None and self.ui.WLRef_checkBox.isChecked(): + self.ui.result_textBrowser.setText("You need to load a White Light Ref file.") + else: + return True + + def plot(self): + try: + if self.opened_from_flim: + flim_data = self.sum_data_from_flim.T + interp = interpolate.interp1d(flim_data[:,0], flim_data[:,1]) + x_range = [flim_data[:,0][0], flim_data[:,0][-1]] + xnew = np.linspace(x_range[0], x_range[1], 100 ) + ynew = interp(xnew) + self.file = np.zeros((xnew.shape[0], 2)) + self.file[:,0] = xnew + self.file[:,1] = ynew + self.x = xnew + self.y = ynew + + elif self.file is None: #elif + self.ui.result_textBrowser.setText("You need to load a data file.") + else: + self.x = self.file[:,0] + self.y = self.file[:,1] + + if self.check_loaded_files == True: #check the following conditions if all required files have been provided + if self.ui.subtract_bck_radioButton.isChecked() == True and self.ui.WLRef_checkBox.isChecked() == False: + bck_y = self.bck_file[:,1] + self.y = self.y - bck_y + elif self.ui.subtract_bck_radioButton.isChecked() == False and self.ui.WLRef_checkBox.isChecked() == True: + wlref_y = self.wlref_file[:,1] + self.y = (self.y)/wlref_y + + elif self.ui.subtract_bck_radioButton.isChecked() == True and self.ui.WLRef_checkBox.isChecked() == True: + bck_y = self.bck_file[:,1] + wlref_y = self.wlref_file[:,1] + self.y = (self.y-bck_y)/wlref_y + + + if self.ui.norm_checkBox.isChecked(): + self.normalize() + + self.ui.plot.plot(self.x, self.y, clear=self.clear_check(), pen='r') + + except Exception as e: + self.ui.result_textBrowser.append(str(e)) + pass + self.ui.plot.setLabel('left', 'Intensity', units='a.u.') + self.ui.plot.setLabel('bottom', 'Wavelength (nm)') + + def normalize(self): + self.y = (self.y) / np.amax(self.y) + + def clear_plot(self): + self.ui.plot.clear() + self.ui.result_textBrowser.clear() + + def clear_check(self): + if self.ui.clear_checkBox.isChecked() == True: + return True + elif self.ui.clear_checkBox.isChecked() == False: + return False + + def fit_and_plot(self): + fit_func = self.ui.fitFunc_comboBox.currentText() + + try: + self.plot() + if self.opened_from_flim: + self.file = np.zeros((self.x.shape[0], 2)) + self.file[:,0] = self.x + self.file[:,1] = self.y + + if self.ui.plot_without_bck_radioButton.isChecked(): #if plot w/o bck, create dummy bck_file + self.bck_file = np.zeros(shape=(self.file.shape[0], 2)) + self.bck_file[:,0] = self.file[:,0] - # if self.ui.subtract_bck_radioButton.isChecked() == False: - # self.ui.result_textBrowser.setText("You need to check the subtract background option!") - if self.check_loaded_files is None: - pass - else: - - if fit_func == "Single Gaussian": #and self.ui.subtract_bck_radioButton.isChecked() == True: - single_gauss = Single_Gaussian(self.file, self.bck_file, wlref=self.wlref_file) - if self.ui.adjust_param_checkBox.isChecked(): - center1_min = self.ui.single_peakcenter1_min_spinBox.value() - center1_max = self.ui.single_peakcenter1_max_spinBox.value() - center1_guess = self.ui.single_peakcenter1_guess_spinBox.value() - sigma1_guess = self.ui.single_sigma1_guess_spinBox.value() - self.result = single_gauss.gaussian_model_w_lims(center1_guess, sigma1_guess, - [center1_min, center1_max]) - else: - self.result = single_gauss.gaussian_model() - self.ui.plot.plot(self.x, self.y, clear=self.clear_check(), pen='r') - self.ui.plot.plot(self.x, self.result.best_fit, clear=False, pen='k') - self.ui.result_textBrowser.setText(self.result.fit_report()) - - elif fit_func == "Single Lorentzian": #and self.ui.subtract_bck_radioButton.isChecked() == True: - single_lorentzian = Single_Lorentzian(self.file, self.bck_file, wlref=self.wlref_file) - - if self.ui.adjust_param_checkBox.isChecked(): - center1_min = self.ui.single_peakcenter1_min_spinBox.value() - center1_max = self.ui.single_peakcenter1_max_spinBox.value() - center1_guess = self.ui.single_peakcenter1_guess_spinBox.value() - sigma1_guess = self.ui.single_sigma1_guess_spinBox.value() - self.result = single_lorentzian.lorentzian_model_w_lims(center1_guess, sigma1_guess, - [center1_min, center1_max]) - else: - self.result = single_lorentzian.lorentzian_model() - self.ui.plot.plot(self.x, self.y, clear=self.clear_check(), pen='r') - self.ui.plot.plot(self.x, self.result.best_fit, clear=False, pen='k') - self.ui.result_textBrowser.setText(self.result.fit_report()) - - elif fit_func == "Double Gaussian": #and self.ui.subtract_bck_radioButton.isChecked() == True: - double_gauss = Double_Gaussian(self.file, self.bck_file, wlref=self.wlref_file) - if self.ui.adjust_param_checkBox.isChecked(): - center1_min = self.ui.double_peakcenter1_min_spinBox.value() - center1_max = self.ui.double_peakcenter1_max_spinBox.value() - center2_min = self.ui.double_peakcenter2_min_spinBox.value() - center2_max = self.ui.double_peakcenter2_max_spinBox.value() - center1_guess = self.ui.double_peakcenter1_guess_spinBox.value() - sigma1_guess = self.ui.double_sigma1_guess_spinBox.value() - center2_guess = self.ui.double_peakcenter2_guess_spinBox.value() - sigma2_guess = self.ui.double_sigma2_guess_spinBox.value() - - peak_pos = [center1_guess, center2_guess] - sigma = [sigma1_guess, sigma2_guess] - min_max_range = [ [center1_min, center1_max], [center2_min, center2_max] ] - self.result = double_gauss.gaussian_model_w_lims(peak_pos, sigma, min_max_range) - - else: - self.result = double_gauss.gaussian_model() - - self.ui.plot.plot(self.x, self.y, clear=self.clear_check(), pen='r') - self.ui.plot.plot(self.x, self.result.best_fit, clear=False, pen='k') - if self.ui.plot_components_checkBox.isChecked(): - comps = self.result.eval_components(x=self.x) - self.ui.plot.plot(self.x, comps['g1_'], pen='b', clear=False) - self.ui.plot.plot(self.x, comps['g2_'], pen='g', clear=False) - - self.ui.result_textBrowser.setText(self.result.fit_report()) - - elif fit_func == "Triple Gaussian": #and self.ui.subtract_bck_radioButton.isChecked() == True: - #currently only works for triple gaussian (n=3) - multiple_gauss = Multi_Gaussian(self.file, self.bck_file, 3, wlref=self.wlref_file) - if self.ui.adjust_param_checkBox.isChecked(): - center1_min = self.ui.multi_peakcenter1_min_spinBox.value() - center1_max = self.ui.multi_peakcenter1_max_spinBox.value() - center2_min = self.ui.multi_peakcenter2_min_spinBox.value() - center2_max = self.ui.multi_peakcenter2_max_spinBox.value() - center3_min = self.ui.multi_peakcenter3_min_spinBox.value() - center3_max = self.ui.multi_peakcenter3_max_spinBox.value() - center1_guess = self.ui.multi_peakcenter1_guess_spinBox.value() - sigma1_guess = self.ui.multi_sigma1_guess_spinBox.value() - center2_guess = self.ui.multi_peakcenter2_guess_spinBox.value() - sigma2_guess = self.ui.multi_sigma2_guess_spinBox.value() - center3_guess = self.ui.multi_peakcenter3_guess_spinBox.value() - sigma3_guess = self.ui.multi_sigma3_guess_spinBox.value() - num_gaussians = 3 - peak_pos = [center1_guess, center2_guess, center3_guess] - sigma = [sigma1_guess, sigma2_guess, sigma3_guess] - min_max_range = [ [center1_min, center1_max], [center2_min, center2_max], [center3_min, center3_max] ] - - self.result = multiple_gauss.gaussian_model_w_lims(peak_pos, sigma, min_max_range) - else: - self.result = multiple_gauss.gaussian_model() - - self.ui.plot.plot(self.x, self.y, clear=self.clear_check(), pen='r') - self.ui.plot.plot(self.x, self.result.best_fit, clear=False, pen='k') - if self.ui.plot_components_checkBox.isChecked(): - comps = self.result.eval_components(x=self.x) - self.ui.plot.plot(self.x, comps['g1_'], pen='b', clear=False) - self.ui.plot.plot(self.x, comps['g2_'], pen='g', clear=False) - self.ui.plot.plot(self.x, comps['g3_'], pen='c', clear=False) - self.ui.result_textBrowser.setText(self.result.fit_report()) - - self.data_list.append(self.ui.result_textBrowser.toPlainText()) - - except Exception as e: - self.ui.result_textBrowser.append(str(e)) - - def pub_ready_plot_export(self): - filename = QtWidgets.QFileDialog.getSaveFileName(self,caption="Filename with EXTENSION") - try: - try: - data = self.spec_scan_file - param_selection = str(self.ui.comboBox.currentText()) - if param_selection == 'pk_pos': label = 'PL Peak Position (n.m.)' - elif param_selection == 'fwhm': label = 'PL FWHM (n.m.)' - cpm.plot_confocal(self.img, figsize=(10,10), stepsize = data['Scan Parameters']['X step size (um)'], cmap="seismic", cbar_label=label) - plt.savefig(filename[0],bbox_inches='tight', dpi=300) - plt.close() - except: - plt.figure(figsize=(8,6)) - plt.tick_params(direction='out', length=8, width=3.5) - plt.plot(self.x, self.y) - plt.plot(self.x, self.result.best_fit,'k') - plt.xlabel("Wavelength (nm)", fontsize=20, fontweight='bold') - plt.ylabel("Intensity (a.u.)", fontsize=20, fontweight='bold') - plt.tight_layout() - - plt.savefig(filename[0],bbox_inches='tight', dpi=300) - plt.close() - - except AttributeError: - self.ui.result_textBrowser.setText("Need to fit the data first!") - - def export_data(self): - """ Save fit params and srv calculations stored in data_list as .txt """ - folder = os.path.dirname(self.single_spec_filename[0]) - filename_ext = os.path.basename(self.single_spec_filename[0]) - filename = os.path.splitext(filename_ext)[0] #get filename without extension - - path = folder + "/" + filename + "_fit_results.txt" - if not os.path.exists(path): - file = open(path, "w+") - else: - file = open(path, "a+") - - for i in range(len(self.data_list)): - file.write(self.data_list[i] + "\n\n") - - self.data_list = [] - file.close() - - def clear_export_data(self): - self.data_list = [] - - - """ Scan spectra functions """ - def get_data_params(self): - data = self.spec_scan_file - if self.scan_file_type == "pkl": - self.intensities = data['Intensities'] - self.wavelengths = data['Wavelengths'] - # try: - self.x_scan_size = data['Scan Parameters']['X scan size (um)'] - self.y_scan_size = data['Scan Parameters']['Y scan size (um)'] - self.x_step_size = data['Scan Parameters']['X step size (um)'] - self.y_step_size = data['Scan Parameters']['Y step size (um)'] - # except: # TODO test and debug loading pkl file w/o scan parameters - # self.configure_scan_params() - # while not hasattr(self, "scan_params_entered"): - # pass - # self.x_scan_size = self.param_window.ui.x_scan_size_spinBox.value() - # self.y_scan_size = self.param_window.ui.y_scan_size_spinBox.value() - # self.x_step_size = self.param_window.ui.x_step_size_spinBox.value() - # self.y_step_size = self.param_window.ui.y_step_size_spinBox.value() - - else: #run this if scan file is h5 - self.x_scan_size = data['Scan Parameters'].attrs['X scan size (um)'] - self.y_scan_size = data['Scan Parameters'].attrs['Y scan size (um)'] - self.x_step_size = data['Scan Parameters'].attrs['X step size (um)'] - self.y_step_size = data['Scan Parameters'].attrs['Y step size (um)'] - self.intensities = data['Intensities'][()] #get dataset values - self.wavelengths = data['Wavelengths'][()] - - self.numb_x_pixels = int(self.x_scan_size/self.x_step_size) - self.numb_y_pixels = int(self.y_scan_size/self.y_step_size) - - """Open param window and get peak center range values and assign it to variables to use later""" - # def configure_scan_params(self): - # self.param_window = ParamWindow() - # self.param_window.peak_range.connect(self.peak_range) - - # def peak_range(self, peaks): - # self.center_min = peaks[0] - # self.center_max = peaks[1] - - def plot_fit_scan(self): - try: - if self.ui.use_raw_scan_settings.isChecked(): - num_x = self.numb_x_pixels - num_y =self.numb_y_pixels - else: - num_x = self.ui.num_x_spinBox.value() - num_y = self.ui.num_y_spinBox.value() - - numb_of_points = num_x * num_y #75*75 - - fwhm = np.zeros(shape=(numb_of_points,1)) - pk_pos = np.zeros(shape=(numb_of_points,1)) + # if self.ui.subtract_bck_radioButton.isChecked() == False: + # self.ui.result_textBrowser.setText("You need to check the subtract background option!") + if self.check_loaded_files is None: + pass + else: + + if fit_func == "Single Gaussian": #and self.ui.subtract_bck_radioButton.isChecked() == True: + single_gauss = Single_Gaussian(self.file, self.bck_file, wlref=self.wlref_file) + if self.ui.adjust_param_checkBox.isChecked(): + center1_min = self.ui.single_peakcenter1_min_spinBox.value() + center1_max = self.ui.single_peakcenter1_max_spinBox.value() + center1_guess = self.ui.single_peakcenter1_guess_spinBox.value() + sigma1_guess = self.ui.single_sigma1_guess_spinBox.value() + self.result = single_gauss.gaussian_model_w_lims(center1_guess, sigma1_guess, + [center1_min, center1_max]) + else: + self.result = single_gauss.gaussian_model() + self.ui.plot.plot(self.x, self.y, clear=self.clear_check(), pen='r') + self.ui.plot.plot(self.x, self.result.best_fit, clear=False, pen='k') + self.ui.result_textBrowser.setText(self.result.fit_report()) + + elif fit_func == "Single Lorentzian": #and self.ui.subtract_bck_radioButton.isChecked() == True: + single_lorentzian = Single_Lorentzian(self.file, self.bck_file, wlref=self.wlref_file) + + if self.ui.adjust_param_checkBox.isChecked(): + center1_min = self.ui.single_peakcenter1_min_spinBox.value() + center1_max = self.ui.single_peakcenter1_max_spinBox.value() + center1_guess = self.ui.single_peakcenter1_guess_spinBox.value() + sigma1_guess = self.ui.single_sigma1_guess_spinBox.value() + self.result = single_lorentzian.lorentzian_model_w_lims(center1_guess, sigma1_guess, + [center1_min, center1_max]) + else: + self.result = single_lorentzian.lorentzian_model() + self.ui.plot.plot(self.x, self.y, clear=self.clear_check(), pen='r') + self.ui.plot.plot(self.x, self.result.best_fit, clear=False, pen='k') + self.ui.result_textBrowser.setText(self.result.fit_report()) + + elif fit_func == "Double Gaussian": #and self.ui.subtract_bck_radioButton.isChecked() == True: + double_gauss = Double_Gaussian(self.file, self.bck_file, wlref=self.wlref_file) + if self.ui.adjust_param_checkBox.isChecked(): + center1_min = self.ui.double_peakcenter1_min_spinBox.value() + center1_max = self.ui.double_peakcenter1_max_spinBox.value() + center2_min = self.ui.double_peakcenter2_min_spinBox.value() + center2_max = self.ui.double_peakcenter2_max_spinBox.value() + center1_guess = self.ui.double_peakcenter1_guess_spinBox.value() + sigma1_guess = self.ui.double_sigma1_guess_spinBox.value() + center2_guess = self.ui.double_peakcenter2_guess_spinBox.value() + sigma2_guess = self.ui.double_sigma2_guess_spinBox.value() + + peak_pos = [center1_guess, center2_guess] + sigma = [sigma1_guess, sigma2_guess] + min_max_range = [ [center1_min, center1_max], [center2_min, center2_max] ] + self.result = double_gauss.gaussian_model_w_lims(peak_pos, sigma, min_max_range) + + else: + self.result = double_gauss.gaussian_model() + + self.ui.plot.plot(self.x, self.y, clear=self.clear_check(), pen='r') + self.ui.plot.plot(self.x, self.result.best_fit, clear=False, pen='k') + if self.ui.plot_components_checkBox.isChecked(): + comps = self.result.eval_components(x=self.x) + self.ui.plot.plot(self.x, comps['g1_'], pen='b', clear=False) + self.ui.plot.plot(self.x, comps['g2_'], pen='g', clear=False) + + self.ui.result_textBrowser.setText(self.result.fit_report()) + + elif fit_func == "Triple Gaussian": #and self.ui.subtract_bck_radioButton.isChecked() == True: + #currently only works for triple gaussian (n=3) + multiple_gauss = Multi_Gaussian(self.file, self.bck_file, 3, wlref=self.wlref_file) + if self.ui.adjust_param_checkBox.isChecked(): + center1_min = self.ui.multi_peakcenter1_min_spinBox.value() + center1_max = self.ui.multi_peakcenter1_max_spinBox.value() + center2_min = self.ui.multi_peakcenter2_min_spinBox.value() + center2_max = self.ui.multi_peakcenter2_max_spinBox.value() + center3_min = self.ui.multi_peakcenter3_min_spinBox.value() + center3_max = self.ui.multi_peakcenter3_max_spinBox.value() + center1_guess = self.ui.multi_peakcenter1_guess_spinBox.value() + sigma1_guess = self.ui.multi_sigma1_guess_spinBox.value() + center2_guess = self.ui.multi_peakcenter2_guess_spinBox.value() + sigma2_guess = self.ui.multi_sigma2_guess_spinBox.value() + center3_guess = self.ui.multi_peakcenter3_guess_spinBox.value() + sigma3_guess = self.ui.multi_sigma3_guess_spinBox.value() + num_gaussians = 3 + peak_pos = [center1_guess, center2_guess, center3_guess] + sigma = [sigma1_guess, sigma2_guess, sigma3_guess] + min_max_range = [ [center1_min, center1_max], [center2_min, center2_max], [center3_min, center3_max] ] + + self.result = multiple_gauss.gaussian_model_w_lims(peak_pos, sigma, min_max_range) + else: + self.result = multiple_gauss.gaussian_model() + + self.ui.plot.plot(self.x, self.y, clear=self.clear_check(), pen='r') + self.ui.plot.plot(self.x, self.result.best_fit, clear=False, pen='k') + if self.ui.plot_components_checkBox.isChecked(): + comps = self.result.eval_components(x=self.x) + self.ui.plot.plot(self.x, comps['g1_'], pen='b', clear=False) + self.ui.plot.plot(self.x, comps['g2_'], pen='g', clear=False) + self.ui.plot.plot(self.x, comps['g3_'], pen='c', clear=False) + self.ui.result_textBrowser.setText(self.result.fit_report()) + + self.data_list.append(self.ui.result_textBrowser.toPlainText()) + + except Exception as e: + self.ui.result_textBrowser.append(str(e)) + + def pub_ready_plot_export(self): + filename = QtWidgets.QFileDialog.getSaveFileName(self,caption="Filename with EXTENSION") + try: + try: + data = self.spec_scan_file + param_selection = str(self.ui.comboBox.currentText()) + if param_selection == 'pk_pos': label = 'PL Peak Position (n.m.)' + elif param_selection == 'fwhm': label = 'PL FWHM (n.m.)' + cpm.plot_confocal(self.img, figsize=(10,10), stepsize = data['Scan Parameters']['X step size (um)'], cmap="seismic", cbar_label=label) + plt.savefig(filename[0],bbox_inches='tight', dpi=300) + plt.close() + except: + plt.figure(figsize=(8,6)) + plt.tick_params(direction='out', length=8, width=3.5) + plt.plot(self.x, self.y) + plt.plot(self.x, self.result.best_fit,'k') + plt.xlabel("Wavelength (nm)", fontsize=20, fontweight='bold') + plt.ylabel("Intensity (a.u.)", fontsize=20, fontweight='bold') + plt.tight_layout() + + plt.savefig(filename[0],bbox_inches='tight', dpi=300) + plt.close() + + except AttributeError: + self.ui.result_textBrowser.setText("Need to fit the data first!") + + def export_data(self): + """ Save fit params and srv calculations stored in data_list as .txt """ + folder = os.path.dirname(self.single_spec_filename[0]) + filename_ext = os.path.basename(self.single_spec_filename[0]) + filename = os.path.splitext(filename_ext)[0] #get filename without extension + + path = folder + "/" + filename + "_fit_results.txt" + if not os.path.exists(path): + file = open(path, "w+") + else: + file = open(path, "a+") + + for i in range(len(self.data_list)): + file.write(self.data_list[i] + "\n\n") + + self.data_list = [] + file.close() + + def clear_export_data(self): + self.data_list = [] + + + """ Scan spectra functions """ + def get_data_params(self): + data = self.spec_scan_file + if self.scan_file_type == "pkl": + self.intensities = data['Intensities'] + self.wavelengths = data['Wavelengths'] + # try: + self.x_scan_size = data['Scan Parameters']['X scan size (um)'] + self.y_scan_size = data['Scan Parameters']['Y scan size (um)'] + self.x_step_size = data['Scan Parameters']['X step size (um)'] + self.y_step_size = data['Scan Parameters']['Y step size (um)'] + # except: # TODO test and debug loading pkl file w/o scan parameters + # self.configure_scan_params() + # while not hasattr(self, "scan_params_entered"): + # pass + # self.x_scan_size = self.param_window.ui.x_scan_size_spinBox.value() + # self.y_scan_size = self.param_window.ui.y_scan_size_spinBox.value() + # self.x_step_size = self.param_window.ui.x_step_size_spinBox.value() + # self.y_step_size = self.param_window.ui.y_step_size_spinBox.value() + + else: #run this if scan file is h5 + self.x_scan_size = data['Scan Parameters'].attrs['X scan size (um)'] + self.y_scan_size = data['Scan Parameters'].attrs['Y scan size (um)'] + self.x_step_size = data['Scan Parameters'].attrs['X step size (um)'] + self.y_step_size = data['Scan Parameters'].attrs['Y step size (um)'] + self.intensities = data['Intensities'][()] #get dataset values + self.wavelengths = data['Wavelengths'][()] + + self.numb_x_pixels = int(self.x_scan_size/self.x_step_size) + self.numb_y_pixels = int(self.y_scan_size/self.y_step_size) + + """Open param window and get peak center range values and assign it to variables to use later""" + # def configure_scan_params(self): + # self.param_window = ParamWindow() + # self.param_window.peak_range.connect(self.peak_range) + + # def peak_range(self, peaks): + # self.center_min = peaks[0] + # self.center_max = peaks[1] + + def plot_fit_scan(self): + try: + if self.ui.use_raw_scan_settings.isChecked(): + num_x = self.numb_x_pixels + num_y =self.numb_y_pixels + else: + num_x = self.ui.num_x_spinBox.value() + num_y = self.ui.num_y_spinBox.value() + + numb_of_points = num_x * num_y #75*75 + + fwhm = np.zeros(shape=(numb_of_points,1)) + pk_pos = np.zeros(shape=(numb_of_points,1)) # pk_pos_plus = np.zeros(shape=(numb_of_points,1)) # pk_pos_minus = np.zeros(shape=(numb_of_points,1)) - sigma = np.zeros(shape=(numb_of_points,1)) - height = np.zeros(shape=(numb_of_points,1)) - - for i in range(numb_of_points): - fwhm[i, 0] = self.fit_scan_file['result_'+str(i)].values['g1_fwhm'] - pk_pos[i, 0] = self.fit_scan_file['result_'+str(i)].values['g1_center'] - sigma[i, 0] = self.fit_scan_file['result_'+str(i)].values['g1_sigma'] - height[i, 0] = self.fit_scan_file['result_'+str(i)].values['g1_height'] - - newshape = (num_x, num_y) - - param_selection = str(self.ui.comboBox.currentText()) - self.img = np.reshape(eval(param_selection), newshape) - - if self.ui.use_raw_scan_settings.isChecked(): - self.ui.fit_scan_viewbox.setImage(self.img, scale= - (self.x_step_size, - self.y_step_size)) - scale = pg.ScaleBar(size=2,suffix='um') - scale.setParentItem(self.ui.fit_scan_viewbox.view) - scale.anchor((1, 1), (1, 1), offset=(-30, -30)) - self.ui.fit_scan_viewbox.view.sigRangeChanged.connect(lambda: updateDelay(scale, 10)) - else: - self.ui.fit_scan_viewbox.setImage(self.img) - - self.ui.fit_scan_viewbox.view.invertY(False) - - except Exception as e: - self.ui.result_textBrowser2.append(str(e)) - pass - - def plot_raw_scan(self): - try: - # TODO test line scan plots - - intensities = self.intensities.T #this is only there because of how we are saving the data in the app - intensities = np.reshape(intensities, newshape=(2048,self.numb_x_pixels, self.numb_y_pixels)) - self.ui.raw_scan_viewbox.setImage(intensities, scale= - (self.x_step_size, - self.y_step_size), xvals=self.wavelengths) - - #roi_plot = self.ui.raw_scan_viewBox.getRoiPlot() - #roi_plot.plot(data['Wavelengths'], intensities) - self.ui.raw_scan_viewbox.view.invertY(False) - scale = pg.ScaleBar(size=2,suffix='um') - scale.setParentItem(self.ui.raw_scan_viewbox.view) - scale.anchor((1, 1), (1, 1), offset=(-30, -30)) - self.ui.raw_scan_viewbox.view.sigRangeChanged.connect(lambda: updateDelay(scale, 10)) - - except Exception as e: - self.ui.result_textBrowser2.append(str(e)) - - def plot_intensity_sums(self): - try: - # TODO test line scan plots - - #intensities = np.reshape(intensities, newshape=(2048, numb_pixels_X*numb_pixels_Y)) - - sums = np.sum(self.intensities, axis=-1) - sums = np.reshape(sums, newshape=(self.numb_x_pixels, self.numb_y_pixels)) - - self.ui.intensity_sums_viewBox.setImage(sums, scale= - (self.x_step_size, - self.y_step_size)) - self.ui.intensity_sums_viewBox.view.invertY(False) - - scale = pg.ScaleBar(size=2,suffix='um') - scale.setParentItem(self.ui.intensity_sums_viewBox.view) - scale.anchor((1, 1), (1, 1), offset=(-30, -30)) - self.ui.intensity_sums_viewBox.view.sigRangeChanged.connect(lambda: updateDelay(scale, 10)) - - except Exception as e: - self.ui.result_textBrowser2.append(str(e)) - - - def fit_and_plot_scan(self): + sigma = np.zeros(shape=(numb_of_points,1)) + height = np.zeros(shape=(numb_of_points,1)) + + for i in range(numb_of_points): + fwhm[i, 0] = self.fit_scan_file['result_'+str(i)].values['g1_fwhm'] + pk_pos[i, 0] = self.fit_scan_file['result_'+str(i)].values['g1_center'] + sigma[i, 0] = self.fit_scan_file['result_'+str(i)].values['g1_sigma'] + height[i, 0] = self.fit_scan_file['result_'+str(i)].values['g1_height'] + + newshape = (num_x, num_y) + + param_selection = str(self.ui.comboBox.currentText()) + self.img = np.reshape(eval(param_selection), newshape) + + if self.ui.use_raw_scan_settings.isChecked(): + self.ui.fit_scan_viewbox.setImage(self.img, scale= + (self.x_step_size, + self.y_step_size)) + scale = pg.ScaleBar(size=2,suffix='um') + scale.setParentItem(self.ui.fit_scan_viewbox.view) + scale.anchor((1, 1), (1, 1), offset=(-30, -30)) + self.ui.fit_scan_viewbox.view.sigRangeChanged.connect(lambda: updateDelay(scale, 10)) + else: + self.ui.fit_scan_viewbox.setImage(self.img) + + self.ui.fit_scan_viewbox.view.invertY(False) + + except Exception as e: + self.ui.result_textBrowser2.append(str(e)) + pass + + def plot_raw_scan(self): + try: + # TODO test line scan plots + + intensities = self.intensities.T #this is only there because of how we are saving the data in the app + intensities = np.reshape(intensities, newshape=(2048,self.numb_x_pixels, self.numb_y_pixels)) + self.ui.raw_scan_viewbox.setImage(intensities, scale= + (self.x_step_size, + self.y_step_size), xvals=self.wavelengths) + + #roi_plot = self.ui.raw_scan_viewBox.getRoiPlot() + #roi_plot.plot(data['Wavelengths'], intensities) + self.ui.raw_scan_viewbox.view.invertY(False) + scale = pg.ScaleBar(size=2,suffix='um') + scale.setParentItem(self.ui.raw_scan_viewbox.view) + scale.anchor((1, 1), (1, 1), offset=(-30, -30)) + self.ui.raw_scan_viewbox.view.sigRangeChanged.connect(lambda: updateDelay(scale, 10)) + + except Exception as e: + self.ui.result_textBrowser2.append(str(e)) + + def plot_intensity_sums(self): + try: + # TODO test line scan plots + + #intensities = np.reshape(intensities, newshape=(2048, numb_pixels_X*numb_pixels_Y)) + + sums = np.sum(self.intensities, axis=-1) + sums = np.reshape(sums, newshape=(self.numb_x_pixels, self.numb_y_pixels)) + + self.ui.intensity_sums_viewBox.setImage(sums, scale= + (self.x_step_size, + self.y_step_size)) + self.ui.intensity_sums_viewBox.view.invertY(False) + + scale = pg.ScaleBar(size=2,suffix='um') + scale.setParentItem(self.ui.intensity_sums_viewBox.view) + scale.anchor((1, 1), (1, 1), offset=(-30, -30)) + self.ui.intensity_sums_viewBox.view.sigRangeChanged.connect(lambda: updateDelay(scale, 10)) + + except Exception as e: + self.ui.result_textBrowser2.append(str(e)) + + + def fit_and_plot_scan(self): # self.ui.result_textBrowser.append("Starting Scan Fitting") - print("Starting Scan Fitting") - - try: - """Define starting and stopping wavelength values here""" - start_nm = int(self.ui.start_nm_spinBox.value()) - stop_nm = int(self.ui.stop_nm_spinBox.value()) - - ref = self.bck_file - index = (ref[:,0]>start_nm) & (ref[:,0]start_nm) & (xstart_nm) & (ref[:,0]start_nm) & (x Date: Tue, 27 Aug 2019 16:40:20 -0700 Subject: [PATCH 05/63] added 4th order poly fit for scattering correction, can choose b/w mean value corr and 4th order corr --- .../UV_Vis_analysis/uv_vis_analysis.py | 26 +++++++++--- .../UV_Vis_analysis/uv_vis_analysis_gui.ui | 40 ++++++++++++++++--- 2 files changed, 56 insertions(+), 10 deletions(-) diff --git a/PythonGUI_apps/UV_Vis_analysis/uv_vis_analysis.py b/PythonGUI_apps/UV_Vis_analysis/uv_vis_analysis.py index 44e2ffb..8c860cb 100644 --- a/PythonGUI_apps/UV_Vis_analysis/uv_vis_analysis.py +++ b/PythonGUI_apps/UV_Vis_analysis/uv_vis_analysis.py @@ -52,6 +52,8 @@ def __init__(self): self.correction_region.setRegion((self.correction_region_min, self.correction_region_max)) #setup uv vis ui signals + self.ui.correct_for_scattering_checkBox.stateChanged.connect(self.scattering_checkBox_state) + self.scatter_corrected = False self.ui.actionLoad_data.triggered.connect(self.open_data_file) self.ui.plot_absorbance_pushButton.clicked.connect(self.plot_absorbance) self.ui.clear_uvvis_pushButton.clicked.connect(self.clear_uvvis) @@ -85,14 +87,28 @@ def open_data_file(self): def update_correction_region(self): """ Update correction region variables from region """ self.correction_region_min, self.correction_region_max = self.correction_region.getRegion() + + def scattering_checkBox_state(self): + if self.ui.correct_for_scattering_checkBox.isChecked(): + self.scatter_corrected = True + self.ui.mean_radioButton.setEnabled(True) + self.ui.fourth_orderpoly_radioButton.setEnabled(True) + else: + self.scatter_corrected = False + self.ui.mean_radioButton.setEnabled(False) + self.ui.fourth_orderpoly_radioButton.setEnabled(False) def plot_absorbance(self): try: - self.scatter_corrected = False self.plotted_absorbance = self.Absorbance #by default set to original absorbance data - if self.ui.correct_for_scattering_checkBox.isChecked(): #if checked, correct absorbance data - self.scatter_corrected = True - self.plotted_absorbance = self.Absorbance - np.mean(self.Absorbance[(self.Wavelength>self.correction_region_min) & (self.Wavelengthself.correction_region_min) & (self.Wavelengthself.correction_region_min) & (self.Wavelengthself.correction_region_min) & (self.Wavelength self.hv_min) & (self.hv < self.hv_max) model = np.polyfit(self.hv[self.index], self.Alpha_hv[self.index], 1) self.Alpha_hv_fit = self.hv * model[0] + model[1] #This is the linear fit diff --git a/PythonGUI_apps/UV_Vis_analysis/uv_vis_analysis_gui.ui b/PythonGUI_apps/UV_Vis_analysis/uv_vis_analysis_gui.ui index c3289df..85bd935 100644 --- a/PythonGUI_apps/UV_Vis_analysis/uv_vis_analysis_gui.ui +++ b/PythonGUI_apps/UV_Vis_analysis/uv_vis_analysis_gui.ui @@ -23,27 +23,57 @@ - + + + + Scattering Correction + + + + Plot - - + + + + false + - Correct for scattering + 4th Order Polynomial + + + true - + Clear + + + + Correct for scattering + + + + + + + false + + + Simple Mean + + + From eca3884e374df60f7a5adcb4f03dca7ecd919adc Mon Sep 17 00:00:00 2001 From: SarthakJariwala <35085572+SarthakJariwala@users.noreply.github.com> Date: Tue, 27 Aug 2019 16:48:48 -0700 Subject: [PATCH 06/63] Update README.md --- README.md | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 63 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index e637c50..719ca48 100644 --- a/README.md +++ b/README.md @@ -3,20 +3,77 @@ GUI Python apps written in python and qt for quick analysis of custom data. It a _**Python is not required to use GLabViz**_ (see **How to use?**) -The primary users for this Python package are Ginger Lab members at the University of Washington, Seattle but is licensed under MIT License and open for everyone to use. +[_**DOWNLOAD HERE**_](https://github.com/SarthakJariwala/Python_GUI_apps/releases) + +The primary users for this Python package application are Ginger Lab members at the University of Washington, Seattle but is licensed under MIT License and open for everyone to use. ## Includes * Fluorescence Lifetime Analysis + * Analyze lifetime + * Fit data with or without IRF + * Fit with stretched, single, or double exponential functions by diff_ev or fmin_tnc + * Calculate surface recombination velocity + * Export graph and fit results * Spectra Analysis + * Analyze single spectrum + * Fit with or without background and white light + * Fit with single Lorentzian, single Gaussian, double Gaussian, triple Gaussian models + * Export graph and fit results + * Analyze spectra scan + * Load spectra scan data in .h5 or .pkl files + * Plot raw scan data + * Plot scan intensity sums + * Plot fitted scan by pk_pos, fwhm, sigma, or height + * Export fitted scan + * .pkl to .txt, .pkl to .h5 converters * Fluorescence Lifetime Imaging Microscopy (FLIM) Data Analysis + * Load lifetime scans in .h5 or .pkl files + * Plot histogram intensity sums and analyze PSF + * Export intensities array and intensities image + * Plot raw histogram data and analyze lifetime + * Compare lifetime in two different regions * Photluminescence Quantum Efficiency (PLQE) Analysis + * Plot PLQE data + * Calculate PLQE * UV-Vis Data Analysis + * Plot UV-Vis data + * Correct UV-Vis data for scattering + * Plot Tauc data + * Calculate bandgap + * Export UV-Vis and Tauc plots * General *H5* View and Plot + * Load .h5 file to view file structure + * Plot datasets as a graph or an image * *H5* and *PKL* File Viewer + * Load .h5 or .pkl file to view file structure +* Image Analysis + * Load image on SPOT or Pixera settings, or specify pixel size + * Handle RGB and greyscale images + * Select magnification + * Color profile horizontally or vertically + +## Screenshots +### Welcome Screen +![Welcome Screen](https://github.com/SarthakJariwala/Python_GUI_apps/blob/master/Screenshots/GLabViz_interface_1.png) +### Lifetime Analysis +![Lifetime Analysis](https://github.com/SarthakJariwala/Python_GUI_apps/blob/master/Screenshots/GLabViz_Lifetime_analysis_2.png) +### Spectra Analysis +![Single Spectrum](https://github.com/SarthakJariwala/Python_GUI_apps/blob/master/Screenshots/GLabViz_Spectrum_analysis_1.png) +![Scan Data](https://github.com/SarthakJariwala/Python_GUI_apps/blob/master/Screenshots/GLabViz_Spectrum_analysis_2.png) +### FLIM Analysis +![FLIM Analysis](https://github.com/SarthakJariwala/Python_GUI_apps/blob/master/Screenshots/GLabViz_FLIM_analysis_2.png) +### UV-Vis Analysis +![UV-Vis Analysis](https://github.com/SarthakJariwala/Python_GUI_apps/blob/master/Screenshots/GLabViz_UVvis_analysis_1.PNG) +### H5 & Pkl View +![H5-pkl-viewer](https://github.com/SarthakJariwala/Python_GUI_apps/blob/master/Screenshots/GLabViz_h5_ViewPlot_analysis_1.PNG) +### H5 Quick Plot +![h5- quick plot](https://github.com/SarthakJariwala/Python_GUI_apps/blob/master/Screenshots/GLabViz_h5_ViewPlot_analysis_2.PNG) +### Image Analysis +![Image Analysis](https://github.com/SarthakJariwala/Python_GUI_apps/blob/master/Screenshots/GLabViz_Image_analysis_1.png) ## How to use? ### Standalone App - without Python or any dependencies (_only for Windows users_) -* Under the releases page, download the latest release of the _**DataBrowser**_ zip file +* Under the [releases](https://github.com/SarthakJariwala/Python_GUI_apps/releases) page, download the latest release of the _**DataBrowser**_ zip file * Extract the zip file and run _**DataBrowser.exe**_ ### With Python and its dependencies ``` @@ -30,16 +87,16 @@ python DataBrowser.py ``` #### Dependencies -* ScopeFoundry -* pyqtgraph +* [ScopeFoundry](https://github.com/ScopeFoundry/ScopeFoundry) +* [pyqtgraph](http://www.pyqtgraph.org/) * numpy * pyqt * qtpy * h5py * matplotlib * scipy -* lmfit -* customplotting +* [lmfit](https://lmfit.github.io/lmfit-py/) +* [customplotting](https://github.com/SarthakJariwala/Custom-Plotting) #### Installing dependencies from command-line ``` From e00d96e9f14cf35332fbc89f2992e3322cd24ca2 Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Wed, 28 Aug 2019 15:35:31 -0700 Subject: [PATCH 07/63] load in text file of histogram sums for plotting, old labview txt files can now be opened in this with stepsize as an input parameter --- PythonGUI_apps/FLIM_analysis/FLIM_plot.py | 53 ++++++++++++++++--- .../FLIM_analysis/step_size_labview_files.ui | 44 +++++++++++++++ 2 files changed, 91 insertions(+), 6 deletions(-) create mode 100644 PythonGUI_apps/FLIM_analysis/step_size_labview_files.ui diff --git a/PythonGUI_apps/FLIM_analysis/FLIM_plot.py b/PythonGUI_apps/FLIM_analysis/FLIM_plot.py index 8a0124f..25b19ed 100644 --- a/PythonGUI_apps/FLIM_analysis/FLIM_plot.py +++ b/PythonGUI_apps/FLIM_analysis/FLIM_plot.py @@ -62,14 +62,20 @@ def __init__(self): def open_file(self): """ Open FLIM scan file """ try: - self.filename = QtWidgets.QFileDialog.getOpenFileName(self, filter="Scan files (*.pkl *.h5)") + self.filename = QtWidgets.QFileDialog.getOpenFileName(self, filter="Scan files (*.pkl *.h5 *.txt)") if ".pkl" in self.filename[0]: self.flim_scan_file = pickle.load(open(self.filename[0], 'rb')) self.scan_file_type = "pkl" + self.get_data_params() elif ".h5" in self.filename[0]: self.flim_scan_file = h5py.File(self.filename[0], 'r') self.scan_file_type = "h5" - self.get_data_params() + self.get_data_params() + elif ".txt" in self.filename[0]: + self.intensity_sums = np.loadtxt(self.filename[0]).T + self.stepsize_window = StepSizeWindow() + self.stepsize_window.stepsize_signal.connect(self.get_stepsize) + self.scan_file_type = "txt" # self.pkl_file = pickle.load(open(self.filename[0], 'rb')) except Exception as err: print(format(err)) @@ -81,6 +87,14 @@ def import_pkl_to_convert(self): self.ui.result_textBrowser.append("Done Loading - .pkl to convert") except: pass + + def get_stepsize(self): + """ Get step size from user input -- specfically written for loading + txt files from legacy labview code, but can also be run on txt file + saved using the new FLIM acquistion code """ + self.stepsize = eval(self.stepsize_window.ui.stepsize_textEdit.toPlainText()) + self.x_step_size = self.stepsize + self.y_step_size = self.stepsize def get_data_params(self): @@ -106,14 +120,19 @@ def get_data_params(self): def plot_intensity_sums(self): try: - self.hist_data = np.reshape(self.hist_data, newshape=(self.hist_data.shape[0], self.numb_x_pixels*self.numb_y_pixels)) - self.intensity_sums = np.sum(self.hist_data, axis=0) #sum intensities for each pixel - self.intensity_sums = np.reshape(self.intensity_sums, newshape=(self.numb_x_pixels, self.numb_y_pixels)) + if self.scan_file_type is "pkl" or self.scan_file_type is "h5": + pg.setConfigOption('imageAxisOrder', 'row-major') + self.hist_data = np.reshape(self.hist_data, newshape=(self.hist_data.shape[0], self.numb_x_pixels*self.numb_y_pixels)) + self.intensity_sums = np.sum(self.hist_data, axis=0) #sum intensities for each pixel + self.intensity_sums = np.reshape(self.intensity_sums, newshape=(self.numb_x_pixels, self.numb_y_pixels)) + else: + pg.setConfigOption('imageAxisOrder', 'col-major') self.ui.intensity_sums_viewBox.view.invertY(False) # stop y axis invert self.ui.intensity_sums_viewBox.setImage(self.intensity_sums, scale= (self.x_step_size, self.y_step_size)) - self.ui.intensity_sums_viewBox.roi.setSize([self.x_scan_size, self.y_step_size]) #line roi + if self.scan_file_type is "pkl" or self.scan_file_type is "h5": + self.ui.intensity_sums_viewBox.roi.setSize([self.x_scan_size, self.y_step_size]) #line roi scale = pg.ScaleBar(size=1,suffix='um') scale.setParentItem(self.ui.intensity_sums_viewBox.view) scale.anchor((1, 1), (1, 1), offset=(-30, -30)) @@ -292,6 +311,28 @@ def close_application(self): else: pass +"""Skip rows GUI""" +ui_file_path = (base_path / "step_size_labview_files.ui").resolve() +stepsize_WindowTemplate, stepsize_TemplateBaseClass = pg.Qt.loadUiType(ui_file_path) + +class StepSizeWindow(stepsize_TemplateBaseClass): + + stepsize_signal = QtCore.pyqtSignal() #signal to help with pass info back to MainWindow + + def __init__(self): + stepsize_TemplateBaseClass.__init__(self) + + # Create the param window + self.ui = stepsize_WindowTemplate() + self.ui.setupUi(self) + self.ui.done_pushButton.clicked.connect(self.done) + self.setWindowFlag(QtCore.Qt.WindowCloseButtonHint, False) + self.show() + + def done(self): + self.stepsize_signal.emit() + self.close() + """Run the Main Window""" def run(): win = MainWindow() diff --git a/PythonGUI_apps/FLIM_analysis/step_size_labview_files.ui b/PythonGUI_apps/FLIM_analysis/step_size_labview_files.ui new file mode 100644 index 0000000..a553498 --- /dev/null +++ b/PythonGUI_apps/FLIM_analysis/step_size_labview_files.ui @@ -0,0 +1,44 @@ + + + Form + + + + 0 + 0 + 203 + 118 + + + + Form + + + + + + + 12 + + + + StepSize +(in um) + + + + + + + + + + Done! + + + + + + + + From 06ba42d431473c1c2ca92fdafc0e86cd1ef8aac0 Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Wed, 28 Aug 2019 15:51:20 -0700 Subject: [PATCH 08/63] ui modifications, change textedit to spinbox --- PythonGUI_apps/FLIM_analysis/FLIM_plot.py | 2 +- .../FLIM_analysis/step_size_labview_files.ui | 31 ++++++++++++++----- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/PythonGUI_apps/FLIM_analysis/FLIM_plot.py b/PythonGUI_apps/FLIM_analysis/FLIM_plot.py index 25b19ed..e3fbf0b 100644 --- a/PythonGUI_apps/FLIM_analysis/FLIM_plot.py +++ b/PythonGUI_apps/FLIM_analysis/FLIM_plot.py @@ -92,7 +92,7 @@ def get_stepsize(self): """ Get step size from user input -- specfically written for loading txt files from legacy labview code, but can also be run on txt file saved using the new FLIM acquistion code """ - self.stepsize = eval(self.stepsize_window.ui.stepsize_textEdit.toPlainText()) + self.stepsize = self.stepsize_window.ui.stepsize_doubleSpinBox.value() self.x_step_size = self.stepsize self.y_step_size = self.stepsize diff --git a/PythonGUI_apps/FLIM_analysis/step_size_labview_files.ui b/PythonGUI_apps/FLIM_analysis/step_size_labview_files.ui index a553498..2078fb7 100644 --- a/PythonGUI_apps/FLIM_analysis/step_size_labview_files.ui +++ b/PythonGUI_apps/FLIM_analysis/step_size_labview_files.ui @@ -6,8 +6,8 @@ 0 0 - 203 - 118 + 255 + 75 @@ -22,14 +22,10 @@ - StepSize -(in um) + Step Size (um) - - - @@ -37,6 +33,27 @@ + + + + + 12 + + + + 4 + + + 100.000000000000000 + + + 0.100000000000000 + + + 0.100000000000000 + + + From c44991bfa219200774549d1e08bc1b0c24bf2b77 Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Wed, 28 Aug 2019 16:49:16 -0700 Subject: [PATCH 09/63] launch h5/pkl viewer when h5 or pkl file is loaded in FLIM Analysis, provides more insight into data and its structure --- PythonGUI_apps/FLIM_analysis/FLIM_plot.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/PythonGUI_apps/FLIM_analysis/FLIM_plot.py b/PythonGUI_apps/FLIM_analysis/FLIM_plot.py index e3fbf0b..38a1a6a 100644 --- a/PythonGUI_apps/FLIM_analysis/FLIM_plot.py +++ b/PythonGUI_apps/FLIM_analysis/FLIM_plot.py @@ -13,8 +13,10 @@ sys.path.append(os.path.abspath('../Lifetime_analysis')) sys.path.append(os.path.abspath('../Spectrum_analysis')) +sys.path.append(os.path.abspath('../H5_Pkl')) from Lifetime_analysis import Lifetime_plot_fit from Spectrum_analysis import Spectra_plot_fit +from H5_Pkl import h5_pkl_view # local modules pg.mkQApp() @@ -66,10 +68,12 @@ def open_file(self): if ".pkl" in self.filename[0]: self.flim_scan_file = pickle.load(open(self.filename[0], 'rb')) self.scan_file_type = "pkl" + self.launch_h5_pkl_viewer() self.get_data_params() elif ".h5" in self.filename[0]: self.flim_scan_file = h5py.File(self.filename[0], 'r') self.scan_file_type = "h5" + self.launch_h5_pkl_viewer() self.get_data_params() elif ".txt" in self.filename[0]: self.intensity_sums = np.loadtxt(self.filename[0]).T @@ -79,6 +83,11 @@ def open_file(self): # self.pkl_file = pickle.load(open(self.filename[0], 'rb')) except Exception as err: print(format(err)) + + def launch_h5_pkl_viewer(self): + """ Launches H5/PKL viewer to give an insight into the data and its structure""" + viewer_window = h5_pkl_view.H5PklView(sys.argv) + viewer_window.settings['data_filename'] = self.filename[0] def import_pkl_to_convert(self): """ Open pkl file to convert to h5 """ From 793f4bf2687ce7b2dd2d8d4442141dee5d2b99b7 Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Wed, 28 Aug 2019 17:13:20 -0700 Subject: [PATCH 10/63] launch pkl/h5 viewer for spectra scan raw and fit files --- .../Spectrum_analysis/Spectra_plot_fit.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py index 626bce0..5bfe487 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py @@ -19,6 +19,9 @@ from lmfit.models import GaussianModel from scipy import interpolate import customplotting.mscope as cpm + +sys.path.append(os.path.abspath('../H5_Pkl')) +from H5_Pkl import h5_pkl_view # local modules try: from Spectra_fit_funcs import Spectra_Fit, Single_Gaussian, Single_Lorentzian, Double_Gaussian, Multi_Gaussian @@ -166,11 +169,14 @@ def open_wlref_file(self): def open_spectra_scan_file(self): try: filename = QtWidgets.QFileDialog.getOpenFileName(self, filter="Scan files (*.pkl *.h5)") + self.filename_for_viewer_launch = filename[0] if ".pkl" in filename[0]: self.spec_scan_file = pickle.load(open(filename[0], 'rb')) + self.launch_h5_pkl_viewer() self.scan_file_type = "pkl" elif ".h5" in filename[0]: self.spec_scan_file = h5py.File(filename[0], 'r') + self.launch_h5_pkl_viewer() self.scan_file_type = "h5" self.get_data_params() self.ui.result_textBrowser2.append("Done Loading - Spectra Scan File") @@ -190,7 +196,9 @@ def open_spectra_bck_file(self): def open_fit_scan_file(self): try: filename = QtWidgets.QFileDialog.getOpenFileName(self) + self.filename_for_viewer_launch = filename[0] self.fit_scan_file = pickle.load(open(filename[0], 'rb')) + self.launch_h5_pkl_viewer() # TODO Needs to implement reading the fit result datatype in PKL Viewer self.ui.result_textBrowser2.append("Done Loading - Scan Fit File") except Exception as e: self.ui.result_textBrowser2.append(str(e)) @@ -200,9 +208,16 @@ def open_pkl_file(self): """ Open pkl file to convert to txt """ try: self.pkl_to_convert = QtWidgets.QFileDialog.getOpenFileName(self) + self.filename_for_viewer_launch = self.pkl_to_convert[0] + self.launch_h5_pkl_viewer() except: pass + def launch_h5_pkl_viewer(self): + """ Launches H5/PKL viewer to give an insight into the data and its structure""" + viewer_window = h5_pkl_view.H5PklView(sys.argv) + viewer_window.settings['data_filename'] = self.filename_for_viewer_launch + def switch_overall_tab(self): """ Enable/disable fit settings on right depending on current tab """ if self.ui.tabWidget.currentIndex() == 0: @@ -625,6 +640,7 @@ def plot_intensity_sums(self): def fit_and_plot_scan(self): # self.ui.result_textBrowser.append("Starting Scan Fitting") print("Starting Scan Fitting") + print("Using Single Gaussian to Fit\nThis is the only fitting functions implemented") try: """Define starting and stopping wavelength values here""" From 04d4828143f91280b6718b8aa9f3a95388a42d14 Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Thu, 29 Aug 2019 13:20:30 -0700 Subject: [PATCH 11/63] implemented much faster saving of fit file and loading fit file, option to save entire model or only best fit values, minor gui changes --- .../Spectrum_analysis/Spectra_plot_fit.py | 32 +++++++++++++------ .../Spectrum_analysis/Spectra_plot_fit_gui.ui | 13 ++++++++ 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py index 5bfe487..7b3b9db 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py @@ -223,17 +223,20 @@ def switch_overall_tab(self): if self.ui.tabWidget.currentIndex() == 0: self.ui.fitting_settings_groupBox.setEnabled(True) self.ui.fit_pushButton.setEnabled(True) - self.ui.fit_scan_pushButton.setEnabled(True) + self.ui.fit_scan_pushButton.setEnabled(False) + self.ui.save_all_checkBox.setEnabled(False) self.ui.scan_fit_settings_groupBox.setEnabled(False) elif self.ui.tabWidget.currentIndex() == 1: self.ui.fitting_settings_groupBox.setEnabled(False) self.ui.fit_pushButton.setEnabled(False) self.ui.fit_scan_pushButton.setEnabled(True) + self.ui.save_all_checkBox.setEnabled(True) self.ui.scan_fit_settings_groupBox.setEnabled(True) elif self.ui.tabWidget.currentIndex() == 2: self.ui.fitting_settings_groupBox.setEnabled(False) self.ui.fit_pushButton.setEnabled(False) self.ui.fit_scan_pushButton.setEnabled(False) + self.ui.save_all_checkBox.setEnabled(False) self.ui.scan_fit_settings_groupBox.setEnabled(False) """ Single spectrum functions """ @@ -560,16 +563,22 @@ def plot_fit_scan(self): fwhm = np.zeros(shape=(numb_of_points,1)) pk_pos = np.zeros(shape=(numb_of_points,1)) -# pk_pos_plus = np.zeros(shape=(numb_of_points,1)) -# pk_pos_minus = np.zeros(shape=(numb_of_points,1)) sigma = np.zeros(shape=(numb_of_points,1)) - height = np.zeros(shape=(numb_of_points,1)) +# height = np.zeros(shape=(numb_of_points,1)) - for i in range(numb_of_points): - fwhm[i, 0] = self.fit_scan_file['result_'+str(i)].values['g1_fwhm'] - pk_pos[i, 0] = self.fit_scan_file['result_'+str(i)].values['g1_center'] - sigma[i, 0] = self.fit_scan_file['result_'+str(i)].values['g1_sigma'] - height[i, 0] = self.fit_scan_file['result_'+str(i)].values['g1_height'] + if type(self.fit_scan_file['result_0']) == dict: + for i in range(numb_of_points): + fwhm[i, 0] = 2.3548200*self.fit_scan_file['result_'+str(i)]['g1_sigma'] + pk_pos[i, 0] = self.fit_scan_file['result_'+str(i)]['g1_center'] + sigma[i, 0] = self.fit_scan_file['result_'+str(i)]['g1_sigma'] +# height[i, 0] = self.fit_scan_file['result_'+str(i)].values['g1_height'] + + elif type(self.fit_scan_file['result_0']) == lmfit.model.ModelResult: + for i in range(numb_of_points): + fwhm[i, 0] = self.fit_scan_file['result_'+str(i)].values['g1_fwhm'] + pk_pos[i, 0] = self.fit_scan_file['result_'+str(i)].values['g1_center'] + sigma[i, 0] = self.fit_scan_file['result_'+str(i)].values['g1_sigma'] +# height[i, 0] = self.fit_scan_file['result_'+str(i)].values['g1_height'] newshape = (num_x, num_y) @@ -668,7 +677,10 @@ def fit_and_plot_scan(self): gmodel = GaussianModel(prefix = 'g1_') # calling gaussian model pars = gmodel.guess(y, x=x) # parameters - center, width, height result = gmodel.fit(y, pars, x=x, nan_policy='propagate') - result_dict["result_"+str(i)] = result + if self.ui.save_all_checkBox.isChecked(): + result_dict["result_"+str(i)] = result + else: + result_dict["result_"+str(i)] = result.best_values # self.ui.result_textBrowser.append("Scan Fitting Complete!") print("Scan Fitting Complete!") diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui index a176bdd..414d759 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui @@ -624,8 +624,21 @@ + + + + false + + + Save Entire Fit Model (File will be large and will take longer) + + + + + false + 10 From ded12b585f6f2c1243f0179b18c680bf1788679c Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Fri, 30 Aug 2019 10:25:11 -0700 Subject: [PATCH 12/63] minor import statement fix --- PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py index 7b3b9db..fd368dc 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py @@ -15,7 +15,7 @@ import numpy as np import matplotlib.pyplot as plt import pickle -import time +import lmfit from lmfit.models import GaussianModel from scipy import interpolate import customplotting.mscope as cpm @@ -439,7 +439,7 @@ def fit_and_plot(self): sigma2_guess = self.ui.multi_sigma2_guess_spinBox.value() center3_guess = self.ui.multi_peakcenter3_guess_spinBox.value() sigma3_guess = self.ui.multi_sigma3_guess_spinBox.value() - num_gaussians = 3 +# num_gaussians = 3 peak_pos = [center1_guess, center2_guess, center3_guess] sigma = [sigma1_guess, sigma2_guess, sigma3_guess] min_max_range = [ [center1_min, center1_max], [center2_min, center2_max], [center3_min, center3_max] ] @@ -656,6 +656,8 @@ def fit_and_plot_scan(self): start_nm = int(self.ui.start_nm_spinBox.value()) stop_nm = int(self.ui.stop_nm_spinBox.value()) + if self.bck_file is None: + print("Load Background file!") ref = self.bck_file index = (ref[:,0]>start_nm) & (ref[:,0] Date: Fri, 30 Aug 2019 10:26:43 -0700 Subject: [PATCH 13/63] pkl view now reads lmfit ModelResult from a saved fit result file and will output it as such --- PythonGUI_apps/H5_Pkl/pkl_tree.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/PythonGUI_apps/H5_Pkl/pkl_tree.py b/PythonGUI_apps/H5_Pkl/pkl_tree.py index 3a24c76..e60a85e 100644 --- a/PythonGUI_apps/H5_Pkl/pkl_tree.py +++ b/PythonGUI_apps/H5_Pkl/pkl_tree.py @@ -3,6 +3,7 @@ import h5py import pickle import numpy as np +import lmfit class PklTreeSearchView(DataBrowserView): @@ -85,11 +86,13 @@ def traverse_dict(self, dictionary, previous_dict, level): self.tree_str += indent + "|> {}/
".format(print_string) level += 1 previous_dict = dictionary[key] - self.traverse_dict(dictionary[key], previous_dict, level) + self.traverse_dict(dictionary[key], previous_dict, level) else: value = dictionary[key] if type(value) == np.ndarray or type(value)==np.memmap: value = str(value.shape) + " " + str(value.dtype) + elif type(value) == lmfit.model.ModelResult: + value = "lmfit.model.ModelResult" # if type(value) == list and len(value) > 5: ##account for data stored in lists # value = str(np.asarray(value).shape) + " " + str(type(value[0])) From ccee7dfdc2977975a1266c91c8fa84acacf702fe Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Fri, 30 Aug 2019 12:25:25 -0700 Subject: [PATCH 14/63] implement busy cursor, fit files now have 'Scan Paramaters' and 'OceanOptics Parameters', fix export of scan images --- .../Spectrum_analysis/Spectra_plot_fit.py | 26 ++++++++++++------- .../Spectrum_analysis/Spectra_plot_fit_gui.ui | 10 ------- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py index fd368dc..4a075c5 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py @@ -196,10 +196,11 @@ def open_spectra_bck_file(self): def open_fit_scan_file(self): try: filename = QtWidgets.QFileDialog.getOpenFileName(self) - self.filename_for_viewer_launch = filename[0] - self.fit_scan_file = pickle.load(open(filename[0], 'rb')) - self.launch_h5_pkl_viewer() # TODO Needs to implement reading the fit result datatype in PKL Viewer - self.ui.result_textBrowser2.append("Done Loading - Scan Fit File") + with pg.BusyCursor(): + self.filename_for_viewer_launch = filename[0] + self.fit_scan_file = pickle.load(open(filename[0], 'rb')) + self.launch_h5_pkl_viewer() # TODO Needs to implement reading the fit result datatype in PKL Viewer + self.ui.result_textBrowser2.append("Done Loading - Scan Fit File") except Exception as e: self.ui.result_textBrowser2.append(str(e)) pass @@ -466,7 +467,10 @@ def pub_ready_plot_export(self): filename = QtWidgets.QFileDialog.getSaveFileName(self,caption="Filename with EXTENSION") try: try: - data = self.spec_scan_file + try: + data = self.spec_scan_file + except: + data = self.fit_scan_file param_selection = str(self.ui.comboBox.currentText()) if param_selection == 'pk_pos': label = 'PL Peak Position (n.m.)' elif param_selection == 'fwhm': label = 'PL FWHM (n.m.)' @@ -563,21 +567,21 @@ def plot_fit_scan(self): fwhm = np.zeros(shape=(numb_of_points,1)) pk_pos = np.zeros(shape=(numb_of_points,1)) - sigma = np.zeros(shape=(numb_of_points,1)) +# sigma = np.zeros(shape=(numb_of_points,1)) # height = np.zeros(shape=(numb_of_points,1)) if type(self.fit_scan_file['result_0']) == dict: for i in range(numb_of_points): fwhm[i, 0] = 2.3548200*self.fit_scan_file['result_'+str(i)]['g1_sigma'] pk_pos[i, 0] = self.fit_scan_file['result_'+str(i)]['g1_center'] - sigma[i, 0] = self.fit_scan_file['result_'+str(i)]['g1_sigma'] +# sigma[i, 0] = self.fit_scan_file['result_'+str(i)]['g1_sigma'] # height[i, 0] = self.fit_scan_file['result_'+str(i)].values['g1_height'] elif type(self.fit_scan_file['result_0']) == lmfit.model.ModelResult: for i in range(numb_of_points): fwhm[i, 0] = self.fit_scan_file['result_'+str(i)].values['g1_fwhm'] pk_pos[i, 0] = self.fit_scan_file['result_'+str(i)].values['g1_center'] - sigma[i, 0] = self.fit_scan_file['result_'+str(i)].values['g1_sigma'] +# sigma[i, 0] = self.fit_scan_file['result_'+str(i)].values['g1_sigma'] # height[i, 0] = self.fit_scan_file['result_'+str(i)].values['g1_height'] newshape = (num_x, num_y) @@ -667,6 +671,8 @@ def fit_and_plot_scan(self): data_array = self.intensities result_dict = {} + result_dict["Scan Parameters"] = self.spec_scan_file['Scan Parameters'] + result_dict["OceanOptics Parameters"] = self.spec_scan_file["OceanOptics Parameters"] for i in range(data_array.shape[0]): @@ -683,7 +689,7 @@ def fit_and_plot_scan(self): result_dict["result_"+str(i)] = result else: result_dict["result_"+str(i)] = result.best_values - + # self.ui.result_textBrowser.append("Scan Fitting Complete!") print("Scan Fitting Complete!") @@ -755,7 +761,7 @@ def pkl_params_to_txt(self): f.write("%s\n" % str(item[1])) #write value def pkl_to_h5(self): - """ Convert scan .pkl file to h5 """ + """ Convert raw scan .pkl file to h5 """ folder = os.path.dirname(self.pkl_to_convert[0]) filename_ext = os.path.basename(self.pkl_to_convert[0]) filename = os.path.splitext(filename_ext)[0] #get filename without extension diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui index 414d759..8da6cb0 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui @@ -1042,16 +1042,6 @@ Ready Figure fwhm
- - - sigma - - - - - height - - From 48ddbf1fc0078bf6e39e87dd0e22b51874debf1b Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Fri, 30 Aug 2019 12:31:31 -0700 Subject: [PATCH 15/63] minor fixes --- .../Spectrum_analysis/Spectra_plot_fit.py | 105 +++++++++--------- 1 file changed, 53 insertions(+), 52 deletions(-) diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py index 4a075c5..3c1d0e3 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py @@ -655,63 +655,64 @@ def fit_and_plot_scan(self): print("Starting Scan Fitting") print("Using Single Gaussian to Fit\nThis is the only fitting functions implemented") - try: - """Define starting and stopping wavelength values here""" - start_nm = int(self.ui.start_nm_spinBox.value()) - stop_nm = int(self.ui.stop_nm_spinBox.value()) - - if self.bck_file is None: - print("Load Background file!") - ref = self.bck_file - index = (ref[:,0]>start_nm) & (ref[:,0]start_nm) & (ref[:,0]start_nm) & (xstart_nm) & (x Date: Mon, 2 Sep 2019 16:06:07 -0700 Subject: [PATCH 16/63] analyze individual spectrum fits from spectra fit file, will open matplotlibwindow for plots, and checkbox for controlling when to launch h5-pkl dataviewer --- .../Spectrum_analysis/Spectra_plot_fit.py | 101 ++++++++++++------ .../Spectrum_analysis/Spectra_plot_fit_gui.ui | 24 +++++ .../Spectrum_analysis/analyze_fit_results.ui | 78 ++++++++++++++ .../pyqtgraph_MATPLOTLIBWIDGET.py | 56 ++++++++++ 4 files changed, 228 insertions(+), 31 deletions(-) create mode 100644 PythonGUI_apps/Spectrum_analysis/analyze_fit_results.ui create mode 100644 PythonGUI_apps/Spectrum_analysis/pyqtgraph_MATPLOTLIBWIDGET.py diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py index 3c1d0e3..14ed6a7 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py @@ -14,6 +14,7 @@ from pyqtgraph.Qt import QtCore, QtGui, QtWidgets#, QColorDialog import numpy as np import matplotlib.pyplot as plt +import matplotlib import pickle import lmfit from lmfit.models import GaussianModel @@ -25,17 +26,20 @@ # local modules try: from Spectra_fit_funcs import Spectra_Fit, Single_Gaussian, Single_Lorentzian, Double_Gaussian, Multi_Gaussian + from pyqtgraph_MATPLOTLIBWIDGET import MatplotlibWidget except: from Spectrum_analysis.Spectra_fit_funcs import Spectra_Fit, Single_Gaussian, Single_Lorentzian, Double_Gaussian, Multi_Gaussian + from Spectrum_analysis.pyqtgraph_MATPLOTLIBWIDGET import MatplotlibWidget +matplotlib.use('Qt5Agg') """Recylce params for plotting""" -plt.rc('xtick', labelsize = 20) -plt.rc('xtick.major', pad = 3) -plt.rc('ytick', labelsize = 20) -plt.rc('lines', lw = 1.5, markersize = 7.5) -plt.rc('legend', fontsize = 20) -plt.rc('axes', linewidth=3.5) +plt.rc('xtick', labelsize = 10) +plt.rc('xtick.major', pad = 1) +plt.rc('ytick', labelsize = 10) +plt.rc('lines', lw = 1.5, markersize = 3.5) +plt.rc('legend', fontsize = 10) +plt.rc('axes', linewidth=1.5) pg.mkQApp() pg.setConfigOption('background', 'w') @@ -85,6 +89,7 @@ def __init__(self): self.ui.clear_pushButton.clicked.connect(self.clear_plot) self.ui.export_single_figure_pushButton.clicked.connect(self.pub_ready_plot_export) self.ui.export_scan_figure_pushButton.clicked.connect(self.pub_ready_plot_export) + self.ui.analyze_spectra_fits_pushButton.clicked.connect(self.analyze_spectra_fits) self.ui.import_pkl_pushButton.clicked.connect(self.open_pkl_file) self.ui.data_txt_pushButton.clicked.connect(self.pkl_data_to_txt) @@ -117,6 +122,9 @@ def __init__(self): #variables accounting for data received from FLIM analysis self.opened_from_flim = False #switched to True in FLIM_plot when "analyze lifetime" clicked self.sum_data_from_flim = [] + + # fit scan file variable set to None for analyze_spectra_fits + self.fit_scan_file = None #container for data to append to txt file self.data_list = [] @@ -172,11 +180,13 @@ def open_spectra_scan_file(self): self.filename_for_viewer_launch = filename[0] if ".pkl" in filename[0]: self.spec_scan_file = pickle.load(open(filename[0], 'rb')) - self.launch_h5_pkl_viewer() + if self.ui.launch_data_viewer_checkBox.isChecked(): + self.launch_h5_pkl_viewer() self.scan_file_type = "pkl" elif ".h5" in filename[0]: self.spec_scan_file = h5py.File(filename[0], 'r') - self.launch_h5_pkl_viewer() + if self.ui.launch_data_viewer_checkBox.isChecked(): + self.launch_h5_pkl_viewer() self.scan_file_type = "h5" self.get_data_params() self.ui.result_textBrowser2.append("Done Loading - Spectra Scan File") @@ -199,7 +209,8 @@ def open_fit_scan_file(self): with pg.BusyCursor(): self.filename_for_viewer_launch = filename[0] self.fit_scan_file = pickle.load(open(filename[0], 'rb')) - self.launch_h5_pkl_viewer() # TODO Needs to implement reading the fit result datatype in PKL Viewer + if self.ui.launch_data_viewer_checkBox.isChecked(): + self.launch_h5_pkl_viewer() # TODO Needs to implement reading the fit result datatype in PKL Viewer self.ui.result_textBrowser2.append("Done Loading - Scan Fit File") except Exception as e: self.ui.result_textBrowser2.append(str(e)) @@ -219,6 +230,14 @@ def launch_h5_pkl_viewer(self): viewer_window = h5_pkl_view.H5PklView(sys.argv) viewer_window.settings['data_filename'] = self.filename_for_viewer_launch + def analyze_spectra_fits(self): + """Analyze fits to the individual spectrum within a spectra scan fit file""" + if self.fit_scan_file is None: + self.open_fit_scan_file() + + analyze_window = Analyze(scan_fit_file=self.fit_scan_file) + analyze_window.run() + def switch_overall_tab(self): """ Enable/disable fit settings on right depending on current tab """ if self.ui.tabWidget.currentIndex() == 0: @@ -465,6 +484,13 @@ def fit_and_plot(self): def pub_ready_plot_export(self): filename = QtWidgets.QFileDialog.getSaveFileName(self,caption="Filename with EXTENSION") + """Recylce params for plotting""" + plt.rc('xtick', labelsize = 20) + plt.rc('xtick.major', pad = 3) + plt.rc('ytick', labelsize = 20) + plt.rc('lines', lw = 1.5, markersize = 7.5) + plt.rc('legend', fontsize = 20) + plt.rc('axes', linewidth=3.5) try: try: try: @@ -801,36 +827,49 @@ def close_application(self): pass -"""Parameter Window GUI and Functions""" -# param_file_path = (base_path / "scan_params_input.ui").resolve() +"""Analyze Window GUI and Functions""" +base_path = Path(__file__).parent +file_path = (base_path / "analyze_fit_results.ui").resolve() -# param_uiFile = param_file_path +uiFile = file_path -# param_WindowTemplate, param_TemplateBaseClass = pg.Qt.loadUiType(param_uiFile) +Analyze_WindowTemplate, Analyze_TemplateBaseClass = pg.Qt.loadUiType(uiFile) -# class ParamWindow(param_TemplateBaseClass): +class Analyze(Analyze_TemplateBaseClass): -# #peak_range = QtCore.pyqtSignal(list) - -# def __init__(self): -# # super(param_TemplateBaseClass, self).__init__() -# param_TemplateBaseClass.__init__(self) + def __init__(self, scan_fit_file): + pg.setConfigOption('imageAxisOrder', 'row-major') + super(Analyze_TemplateBaseClass, self).__init__() -# # Create the param window -# self.pui = param_WindowTemplate() -# self.pui.setupUi(self) + # Create the main window + self.ui = Analyze_WindowTemplate() + self.ui.setupUi(self) -# self.pui.done_pushButton.clicked.connect(self.done) + self.ui.plot_pushButton.clicked.connect(self.plot) -# self.show() - - + self.fit_scan_file = scan_fit_file + self.show() + + def plot(self): + matplotlib.use('Qt5Agg') + try: + result_no = int(self.ui.result_spinBox.value()) + if type(self.fit_scan_file['result_0']) == lmfit.model.ModelResult: + self.ui.graphicsView = MatplotlibWidget(dpi=300) + self.fit_scan_file['result_'+str(result_no)].plot(fig=MatplotlibWidget(size=(12,8)).getFigure().add_subplot(111)) + plt.tick_params(length=8, width=3) + plt.xlabel("Wavelength (nm)", fontsize=25, fontweight='bold') + plt.ylabel("Intensity (a.u.)", fontsize=25, fontweight='bold') + plt.show() + plt.tight_layout() + except Exception as e: + print(str(e)) + pass -# def done(self): -# #center_min, center_max = self.current_peak_range() -# #self.peak_range.emit([center_min, center_max]) -# self.close() -# self.scan_params_entered = True + def run(self): + win = Analyze() + QtGui.QApplication.instance().exec_() + return win """Run the Main Window""" def run(): diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui index 8da6cb0..ac27289 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui @@ -1128,6 +1128,18 @@ Ready Figure + + + + + 12 + + + + Analyze Spectra Fits + + + @@ -1214,6 +1226,18 @@ Ready Figure + + + + + 12 + + + + Launch Data Viewer + + + diff --git a/PythonGUI_apps/Spectrum_analysis/analyze_fit_results.ui b/PythonGUI_apps/Spectrum_analysis/analyze_fit_results.ui new file mode 100644 index 0000000..0110f8e --- /dev/null +++ b/PythonGUI_apps/Spectrum_analysis/analyze_fit_results.ui @@ -0,0 +1,78 @@ + + + Form + + + + 0 + 0 + 543 + 199 + + + + Analze Fit Results + + + + + + + 12 + + + + 1000000000 + + + + + + + + 15 + + + + Analyze Fit Results + + + Qt::AlignCenter + + + + + + + + 12 + + + + Result number: + + + Qt::AlignCenter + + + + + + + + 12 + + + + Check! + + + + + + + + + + + diff --git a/PythonGUI_apps/Spectrum_analysis/pyqtgraph_MATPLOTLIBWIDGET.py b/PythonGUI_apps/Spectrum_analysis/pyqtgraph_MATPLOTLIBWIDGET.py new file mode 100644 index 0000000..ba2f59c --- /dev/null +++ b/PythonGUI_apps/Spectrum_analysis/pyqtgraph_MATPLOTLIBWIDGET.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Sep 2 13:02:50 2019 + +@author: Sarthak +""" + +from pyqtgraph.Qt import QtGui, QtCore, USE_PYSIDE, USE_PYQT5 +import matplotlib + +#if not USE_PYQT5: +# if USE_PYSIDE: +# matplotlib.rcParams['backend.qt4']='PySide' +# +# from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas +# from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar +#else: +from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas +from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar + +from matplotlib.figure import Figure + +if matplotlib.get_backend() is not 'Qt5Agg': + matplotlib.use('Qt5Agg') + +class MatplotlibWidget(QtGui.QWidget): + """ + Implements a Matplotlib figure inside a QWidget. + Use getFigure() and redraw() to interact with matplotlib. + + Example:: + + mw = MatplotlibWidget() + subplot = mw.getFigure().add_subplot(111) + subplot.plot(x,y) + mw.draw() + """ + + def __init__(self, size=(5.0, 4.0), dpi=100): + QtGui.QWidget.__init__(self) + self.fig = Figure(size, dpi=dpi) + self.canvas = FigureCanvas(self.fig) + self.canvas.setParent(self) + self.toolbar = NavigationToolbar(self.canvas, self) + + self.vbox = QtGui.QVBoxLayout() + self.vbox.addWidget(self.toolbar) + self.vbox.addWidget(self.canvas) + + self.setLayout(self.vbox) + + def getFigure(self): + return self.fig + + def draw(self): + self.canvas.draw() \ No newline at end of file From e7c5fb5a7ffa3241d4ca3f1faf7ee99a8fb1a17c Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Mon, 2 Sep 2019 16:07:48 -0700 Subject: [PATCH 17/63] remove old ui file --- .../Spectrum_analysis/peak_bounds_input.ui | 122 ------------------ 1 file changed, 122 deletions(-) delete mode 100644 PythonGUI_apps/Spectrum_analysis/peak_bounds_input.ui diff --git a/PythonGUI_apps/Spectrum_analysis/peak_bounds_input.ui b/PythonGUI_apps/Spectrum_analysis/peak_bounds_input.ui deleted file mode 100644 index c532068..0000000 --- a/PythonGUI_apps/Spectrum_analysis/peak_bounds_input.ui +++ /dev/null @@ -1,122 +0,0 @@ - - - MainWindow - - - - 0 - 0 - 359 - 600 - - - - MainWindow - - - - - - - - - - 15 - - - - Peak Center - - - - - - - - 12 - - - - Minimum (nm) - - - - - - - - 12 - - - - 300.000000000000000 - - - 1000.000000000000000 - - - 500.000000000000000 - - - - - - - - 12 - - - - Maximum (nm) - - - - - - - - 12 - - - - 300.000000000000000 - - - 1000.000000000000000 - - - 600.000000000000000 - - - - - - - - - - 15 - - - - Done! - - - - - - - - - 0 - 0 - 359 - 38 - - - - - - - - From c08e5720797c886306584eec18017d364fa85a86 Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Mon, 2 Sep 2019 18:06:57 -0700 Subject: [PATCH 18/63] add a new table view for general use, can be easily edited, selectively or completely saved and opened in notepad --- PythonGUI_apps/DataBrowser.py | 7 +- PythonGUI_apps/Table/Table_widget.py | 145 +++++++++++++++++++++++ PythonGUI_apps/Table/Table_widget_gui.ui | 70 +++++++++++ PythonGUI_apps/Table/__init__.py | 7 ++ 4 files changed, 227 insertions(+), 2 deletions(-) create mode 100644 PythonGUI_apps/Table/Table_widget.py create mode 100644 PythonGUI_apps/Table/Table_widget_gui.ui create mode 100644 PythonGUI_apps/Table/__init__.py diff --git a/PythonGUI_apps/DataBrowser.py b/PythonGUI_apps/DataBrowser.py index 250e42a..5a276fc 100644 --- a/PythonGUI_apps/DataBrowser.py +++ b/PythonGUI_apps/DataBrowser.py @@ -19,6 +19,7 @@ from PLQE_analysis import plqe_analysis from H5_Pkl import h5_pkl_view, h5_view_and_plot from Image_analysis import Image_analysis +from Table import Table_widget pg.mkQApp() #pg.setConfigOption('background', 'w') @@ -38,7 +39,7 @@ def __init__(self): self.ui = WindowTemplate() self.ui.setupUi(self) self.ui.select_comboBox.addItems(["Lifetime Analysis", "Spectrum Analysis", "FLIM Analysis", - "UV-Vis Analysis", "PLQE Analysis", "H5 View/Plot", "H5/PKL Viewer", "Image Analysis"]) + "UV-Vis Analysis", "PLQE Analysis", "H5 View/Plot", "H5/PKL Viewer", "Image Analysis", "Table View"]) self.ui.load_pushButton.clicked.connect(self.load_app) self.show() @@ -72,7 +73,9 @@ def load_app(self): elif analysis_software == "Image Analysis": self.image_window = Image_analysis.MainWindow() self.image_window.show() - + elif analysis_software == "Table View": + self.table_widget = Table_widget.MainWindow() + self.table_widget.show() def run(): diff --git a/PythonGUI_apps/Table/Table_widget.py b/PythonGUI_apps/Table/Table_widget.py new file mode 100644 index 0000000..a30c030 --- /dev/null +++ b/PythonGUI_apps/Table/Table_widget.py @@ -0,0 +1,145 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Sep 2 17:04:49 2019 + +@author: Sarthak +""" + +from pathlib import Path +import pyqtgraph as pg +from pyqtgraph.python2_3 import asUnicode +from pyqtgraph.Qt import QtCore, QtGui + + +pg.mkQApp() +pg.setConfigOption('background', 'w') + + +base_path = Path(__file__).parent +file_path = (base_path / "Table_widget_gui.ui").resolve() + +uiFile = file_path + +WindowTemplate, TemplateBaseClass = pg.Qt.loadUiType(uiFile) + +class MainWindow(TemplateBaseClass): + + def __init__(self): + super(TemplateBaseClass, self).__init__() + + # Create the main window + self.ui = WindowTemplate() + self.ui.setupUi(self) + + self.clear() + + self.ui.clear_pushButton.clicked.connect(self.clear) + self.ui.add_row_pushButton.clicked.connect(self.add_row) + self.ui.add_column_pushButton.clicked.connect(self.add_column) + + """Saving and Copying --- implemented from pyqtgraph TableWidget""" + self.contextMenu = QtGui.QMenu() + self.contextMenu.addAction('Copy Selection').triggered.connect(self.copySel) + self.contextMenu.addAction('Copy All').triggered.connect(self.copyAll) + self.contextMenu.addAction('Save Selection').triggered.connect(self.saveSel) + self.contextMenu.addAction('Save All').triggered.connect(self.saveAll) + + self.show() + + def clear(self): + self.ui.tableWidget.clear() + self.verticalHeadersSet = False + self.horizontalHeadersSet = False + + def add_row(self): + row_position = self.ui.tableWidget.rowCount() + self.ui.tableWidget.insertRow(row_position) + + def add_column(self): + column_position = self.ui.tableWidget.columnCount() + self.ui.tableWidget.insertColumn(column_position) + + def save_table(self):# Needs to be implemented + print(self.ui.tableWidget.currentItem().text()) + + def serialize(self, useSelection=False): + """Convert entire table (or just selected area) into tab-separated text values""" + if useSelection: + selection = self.ui.tableWidget.selectedRanges()[0] + rows = list(range(selection.topRow(), + selection.bottomRow() + 1)) + columns = list(range(selection.leftColumn(), + selection.rightColumn() + 1)) + else: + rows = list(range(self.ui.tableWidget.rowCount())) + columns = list(range(self.ui.tableWidget.columnCount())) + + data = [] + if self.horizontalHeadersSet: + row = [] + if self.verticalHeadersSet: + row.append(asUnicode('')) + + for c in columns: + row.append(asUnicode(self.ui.tableWidget.horizontalHeaderItem(c).text())) + data.append(row) + + for r in rows: + row = [] + if self.verticalHeadersSet: + row.append(asUnicode(self.ui.tableWidget.verticalHeaderItem(r).text())) + for c in columns: + item = self.ui.tableWidget.item(r, c) + if item is not None: + row.append(asUnicode(item.text())) + else: + row.append(asUnicode('')) + data.append(row) + + s = '' + for row in data: + s += ('\t'.join(row) + '\n') + return s + + + def copySel(self): + """Copy selected data to clipboard.""" + QtGui.QApplication.clipboard().setText(self.serialize(useSelection=True)) + + def copyAll(self): + """Copy all data to clipboard.""" + QtGui.QApplication.clipboard().setText(self.serialize(useSelection=False)) + + + def saveSel(self): + """Save selected data to file.""" + self.save(self.serialize(useSelection=True)) + + + def saveAll(self): + """Save all data to file.""" + self.save(self.serialize(useSelection=False)) + + + def save(self, data): + fileName = QtGui.QFileDialog.getSaveFileName(self, "Save As..", "", "Tab-separated values (*.tsv)") + if fileName == '': + return + open(fileName[0], 'w').write(data) + + def contextMenuEvent(self, ev): + self.contextMenu.popup(ev.globalPos()) + + def keyPressEvent(self, ev): + if ev.key() == QtCore.Qt.Key_C and ev.modifiers() == QtCore.Qt.ControlModifier: + ev.accept() + self.copySel() +# else: +# QtGui.QTableWidget.keyPressEvent(self, ev) +"""Run the Main Window""" +def run(): + win = MainWindow() + QtGui.QApplication.instance().exec_() + return win + +run() \ No newline at end of file diff --git a/PythonGUI_apps/Table/Table_widget_gui.ui b/PythonGUI_apps/Table/Table_widget_gui.ui new file mode 100644 index 0000000..d5fae7e --- /dev/null +++ b/PythonGUI_apps/Table/Table_widget_gui.ui @@ -0,0 +1,70 @@ + + + Form + + + + 0 + 0 + 658 + 438 + + + + TableWidget + + + + + + Add Row + + + + + + + Add Column + + + + + + + Clear + + + + + + + 12 + + + 6 + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/PythonGUI_apps/Table/__init__.py b/PythonGUI_apps/Table/__init__.py new file mode 100644 index 0000000..1a21e72 --- /dev/null +++ b/PythonGUI_apps/Table/__init__.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Sep 2 17:52:35 2019 + +@author: Sarthak +""" + From 30686b95a50b4f3a6148966272dadaad694b05aa Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Mon, 2 Sep 2019 18:08:32 -0700 Subject: [PATCH 19/63] comment correction --- PythonGUI_apps/Table/Table_widget.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PythonGUI_apps/Table/Table_widget.py b/PythonGUI_apps/Table/Table_widget.py index a30c030..4c7b447 100644 --- a/PythonGUI_apps/Table/Table_widget.py +++ b/PythonGUI_apps/Table/Table_widget.py @@ -142,4 +142,4 @@ def run(): QtGui.QApplication.instance().exec_() return win -run() \ No newline at end of file +#run() \ No newline at end of file From c9587b46ae3d1a8e7938e83f23f229c8dda1b760 Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Tue, 3 Sep 2019 12:20:28 -0700 Subject: [PATCH 20/63] minor gui fixes --- .../Spectrum_analysis/Spectra_plot_fit.py | 4 +- .../Spectrum_analysis/analyze_fit_results.ui | 131 ++++++++++-------- 2 files changed, 74 insertions(+), 61 deletions(-) diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py index 14ed6a7..04fab3f 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py @@ -855,8 +855,8 @@ def plot(self): try: result_no = int(self.ui.result_spinBox.value()) if type(self.fit_scan_file['result_0']) == lmfit.model.ModelResult: - self.ui.graphicsView = MatplotlibWidget(dpi=300) - self.fit_scan_file['result_'+str(result_no)].plot(fig=MatplotlibWidget(size=(12,8)).getFigure().add_subplot(111)) + self.matplotlibwidget = MatplotlibWidget(size=(12,8), dpi=300) + self.fit_scan_file['result_'+str(result_no)].plot(fig=self.matplotlibwidget.getFigure().add_subplot(111)) plt.tick_params(length=8, width=3) plt.xlabel("Wavelength (nm)", fontsize=25, fontweight='bold') plt.ylabel("Intensity (a.u.)", fontsize=25, fontweight='bold') diff --git a/PythonGUI_apps/Spectrum_analysis/analyze_fit_results.ui b/PythonGUI_apps/Spectrum_analysis/analyze_fit_results.ui index 0110f8e..7669c5a 100644 --- a/PythonGUI_apps/Spectrum_analysis/analyze_fit_results.ui +++ b/PythonGUI_apps/Spectrum_analysis/analyze_fit_results.ui @@ -6,70 +6,83 @@ 0 0 - 543 - 199 + 664 + 136 Analze Fit Results - - - - - - 12 - - - - 1000000000 - - - - - - - - 15 - - - - Analyze Fit Results - - - Qt::AlignCenter - - - - - - - - 12 - - - - Result number: - - - Qt::AlignCenter - - - - - - - - 12 - - - - Check! - - - - - + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + 12 + + + + Check! + + + + + + + + 12 + + + + 1000000000 + + + + + + + + 12 + + + + Result number: + + + Qt::AlignCenter + + + + + + + + 15 + + + + Analyze Fit Results + + + Qt::AlignCenter + + + + + + + From f2ded3ecf1fc10da47afb3441c1fc627d3eec82e Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Wed, 4 Sep 2019 11:20:53 -0700 Subject: [PATCH 21/63] fixed background correction problem for analyzing PSF, corrected using LinearModel from lmfit as autobackground correction as part of a composite model with Gaussian Model --- .../Spectrum_analysis/Spectra_plot_fit.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py index 04fab3f..3697112 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py @@ -17,7 +17,7 @@ import matplotlib import pickle import lmfit -from lmfit.models import GaussianModel +from lmfit.models import GaussianModel, LinearModel from scipy import interpolate import customplotting.mscope as cpm @@ -372,6 +372,16 @@ def fit_and_plot(self): self.file = np.zeros((self.x.shape[0], 2)) self.file[:,0] = self.x self.file[:,1] = self.y + bck = lmfit.models.LinearModel(prefix='line_') + gmodel = GaussianModel(prefix='g1_') + pars = bck.make_params(intercept=self.y.min(), slope=0) + pars += gmodel.guess(self.y, x=self.x) + comp_model = gmodel + bck + self.result = comp_model.fit(self.y, pars, x=self.x, nan_policy='propagate') + self.ui.plot.plot(self.x, self.y, clear=self.clear_check(), pen='r') + self.ui.plot.plot(self.x, self.result.best_fit, clear=False, pen='k') + self.ui.result_textBrowser.setText(self.result.fit_report()) + if self.ui.plot_without_bck_radioButton.isChecked(): #if plot w/o bck, create dummy bck_file self.bck_file = np.zeros(shape=(self.file.shape[0], 2)) @@ -381,6 +391,8 @@ def fit_and_plot(self): # self.ui.result_textBrowser.setText("You need to check the subtract background option!") if self.check_loaded_files is None: pass + elif self.opened_from_flim: + pass else: if fit_func == "Single Gaussian": #and self.ui.subtract_bck_radioButton.isChecked() == True: From a107fea76dfff21c3635c17d8e112a24c3307f81 Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Mon, 9 Sep 2019 15:26:32 -0700 Subject: [PATCH 22/63] fix single spec file input, fix plot function for single spectrum --- PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py index 3697112..2b3b473 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py @@ -139,7 +139,7 @@ def open_file(self): try: self.file = np.loadtxt(self.single_spec_filename[0], skiprows = 1, delimiter=" ") except: - np.loadtxt(self.single_spec_filename[0], skiprows = 16, delimiter='\t') + self.file = np.loadtxt(self.single_spec_filename[0], skiprows = 16, delimiter='\t') except: self.file = np.genfromtxt(self.single_spec_filename[0], skip_header=1, skip_footer=3, delimiter='\t') self.opened_from_flim = False @@ -324,8 +324,10 @@ def plot(self): else: self.x = self.file[:,0] self.y = self.file[:,1] + + self.check_loaded_files() - if self.check_loaded_files == True: #check the following conditions if all required files have been provided + if self.check_loaded_files() == True: #check the following conditions if all required files have been provided if self.ui.subtract_bck_radioButton.isChecked() == True and self.ui.WLRef_checkBox.isChecked() == False: bck_y = self.bck_file[:,1] self.y = self.y - bck_y From 72b545759b7eef69ac76807c45d753ca658b4b53 Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Mon, 14 Oct 2019 19:16:37 -0700 Subject: [PATCH 23/63] auto configure wavelength range for PhotonEtc hyperspec data, no need to input it --- PythonGUI_apps/H5_Pkl/h5_tree.py | 1 + PythonGUI_apps/H5_Pkl/h5_view_and_plot.py | 10 +++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/PythonGUI_apps/H5_Pkl/h5_tree.py b/PythonGUI_apps/H5_Pkl/h5_tree.py index c087f78..6d82566 100644 --- a/PythonGUI_apps/H5_Pkl/h5_tree.py +++ b/PythonGUI_apps/H5_Pkl/h5_tree.py @@ -40,6 +40,7 @@ def on_change_data_filename(self, fname=None): self.f = h5py.File(fname, 'r') self.on_new_search_text() self.databrowser.ui.statusbar.showMessage("") + return self.f except Exception as err: msg = "Failed to load %s:\n%s" %(fname, err) diff --git a/PythonGUI_apps/H5_Pkl/h5_view_and_plot.py b/PythonGUI_apps/H5_Pkl/h5_view_and_plot.py index 760cd46..18f3635 100644 --- a/PythonGUI_apps/H5_Pkl/h5_view_and_plot.py +++ b/PythonGUI_apps/H5_Pkl/h5_view_and_plot.py @@ -73,7 +73,7 @@ def on_change_data_filename(self): try: fname = self.settings.data_filename.val if os.path.isfile(fname): - self.h5treeview.on_change_data_filename(fname) + self.f = self.h5treeview.on_change_data_filename(fname) self.ui.dataview_placeholder.hide() self.h5treeview.ui.show() except: @@ -96,8 +96,12 @@ def plot_dataset(self): elif self.dataset_shape == 2 and self.ui.image_radioButton.isChecked(): self.data_img.setImage(data) elif self.dataset_shape == 3: - x_start = self.ui.imageView_x_start_spinBox.value() - x_end = self.ui.imageView_x_end_spinBox.value() + if self.f['Cube/Info/Cube'].attrs['AcqMode'] == b'Hyperspectral Acquisition': # This works for our PhotonEtc. Hyperspectral Camera output + x_start = int(self.f['Cube/Info/Cube'].attrs['LowerWavelength']) + x_end = int(self.f['Cube/Info/Cube'].attrs['UpperWavelength']) + else: + x_start = self.ui.imageView_x_start_spinBox.value() + x_end = self.ui.imageView_x_end_spinBox.value() num_points = self.dataset.shape[0] x_values = np.linspace(x_start, x_end, num_points) #scale x axis self.ui.data_imageView.setImage(data, xvals=x_values) From 7110331c3020d42f9c9c272031f117772dcb8419 Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Mon, 21 Oct 2019 18:35:03 -0700 Subject: [PATCH 24/63] added option to smooth traces using simple boxcar width smoothening --- .../Lifetime_analysis_gui_layout.ui | 30 +++++++++++++++++++ .../Lifetime_analysis/Lifetime_plot_fit.py | 11 +++++++ 2 files changed, 41 insertions(+) diff --git a/PythonGUI_apps/Lifetime_analysis/Lifetime_analysis_gui_layout.ui b/PythonGUI_apps/Lifetime_analysis/Lifetime_analysis_gui_layout.ui index e80df57..4a1cb48 100644 --- a/PythonGUI_apps/Lifetime_analysis/Lifetime_analysis_gui_layout.ui +++ b/PythonGUI_apps/Lifetime_analysis/Lifetime_analysis_gui_layout.ui @@ -1251,6 +1251,36 @@ + + + + + 12 + + + + Smooth Data + + + + + + + false + + + + 12 + + + + 1 + + + 1000 + + + diff --git a/PythonGUI_apps/Lifetime_analysis/Lifetime_plot_fit.py b/PythonGUI_apps/Lifetime_analysis/Lifetime_plot_fit.py index fb9bca5..da21ae5 100644 --- a/PythonGUI_apps/Lifetime_analysis/Lifetime_plot_fit.py +++ b/PythonGUI_apps/Lifetime_analysis/Lifetime_plot_fit.py @@ -77,6 +77,7 @@ def __init__(self): self.ui.separate_irf_checkBox.stateChanged.connect(self.switch_open_irf) self.ui.export_data_pushButton.clicked.connect(self.export_data) self.ui.clear_export_data_pushButton.clicked.connect(self.clear_export_data) + self.ui.smoothData_checkBox.stateChanged.connect(self.smooth_trace_enabled) #set up plot color button self.plot_color_button = pg.ColorButton(color=(255,0,0)) @@ -187,6 +188,13 @@ def plot_color_changed(self): """ Grab new plot_color when color button value is changed """ self.plot_color = self.plot_color_button.color() + def smooth_trace_enabled(self): + """Enable smooth spin box when smooth data is checked""" + if self.ui.smoothData_checkBox.isChecked(): + self.ui.smoothData_spinBox.setEnabled(True) + else: + self.ui.smoothData_spinBox.setEnabled(False) + def acquire_settings(self, mode="data"): """ Acquire data or irf from channel specified in spinbox. @@ -215,6 +223,9 @@ def acquire_settings(self, mode="data"): length = np.shape(y)[0] x = np.arange(0, length, 1) * self.resolution + + if self.ui.smoothData_checkBox.isChecked() and mode=="data": + y = np.convolve(y, np.ones(self.ui.smoothData_spinBox.value())/self.ui.smoothData_spinBox.value(), mode="same") return x,y except Exception as e: From 44135337d4c5d9ae3b8fd2ddca9e2a0434110cf1 Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Fri, 25 Oct 2019 14:41:05 -0700 Subject: [PATCH 25/63] create a new export plot ui window --- .../Lifetime_analysis/export_plot.ui | 270 ++++++++++++++++++ 1 file changed, 270 insertions(+) create mode 100644 PythonGUI_apps/Lifetime_analysis/export_plot.ui diff --git a/PythonGUI_apps/Lifetime_analysis/export_plot.ui b/PythonGUI_apps/Lifetime_analysis/export_plot.ui new file mode 100644 index 0000000..42076b1 --- /dev/null +++ b/PythonGUI_apps/Lifetime_analysis/export_plot.ui @@ -0,0 +1,270 @@ + + + Form + + + + 0 + 0 + 573 + 322 + + + + Form + + + + + + + 15 + + + + X limits + + + + + + + + 12 + + + + Upper + + + + + + + + 12 + + + + 3000000 + + + + + + + + 12 + + + + Lower (10^) + + + + + + + + 12 + + + + 1 + + + -100.000000000000000 + + + 1.500000000000000 + + + + + + + + 15 + + + + Color + + + + + + + + 12 + + + + Trace + + + + + + + + 12 + + + + Lower + + + + + + + + 12 + + + + 3000000 + + + + + + + + 15 + + + + Y limits + + + + + + + + 12 + + + + -100 + + + -2 + + + + + + + + 12 + + + + Upper + + + + + + + + 12 + + + + Legend 2 + + + + + + + + 12 + + + + + + + + + 12 + + + + + + + + + 12 + + + + + + + + + 12 + + + + Fit + + + + + + + + 12 + + + + + + + + + 15 + + + + Legends + + + + + + + + 12 + + + + Legend 1 + + + + + + + + 17 + + + + Export Graph + + + + + + + + From 2fa77a70f01f3de620693901e9f0f337c16e641e Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Mon, 28 Oct 2019 16:27:56 -0700 Subject: [PATCH 26/63] parameters for export figure can now be controlled using export fig window popup, all functionality working for X-Y plot export for two traces --- .../Lifetime_analysis/Lifetime_plot_fit.py | 54 +++++++++++++++++-- .../Lifetime_analysis/export_plot.ui | 40 ++++++++++---- 2 files changed, 78 insertions(+), 16 deletions(-) diff --git a/PythonGUI_apps/Lifetime_analysis/Lifetime_plot_fit.py b/PythonGUI_apps/Lifetime_analysis/Lifetime_plot_fit.py index da21ae5..b26aabd 100644 --- a/PythonGUI_apps/Lifetime_analysis/Lifetime_plot_fit.py +++ b/PythonGUI_apps/Lifetime_analysis/Lifetime_plot_fit.py @@ -67,7 +67,7 @@ def __init__(self): self.ui.plot_pushButton.clicked.connect(self.plot) self.ui.fit_pushButton.clicked.connect(self.call_fit_and_plot) self.ui.clear_pushButton.clicked.connect(self.clear_plot) - self.ui.export_plot_pushButton.clicked.connect(self.pub_ready_plot_export) + self.ui.export_plot_pushButton.clicked.connect(self.export_window)#pub_ready_plot_export self.ui.calculate_srv_pushButton.clicked.connect(self.calculate_srv) self.ui.log_checkBox.stateChanged.connect(self.make_semilog) @@ -518,6 +518,10 @@ def export_data(self): def clear_export_data(self): self.data_list = [] + + def export_window(self): + self.exportplotwindow = ExportPlotWindow() + self.exportplotwindow.export_fig_signal.connect(self.pub_ready_plot_export) def pub_ready_plot_export(self): try: @@ -526,19 +530,27 @@ def pub_ready_plot_export(self): plt.figure(figsize=(8,6)) plt.tick_params(direction='out', length=8, width=3.5) if self.ui.save_w_fit_checkBox.isChecked(): - plt.plot(self.out[:,0],self.out[:,1]/np.max(self.out[:,1])) - plt.plot(self.out[:,0],self.out[:,2]/np.max(self.out[:,1]),'k') + plt.plot(self.out[:,0],self.out[:,1]/np.max(self.out[:,1]),self.exportplotwindow.ui.traceColor_comboBox.currentText()) + plt.plot(self.out[:,0],self.out[:,2]/np.max(self.out[:,1]),self.exportplotwindow.ui.fitColor_comboBox.currentText()) + if self.exportplotwindow.ui.legend_checkBox.isChecked(): + plt.legend([self.exportplotwindow.ui.legend1_lineEdit.text(),self.exportplotwindow.ui.legend2_lineEdit.text()]) else: - plt.plot(self.acquire_settings()[0],self.acquire_settings()[1]/np.max(self.acquire_settings()[1])) + plt.plot(self.acquire_settings()[0],self.acquire_settings()[1]/np.max(self.acquire_settings()[1]), + self.exportplotwindow.ui.traceColor_comboBox.currentText()) + if self.exportplotwindow.ui.legend_checkBox.isChecked(): + plt.legend([self.exportplotwindow.ui.legend1_lineEdit.text()]) plt.yscale('log') plt.xlabel("Time (ns)", fontsize=20, fontweight='bold') plt.ylabel("Intensity (norm.)", fontsize=20, fontweight='bold') plt.tight_layout() + plt.xlim([self.exportplotwindow.ui.lowerX_spinBox.value(),self.exportplotwindow.ui.upperX_spinBox.value()]) + plt.ylim([10**(self.exportplotwindow.ui.lowerY_spinBox.value()),self.exportplotwindow.ui.upperY_doubleSpinBox.value()]) plt.savefig(filename[0],bbox_inches='tight', dpi=300) plt.close() - except: + except Exception as e: + self.ui.Result_textBrowser.append(format(e)) pass def close_application(self): @@ -572,6 +584,38 @@ def done(self): self.skip_rows_signal.emit() self.close() +"""Export plot GUI""" +ui_file_path = (base_path / "export_plot.ui").resolve() +export_WindowTemplate, export_TemplateBaseClass = pg.Qt.loadUiType(ui_file_path) + +class ExportPlotWindow(export_TemplateBaseClass): + + export_fig_signal = QtCore.pyqtSignal() + + def __init__(self): + export_TemplateBaseClass.__init__(self) + + self.ui = export_WindowTemplate() + self.ui.setupUi(self) + self.ui.traceColor_comboBox.addItems(["C0","C1","C2","C3","C4","C5","C6","C7", "r", "g", "b", "y", "k"]) + self.ui.fitColor_comboBox.addItems(["k", "r", "b", "y", "g","C0","C1","C2","C3","C4","C5","C6","C7"]) + self.ui.export_pushButton.clicked.connect(self.export) + self.ui.legend_checkBox.stateChanged.connect(self.legend_title) + self.show() + + def legend_title(self): + if self.ui.legend_checkBox.isChecked(): + self.ui.legend1_lineEdit.setEnabled(True) + self.ui.legend2_lineEdit.setEnabled(True) + else: + self.ui.legend1_lineEdit.setEnabled(False) + self.ui.legend2_lineEdit.setEnabled(False) + + def export(self): + self.export_fig_signal.emit() + self.close() + + def run(): win = MainWindow() QtGui.QApplication.instance().exec_() diff --git a/PythonGUI_apps/Lifetime_analysis/export_plot.ui b/PythonGUI_apps/Lifetime_analysis/export_plot.ui index 42076b1..10ce4db 100644 --- a/PythonGUI_apps/Lifetime_analysis/export_plot.ui +++ b/PythonGUI_apps/Lifetime_analysis/export_plot.ui @@ -6,8 +6,8 @@ 0 0 - 573 - 322 + 714 + 435 @@ -167,7 +167,19 @@ - + + + + + 17 + + + + Export Graph + + + + @@ -179,8 +191,11 @@ - + + + false + 12 @@ -218,8 +233,11 @@ - + + + false + 12 @@ -227,7 +245,7 @@ - + @@ -239,7 +257,7 @@ - + @@ -251,15 +269,15 @@ - - + + - 17 + 15 - Export Graph + Add Legends to the Plot From 73f20115d897069249fe5845085cdc94b44b0caf Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Mon, 28 Oct 2019 16:33:30 -0700 Subject: [PATCH 27/63] change upper X lim auto display value --- PythonGUI_apps/Lifetime_analysis/export_plot.ui | 3 +++ 1 file changed, 3 insertions(+) diff --git a/PythonGUI_apps/Lifetime_analysis/export_plot.ui b/PythonGUI_apps/Lifetime_analysis/export_plot.ui index 10ce4db..f212d6d 100644 --- a/PythonGUI_apps/Lifetime_analysis/export_plot.ui +++ b/PythonGUI_apps/Lifetime_analysis/export_plot.ui @@ -48,6 +48,9 @@ 3000000 + + 1000 + From 5bf7e64e4f67b41fff677b0553d58c77b2f170d9 Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Tue, 29 Oct 2019 14:54:02 -0700 Subject: [PATCH 28/63] inlcude export figure window for exporting images --- .../Spectrum_analysis/Spectra_plot_fit.py | 68 +++++++- .../Spectrum_analysis/export_fig_gui.ui | 156 ++++++++++++++++++ 2 files changed, 217 insertions(+), 7 deletions(-) create mode 100644 PythonGUI_apps/Spectrum_analysis/export_fig_gui.ui diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py index 2b3b473..f7ff734 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py @@ -88,7 +88,7 @@ def __init__(self): # self.ui.config_fit_params_pushButton.clicked.connect(self.configure_fit_params) self.ui.clear_pushButton.clicked.connect(self.clear_plot) self.ui.export_single_figure_pushButton.clicked.connect(self.pub_ready_plot_export) - self.ui.export_scan_figure_pushButton.clicked.connect(self.pub_ready_plot_export) + self.ui.export_scan_figure_pushButton.clicked.connect(self.export_window) self.ui.analyze_spectra_fits_pushButton.clicked.connect(self.analyze_spectra_fits) self.ui.import_pkl_pushButton.clicked.connect(self.open_pkl_file) @@ -495,6 +495,10 @@ def fit_and_plot(self): except Exception as e: self.ui.result_textBrowser.append(str(e)) + + def export_window(self): + self.export_window = ExportFigureWindow() + self.export_window.export_fig_signal.connect(self.pub_ready_plot_export) def pub_ready_plot_export(self): filename = QtWidgets.QFileDialog.getSaveFileName(self,caption="Filename with EXTENSION") @@ -511,10 +515,21 @@ def pub_ready_plot_export(self): data = self.spec_scan_file except: data = self.fit_scan_file - param_selection = str(self.ui.comboBox.currentText()) - if param_selection == 'pk_pos': label = 'PL Peak Position (n.m.)' - elif param_selection == 'fwhm': label = 'PL FWHM (n.m.)' - cpm.plot_confocal(self.img, figsize=(10,10), stepsize = data['Scan Parameters']['X step size (um)'], cmap="seismic", cbar_label=label) + if self.export_window.ui.reverse_checkBox.isChecked(): + colormap = str(self.export_window.ui.cmap_comboBox.currentText())+"_r" + else: + colormap = str(self.export_window.ui.cmap_comboBox.currentText()) + if str(self.export_window.ui.dataChannel_comboBox.currentText()) == "Fitted": + param_selection = str(self.ui.comboBox.currentText()) + if param_selection == 'pk_pos': label = 'PL Peak Position (n.m.)' + elif param_selection == 'fwhm': label = 'PL FWHM (n.m.)' + cpm.plot_confocal(self.img, figsize=(10,10), stepsize = data['Scan Parameters']['X step size (um)'], cmap=colormap, cbar_label=label, + vmin=self.export_window.ui.vmin_spinBox.value(), vmax=self.export_window.ui.vmax_spinBox.value()) + elif str(self.export_window.ui.dataChannel_comboBox.currentText()) == "Raw": + cpm.plot_confocal(self.sums, figsize=(10,10), stepsize = data['Scan Parameters']['X step size (um)'], cmap=colormap, + vmin=self.export_window.ui.vmin_spinBox.value(), vmax=self.export_window.ui.vmax_spinBox.value()) + plt.tick_params(direction='out', length=8, width=3.5) + plt.tight_layout() plt.savefig(filename[0],bbox_inches='tight', dpi=300) plt.close() except: @@ -674,9 +689,9 @@ def plot_intensity_sums(self): #intensities = np.reshape(intensities, newshape=(2048, numb_pixels_X*numb_pixels_Y)) sums = np.sum(self.intensities, axis=-1) - sums = np.reshape(sums, newshape=(self.numb_x_pixels, self.numb_y_pixels)) + self.sums = np.reshape(sums, newshape=(self.numb_x_pixels, self.numb_y_pixels)) - self.ui.intensity_sums_viewBox.setImage(sums, scale= + self.ui.intensity_sums_viewBox.setImage(self.sums, scale= (self.x_step_size, self.y_step_size)) self.ui.intensity_sums_viewBox.view.invertY(False) @@ -884,6 +899,45 @@ def run(self): win = Analyze() QtGui.QApplication.instance().exec_() return win + +"""Export Images GUI""" +ui_file_path = (base_path / "export_fig_gui.ui").resolve() +export_WindowTemplate, export_TemplateBaseClass = pg.Qt.loadUiType(ui_file_path) + +class ExportFigureWindow(export_TemplateBaseClass): + + export_fig_signal = QtCore.pyqtSignal() + + def __init__(self): + export_TemplateBaseClass.__init__(self) + + self.ui = export_WindowTemplate() + self.ui.setupUi(self) + self.ui.cmap_comboBox.addItems(['viridis', 'plasma', 'inferno', 'magma', + 'cividis','Greys', 'Purples', 'Blues', + 'Greens', 'Oranges', 'Reds', 'YlOrBr', + 'YlOrRd', 'OrRd', 'PuRd', 'RdPu', 'BuPu', + 'GnBu', 'PuBu', 'YlGnBu', 'PuBuGn', 'BuGn', + 'YlGn', 'binary', 'gist_yarg', 'gist_gray', + 'gray', 'bone', 'pink', 'spring', 'summer', + 'autumn', 'winter', 'cool', 'Wistia', 'hot', + 'afmhot', 'gist_heat', 'copper', 'rainbow', 'jet']) + self.ui.dataChannel_comboBox.addItems(['Raw', 'Fitted']) + self.ui.exportFig_pushButton.clicked.connect(self.export) +# self.ui.legend_checkBox.stateChanged.connect(self.legend_title) + self.show() + +# def legend_title(self): +# if self.ui.legend_checkBox.isChecked(): +# self.ui.legend1_lineEdit.setEnabled(True) +# self.ui.legend2_lineEdit.setEnabled(True) +# else: +# self.ui.legend1_lineEdit.setEnabled(False) +# self.ui.legend2_lineEdit.setEnabled(False) + + def export(self): + self.export_fig_signal.emit() + self.close() """Run the Main Window""" def run(): diff --git a/PythonGUI_apps/Spectrum_analysis/export_fig_gui.ui b/PythonGUI_apps/Spectrum_analysis/export_fig_gui.ui new file mode 100644 index 0000000..569aa1b --- /dev/null +++ b/PythonGUI_apps/Spectrum_analysis/export_fig_gui.ui @@ -0,0 +1,156 @@ + + + ExportFigure + + + + 0 + 0 + 302 + 317 + + + + Form + + + + + + + 15 + + + + 1000000000 + + + + + + + + 15 + + + + Color Bar Label + + + + + + + + 15 + + + + Data Channel to Save + + + + + + + + 15 + + + + + + + + + 15 + + + + + + + + + 15 + + + + ColorMap + + + + + + + + 15 + + + + 1000000000 + + + + + + + + 15 + + + + ColorBar Min + + + + + + + + 15 + + + + ColorBar Max + + + + + + + + 15 + + + + + + + + + 15 + + + + Export Figure + + + + + + + + 15 + + + + Reversed + + + + + + + + From 4532fa1f89a5e75ef9b80db80a0bd7cf3aef995f Mon Sep 17 00:00:00 2001 From: Sarthak Jariwala Date: Sun, 3 Nov 2019 18:29:50 -0800 Subject: [PATCH 29/63] calculate both conditions, srv1=srv2 and srv1=0, while doing srv calculations --- .../Lifetime_analysis_gui_layout.ui | 93 +++++++++++++------ .../Lifetime_analysis/Lifetime_plot_fit.py | 26 +++--- 2 files changed, 77 insertions(+), 42 deletions(-) diff --git a/PythonGUI_apps/Lifetime_analysis/Lifetime_analysis_gui_layout.ui b/PythonGUI_apps/Lifetime_analysis/Lifetime_analysis_gui_layout.ui index 4a1cb48..53f58dd 100644 --- a/PythonGUI_apps/Lifetime_analysis/Lifetime_analysis_gui_layout.ui +++ b/PythonGUI_apps/Lifetime_analysis/Lifetime_analysis_gui_layout.ui @@ -7,7 +7,7 @@ 0 0 1490 - 1201 + 1583 @@ -925,6 +925,23 @@ + + + + 4 + + + 9999999.000000000000000 + + + + + + + 0 + + + @@ -932,13 +949,23 @@ - + SRV (cm/s) + + + + 100000.000000000000000 + + + 8000.000000000000000 + + + @@ -946,58 +973,64 @@ - - + + - SRV1 = SRV2 + Surface Lifetime (ns) - - + + - Calculate + Average Lifetime (ns) - - - - 100000.000000000000000 - - - 8000.000000000000000 + + + + Calculate - - + + - Surface Lifetime (ns) + SRV (cm/s) - - + + 0 - - + + + + + 75 + true + + - Average Lifetime (ns) + SRV1 = SRV2 - - - - 4 + + + + + 75 + true + - - 9999999.000000000000000 + + SRV1 = 0 @@ -1292,7 +1325,7 @@ 0 0 1490 - 21 + 38 diff --git a/PythonGUI_apps/Lifetime_analysis/Lifetime_plot_fit.py b/PythonGUI_apps/Lifetime_analysis/Lifetime_plot_fit.py index b26aabd..dd1b0cb 100644 --- a/PythonGUI_apps/Lifetime_analysis/Lifetime_plot_fit.py +++ b/PythonGUI_apps/Lifetime_analysis/Lifetime_plot_fit.py @@ -476,12 +476,11 @@ def calculate_srv (self): self.thickness = self.ui.thickness_spinBox.value()*1e-7 # convert to cm self.diffusion_coeffecient = self.ui.diffusion_coefficient_spinBox.value() # in cm2/s - if self.ui.srv1_srv2_checkBox.isChecked(): - self.srv = self.thickness / (2*((1e-9*self.surface_lifetime) - ((1/self.diffusion_coeffecient)*((self.thickness/np.pi)**2)) )) - else: - self.srv = self.thickness / ((1e-9*self.surface_lifetime) - ((4/self.diffusion_coeffecient)*((self.thickness/np.pi)**2)) ) + self.srv1_srv2_equal = self.thickness / (2*((1e-9*self.surface_lifetime) - ((1/self.diffusion_coeffecient)*((self.thickness/np.pi)**2)) )) + self.srv1_zero = self.thickness / ((1e-9*self.surface_lifetime) - ((4/self.diffusion_coeffecient)*((self.thickness/np.pi)**2)) ) - self.ui.srv_label.setText(str(self.srv)) + self.ui.srv1_srv2_equal_label.setText(str(self.srv1_srv2_equal)) + self.ui.srv1_zero_label.setText(str(self.srv1_zero)) def get_srv_string(self): """ Get info from SRV Calculation groupbox as string """ @@ -490,12 +489,13 @@ def get_srv_string(self): + "\nBulk Lifetime (ns): " + str(self.ui.bulk_lifetime_spinBox.value()) \ + "\nThickness (nm): " + str(self.ui.thickness_spinBox.value()) \ + "\nDiffusion Coefficient (cm2/s): " + str(self.ui.diffusion_coefficient_spinBox.value()) - if self.ui.srv1_srv2_checkBox.isChecked(): - srv_string += "\nSRV1 = SRV2" - else: - srv_string += "\nSRV1 = 0" - srv_string += "\nSurface Lifetime (ns): " + self.ui.surface_lifetime_label.text() \ - + "\nSRV (cm/s): " + self.ui.srv_label.text() + srv_string += "\nSurface Lifetime (ns): " + self.ui.surface_lifetime_label.text() + + srv_string += "\nSRV1 = SRV2"\ + + "\nSRV (cm/s): " + self.ui.srv1_srv2_equal_label.text() + + srv_string += "\nSRV1 = 0"\ + + "\nSRV (cm/s): " + self.ui.srv1_zero_label.text() return srv_string def export_data(self): @@ -530,8 +530,10 @@ def pub_ready_plot_export(self): plt.figure(figsize=(8,6)) plt.tick_params(direction='out', length=8, width=3.5) if self.ui.save_w_fit_checkBox.isChecked(): + print("inside if") plt.plot(self.out[:,0],self.out[:,1]/np.max(self.out[:,1]),self.exportplotwindow.ui.traceColor_comboBox.currentText()) plt.plot(self.out[:,0],self.out[:,2]/np.max(self.out[:,1]),self.exportplotwindow.ui.fitColor_comboBox.currentText()) + print("finished plotting") if self.exportplotwindow.ui.legend_checkBox.isChecked(): plt.legend([self.exportplotwindow.ui.legend1_lineEdit.text(),self.exportplotwindow.ui.legend2_lineEdit.text()]) else: @@ -544,7 +546,7 @@ def pub_ready_plot_export(self): plt.ylabel("Intensity (norm.)", fontsize=20, fontweight='bold') plt.tight_layout() plt.xlim([self.exportplotwindow.ui.lowerX_spinBox.value(),self.exportplotwindow.ui.upperX_spinBox.value()]) - plt.ylim([10**(self.exportplotwindow.ui.lowerY_spinBox.value()),self.exportplotwindow.ui.upperY_doubleSpinBox.value()]) + plt.ylim([self.exportplotwindow.ui.lowerY_spinBox.value(),self.exportplotwindow.ui.upperY_doubleSpinBox.value()]) plt.savefig(filename[0],bbox_inches='tight', dpi=300) plt.close() From ae68877406102be413cb5d73c884d8f8cf4ccdb4 Mon Sep 17 00:00:00 2001 From: Sarthak Jariwala Date: Sun, 3 Nov 2019 18:34:47 -0800 Subject: [PATCH 30/63] change x lower lim to include negative numbers, y lower lim is now 4 decimals --- .../Lifetime_analysis/export_plot.ui | 40 +++++++++++-------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/PythonGUI_apps/Lifetime_analysis/export_plot.ui b/PythonGUI_apps/Lifetime_analysis/export_plot.ui index f212d6d..31e3b40 100644 --- a/PythonGUI_apps/Lifetime_analysis/export_plot.ui +++ b/PythonGUI_apps/Lifetime_analysis/export_plot.ui @@ -6,7 +6,7 @@ 0 0 - 714 + 980 435 @@ -61,7 +61,7 @@ - Lower (10^) + Lower @@ -126,6 +126,9 @@ 12 + + -10000 + 3000000 @@ -143,21 +146,6 @@ - - - - - 12 - - - - -100 - - - -2 - - - @@ -284,6 +272,24 @@ + + + + + 12 + + + + 4 + + + 0.000000000000000 + + + 0.010000000000000 + + + From 0d21d2d5c8e328156a3a29f031d21bfc2ed493f7 Mon Sep 17 00:00:00 2001 From: Sarthak Jariwala Date: Sun, 3 Nov 2019 21:23:28 -0800 Subject: [PATCH 31/63] Refactor Code to have a separate Export Window module imported when required --- .../Export_Windows/Export_window.py | 71 +++++ PythonGUI_apps/Export_Windows/__init__.py | 1 + .../Export_Windows/export_fig_gui.ui | 156 +++++++++ PythonGUI_apps/Export_Windows/export_plot.ui | 297 ++++++++++++++++++ .../Lifetime_analysis/Lifetime_plot_fit.py | 39 +-- .../Spectrum_analysis/Spectra_plot_fit.py | 42 +-- 6 files changed, 542 insertions(+), 64 deletions(-) create mode 100644 PythonGUI_apps/Export_Windows/Export_window.py create mode 100644 PythonGUI_apps/Export_Windows/__init__.py create mode 100644 PythonGUI_apps/Export_Windows/export_fig_gui.ui create mode 100644 PythonGUI_apps/Export_Windows/export_plot.ui diff --git a/PythonGUI_apps/Export_Windows/Export_window.py b/PythonGUI_apps/Export_Windows/Export_window.py new file mode 100644 index 0000000..060ffc8 --- /dev/null +++ b/PythonGUI_apps/Export_Windows/Export_window.py @@ -0,0 +1,71 @@ +# -*- coding: utf-8 -*- +""" +Created on Sun Nov 3 20:43:12 2019 + +@author: sarth +""" +from pathlib import Path +import pyqtgraph as pg +from pyqtgraph.Qt import QtCore, QtGui + +"""Export Images GUI""" +base_path = Path(__file__).parent +ui_file_path = (base_path / "export_fig_gui.ui").resolve() +export_WindowTemplate, export_TemplateBaseClass = pg.Qt.loadUiType(ui_file_path) + +class ExportFigureWindow(export_TemplateBaseClass): + + export_fig_signal = QtCore.pyqtSignal() + + def __init__(self): + export_TemplateBaseClass.__init__(self) + + self.ui = export_WindowTemplate() + self.ui.setupUi(self) + self.ui.cmap_comboBox.addItems(['viridis', 'plasma', 'inferno', 'magma', + 'cividis','Greys', 'Purples', 'Blues', + 'Greens', 'Oranges', 'Reds', 'YlOrBr', + 'YlOrRd', 'OrRd', 'PuRd', 'RdPu', 'BuPu', + 'GnBu', 'PuBu', 'YlGnBu', 'PuBuGn', 'BuGn', + 'YlGn', 'binary', 'gist_yarg', 'gist_gray', + 'gray', 'bone', 'pink', 'spring', 'summer', + 'autumn', 'winter', 'cool', 'Wistia', 'hot', + 'afmhot', 'gist_heat', 'copper', 'rainbow', 'jet']) +# self.ui.dataChannel_comboBox.addItems(['Raw', 'Fitted']) + self.ui.exportFig_pushButton.clicked.connect(self.export) + self.show() + + def export(self): + self.export_fig_signal.emit() + self.close() + +"""Export plot GUI""" +ui_file_path = (base_path / "export_plot.ui").resolve() +export_WindowTemplate, export_TemplateBaseClass = pg.Qt.loadUiType(ui_file_path) + +class ExportPlotWindow(export_TemplateBaseClass): + + export_fig_signal = QtCore.pyqtSignal() + + def __init__(self): + export_TemplateBaseClass.__init__(self) + + self.ui = export_WindowTemplate() + self.ui.setupUi(self) + self.ui.traceColor_comboBox.addItems(["C0","C1","C2","C3","C4","C5","C6","C7", "r", "g", "b", "y", "k"]) + self.ui.fitColor_comboBox.addItems(["k", "r", "b", "y", "g","C0","C1","C2","C3","C4","C5","C6","C7"]) + self.ui.export_pushButton.clicked.connect(self.export) + self.ui.legend_checkBox.stateChanged.connect(self.legend_title) + self.show() + + def legend_title(self): + if self.ui.legend_checkBox.isChecked(): + self.ui.legend1_lineEdit.setEnabled(True) + self.ui.legend2_lineEdit.setEnabled(True) + else: + self.ui.legend1_lineEdit.setEnabled(False) + self.ui.legend2_lineEdit.setEnabled(False) + + def export(self): + self.export_fig_signal.emit() + self.close() \ No newline at end of file diff --git a/PythonGUI_apps/Export_Windows/__init__.py b/PythonGUI_apps/Export_Windows/__init__.py new file mode 100644 index 0000000..7c68785 --- /dev/null +++ b/PythonGUI_apps/Export_Windows/__init__.py @@ -0,0 +1 @@ +# -*- coding: utf-8 -*- \ No newline at end of file diff --git a/PythonGUI_apps/Export_Windows/export_fig_gui.ui b/PythonGUI_apps/Export_Windows/export_fig_gui.ui new file mode 100644 index 0000000..569aa1b --- /dev/null +++ b/PythonGUI_apps/Export_Windows/export_fig_gui.ui @@ -0,0 +1,156 @@ + + + ExportFigure + + + + 0 + 0 + 302 + 317 + + + + Form + + + + + + + 15 + + + + 1000000000 + + + + + + + + 15 + + + + Color Bar Label + + + + + + + + 15 + + + + Data Channel to Save + + + + + + + + 15 + + + + + + + + + 15 + + + + + + + + + 15 + + + + ColorMap + + + + + + + + 15 + + + + 1000000000 + + + + + + + + 15 + + + + ColorBar Min + + + + + + + + 15 + + + + ColorBar Max + + + + + + + + 15 + + + + + + + + + 15 + + + + Export Figure + + + + + + + + 15 + + + + Reversed + + + + + + + + diff --git a/PythonGUI_apps/Export_Windows/export_plot.ui b/PythonGUI_apps/Export_Windows/export_plot.ui new file mode 100644 index 0000000..31e3b40 --- /dev/null +++ b/PythonGUI_apps/Export_Windows/export_plot.ui @@ -0,0 +1,297 @@ + + + Form + + + + 0 + 0 + 980 + 435 + + + + Form + + + + + + + 15 + + + + X limits + + + + + + + + 12 + + + + Upper + + + + + + + + 12 + + + + 3000000 + + + 1000 + + + + + + + + 12 + + + + Lower + + + + + + + + 12 + + + + 1 + + + -100.000000000000000 + + + 1.500000000000000 + + + + + + + + 15 + + + + Color + + + + + + + + 12 + + + + Trace + + + + + + + + 12 + + + + Lower + + + + + + + + 12 + + + + -10000 + + + 3000000 + + + + + + + + 15 + + + + Y limits + + + + + + + + 12 + + + + Upper + + + + + + + + 17 + + + + Export Graph + + + + + + + + 12 + + + + Legend 2 + + + + + + + false + + + + 12 + + + + + + + + + 12 + + + + + + + + + 12 + + + + + + + + + 12 + + + + Fit + + + + + + + false + + + + 12 + + + + + + + + + 15 + + + + Legends + + + + + + + + 12 + + + + Legend 1 + + + + + + + + 15 + + + + Add Legends to the Plot + + + + + + + + 12 + + + + 4 + + + 0.000000000000000 + + + 0.010000000000000 + + + + + + + + diff --git a/PythonGUI_apps/Lifetime_analysis/Lifetime_plot_fit.py b/PythonGUI_apps/Lifetime_analysis/Lifetime_plot_fit.py index dd1b0cb..3081d89 100644 --- a/PythonGUI_apps/Lifetime_analysis/Lifetime_plot_fit.py +++ b/PythonGUI_apps/Lifetime_analysis/Lifetime_plot_fit.py @@ -16,6 +16,12 @@ import numpy as np import matplotlib.pyplot as plt +sys.path.append(os.path.abspath('../Export_Windows')) +try: + from Export_window import ExportPlotWindow +except: + from Export_Windows.Export_window import ExportPlotWindow + # local module imports try: from Lifetime_analysis.Fit_functions import stretch_exp_fit, double_exp_fit, single_exp_fit @@ -530,10 +536,8 @@ def pub_ready_plot_export(self): plt.figure(figsize=(8,6)) plt.tick_params(direction='out', length=8, width=3.5) if self.ui.save_w_fit_checkBox.isChecked(): - print("inside if") plt.plot(self.out[:,0],self.out[:,1]/np.max(self.out[:,1]),self.exportplotwindow.ui.traceColor_comboBox.currentText()) plt.plot(self.out[:,0],self.out[:,2]/np.max(self.out[:,1]),self.exportplotwindow.ui.fitColor_comboBox.currentText()) - print("finished plotting") if self.exportplotwindow.ui.legend_checkBox.isChecked(): plt.legend([self.exportplotwindow.ui.legend1_lineEdit.text(),self.exportplotwindow.ui.legend2_lineEdit.text()]) else: @@ -586,37 +590,6 @@ def done(self): self.skip_rows_signal.emit() self.close() -"""Export plot GUI""" -ui_file_path = (base_path / "export_plot.ui").resolve() -export_WindowTemplate, export_TemplateBaseClass = pg.Qt.loadUiType(ui_file_path) - -class ExportPlotWindow(export_TemplateBaseClass): - - export_fig_signal = QtCore.pyqtSignal() - - def __init__(self): - export_TemplateBaseClass.__init__(self) - - self.ui = export_WindowTemplate() - self.ui.setupUi(self) - self.ui.traceColor_comboBox.addItems(["C0","C1","C2","C3","C4","C5","C6","C7", "r", "g", "b", "y", "k"]) - self.ui.fitColor_comboBox.addItems(["k", "r", "b", "y", "g","C0","C1","C2","C3","C4","C5","C6","C7"]) - self.ui.export_pushButton.clicked.connect(self.export) - self.ui.legend_checkBox.stateChanged.connect(self.legend_title) - self.show() - - def legend_title(self): - if self.ui.legend_checkBox.isChecked(): - self.ui.legend1_lineEdit.setEnabled(True) - self.ui.legend2_lineEdit.setEnabled(True) - else: - self.ui.legend1_lineEdit.setEnabled(False) - self.ui.legend2_lineEdit.setEnabled(False) - - def export(self): - self.export_fig_signal.emit() - self.close() - def run(): win = MainWindow() diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py index f7ff734..f43f124 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py @@ -23,6 +23,11 @@ sys.path.append(os.path.abspath('../H5_Pkl')) from H5_Pkl import h5_pkl_view +sys.path.append(os.path.abspath('../Export_Windows')) +try: + from Export_window import ExportFigureWindow +except: + from Export_Windows.Export_window import ExportFigureWindow # local modules try: from Spectra_fit_funcs import Spectra_Fit, Single_Gaussian, Single_Lorentzian, Double_Gaussian, Multi_Gaussian @@ -497,7 +502,7 @@ def fit_and_plot(self): self.ui.result_textBrowser.append(str(e)) def export_window(self): - self.export_window = ExportFigureWindow() + self.export_window = ExportImages() self.export_window.export_fig_signal.connect(self.pub_ready_plot_export) def pub_ready_plot_export(self): @@ -901,43 +906,18 @@ def run(self): return win """Export Images GUI""" -ui_file_path = (base_path / "export_fig_gui.ui").resolve() -export_WindowTemplate, export_TemplateBaseClass = pg.Qt.loadUiType(ui_file_path) +#ui_file_path = (base_path / "export_fig_gui.ui").resolve() +#export_WindowTemplate, export_TemplateBaseClass = pg.Qt.loadUiType(ui_file_path) -class ExportFigureWindow(export_TemplateBaseClass): +class ExportImages(ExportFigureWindow): export_fig_signal = QtCore.pyqtSignal() def __init__(self): - export_TemplateBaseClass.__init__(self) + ExportFigureWindow.__init__(self) - self.ui = export_WindowTemplate() - self.ui.setupUi(self) - self.ui.cmap_comboBox.addItems(['viridis', 'plasma', 'inferno', 'magma', - 'cividis','Greys', 'Purples', 'Blues', - 'Greens', 'Oranges', 'Reds', 'YlOrBr', - 'YlOrRd', 'OrRd', 'PuRd', 'RdPu', 'BuPu', - 'GnBu', 'PuBu', 'YlGnBu', 'PuBuGn', 'BuGn', - 'YlGn', 'binary', 'gist_yarg', 'gist_gray', - 'gray', 'bone', 'pink', 'spring', 'summer', - 'autumn', 'winter', 'cool', 'Wistia', 'hot', - 'afmhot', 'gist_heat', 'copper', 'rainbow', 'jet']) self.ui.dataChannel_comboBox.addItems(['Raw', 'Fitted']) - self.ui.exportFig_pushButton.clicked.connect(self.export) -# self.ui.legend_checkBox.stateChanged.connect(self.legend_title) - self.show() - -# def legend_title(self): -# if self.ui.legend_checkBox.isChecked(): -# self.ui.legend1_lineEdit.setEnabled(True) -# self.ui.legend2_lineEdit.setEnabled(True) -# else: -# self.ui.legend1_lineEdit.setEnabled(False) -# self.ui.legend2_lineEdit.setEnabled(False) - - def export(self): - self.export_fig_signal.emit() - self.close() + """Run the Main Window""" def run(): From fe38a7aa496854ff86ce8f13583ebbb98ccc0157 Mon Sep 17 00:00:00 2001 From: Sarthak Jariwala Date: Sun, 3 Nov 2019 21:24:15 -0800 Subject: [PATCH 32/63] delete ui files- cosequence of code refactor Can now be found in Wxport_window folder --- .../Lifetime_analysis/export_plot.ui | 297 ------------------ .../Spectrum_analysis/export_fig_gui.ui | 156 --------- 2 files changed, 453 deletions(-) delete mode 100644 PythonGUI_apps/Lifetime_analysis/export_plot.ui delete mode 100644 PythonGUI_apps/Spectrum_analysis/export_fig_gui.ui diff --git a/PythonGUI_apps/Lifetime_analysis/export_plot.ui b/PythonGUI_apps/Lifetime_analysis/export_plot.ui deleted file mode 100644 index 31e3b40..0000000 --- a/PythonGUI_apps/Lifetime_analysis/export_plot.ui +++ /dev/null @@ -1,297 +0,0 @@ - - - Form - - - - 0 - 0 - 980 - 435 - - - - Form - - - - - - - 15 - - - - X limits - - - - - - - - 12 - - - - Upper - - - - - - - - 12 - - - - 3000000 - - - 1000 - - - - - - - - 12 - - - - Lower - - - - - - - - 12 - - - - 1 - - - -100.000000000000000 - - - 1.500000000000000 - - - - - - - - 15 - - - - Color - - - - - - - - 12 - - - - Trace - - - - - - - - 12 - - - - Lower - - - - - - - - 12 - - - - -10000 - - - 3000000 - - - - - - - - 15 - - - - Y limits - - - - - - - - 12 - - - - Upper - - - - - - - - 17 - - - - Export Graph - - - - - - - - 12 - - - - Legend 2 - - - - - - - false - - - - 12 - - - - - - - - - 12 - - - - - - - - - 12 - - - - - - - - - 12 - - - - Fit - - - - - - - false - - - - 12 - - - - - - - - - 15 - - - - Legends - - - - - - - - 12 - - - - Legend 1 - - - - - - - - 15 - - - - Add Legends to the Plot - - - - - - - - 12 - - - - 4 - - - 0.000000000000000 - - - 0.010000000000000 - - - - - - - - diff --git a/PythonGUI_apps/Spectrum_analysis/export_fig_gui.ui b/PythonGUI_apps/Spectrum_analysis/export_fig_gui.ui deleted file mode 100644 index 569aa1b..0000000 --- a/PythonGUI_apps/Spectrum_analysis/export_fig_gui.ui +++ /dev/null @@ -1,156 +0,0 @@ - - - ExportFigure - - - - 0 - 0 - 302 - 317 - - - - Form - - - - - - - 15 - - - - 1000000000 - - - - - - - - 15 - - - - Color Bar Label - - - - - - - - 15 - - - - Data Channel to Save - - - - - - - - 15 - - - - - - - - - 15 - - - - - - - - - 15 - - - - ColorMap - - - - - - - - 15 - - - - 1000000000 - - - - - - - - 15 - - - - ColorBar Min - - - - - - - - 15 - - - - ColorBar Max - - - - - - - - 15 - - - - - - - - - 15 - - - - Export Figure - - - - - - - - 15 - - - - Reversed - - - - - - - - From 6d5a0e95c481b00ea3a62cc3dbb17883dfdfb552 Mon Sep 17 00:00:00 2001 From: Sarthak Jariwala Date: Sun, 3 Nov 2019 21:33:08 -0800 Subject: [PATCH 33/63] update ExportImages class --- .../Spectrum_analysis/Spectra_plot_fit.py | 1854 ++++++++--------- 1 file changed, 926 insertions(+), 928 deletions(-) diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py index f43f124..6479c4a 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py @@ -1,929 +1,927 @@ -# -*- coding: utf-8 -*- -""" -Created on Wed Mar 27 16:50:26 2019 - -@author: Sarthak -""" - -# system imports -import sys -import h5py -from pathlib import Path -import os.path -import pyqtgraph as pg -from pyqtgraph.Qt import QtCore, QtGui, QtWidgets#, QColorDialog -import numpy as np -import matplotlib.pyplot as plt -import matplotlib -import pickle -import lmfit -from lmfit.models import GaussianModel, LinearModel -from scipy import interpolate -import customplotting.mscope as cpm - -sys.path.append(os.path.abspath('../H5_Pkl')) -from H5_Pkl import h5_pkl_view -sys.path.append(os.path.abspath('../Export_Windows')) -try: - from Export_window import ExportFigureWindow -except: - from Export_Windows.Export_window import ExportFigureWindow -# local modules -try: - from Spectra_fit_funcs import Spectra_Fit, Single_Gaussian, Single_Lorentzian, Double_Gaussian, Multi_Gaussian - from pyqtgraph_MATPLOTLIBWIDGET import MatplotlibWidget -except: - from Spectrum_analysis.Spectra_fit_funcs import Spectra_Fit, Single_Gaussian, Single_Lorentzian, Double_Gaussian, Multi_Gaussian - from Spectrum_analysis.pyqtgraph_MATPLOTLIBWIDGET import MatplotlibWidget - -matplotlib.use('Qt5Agg') - -"""Recylce params for plotting""" -plt.rc('xtick', labelsize = 10) -plt.rc('xtick.major', pad = 1) -plt.rc('ytick', labelsize = 10) -plt.rc('lines', lw = 1.5, markersize = 3.5) -plt.rc('legend', fontsize = 10) -plt.rc('axes', linewidth=1.5) - -pg.mkQApp() -pg.setConfigOption('background', 'w') - - -base_path = Path(__file__).parent -file_path = (base_path / "Spectra_plot_fit_gui.ui").resolve() - -uiFile = file_path - -WindowTemplate, TemplateBaseClass = pg.Qt.loadUiType(uiFile) - -def updateDelay(scale, time): - """ Hack fix for scalebar inaccuracy""" - QtCore.QTimer.singleShot(time, scale.updateBar) - -class MainWindow(TemplateBaseClass): - - def __init__(self): - pg.setConfigOption('imageAxisOrder', 'row-major') - super(TemplateBaseClass, self).__init__() - - # Create the main window - self.ui = WindowTemplate() - self.ui.setupUi(self) - - # self.ui.fitFunc_comboBox.addItems(["Single Gaussian","Single Lorentzian", "Double Gaussian", "Multiple Gaussians"]) -# self.ui.actionExit.triggered.connect(self.close_application) - - ##setup ui signals - self.ui.importSpec_pushButton.clicked.connect(self.open_file) - self.ui.importBck_pushButton.clicked.connect(self.open_bck_file) - self.ui.importWLRef_pushButton.clicked.connect(self.open_wlref_file) - - self.ui.load_spectra_scan_pushButton.clicked.connect(self.open_spectra_scan_file) - self.ui.load_bck_file_pushButton.clicked.connect(self.open_spectra_bck_file) - self.ui.load_fitted_scan_pushButton.clicked.connect(self.open_fit_scan_file) - - self.ui.plot_pushButton.clicked.connect(self.plot) - self.ui.plot_fit_scan_pushButton.clicked.connect(self.plot_fit_scan) - self.ui.plot_raw_scan_pushButton.clicked.connect(self.plot_raw_scan) - self.ui.plot_intensity_sums_pushButton.clicked.connect(self.plot_intensity_sums) - - self.ui.fit_pushButton.clicked.connect(self.fit_and_plot) - self.ui.fit_scan_pushButton.clicked.connect(self.fit_and_plot_scan) - # self.ui.config_fit_params_pushButton.clicked.connect(self.configure_fit_params) - self.ui.clear_pushButton.clicked.connect(self.clear_plot) - self.ui.export_single_figure_pushButton.clicked.connect(self.pub_ready_plot_export) - self.ui.export_scan_figure_pushButton.clicked.connect(self.export_window) - self.ui.analyze_spectra_fits_pushButton.clicked.connect(self.analyze_spectra_fits) - - self.ui.import_pkl_pushButton.clicked.connect(self.open_pkl_file) - self.ui.data_txt_pushButton.clicked.connect(self.pkl_data_to_txt) - self.ui.scan_params_txt_pushButton.clicked.connect(self.pkl_params_to_txt) - - self.ui.pkl_to_h5_pushButton.clicked.connect(self.pkl_to_h5) - - self.ui.tabWidget.currentChanged.connect(self.switch_overall_tab) - self.ui.fitFunc_comboBox.currentTextChanged.connect(self.switch_bounds_and_guess_tab) - self.ui.adjust_param_checkBox.stateChanged.connect(self.switch_adjust_param) - - self.ui.export_data_pushButton.clicked.connect(self.export_data) - self.ui.clear_export_data_pushButton.clicked.connect(self.clear_export_data) - - # for i in reversed(range(self.ui.bounds_groupBox.layout().count())): - # self.ui.bounds_groupBox.layout().itemAt(i).widget().deleteLater() - #self.ui.single_bounds_page.layout().addWidget(QtWidgets.QPushButton("test")) - - self.file = None - self.bck_file = None - self.wlref_file = None - self.x = None - self.y = None - self.out = None # output file after fitting - - # Peak parameters if adjust params is selected - self.center_min = None - self.center_max = None - - #variables accounting for data received from FLIM analysis - self.opened_from_flim = False #switched to True in FLIM_plot when "analyze lifetime" clicked - self.sum_data_from_flim = [] - - # fit scan file variable set to None for analyze_spectra_fits - self.fit_scan_file = None - - #container for data to append to txt file - self.data_list = [] - - self.show() - - """ Open Single Spectrum files """ - def open_file(self): - try: - self.single_spec_filename = QtWidgets.QFileDialog.getOpenFileName(self) - try: - try: - self.file = np.loadtxt(self.single_spec_filename[0], skiprows = 1, delimiter=" ") - except: - self.file = np.loadtxt(self.single_spec_filename[0], skiprows = 16, delimiter='\t') - except: - self.file = np.genfromtxt(self.single_spec_filename[0], skip_header=1, skip_footer=3, delimiter='\t') - self.opened_from_flim = False - except: - pass - - def open_bck_file(self): - try: - filename = QtWidgets.QFileDialog.getOpenFileName(self) - try: - try: - self.bck_file = np.loadtxt(filename[0], skiprows=1, delimiter=" ") - except: - self.bck_file = np.loadtxt(filename[0], skiprows = 16, delimiter='\t') - except: - self.bck_file = np.genfromtxt(filename[0], skip_header=1, skip_footer=3, delimiter='\t') - except Exception as e: - self.ui.result_textBrowser.append(str(e)) - pass - - def open_wlref_file(self): - try: - filename = QtWidgets.QFileDialog.getOpenFileName(self) - try: - try: - self.wlref_file = np.loadtxt(filename[0], skiprows=1, delimiter= " ") - except: - self.wlref_file = np.loadtxt(filename[0], skiprows = 16, delimiter='\t') - except: - self.wlref_file = np.genfromtxt(filename[0], skip_header=1, skip_footer=3, delimiter='\t') - except: - pass - - """Open Scan Files""" - def open_spectra_scan_file(self): - try: - filename = QtWidgets.QFileDialog.getOpenFileName(self, filter="Scan files (*.pkl *.h5)") - self.filename_for_viewer_launch = filename[0] - if ".pkl" in filename[0]: - self.spec_scan_file = pickle.load(open(filename[0], 'rb')) - if self.ui.launch_data_viewer_checkBox.isChecked(): - self.launch_h5_pkl_viewer() - self.scan_file_type = "pkl" - elif ".h5" in filename[0]: - self.spec_scan_file = h5py.File(filename[0], 'r') - if self.ui.launch_data_viewer_checkBox.isChecked(): - self.launch_h5_pkl_viewer() - self.scan_file_type = "h5" - self.get_data_params() - self.ui.result_textBrowser2.append("Done Loading - Spectra Scan File") - except Exception as e: - self.ui.result_textBrowser2.append(str(e)) - pass - - def open_spectra_bck_file(self): - try: - filename = QtWidgets.QFileDialog.getOpenFileName(self) - self.bck_file = np.loadtxt(filename[0])#, skiprows=1, delimiter=None) - self.ui.result_textBrowser2.append("Done Loading - Background File") - except Exception as e: - self.ui.result_textBrowser2.append(str(e)) - pass - - def open_fit_scan_file(self): - try: - filename = QtWidgets.QFileDialog.getOpenFileName(self) - with pg.BusyCursor(): - self.filename_for_viewer_launch = filename[0] - self.fit_scan_file = pickle.load(open(filename[0], 'rb')) - if self.ui.launch_data_viewer_checkBox.isChecked(): - self.launch_h5_pkl_viewer() # TODO Needs to implement reading the fit result datatype in PKL Viewer - self.ui.result_textBrowser2.append("Done Loading - Scan Fit File") - except Exception as e: - self.ui.result_textBrowser2.append(str(e)) - pass - - def open_pkl_file(self): - """ Open pkl file to convert to txt """ - try: - self.pkl_to_convert = QtWidgets.QFileDialog.getOpenFileName(self) - self.filename_for_viewer_launch = self.pkl_to_convert[0] - self.launch_h5_pkl_viewer() - except: - pass - - def launch_h5_pkl_viewer(self): - """ Launches H5/PKL viewer to give an insight into the data and its structure""" - viewer_window = h5_pkl_view.H5PklView(sys.argv) - viewer_window.settings['data_filename'] = self.filename_for_viewer_launch - - def analyze_spectra_fits(self): - """Analyze fits to the individual spectrum within a spectra scan fit file""" - if self.fit_scan_file is None: - self.open_fit_scan_file() - - analyze_window = Analyze(scan_fit_file=self.fit_scan_file) - analyze_window.run() - - def switch_overall_tab(self): - """ Enable/disable fit settings on right depending on current tab """ - if self.ui.tabWidget.currentIndex() == 0: - self.ui.fitting_settings_groupBox.setEnabled(True) - self.ui.fit_pushButton.setEnabled(True) - self.ui.fit_scan_pushButton.setEnabled(False) - self.ui.save_all_checkBox.setEnabled(False) - self.ui.scan_fit_settings_groupBox.setEnabled(False) - elif self.ui.tabWidget.currentIndex() == 1: - self.ui.fitting_settings_groupBox.setEnabled(False) - self.ui.fit_pushButton.setEnabled(False) - self.ui.fit_scan_pushButton.setEnabled(True) - self.ui.save_all_checkBox.setEnabled(True) - self.ui.scan_fit_settings_groupBox.setEnabled(True) - elif self.ui.tabWidget.currentIndex() == 2: - self.ui.fitting_settings_groupBox.setEnabled(False) - self.ui.fit_pushButton.setEnabled(False) - self.ui.fit_scan_pushButton.setEnabled(False) - self.ui.save_all_checkBox.setEnabled(False) - self.ui.scan_fit_settings_groupBox.setEnabled(False) - - """ Single spectrum functions """ - def switch_bounds_and_guess_tab(self): - """ Show the appropriate bounds and initial guess params based on fit function """ - fit_func = self.ui.fitFunc_comboBox.currentText() - if fit_func == "Single Gaussian" or fit_func == "Single Lorentzian": - self.ui.n_label.setEnabled(False) - self.ui.n_spinBox.setEnabled(False) - self.ui.bounds_stackedWidget.setCurrentIndex(0) - self.ui.guess_stackedWidget.setCurrentIndex(0) - self.ui.plot_components_checkBox.setEnabled(False) - self.ui.n_spinBox.setValue(1) - elif fit_func == "Double Gaussian": - self.ui.n_label.setEnabled(False) - self.ui.n_spinBox.setEnabled(False) - self.ui.bounds_stackedWidget.setCurrentIndex(1) - self.ui.guess_stackedWidget.setCurrentIndex(1) - self.ui.plot_components_checkBox.setEnabled(True) - self.ui.n_spinBox.setValue(2) - elif fit_func == "Triple Gaussian": - self.ui.n_label.setEnabled(False) - self.ui.n_spinBox.setEnabled(False) - self.ui.bounds_stackedWidget.setCurrentIndex(2) - self.ui.guess_stackedWidget.setCurrentIndex(2) - self.ui.plot_components_checkBox.setEnabled(True) - self.ui.n_spinBox.setValue(3) - - def switch_adjust_param(self): - """ Enable bounds and initial guess only when adjust parameters is checked """ - checked = self.ui.adjust_param_checkBox.isChecked() - self.ui.bounds_groupBox.setEnabled(checked) - self.ui.guess_groupBox.setEnabled(checked) - - def check_loaded_files(self): - """ - Check if 'subtract background' or 'white light correction' is checked - and if required files have been loaded. - """ - if self.ui.subtract_bck_radioButton.isChecked() and self.bck_file is None: - self.ui.result_textBrowser.setText("You need to load a background file.") - elif self.wlref_file is not None and self.ui.WLRef_checkBox.isChecked() == False: - self.ui.result_textBrowser.setText("You need to check the White Light Correction option!") - elif self.wlref_file is None and self.ui.WLRef_checkBox.isChecked(): - self.ui.result_textBrowser.setText("You need to load a White Light Ref file.") - else: - return True - - def plot(self): - try: - if self.opened_from_flim: - flim_data = self.sum_data_from_flim.T - interp = interpolate.interp1d(flim_data[:,0], flim_data[:,1]) - x_range = [flim_data[:,0][0], flim_data[:,0][-1]] - xnew = np.linspace(x_range[0], x_range[1], 100 ) - ynew = interp(xnew) - self.file = np.zeros((xnew.shape[0], 2)) - self.file[:,0] = xnew - self.file[:,1] = ynew - self.x = xnew - self.y = ynew - - elif self.file is None: #elif - self.ui.result_textBrowser.setText("You need to load a data file.") - else: - self.x = self.file[:,0] - self.y = self.file[:,1] - - self.check_loaded_files() - - if self.check_loaded_files() == True: #check the following conditions if all required files have been provided - if self.ui.subtract_bck_radioButton.isChecked() == True and self.ui.WLRef_checkBox.isChecked() == False: - bck_y = self.bck_file[:,1] - self.y = self.y - bck_y - elif self.ui.subtract_bck_radioButton.isChecked() == False and self.ui.WLRef_checkBox.isChecked() == True: - wlref_y = self.wlref_file[:,1] - self.y = (self.y)/wlref_y - - elif self.ui.subtract_bck_radioButton.isChecked() == True and self.ui.WLRef_checkBox.isChecked() == True: - bck_y = self.bck_file[:,1] - wlref_y = self.wlref_file[:,1] - self.y = (self.y-bck_y)/wlref_y - - - if self.ui.norm_checkBox.isChecked(): - self.normalize() - - self.ui.plot.plot(self.x, self.y, clear=self.clear_check(), pen='r') - - except Exception as e: - self.ui.result_textBrowser.append(str(e)) - pass - self.ui.plot.setLabel('left', 'Intensity', units='a.u.') - self.ui.plot.setLabel('bottom', 'Wavelength (nm)') - - def normalize(self): - self.y = (self.y) / np.amax(self.y) - - def clear_plot(self): - self.ui.plot.clear() - self.ui.result_textBrowser.clear() - - def clear_check(self): - if self.ui.clear_checkBox.isChecked() == True: - return True - elif self.ui.clear_checkBox.isChecked() == False: - return False - - def fit_and_plot(self): - fit_func = self.ui.fitFunc_comboBox.currentText() - - try: - self.plot() - if self.opened_from_flim: - self.file = np.zeros((self.x.shape[0], 2)) - self.file[:,0] = self.x - self.file[:,1] = self.y - bck = lmfit.models.LinearModel(prefix='line_') - gmodel = GaussianModel(prefix='g1_') - pars = bck.make_params(intercept=self.y.min(), slope=0) - pars += gmodel.guess(self.y, x=self.x) - comp_model = gmodel + bck - self.result = comp_model.fit(self.y, pars, x=self.x, nan_policy='propagate') - self.ui.plot.plot(self.x, self.y, clear=self.clear_check(), pen='r') - self.ui.plot.plot(self.x, self.result.best_fit, clear=False, pen='k') - self.ui.result_textBrowser.setText(self.result.fit_report()) - - - if self.ui.plot_without_bck_radioButton.isChecked(): #if plot w/o bck, create dummy bck_file - self.bck_file = np.zeros(shape=(self.file.shape[0], 2)) - self.bck_file[:,0] = self.file[:,0] - - # if self.ui.subtract_bck_radioButton.isChecked() == False: - # self.ui.result_textBrowser.setText("You need to check the subtract background option!") - if self.check_loaded_files is None: - pass - elif self.opened_from_flim: - pass - else: - - if fit_func == "Single Gaussian": #and self.ui.subtract_bck_radioButton.isChecked() == True: - single_gauss = Single_Gaussian(self.file, self.bck_file, wlref=self.wlref_file) - if self.ui.adjust_param_checkBox.isChecked(): - center1_min = self.ui.single_peakcenter1_min_spinBox.value() - center1_max = self.ui.single_peakcenter1_max_spinBox.value() - center1_guess = self.ui.single_peakcenter1_guess_spinBox.value() - sigma1_guess = self.ui.single_sigma1_guess_spinBox.value() - self.result = single_gauss.gaussian_model_w_lims(center1_guess, sigma1_guess, - [center1_min, center1_max]) - else: - self.result = single_gauss.gaussian_model() - self.ui.plot.plot(self.x, self.y, clear=self.clear_check(), pen='r') - self.ui.plot.plot(self.x, self.result.best_fit, clear=False, pen='k') - self.ui.result_textBrowser.setText(self.result.fit_report()) - - elif fit_func == "Single Lorentzian": #and self.ui.subtract_bck_radioButton.isChecked() == True: - single_lorentzian = Single_Lorentzian(self.file, self.bck_file, wlref=self.wlref_file) - - if self.ui.adjust_param_checkBox.isChecked(): - center1_min = self.ui.single_peakcenter1_min_spinBox.value() - center1_max = self.ui.single_peakcenter1_max_spinBox.value() - center1_guess = self.ui.single_peakcenter1_guess_spinBox.value() - sigma1_guess = self.ui.single_sigma1_guess_spinBox.value() - self.result = single_lorentzian.lorentzian_model_w_lims(center1_guess, sigma1_guess, - [center1_min, center1_max]) - else: - self.result = single_lorentzian.lorentzian_model() - self.ui.plot.plot(self.x, self.y, clear=self.clear_check(), pen='r') - self.ui.plot.plot(self.x, self.result.best_fit, clear=False, pen='k') - self.ui.result_textBrowser.setText(self.result.fit_report()) - - elif fit_func == "Double Gaussian": #and self.ui.subtract_bck_radioButton.isChecked() == True: - double_gauss = Double_Gaussian(self.file, self.bck_file, wlref=self.wlref_file) - if self.ui.adjust_param_checkBox.isChecked(): - center1_min = self.ui.double_peakcenter1_min_spinBox.value() - center1_max = self.ui.double_peakcenter1_max_spinBox.value() - center2_min = self.ui.double_peakcenter2_min_spinBox.value() - center2_max = self.ui.double_peakcenter2_max_spinBox.value() - center1_guess = self.ui.double_peakcenter1_guess_spinBox.value() - sigma1_guess = self.ui.double_sigma1_guess_spinBox.value() - center2_guess = self.ui.double_peakcenter2_guess_spinBox.value() - sigma2_guess = self.ui.double_sigma2_guess_spinBox.value() - - peak_pos = [center1_guess, center2_guess] - sigma = [sigma1_guess, sigma2_guess] - min_max_range = [ [center1_min, center1_max], [center2_min, center2_max] ] - self.result = double_gauss.gaussian_model_w_lims(peak_pos, sigma, min_max_range) - - else: - self.result = double_gauss.gaussian_model() - - self.ui.plot.plot(self.x, self.y, clear=self.clear_check(), pen='r') - self.ui.plot.plot(self.x, self.result.best_fit, clear=False, pen='k') - if self.ui.plot_components_checkBox.isChecked(): - comps = self.result.eval_components(x=self.x) - self.ui.plot.plot(self.x, comps['g1_'], pen='b', clear=False) - self.ui.plot.plot(self.x, comps['g2_'], pen='g', clear=False) - - self.ui.result_textBrowser.setText(self.result.fit_report()) - - elif fit_func == "Triple Gaussian": #and self.ui.subtract_bck_radioButton.isChecked() == True: - #currently only works for triple gaussian (n=3) - multiple_gauss = Multi_Gaussian(self.file, self.bck_file, 3, wlref=self.wlref_file) - if self.ui.adjust_param_checkBox.isChecked(): - center1_min = self.ui.multi_peakcenter1_min_spinBox.value() - center1_max = self.ui.multi_peakcenter1_max_spinBox.value() - center2_min = self.ui.multi_peakcenter2_min_spinBox.value() - center2_max = self.ui.multi_peakcenter2_max_spinBox.value() - center3_min = self.ui.multi_peakcenter3_min_spinBox.value() - center3_max = self.ui.multi_peakcenter3_max_spinBox.value() - center1_guess = self.ui.multi_peakcenter1_guess_spinBox.value() - sigma1_guess = self.ui.multi_sigma1_guess_spinBox.value() - center2_guess = self.ui.multi_peakcenter2_guess_spinBox.value() - sigma2_guess = self.ui.multi_sigma2_guess_spinBox.value() - center3_guess = self.ui.multi_peakcenter3_guess_spinBox.value() - sigma3_guess = self.ui.multi_sigma3_guess_spinBox.value() -# num_gaussians = 3 - peak_pos = [center1_guess, center2_guess, center3_guess] - sigma = [sigma1_guess, sigma2_guess, sigma3_guess] - min_max_range = [ [center1_min, center1_max], [center2_min, center2_max], [center3_min, center3_max] ] - - self.result = multiple_gauss.gaussian_model_w_lims(peak_pos, sigma, min_max_range) - else: - self.result = multiple_gauss.gaussian_model() - - self.ui.plot.plot(self.x, self.y, clear=self.clear_check(), pen='r') - self.ui.plot.plot(self.x, self.result.best_fit, clear=False, pen='k') - if self.ui.plot_components_checkBox.isChecked(): - comps = self.result.eval_components(x=self.x) - self.ui.plot.plot(self.x, comps['g1_'], pen='b', clear=False) - self.ui.plot.plot(self.x, comps['g2_'], pen='g', clear=False) - self.ui.plot.plot(self.x, comps['g3_'], pen='c', clear=False) - self.ui.result_textBrowser.setText(self.result.fit_report()) - - self.data_list.append(self.ui.result_textBrowser.toPlainText()) - - except Exception as e: - self.ui.result_textBrowser.append(str(e)) - - def export_window(self): - self.export_window = ExportImages() - self.export_window.export_fig_signal.connect(self.pub_ready_plot_export) - - def pub_ready_plot_export(self): - filename = QtWidgets.QFileDialog.getSaveFileName(self,caption="Filename with EXTENSION") - """Recylce params for plotting""" - plt.rc('xtick', labelsize = 20) - plt.rc('xtick.major', pad = 3) - plt.rc('ytick', labelsize = 20) - plt.rc('lines', lw = 1.5, markersize = 7.5) - plt.rc('legend', fontsize = 20) - plt.rc('axes', linewidth=3.5) - try: - try: - try: - data = self.spec_scan_file - except: - data = self.fit_scan_file - if self.export_window.ui.reverse_checkBox.isChecked(): - colormap = str(self.export_window.ui.cmap_comboBox.currentText())+"_r" - else: - colormap = str(self.export_window.ui.cmap_comboBox.currentText()) - if str(self.export_window.ui.dataChannel_comboBox.currentText()) == "Fitted": - param_selection = str(self.ui.comboBox.currentText()) - if param_selection == 'pk_pos': label = 'PL Peak Position (n.m.)' - elif param_selection == 'fwhm': label = 'PL FWHM (n.m.)' - cpm.plot_confocal(self.img, figsize=(10,10), stepsize = data['Scan Parameters']['X step size (um)'], cmap=colormap, cbar_label=label, - vmin=self.export_window.ui.vmin_spinBox.value(), vmax=self.export_window.ui.vmax_spinBox.value()) - elif str(self.export_window.ui.dataChannel_comboBox.currentText()) == "Raw": - cpm.plot_confocal(self.sums, figsize=(10,10), stepsize = data['Scan Parameters']['X step size (um)'], cmap=colormap, - vmin=self.export_window.ui.vmin_spinBox.value(), vmax=self.export_window.ui.vmax_spinBox.value()) - plt.tick_params(direction='out', length=8, width=3.5) - plt.tight_layout() - plt.savefig(filename[0],bbox_inches='tight', dpi=300) - plt.close() - except: - plt.figure(figsize=(8,6)) - plt.tick_params(direction='out', length=8, width=3.5) - plt.plot(self.x, self.y) - plt.plot(self.x, self.result.best_fit,'k') - plt.xlabel("Wavelength (nm)", fontsize=20, fontweight='bold') - plt.ylabel("Intensity (a.u.)", fontsize=20, fontweight='bold') - plt.tight_layout() - - plt.savefig(filename[0],bbox_inches='tight', dpi=300) - plt.close() - - except AttributeError: - self.ui.result_textBrowser.setText("Need to fit the data first!") - - def export_data(self): - """ Save fit params and srv calculations stored in data_list as .txt """ - folder = os.path.dirname(self.single_spec_filename[0]) - filename_ext = os.path.basename(self.single_spec_filename[0]) - filename = os.path.splitext(filename_ext)[0] #get filename without extension - - path = folder + "/" + filename + "_fit_results.txt" - if not os.path.exists(path): - file = open(path, "w+") - else: - file = open(path, "a+") - - for i in range(len(self.data_list)): - file.write(self.data_list[i] + "\n\n") - - self.data_list = [] - file.close() - - def clear_export_data(self): - self.data_list = [] - - - """ Scan spectra functions """ - def get_data_params(self): - data = self.spec_scan_file - if self.scan_file_type == "pkl": - self.intensities = data['Intensities'] - self.wavelengths = data['Wavelengths'] - # try: - self.x_scan_size = data['Scan Parameters']['X scan size (um)'] - self.y_scan_size = data['Scan Parameters']['Y scan size (um)'] - self.x_step_size = data['Scan Parameters']['X step size (um)'] - self.y_step_size = data['Scan Parameters']['Y step size (um)'] - # except: # TODO test and debug loading pkl file w/o scan parameters - # self.configure_scan_params() - # while not hasattr(self, "scan_params_entered"): - # pass - # self.x_scan_size = self.param_window.ui.x_scan_size_spinBox.value() - # self.y_scan_size = self.param_window.ui.y_scan_size_spinBox.value() - # self.x_step_size = self.param_window.ui.x_step_size_spinBox.value() - # self.y_step_size = self.param_window.ui.y_step_size_spinBox.value() - - else: #run this if scan file is h5 - self.x_scan_size = data['Scan Parameters'].attrs['X scan size (um)'] - self.y_scan_size = data['Scan Parameters'].attrs['Y scan size (um)'] - self.x_step_size = data['Scan Parameters'].attrs['X step size (um)'] - self.y_step_size = data['Scan Parameters'].attrs['Y step size (um)'] - self.intensities = data['Intensities'][()] #get dataset values - self.wavelengths = data['Wavelengths'][()] - - self.numb_x_pixels = int(self.x_scan_size/self.x_step_size) - self.numb_y_pixels = int(self.y_scan_size/self.y_step_size) - - """Open param window and get peak center range values and assign it to variables to use later""" - # def configure_scan_params(self): - # self.param_window = ParamWindow() - # self.param_window.peak_range.connect(self.peak_range) - - # def peak_range(self, peaks): - # self.center_min = peaks[0] - # self.center_max = peaks[1] - - def plot_fit_scan(self): - try: - if self.ui.use_raw_scan_settings.isChecked(): - num_x = self.numb_x_pixels - num_y =self.numb_y_pixels - else: - num_x = self.ui.num_x_spinBox.value() - num_y = self.ui.num_y_spinBox.value() - - numb_of_points = num_x * num_y #75*75 - - fwhm = np.zeros(shape=(numb_of_points,1)) - pk_pos = np.zeros(shape=(numb_of_points,1)) -# sigma = np.zeros(shape=(numb_of_points,1)) -# height = np.zeros(shape=(numb_of_points,1)) - - if type(self.fit_scan_file['result_0']) == dict: - for i in range(numb_of_points): - fwhm[i, 0] = 2.3548200*self.fit_scan_file['result_'+str(i)]['g1_sigma'] - pk_pos[i, 0] = self.fit_scan_file['result_'+str(i)]['g1_center'] -# sigma[i, 0] = self.fit_scan_file['result_'+str(i)]['g1_sigma'] -# height[i, 0] = self.fit_scan_file['result_'+str(i)].values['g1_height'] - - elif type(self.fit_scan_file['result_0']) == lmfit.model.ModelResult: - for i in range(numb_of_points): - fwhm[i, 0] = self.fit_scan_file['result_'+str(i)].values['g1_fwhm'] - pk_pos[i, 0] = self.fit_scan_file['result_'+str(i)].values['g1_center'] -# sigma[i, 0] = self.fit_scan_file['result_'+str(i)].values['g1_sigma'] -# height[i, 0] = self.fit_scan_file['result_'+str(i)].values['g1_height'] - - newshape = (num_x, num_y) - - param_selection = str(self.ui.comboBox.currentText()) - self.img = np.reshape(eval(param_selection), newshape) - - if self.ui.use_raw_scan_settings.isChecked(): - self.ui.fit_scan_viewbox.setImage(self.img, scale= - (self.x_step_size, - self.y_step_size)) - scale = pg.ScaleBar(size=2,suffix='um') - scale.setParentItem(self.ui.fit_scan_viewbox.view) - scale.anchor((1, 1), (1, 1), offset=(-30, -30)) - self.ui.fit_scan_viewbox.view.sigRangeChanged.connect(lambda: updateDelay(scale, 10)) - else: - self.ui.fit_scan_viewbox.setImage(self.img) - - self.ui.fit_scan_viewbox.view.invertY(False) - - except Exception as e: - self.ui.result_textBrowser2.append(str(e)) - pass - - def plot_raw_scan(self): - try: - # TODO test line scan plots - - intensities = self.intensities.T #this is only there because of how we are saving the data in the app - intensities = np.reshape(intensities, newshape=(2048,self.numb_x_pixels, self.numb_y_pixels)) - self.ui.raw_scan_viewbox.setImage(intensities, scale= - (self.x_step_size, - self.y_step_size), xvals=self.wavelengths) - - #roi_plot = self.ui.raw_scan_viewBox.getRoiPlot() - #roi_plot.plot(data['Wavelengths'], intensities) - self.ui.raw_scan_viewbox.view.invertY(False) - scale = pg.ScaleBar(size=2,suffix='um') - scale.setParentItem(self.ui.raw_scan_viewbox.view) - scale.anchor((1, 1), (1, 1), offset=(-30, -30)) - self.ui.raw_scan_viewbox.view.sigRangeChanged.connect(lambda: updateDelay(scale, 10)) - - except Exception as e: - self.ui.result_textBrowser2.append(str(e)) - - def plot_intensity_sums(self): - try: - # TODO test line scan plots - - #intensities = np.reshape(intensities, newshape=(2048, numb_pixels_X*numb_pixels_Y)) - - sums = np.sum(self.intensities, axis=-1) - self.sums = np.reshape(sums, newshape=(self.numb_x_pixels, self.numb_y_pixels)) - - self.ui.intensity_sums_viewBox.setImage(self.sums, scale= - (self.x_step_size, - self.y_step_size)) - self.ui.intensity_sums_viewBox.view.invertY(False) - - scale = pg.ScaleBar(size=2,suffix='um') - scale.setParentItem(self.ui.intensity_sums_viewBox.view) - scale.anchor((1, 1), (1, 1), offset=(-30, -30)) - self.ui.intensity_sums_viewBox.view.sigRangeChanged.connect(lambda: updateDelay(scale, 10)) - - except Exception as e: - self.ui.result_textBrowser2.append(str(e)) - - - def fit_and_plot_scan(self): -# self.ui.result_textBrowser.append("Starting Scan Fitting") - print("Starting Scan Fitting") - print("Using Single Gaussian to Fit\nThis is the only fitting functions implemented") - - with pg.BusyCursor(): - try: - """Define starting and stopping wavelength values here""" - start_nm = int(self.ui.start_nm_spinBox.value()) - stop_nm = int(self.ui.stop_nm_spinBox.value()) - - if self.bck_file is None: - print("Load Background file!") - ref = self.bck_file - index = (ref[:,0]>start_nm) & (ref[:,0]start_nm) & (xstart_nm) & (ref[:,0]start_nm) & (x Date: Sun, 3 Nov 2019 21:53:20 -0800 Subject: [PATCH 34/63] Include CheckBox for ColorBar Label and check for state --- .../Export_Windows/Export_window.py | 7 +++++++ .../Export_Windows/export_fig_gui.ui | 19 +++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/PythonGUI_apps/Export_Windows/Export_window.py b/PythonGUI_apps/Export_Windows/Export_window.py index 060ffc8..da2f545 100644 --- a/PythonGUI_apps/Export_Windows/Export_window.py +++ b/PythonGUI_apps/Export_Windows/Export_window.py @@ -32,9 +32,16 @@ def __init__(self): 'autumn', 'winter', 'cool', 'Wistia', 'hot', 'afmhot', 'gist_heat', 'copper', 'rainbow', 'jet']) # self.ui.dataChannel_comboBox.addItems(['Raw', 'Fitted']) + self.ui.cbar_checkBox.stateChanged.connect(self.cbar_title_state) self.ui.exportFig_pushButton.clicked.connect(self.export) self.show() + def cbar_title_state(self): + if self.ui.cbar_checkBox.isChecked(): + self.ui.cbar_label.setEnabled(True) + else: + self.ui.cbar_label.setEnabled(False) + def export(self): self.export_fig_signal.emit() self.close() diff --git a/PythonGUI_apps/Export_Windows/export_fig_gui.ui b/PythonGUI_apps/Export_Windows/export_fig_gui.ui index 569aa1b..7c4ee58 100644 --- a/PythonGUI_apps/Export_Windows/export_fig_gui.ui +++ b/PythonGUI_apps/Export_Windows/export_fig_gui.ui @@ -6,8 +6,8 @@ 0 0 - 302 - 317 + 572 + 606 @@ -118,6 +118,9 @@ + + false + 15 @@ -149,6 +152,18 @@ + + + + + 15 + + + + + + + From bc1d1ab3a122aaf6bc2a220751a0b3437b414db1 Mon Sep 17 00:00:00 2001 From: Sarthak Jariwala Date: Sun, 3 Nov 2019 22:00:22 -0800 Subject: [PATCH 35/63] Export Window included in FLIM export --- PythonGUI_apps/FLIM_analysis/FLIM_plot.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/PythonGUI_apps/FLIM_analysis/FLIM_plot.py b/PythonGUI_apps/FLIM_analysis/FLIM_plot.py index 38a1a6a..3427e1b 100644 --- a/PythonGUI_apps/FLIM_analysis/FLIM_plot.py +++ b/PythonGUI_apps/FLIM_analysis/FLIM_plot.py @@ -14,9 +14,14 @@ sys.path.append(os.path.abspath('../Lifetime_analysis')) sys.path.append(os.path.abspath('../Spectrum_analysis')) sys.path.append(os.path.abspath('../H5_Pkl')) +sys.path.append(os.path.abspath('../Export_Windows')) from Lifetime_analysis import Lifetime_plot_fit from Spectrum_analysis import Spectra_plot_fit from H5_Pkl import h5_pkl_view +try: + from Export_window import ExportFigureWindow +except: + from Export_Windows.Export_window import ExportFigureWindow # local modules pg.mkQApp() @@ -50,7 +55,7 @@ def __init__(self): self.ui.load_scan_pushButton.clicked.connect(self.open_file) self.ui.plot_intensity_sums_pushButton.clicked.connect(self.plot_intensity_sums) self.ui.plot_raw_hist_data_pushButton.clicked.connect(self.plot_raw_scan) - self.ui.save_intensities_image_pushButton.clicked.connect(self.save_intensities_image) + self.ui.save_intensities_image_pushButton.clicked.connect(self.export_window) self.ui.save_intensities_array_pushButton.clicked.connect(self.save_intensities_array) self.ui.compare_checkBox.stateChanged.connect(self.switch_compare) self.ui.intensity_sums_viewBox.roi.sigRegionChanged.connect(self.line_profile_update_plot) @@ -262,6 +267,10 @@ def on_analyze_lifetime(self): self.lifetime_window.opened_from_flim = True self.lifetime_window.hist_data_from_flim = np.asarray(self.get_raw_hist_curve(0)) self.lifetime_window.ui.Result_textBrowser.setText("Data successfully loaded from FLIM analysis.") + + def export_window(self): + self.export_window = ExportFigurewindow() + self.export_window.export_fig_signal.connect(self.save_intensities_image) def save_intensities_image(self): try: @@ -269,7 +278,15 @@ def save_intensities_image(self): filename_ext = os.path.basename(self.filename[0]) filename = os.path.splitext(filename_ext)[0] #get filename without extension save_to = folder + "\\" + filename + "_intensity_sums.png" - cpm.plot_confocal(self.intensity_sums, FLIM_adjust=False, stepsize=np.abs(self.x_step_size)) + if self.export_window.ui.reverse_checkBox.isChecked(): + colormap = str(self.export_window.ui.cmap_comboBox.currentText())+"_r" + else: + colormap = str(self.export_window.ui.cmap_comboBox.currentText()) + if self.export_window.ui.cbar_checkBox.isChecked(): + label = str(self.export_window.ui.cbar_label.text()) + else: + label = "PL Intensity (a.u.)" + cpm.plot_confocal(self.intensity_sums, FLIM_adjust=False, stepsize=np.abs(self.x_step_size),cmap=colormap, cbar_label=label,vmin=self.export_window.ui.vmin_spinBox.value(), vmax=self.export_window.ui.vmax_spinBox.value()) plt.savefig(save_to, bbox_inches='tight', dpi=300) except Exception as e: print(format(e)) From 95d5606d8f308dcc602a483285eed54c12b49871 Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Mon, 4 Nov 2019 11:49:25 -0800 Subject: [PATCH 36/63] Fix export figure window not popping up issue --- PythonGUI_apps/Export_Windows/Export_window.py | 11 +++++------ PythonGUI_apps/Export_Windows/export_fig_gui.ui | 4 ++-- PythonGUI_apps/FLIM_analysis/FLIM_plot.py | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/PythonGUI_apps/Export_Windows/Export_window.py b/PythonGUI_apps/Export_Windows/Export_window.py index da2f545..f5eccf6 100644 --- a/PythonGUI_apps/Export_Windows/Export_window.py +++ b/PythonGUI_apps/Export_Windows/Export_window.py @@ -11,18 +11,18 @@ """Export Images GUI""" base_path = Path(__file__).parent ui_file_path = (base_path / "export_fig_gui.ui").resolve() -export_WindowTemplate, export_TemplateBaseClass = pg.Qt.loadUiType(ui_file_path) +exportFig_WindowTemplate, exportFig_TemplateBaseClass = pg.Qt.loadUiType(ui_file_path) -class ExportFigureWindow(export_TemplateBaseClass): +class ExportFigureWindow(exportFig_TemplateBaseClass): export_fig_signal = QtCore.pyqtSignal() def __init__(self): - export_TemplateBaseClass.__init__(self) + exportFig_TemplateBaseClass.__init__(self) - self.ui = export_WindowTemplate() + self.ui = exportFig_WindowTemplate() self.ui.setupUi(self) - self.ui.cmap_comboBox.addItems(['viridis', 'plasma', 'inferno', 'magma', + self.ui.cmap_comboBox.addItems(['viridis', 'plasma', 'inferno', 'magma', 'cividis','Greys', 'Purples', 'Blues', 'Greens', 'Oranges', 'Reds', 'YlOrBr', 'YlOrRd', 'OrRd', 'PuRd', 'RdPu', 'BuPu', @@ -31,7 +31,6 @@ def __init__(self): 'gray', 'bone', 'pink', 'spring', 'summer', 'autumn', 'winter', 'cool', 'Wistia', 'hot', 'afmhot', 'gist_heat', 'copper', 'rainbow', 'jet']) -# self.ui.dataChannel_comboBox.addItems(['Raw', 'Fitted']) self.ui.cbar_checkBox.stateChanged.connect(self.cbar_title_state) self.ui.exportFig_pushButton.clicked.connect(self.export) self.show() diff --git a/PythonGUI_apps/Export_Windows/export_fig_gui.ui b/PythonGUI_apps/Export_Windows/export_fig_gui.ui index 7c4ee58..e80e065 100644 --- a/PythonGUI_apps/Export_Windows/export_fig_gui.ui +++ b/PythonGUI_apps/Export_Windows/export_fig_gui.ui @@ -6,8 +6,8 @@ 0 0 - 572 - 606 + 420 + 369 diff --git a/PythonGUI_apps/FLIM_analysis/FLIM_plot.py b/PythonGUI_apps/FLIM_analysis/FLIM_plot.py index 3427e1b..dd6f0ff 100644 --- a/PythonGUI_apps/FLIM_analysis/FLIM_plot.py +++ b/PythonGUI_apps/FLIM_analysis/FLIM_plot.py @@ -269,7 +269,7 @@ def on_analyze_lifetime(self): self.lifetime_window.ui.Result_textBrowser.setText("Data successfully loaded from FLIM analysis.") def export_window(self): - self.export_window = ExportFigurewindow() + self.export_window = ExportFigureWindow() self.export_window.export_fig_signal.connect(self.save_intensities_image) def save_intensities_image(self): From 99892124eef1467bfb3e108e7f4968fbc23bc0f1 Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Tue, 5 Nov 2019 10:14:56 -0800 Subject: [PATCH 37/63] set colorbar values based on min max of data --- PythonGUI_apps/FLIM_analysis/FLIM_plot.py | 7 ++++++- PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/PythonGUI_apps/FLIM_analysis/FLIM_plot.py b/PythonGUI_apps/FLIM_analysis/FLIM_plot.py index dd6f0ff..5f5744f 100644 --- a/PythonGUI_apps/FLIM_analysis/FLIM_plot.py +++ b/PythonGUI_apps/FLIM_analysis/FLIM_plot.py @@ -270,6 +270,8 @@ def on_analyze_lifetime(self): def export_window(self): self.export_window = ExportFigureWindow() + self.export_window.ui.vmin_spinBox.setValue(np.min(self.intensity_sums)) + self.export_window.ui.vmax_spinBox.setValue(np.max(self.intensity_sums)) self.export_window.export_fig_signal.connect(self.save_intensities_image) def save_intensities_image(self): @@ -286,7 +288,10 @@ def save_intensities_image(self): label = str(self.export_window.ui.cbar_label.text()) else: label = "PL Intensity (a.u.)" - cpm.plot_confocal(self.intensity_sums, FLIM_adjust=False, stepsize=np.abs(self.x_step_size),cmap=colormap, cbar_label=label,vmin=self.export_window.ui.vmin_spinBox.value(), vmax=self.export_window.ui.vmax_spinBox.value()) + cpm.plot_confocal(self.intensity_sums, FLIM_adjust=False, + stepsize=np.abs(self.x_step_size),cmap=colormap, + cbar_label=label, vmin=self.export_window.ui.vmin_spinBox.value(), + vmax=self.export_window.ui.vmax_spinBox.value()) plt.savefig(save_to, bbox_inches='tight', dpi=300) except Exception as e: print(format(e)) diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py index 6479c4a..6b16703 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py @@ -528,7 +528,7 @@ def pub_ready_plot_export(self): param_selection = str(self.ui.comboBox.currentText()) if param_selection == 'pk_pos': label = 'PL Peak Position (n.m.)' elif param_selection == 'fwhm': label = 'PL FWHM (n.m.)' - cpm.plot_confocal(self.img, figsize=(10,10), stepsize = data['Scan Parameters']['X step size (um)'], cmap=colormap, cbar_label=label, + cpm.plot_confocal(self.img, stepsize = data['Scan Parameters']['X step size (um)'], cmap=colormap, cbar_label=label, vmin=self.export_window.ui.vmin_spinBox.value(), vmax=self.export_window.ui.vmax_spinBox.value()) elif str(self.export_window.ui.dataChannel_comboBox.currentText()) == "Raw": cpm.plot_confocal(self.sums, figsize=(10,10), stepsize = data['Scan Parameters']['X step size (um)'], cmap=colormap, From 4d8d74d9fc7b411a337d5665d67e90ca7e79dc68 Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Sun, 17 Nov 2019 17:18:46 -0800 Subject: [PATCH 38/63] FIX: X,Y pixels now take np.ceil of ScanSize/StepSize --- PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py index 6b16703..3593a8e 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py @@ -602,8 +602,8 @@ def get_data_params(self): self.intensities = data['Intensities'][()] #get dataset values self.wavelengths = data['Wavelengths'][()] - self.numb_x_pixels = int(self.x_scan_size/self.x_step_size) - self.numb_y_pixels = int(self.y_scan_size/self.y_step_size) + self.numb_x_pixels = int(np.ceil(self.x_scan_size/self.x_step_size)) + self.numb_y_pixels = int(np.ceil(self.y_scan_size/self.y_step_size)) """Open param window and get peak center range values and assign it to variables to use later""" # def configure_scan_params(self): From 9eb4fd51c86eaeba89307132e7bed245bb78a093 Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Wed, 27 Nov 2019 16:09:37 -0800 Subject: [PATCH 39/63] change no of skiprows for csv loading statement --- PythonGUI_apps/UV_Vis_analysis/uv_vis_analysis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PythonGUI_apps/UV_Vis_analysis/uv_vis_analysis.py b/PythonGUI_apps/UV_Vis_analysis/uv_vis_analysis.py index 8c860cb..31c21b8 100644 --- a/PythonGUI_apps/UV_Vis_analysis/uv_vis_analysis.py +++ b/PythonGUI_apps/UV_Vis_analysis/uv_vis_analysis.py @@ -78,7 +78,7 @@ def __init__(self): def open_data_file(self): try: self.filename = QtWidgets.QFileDialog.getOpenFileName(self) - self.data = np.loadtxt(self.filename[0], delimiter = ',', skiprows = 1) + self.data = np.loadtxt(self.filename[0], delimiter = ',', skiprows = 2) self.Wavelength = self.data[:,0] # in nm self.Absorbance = self.data[:,1] except Exception as err: From 804727fc9280a6353e023ceb8d8dbafc9c463647 Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Sat, 30 Nov 2019 13:29:42 -0800 Subject: [PATCH 40/63] FIX:4th order polyfit --- PythonGUI_apps/UV_Vis_analysis/uv_vis_analysis.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PythonGUI_apps/UV_Vis_analysis/uv_vis_analysis.py b/PythonGUI_apps/UV_Vis_analysis/uv_vis_analysis.py index 31c21b8..6302a40 100644 --- a/PythonGUI_apps/UV_Vis_analysis/uv_vis_analysis.py +++ b/PythonGUI_apps/UV_Vis_analysis/uv_vis_analysis.py @@ -105,8 +105,8 @@ def plot_absorbance(self): if self.ui.fourth_orderpoly_radioButton.isChecked(): p = (np.polyfit(self.Wavelength[(self.Wavelength>self.correction_region_min) & (self.Wavelengthself.correction_region_min) & (self.Wavelengthself.correction_region_min) & (self.Wavelengthself.correction_region_min) & (self.Wavelengthself.correction_region_min) & (self.Wavelengthself.correction_region_min) & (self.Wavelength Date: Mon, 9 Dec 2019 15:07:11 -0800 Subject: [PATCH 41/63] FLIM_adjust made False to make it look exactly as the data comes in --- PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py index 3593a8e..3aa897d 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py @@ -528,10 +528,10 @@ def pub_ready_plot_export(self): param_selection = str(self.ui.comboBox.currentText()) if param_selection == 'pk_pos': label = 'PL Peak Position (n.m.)' elif param_selection == 'fwhm': label = 'PL FWHM (n.m.)' - cpm.plot_confocal(self.img, stepsize = data['Scan Parameters']['X step size (um)'], cmap=colormap, cbar_label=label, + cpm.plot_confocal(self.img, FLIM_adjust = False, stepsize = data['Scan Parameters']['X step size (um)'], cmap=colormap, cbar_label=label, vmin=self.export_window.ui.vmin_spinBox.value(), vmax=self.export_window.ui.vmax_spinBox.value()) elif str(self.export_window.ui.dataChannel_comboBox.currentText()) == "Raw": - cpm.plot_confocal(self.sums, figsize=(10,10), stepsize = data['Scan Parameters']['X step size (um)'], cmap=colormap, + cpm.plot_confocal(self.sums, FLIM_adjust = False, figsize=(10,10), stepsize = data['Scan Parameters']['X step size (um)'], cmap=colormap, vmin=self.export_window.ui.vmin_spinBox.value(), vmax=self.export_window.ui.vmax_spinBox.value()) plt.tick_params(direction='out', length=8, width=3.5) plt.tight_layout() From bda05b253d602773a40bf510b7697f00677be318 Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Tue, 11 Feb 2020 15:40:18 -0800 Subject: [PATCH 42/63] added .QUA file type compatibility for analysis --- PythonGUI_apps/PLQE_analysis/plqe_analysis.py | 342 +++++++++--------- 1 file changed, 171 insertions(+), 171 deletions(-) diff --git a/PythonGUI_apps/PLQE_analysis/plqe_analysis.py b/PythonGUI_apps/PLQE_analysis/plqe_analysis.py index 96e3b96..4dc7fd1 100644 --- a/PythonGUI_apps/PLQE_analysis/plqe_analysis.py +++ b/PythonGUI_apps/PLQE_analysis/plqe_analysis.py @@ -5,9 +5,7 @@ from pyqtgraph import exporters from pyqtgraph.Qt import QtCore, QtGui, QtWidgets import matplotlib.pyplot as plt -import pandas as pd import numpy as np -import time # local modules @@ -30,183 +28,185 @@ plt.rc('axes', linewidth = 3.5) class MainWindow(TemplateBaseClass): - - def __init__(self): - super(TemplateBaseClass, self).__init__() - - # Create the main window - self.ui = WindowTemplate() - self.ui.setupUi(self) - - #setup uv vis plot - self.plot = self.ui.plotWidget.getPlotItem() - self.plot.setTitle(title="Wavelength vs. Intensity") - self.plot.setLabel('bottom', 'Wavelength', unit='nm') - self.plot.setLabel('left', 'Intensity', unit='a.u.') - self.plot.setLogMode(x=None, y=1) - - #setup line rois for laser and emission - self.laser_region = pg.LinearRegionItem(brush=QtGui.QBrush(QtGui.QColor(255, 0, 0, 50))) - self.laser_region.sigRegionChanged.connect(self.update_laser_spinBoxes) - self.emission_region = pg.LinearRegionItem() - self.emission_region.sigRegionChanged.connect(self.update_emission_spinBoxes) - self.laser_region.setRegion((200, 400)) - self.emission_region.setRegion((700, 800)) - - #setup ui signals - self.ui.load_data_pushButton.clicked.connect(self.open_data_file) - self.ui.plot_pushButton.clicked.connect(self.plot_intensity) - self.ui.clear_pushButton.clicked.connect(self.clear) - self.ui.calculate_plqe_pushButton.clicked.connect(self.calculate_plqe) - self.ui.laser_start_spinBox.valueChanged.connect(self.update_laser_region) - self.ui.laser_stop_spinBox.valueChanged.connect(self.update_laser_region) - self.ui.emission_start_spinBox.valueChanged.connect(self.update_emission_region) - self.ui.emission_stop_spinBox.valueChanged.connect(self.update_emission_region) - - self.show() - - def open_data_file(self): - """ Open data file """ - try: - self.filename = QtWidgets.QFileDialog.getOpenFileName(self) - #self.data = np.loadtxt(self.filename[0], delimiter = '\t', skiprows = 1) - if ".txt" in self.filename[0]: - self.data = np.loadtxt(self.filename[0], delimiter = '\t', skiprows = 1) - elif ".csv" in self.filename[0]: - self.data = np.loadtxt(self.filename[0], delimiter = ',', skiprows = 1) - self.cs_window = ColSelectionWindow(self.data) - self.cs_window.col_selection_signal.connect(self.open_with_col_selection) - self.nm = np.copy(self.data[:,0]) - #self.ref_data = np.copy(self.data[:,1]) - #self.inpath_data = np.copy(self.data[:,2]) - #self.outpath_data = np.copy(self.data[:,3]) - except Exception as err: - print(format(err)) - - def open_with_col_selection(self): - ref_data_col = self.cs_window.ui.ref_spinBox.value() - 1 #subtract since spinboxes refer to column num and not index - inpath_data_col = self.cs_window.ui.inpath_spinBox.value() - 1 - outpath_data_col = self.cs_window.ui.outpath_spinBox.value() - 1 - self.ref_data = np.copy(self.data[:,ref_data_col]) - self.inpath_data = np.copy(self.data[:,inpath_data_col]) - self.outpath_data = np.copy(self.data[:,outpath_data_col]) - - def update_laser_spinBoxes(self): - """ Update laser spinboxes based on line rois """ - self.laser_start, self.laser_stop = self.laser_region.getRegion() - self.ui.laser_start_spinBox.setValue(self.laser_start) - self.ui.laser_stop_spinBox.setValue(self.laser_stop) - - - def update_emission_spinBoxes(self): - """ Update emission spinboxes based on line rois """ - self.emission_start, self.emission_stop = self.emission_region.getRegion() - self.ui.emission_start_spinBox.setValue(self.emission_start) - self.ui.emission_stop_spinBox.setValue(self.emission_stop) - - def update_laser_region(self): - """ Update laser line rois based on spinboxes """ - laser_start = self.ui.laser_start_spinBox.value() - laser_stop = self.ui.laser_stop_spinBox.value() - self.laser_region.setRegion((laser_start, laser_stop)) - - def update_emission_region(self): - """ Update emission line rois based on spinboxes """ - emission_start = self.ui.emission_start_spinBox.value() - emission_stop = self.ui.emission_stop_spinBox.value() - self.emission_region.setRegion((emission_start, emission_stop)) - - def plot_intensity(self): - try: - self.plot.plot(self.nm, self.inpath_data) - self.plot.addItem(self.laser_region, ignoreBounds=True) - self.plot.addItem(self.emission_region, ignoreBounds=True) - except Exception as err: - print(format(err)) - - def find_nearest(self,array,value): - idx = (np.abs(array-value)).argmin() - return idx - - def calculate_plqe(self): - - nm_interp_step = 1 - nm_interp_start = np.ceil(self.nm[0] / nm_interp_step) * nm_interp_step - nm_interp_stop = np.floor(self.nm[len(self.nm) - 1] / nm_interp_step) * nm_interp_step - nm_interp = np.arange(nm_interp_start, nm_interp_stop + nm_interp_step, nm_interp_step) - - ref_interp = np.interp(nm_interp, self.nm, self.ref_data) - - - inpath_interp = np.interp(nm_interp, self.nm, self.inpath_data) - outpath_interp = np.interp(nm_interp, self.nm, self.outpath_data) - - - """L_x is area under laser profile for experiment x""" - """P_x_ is area under emission profile for experiment x""" - - - #plt.semilogy(nm, a1_outpath_data[:,1]) - - emission_start_idx = self.find_nearest(nm_interp, self.emission_start) - emission_stop_idx = self.find_nearest(nm_interp, self.emission_stop) - - laser_start_idx = self.find_nearest(nm_interp, self.laser_start) - laser_stop_idx = self.find_nearest(nm_interp, self.laser_stop) - - la = np.trapz(ref_interp[laser_start_idx: laser_stop_idx], x = nm_interp[laser_start_idx:laser_stop_idx]) - lb = np.trapz(outpath_interp[laser_start_idx: laser_stop_idx], x = nm_interp[laser_start_idx:laser_stop_idx]) - lc = np.trapz(inpath_interp[laser_start_idx: laser_stop_idx], x = nm_interp[laser_start_idx:laser_stop_idx]) - - pa = np.trapz(ref_interp[emission_start_idx:emission_stop_idx], x = nm_interp[emission_start_idx:emission_stop_idx]) - pb = np.trapz(outpath_interp[emission_start_idx:emission_stop_idx], x = nm_interp[emission_start_idx:emission_stop_idx]) - pc = np.trapz(inpath_interp[emission_start_idx:emission_stop_idx], x = nm_interp[emission_start_idx:emission_stop_idx]) - - absorb = 1.0 - (lc / lb) - - plqe = 100 * (pc - ((1.0 - absorb) * pb)) / (la * absorb) - #print('PLQE Percent = %.3f' %(plqe)) - #return plqe - self.ui.plqe_label.setText("%.3f" %(plqe)) - - def clear(self): - self.plot.clear() + + def __init__(self): + super(TemplateBaseClass, self).__init__() + + # Create the main window + self.ui = WindowTemplate() + self.ui.setupUi(self) + + #setup uv vis plot + self.plot = self.ui.plotWidget.getPlotItem() + self.plot.setTitle(title="Wavelength vs. Intensity") + self.plot.setLabel('bottom', 'Wavelength', unit='nm') + self.plot.setLabel('left', 'Intensity', unit='a.u.') + self.plot.setLogMode(x=None, y=1) + + #setup line rois for laser and emission + self.laser_region = pg.LinearRegionItem(brush=QtGui.QBrush(QtGui.QColor(255, 0, 0, 50))) + self.laser_region.sigRegionChanged.connect(self.update_laser_spinBoxes) + self.emission_region = pg.LinearRegionItem() + self.emission_region.sigRegionChanged.connect(self.update_emission_spinBoxes) + self.laser_region.setRegion((200, 400)) + self.emission_region.setRegion((700, 800)) + + #setup ui signals + self.ui.load_data_pushButton.clicked.connect(self.open_data_file) + self.ui.plot_pushButton.clicked.connect(self.plot_intensity) + self.ui.clear_pushButton.clicked.connect(self.clear) + self.ui.calculate_plqe_pushButton.clicked.connect(self.calculate_plqe) + self.ui.laser_start_spinBox.valueChanged.connect(self.update_laser_region) + self.ui.laser_stop_spinBox.valueChanged.connect(self.update_laser_region) + self.ui.emission_start_spinBox.valueChanged.connect(self.update_emission_region) + self.ui.emission_stop_spinBox.valueChanged.connect(self.update_emission_region) + + self.show() + + def open_data_file(self): + """ Open data file """ + try: + self.filename = QtWidgets.QFileDialog.getOpenFileName(self) + #self.data = np.loadtxt(self.filename[0], delimiter = '\t', skiprows = 1) + if ".txt" in self.filename[0]: + self.data = np.loadtxt(self.filename[0], delimiter = '\t', skiprows = 1, usecols = (0,1,2,3)) + elif ".csv" in self.filename[0]: + self.data = np.loadtxt(self.filename[0], delimiter = ',', skiprows = 1) + elif ".qua" in self.filename[0]: + self.data = np.genfromtxt(self.filename[0], delimiter = '\t', skip_header = 12, usecols = (0,1,2,3)) + self.cs_window = ColSelectionWindow(self.data) + self.cs_window.col_selection_signal.connect(self.open_with_col_selection) + self.nm = np.copy(self.data[:,0]) + #self.ref_data = np.copy(self.data[:,1]) + #self.inpath_data = np.copy(self.data[:,2]) + #self.outpath_data = np.copy(self.data[:,3]) + except Exception as err: + print(format(err)) + + def open_with_col_selection(self): + ref_data_col = self.cs_window.ui.ref_spinBox.value() - 1 #subtract since spinboxes refer to column num and not index + inpath_data_col = self.cs_window.ui.inpath_spinBox.value() - 1 + outpath_data_col = self.cs_window.ui.outpath_spinBox.value() - 1 + self.ref_data = np.copy(self.data[:,ref_data_col]) + self.inpath_data = np.copy(self.data[:,inpath_data_col]) + self.outpath_data = np.copy(self.data[:,outpath_data_col]) + + def update_laser_spinBoxes(self): + """ Update laser spinboxes based on line rois """ + self.laser_start, self.laser_stop = self.laser_region.getRegion() + self.ui.laser_start_spinBox.setValue(self.laser_start) + self.ui.laser_stop_spinBox.setValue(self.laser_stop) + + + def update_emission_spinBoxes(self): + """ Update emission spinboxes based on line rois """ + self.emission_start, self.emission_stop = self.emission_region.getRegion() + self.ui.emission_start_spinBox.setValue(self.emission_start) + self.ui.emission_stop_spinBox.setValue(self.emission_stop) + + def update_laser_region(self): + """ Update laser line rois based on spinboxes """ + laser_start = self.ui.laser_start_spinBox.value() + laser_stop = self.ui.laser_stop_spinBox.value() + self.laser_region.setRegion((laser_start, laser_stop)) + + def update_emission_region(self): + """ Update emission line rois based on spinboxes """ + emission_start = self.ui.emission_start_spinBox.value() + emission_stop = self.ui.emission_stop_spinBox.value() + self.emission_region.setRegion((emission_start, emission_stop)) + + def plot_intensity(self): + try: + self.plot.plot(self.nm, self.inpath_data) + self.plot.addItem(self.laser_region, ignoreBounds=True) + self.plot.addItem(self.emission_region, ignoreBounds=True) + except Exception as err: + print(format(err)) + + def find_nearest(self,array,value): + idx = (np.abs(array-value)).argmin() + return idx + + def calculate_plqe(self): + + nm_interp_step = 1 + nm_interp_start = np.ceil(self.nm[0] / nm_interp_step) * nm_interp_step + nm_interp_stop = np.floor(self.nm[len(self.nm) - 1] / nm_interp_step) * nm_interp_step + nm_interp = np.arange(nm_interp_start, nm_interp_stop + nm_interp_step, nm_interp_step) + + ref_interp = np.interp(nm_interp, self.nm, self.ref_data) + + + inpath_interp = np.interp(nm_interp, self.nm, self.inpath_data) + outpath_interp = np.interp(nm_interp, self.nm, self.outpath_data) + + + """L_x is area under laser profile for experiment x""" + """P_x_ is area under emission profile for experiment x""" + + + #plt.semilogy(nm, a1_outpath_data[:,1]) + + emission_start_idx = self.find_nearest(nm_interp, self.emission_start) + emission_stop_idx = self.find_nearest(nm_interp, self.emission_stop) + + laser_start_idx = self.find_nearest(nm_interp, self.laser_start) + laser_stop_idx = self.find_nearest(nm_interp, self.laser_stop) + + la = np.trapz(ref_interp[laser_start_idx: laser_stop_idx], x = nm_interp[laser_start_idx:laser_stop_idx]) + lb = np.trapz(outpath_interp[laser_start_idx: laser_stop_idx], x = nm_interp[laser_start_idx:laser_stop_idx]) + lc = np.trapz(inpath_interp[laser_start_idx: laser_stop_idx], x = nm_interp[laser_start_idx:laser_stop_idx]) + + pa = np.trapz(ref_interp[emission_start_idx:emission_stop_idx], x = nm_interp[emission_start_idx:emission_stop_idx]) + pb = np.trapz(outpath_interp[emission_start_idx:emission_stop_idx], x = nm_interp[emission_start_idx:emission_stop_idx]) + pc = np.trapz(inpath_interp[emission_start_idx:emission_stop_idx], x = nm_interp[emission_start_idx:emission_stop_idx]) + + absorb = 1.0 - (lc / lb) + + plqe = 100 * (pc - ((1.0 - absorb) * pb)) / (la * absorb) + #print('PLQE Percent = %.3f' %(plqe)) + #return plqe + self.ui.plqe_label.setText("%.3f" %(plqe)) + + def clear(self): + self.plot.clear() """Table view GUI""" ui_file_path = (base_path / "column_selection_gui.ui").resolve() col_selection_WindowTemplate, col_selection_TemplateBaseClass = pg.Qt.loadUiType(ui_file_path) class ColSelectionWindow(col_selection_TemplateBaseClass): - - col_selection_signal = QtCore.pyqtSignal() #signal to help with pass info back to MainWindow - - def __init__(self, data): - col_selection_TemplateBaseClass.__init__(self) - # Create the param window - self.ui = col_selection_WindowTemplate() - self.ui.setupUi(self) - self.ui.done_pushButton.clicked.connect(self.done) - - self.table_widget = pg.TableWidget() - self.ui.data_preview_groupBox.layout().addWidget(self.table_widget) - - self.table_widget.setData(data) - - #self.setWindowFlag(QtCore.Qt.WindowCloseButtonHint, False) - self.show() - - def done(self): - self.col_selection_signal.emit() - self.ui.textBrowser.setText("Data successfully loaded.") - #self.close() - - def closeEvent(self, event): - self.col_selection_signal.emit() + + col_selection_signal = QtCore.pyqtSignal() #signal to help with pass info back to MainWindow + + def __init__(self, data): + col_selection_TemplateBaseClass.__init__(self) + # Create the param window + self.ui = col_selection_WindowTemplate() + self.ui.setupUi(self) + self.ui.done_pushButton.clicked.connect(self.done) + + self.table_widget = pg.TableWidget() + self.ui.data_preview_groupBox.layout().addWidget(self.table_widget) + + self.table_widget.setData(data) + + #self.setWindowFlag(QtCore.Qt.WindowCloseButtonHint, False) + self.show() + + def done(self): + self.col_selection_signal.emit() + self.ui.textBrowser.setText("Data successfully loaded.") + #self.close() + + def closeEvent(self, event): + self.col_selection_signal.emit() """Run the Main Window""" def run(): - win = MainWindow() - QtGui.QApplication.instance().exec_() - return win + win = MainWindow() + QtGui.QApplication.instance().exec_() + return win #run() From 872da744839817cc09daa892a9597651dc3d81e9 Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Tue, 11 Feb 2020 15:41:47 -0800 Subject: [PATCH 43/63] avg lifetime in double exponential assigned to greater of the taus and added to srv calculation --- PythonGUI_apps/Lifetime_analysis/Lifetime_plot_fit.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/PythonGUI_apps/Lifetime_analysis/Lifetime_plot_fit.py b/PythonGUI_apps/Lifetime_analysis/Lifetime_plot_fit.py index 3081d89..27b924d 100644 --- a/PythonGUI_apps/Lifetime_analysis/Lifetime_plot_fit.py +++ b/PythonGUI_apps/Lifetime_analysis/Lifetime_plot_fit.py @@ -432,6 +432,10 @@ def fit_and_plot_with_irf(self): "\ntau2 = %.5f ns" "\nnoise = %.5f counts" %(bestfit_params[0], bestfit_params[1], bestfit_params[2], bestfit_params[3], bestfit_params[4])) #TODO - once tau_avg implemented, set average lifetime spinbox to tau_avg value + if bestfit_params[3] > bestfit_params[1]: + self.ui.average_lifetime_spinBox.setValue(bestfit_params[3]) + elif bestfit_params[1] > bestfit_params[3]: + self.ui.average_lifetime_spinBox.setValue(bestfit_params[1]) elif fit_func == "Single Exponential": #single exponential tab a_bounds = (self.ui.se_a_min_spinBox.value(), self.ui.se_a_max_spinBox.value()) From 2270b02bc2de29b368f4442fdbd97d550e5db088 Mon Sep 17 00:00:00 2001 From: Sarthak Jariwala Date: Sun, 23 Feb 2020 20:40:30 +0100 Subject: [PATCH 44/63] Added another viewing capability for PL line scans after fitting --- .../Spectrum_analysis/Spectra_plot_fit.py | 36 +++++++++++++------ 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py index 3aa897d..89893e5 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py @@ -649,18 +649,32 @@ def plot_fit_scan(self): param_selection = str(self.ui.comboBox.currentText()) self.img = np.reshape(eval(param_selection), newshape) - if self.ui.use_raw_scan_settings.isChecked(): - self.ui.fit_scan_viewbox.setImage(self.img, scale= - (self.x_step_size, - self.y_step_size)) - scale = pg.ScaleBar(size=2,suffix='um') - scale.setParentItem(self.ui.fit_scan_viewbox.view) - scale.anchor((1, 1), (1, 1), offset=(-30, -30)) - self.ui.fit_scan_viewbox.view.sigRangeChanged.connect(lambda: updateDelay(scale, 10)) - else: - self.ui.fit_scan_viewbox.setImage(self.img) + if num_y == 1: + x = np.linspace(0, self.x_scan_size, num_x) + self.graph_layout=pg.GraphicsLayoutWidget() + self.plot = self.graph_layout.addPlot(title="Line Scan") + self.plot.plot(x, self.img[:,0], pen="r") + self.graph_layout.show() + elif num_x == 1: + y = np.linspace(0, self.y_scan_size, num_y) + self.graph_layout=pg.GraphicsLayoutWidget() + self.plot = self.graph_layout.addPlot(title="Line Scan") + self.ui.plot.plot(y, self.img[0,:], pen="r") + self.graph_layout.show() - self.ui.fit_scan_viewbox.view.invertY(False) + else: + if self.ui.use_raw_scan_settings.isChecked(): + self.ui.fit_scan_viewbox.setImage(self.img, scale= + (self.x_step_size, + self.y_step_size)) + scale = pg.ScaleBar(size=2,suffix='um') + scale.setParentItem(self.ui.fit_scan_viewbox.view) + scale.anchor((1, 1), (1, 1), offset=(-30, -30)) + self.ui.fit_scan_viewbox.view.sigRangeChanged.connect(lambda: updateDelay(scale, 10)) + else: + self.ui.fit_scan_viewbox.setImage(self.img) + + self.ui.fit_scan_viewbox.view.invertY(False) except Exception as e: self.ui.result_textBrowser2.append(str(e)) From 7b41091e55885900d35e18fe3992e70466a35180 Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Fri, 6 Mar 2020 18:47:36 -0800 Subject: [PATCH 45/63] Convert Multiple PKL files to H5 and TXT at once --- .../Spectrum_analysis/Spectra_plot_fit.py | 105 +++++++++--------- 1 file changed, 55 insertions(+), 50 deletions(-) diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py index 89893e5..c549ba5 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py @@ -224,9 +224,11 @@ def open_fit_scan_file(self): def open_pkl_file(self): """ Open pkl file to convert to txt """ try: - self.pkl_to_convert = QtWidgets.QFileDialog.getOpenFileName(self) - self.filename_for_viewer_launch = self.pkl_to_convert[0] - self.launch_h5_pkl_viewer() + self.pkl_to_convert = QtWidgets.QFileDialog.getOpenFileNames(self) + files = self.pkl_to_convert[0] + for i in range(len(files)): + self.filename_for_viewer_launch = files[i] + self.launch_h5_pkl_viewer() except: pass @@ -792,59 +794,62 @@ def fit_and_plot_scan(self): """ Pkl conversion functions """ def pkl_data_to_txt(self): """ Get data from ocean optics scan pkl file, convert to txt""" - folder = os.path.dirname(self.pkl_to_convert[0]) - filename_ext = os.path.basename(self.pkl_to_convert[0]) - filename = os.path.splitext(filename_ext)[0] #get filename without extension - pkl_file = pickle.load(open(self.pkl_to_convert[0], 'rb')) - - txt_file = np.zeros(shape=(2048,pkl_file['Intensities'].shape[0] + 1)) - - data_array = pkl_file['Intensities'] - data_array = np.transpose(data_array) - wavelength = pkl_file['Wavelengths'] - - txt_file[:,0] = wavelength - - for i in range(pkl_file['Intensities'].shape[0]): - txt_file[:,i+1] = data_array[:,i] - - np.savetxt(folder +"/"+ filename +"_data.txt", txt_file, fmt = '%.2f', delimiter= "\t", header="wavelength(nm), Intensities at different points") + for i in range(len(self.pkl_to_convert[0])): + folder = os.path.dirname(self.pkl_to_convert[0][i]) + filename_ext = os.path.basename(self.pkl_to_convert[0][i]) + filename = os.path.splitext(filename_ext)[0] #get filename without extension + pkl_file = pickle.load(open(self.pkl_to_convert[0][i], 'rb')) + + txt_file = np.zeros(shape=(2048,pkl_file['Intensities'].shape[0] + 1)) + + data_array = pkl_file['Intensities'] + data_array = np.transpose(data_array) + wavelength = pkl_file['Wavelengths'] + + txt_file[:,0] = wavelength + + for i in range(pkl_file['Intensities'].shape[0]): + txt_file[:,i+1] = data_array[:,i] + + np.savetxt(folder +"/"+ filename +"_data.txt", txt_file, fmt = '%.2f', delimiter= "\t", header="wavelength(nm), Intensities at different points") def pkl_params_to_txt(self): """ Get scan parameters from ocean optics scan pkl file, convert to txt """ - folder = os.path.dirname(self.pkl_to_convert[0]) - filename_ext = os.path.basename(self.pkl_to_convert[0]) - filename = os.path.splitext(filename_ext)[0] #get filename without extension - pkl_file = pickle.load(open(self.pkl_to_convert[0], 'rb')) - - pkl_scan = pkl_file['Scan Parameters'] - pkl_oo = pkl_file['OceanOptics Parameters'] - - param_list = [] - param_list.append(['X scan start (um)', 'Y scan start (um)', 'X scan size (um)', 'Y scan size (um)', - 'X step size (um)', 'Y step size (um)', 'Integration Time (ms)', 'Scans to Average', 'Correct Dark Counts']) #list of param names - param_list.append([ pkl_scan['X scan start (um)'], pkl_scan['Y scan start (um)'], pkl_scan['X scan size (um)'], - pkl_scan['Y scan size (um)'], pkl_scan['X step size (um)'], pkl_scan['Y step size (um)'], - pkl_oo['Integration Time (ms)'], pkl_oo['Scans Averages'], pkl_oo['Correct Dark Counts'] ]) #list of param values - - param_list = list(zip(*param_list)) #transpose so names and values are side-by-side - save_to = folder +"/"+ filename +"_scan_parameters.txt" - - with open(save_to, 'w') as f: - for item in param_list: - f.write("%s\t" % str(item[0])) #write name - f.write("%s\n" % str(item[1])) #write value + for i in range(len(self.pkl_to_convert[0])): + folder = os.path.dirname(self.pkl_to_convert[0][i]) + filename_ext = os.path.basename(self.pkl_to_convert[0][i]) + filename = os.path.splitext(filename_ext)[0] #get filename without extension + pkl_file = pickle.load(open(self.pkl_to_convert[0][i], 'rb')) + + pkl_scan = pkl_file['Scan Parameters'] + pkl_oo = pkl_file['OceanOptics Parameters'] + + param_list = [] + param_list.append(['X scan start (um)', 'Y scan start (um)', 'X scan size (um)', 'Y scan size (um)', + 'X step size (um)', 'Y step size (um)', 'Integration Time (ms)', 'Scans to Average', 'Correct Dark Counts']) #list of param names + param_list.append([ pkl_scan['X scan start (um)'], pkl_scan['Y scan start (um)'], pkl_scan['X scan size (um)'], + pkl_scan['Y scan size (um)'], pkl_scan['X step size (um)'], pkl_scan['Y step size (um)'], + pkl_oo['Integration Time (ms)'], pkl_oo['Scans Averages'], pkl_oo['Correct Dark Counts'] ]) #list of param values + + param_list = list(zip(*param_list)) #transpose so names and values are side-by-side + save_to = folder +"/"+ filename +"_scan_parameters.txt" + + with open(save_to, 'w') as f: + for item in param_list: + f.write("%s\t" % str(item[0])) #write name + f.write("%s\n" % str(item[1])) #write value def pkl_to_h5(self): """ Convert raw scan .pkl file to h5 """ - folder = os.path.dirname(self.pkl_to_convert[0]) - filename_ext = os.path.basename(self.pkl_to_convert[0]) - filename = os.path.splitext(filename_ext)[0] #get filename without extension - pkl_file = pickle.load(open(self.pkl_to_convert[0], 'rb')) - - h5_filename = folder + "/" + filename + ".h5" - h5_file = h5py.File(h5_filename, "w") - self.traverse_dict_into_h5(pkl_file, h5_file) + for i in range(len(self.pkl_to_convert[0])): + folder = os.path.dirname(self.pkl_to_convert[0][i]) + filename_ext = os.path.basename(self.pkl_to_convert[0][i]) + filename = os.path.splitext(filename_ext)[0] #get filename without extension + pkl_file = pickle.load(open(self.pkl_to_convert[0][i], 'rb')) + + h5_filename = folder + "/" + filename + ".h5" + h5_file = h5py.File(h5_filename, "w") + self.traverse_dict_into_h5(pkl_file, h5_file) def traverse_dict_into_h5(self, dictionary, h5_output): """ From ceb7c6e58a997d71bf0646a68ac6d7f01da99f15 Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Fri, 6 Mar 2020 18:48:33 -0800 Subject: [PATCH 46/63] increase skipheader for QUA files --- PythonGUI_apps/PLQE_analysis/plqe_analysis.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/PythonGUI_apps/PLQE_analysis/plqe_analysis.py b/PythonGUI_apps/PLQE_analysis/plqe_analysis.py index 4dc7fd1..9c7b4e2 100644 --- a/PythonGUI_apps/PLQE_analysis/plqe_analysis.py +++ b/PythonGUI_apps/PLQE_analysis/plqe_analysis.py @@ -69,11 +69,11 @@ def open_data_file(self): self.filename = QtWidgets.QFileDialog.getOpenFileName(self) #self.data = np.loadtxt(self.filename[0], delimiter = '\t', skiprows = 1) if ".txt" in self.filename[0]: - self.data = np.loadtxt(self.filename[0], delimiter = '\t', skiprows = 1, usecols = (0,1,2,3)) + self.data = np.loadtxt(self.filename[0], delimiter = '\t', skiprows = 1) elif ".csv" in self.filename[0]: self.data = np.loadtxt(self.filename[0], delimiter = ',', skiprows = 1) elif ".qua" in self.filename[0]: - self.data = np.genfromtxt(self.filename[0], delimiter = '\t', skip_header = 12, usecols = (0,1,2,3)) + self.data = np.genfromtxt(self.filename[0], delimiter = '\t', skip_header = 28) self.cs_window = ColSelectionWindow(self.data) self.cs_window.col_selection_signal.connect(self.open_with_col_selection) self.nm = np.copy(self.data[:,0]) @@ -118,7 +118,7 @@ def update_emission_region(self): def plot_intensity(self): try: - self.plot.plot(self.nm, self.inpath_data) + self.plot.plot(self.nm, self.inpath_data, pen='r') self.plot.addItem(self.laser_region, ignoreBounds=True) self.plot.addItem(self.emission_region, ignoreBounds=True) except Exception as err: From 90278cb88aa2737306f1e39b365eba6314511ae4 Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Fri, 6 Mar 2020 18:49:52 -0800 Subject: [PATCH 47/63] add TODO note --- PythonGUI_apps/PLQE_analysis/plqe_analysis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PythonGUI_apps/PLQE_analysis/plqe_analysis.py b/PythonGUI_apps/PLQE_analysis/plqe_analysis.py index 9c7b4e2..3e42a4f 100644 --- a/PythonGUI_apps/PLQE_analysis/plqe_analysis.py +++ b/PythonGUI_apps/PLQE_analysis/plqe_analysis.py @@ -72,7 +72,7 @@ def open_data_file(self): self.data = np.loadtxt(self.filename[0], delimiter = '\t', skiprows = 1) elif ".csv" in self.filename[0]: self.data = np.loadtxt(self.filename[0], delimiter = ',', skiprows = 1) - elif ".qua" in self.filename[0]: + elif ".qua" in self.filename[0]:#TODO: Include a Pop-up window for input for skipping header self.data = np.genfromtxt(self.filename[0], delimiter = '\t', skip_header = 28) self.cs_window = ColSelectionWindow(self.data) self.cs_window.col_selection_signal.connect(self.open_with_col_selection) From ced176bf743181969d26ece9e205c3cf9647ee08 Mon Sep 17 00:00:00 2001 From: Sarthak Jariwala Date: Wed, 11 Mar 2020 23:11:27 -0700 Subject: [PATCH 48/63] pop up plots for spectra scans and fits --- .../Spectrum_analysis/Spectra_plot_fit.py | 39 +++++++++++-------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py index c549ba5..3c3bed6 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py @@ -228,7 +228,8 @@ def open_pkl_file(self): files = self.pkl_to_convert[0] for i in range(len(files)): self.filename_for_viewer_launch = files[i] - self.launch_h5_pkl_viewer() + if self.ui.launch_data_viewer_checkBox_2.isChecked(): + self.launch_h5_pkl_viewer() except: pass @@ -661,22 +662,24 @@ def plot_fit_scan(self): y = np.linspace(0, self.y_scan_size, num_y) self.graph_layout=pg.GraphicsLayoutWidget() self.plot = self.graph_layout.addPlot(title="Line Scan") - self.ui.plot.plot(y, self.img[0,:], pen="r") + self.plot.plot(y, self.img[0,:], pen="r") self.graph_layout.show() else: + self.fit_scan_viewbox = pg.ImageView() if self.ui.use_raw_scan_settings.isChecked(): - self.ui.fit_scan_viewbox.setImage(self.img, scale= + self.fit_scan_viewbox.setImage(self.img, scale= (self.x_step_size, self.y_step_size)) scale = pg.ScaleBar(size=2,suffix='um') - scale.setParentItem(self.ui.fit_scan_viewbox.view) + scale.setParentItem(self.fit_scan_viewbox.view) scale.anchor((1, 1), (1, 1), offset=(-30, -30)) - self.ui.fit_scan_viewbox.view.sigRangeChanged.connect(lambda: updateDelay(scale, 10)) + self.fit_scan_viewbox.view.sigRangeChanged.connect(lambda: updateDelay(scale, 10)) else: - self.ui.fit_scan_viewbox.setImage(self.img) + self.fit_scan_viewbox.setImage(self.img) - self.ui.fit_scan_viewbox.view.invertY(False) + self.fit_scan_viewbox.view.invertY(False) + self.fit_scan_viewbox.show() except Exception as e: self.ui.result_textBrowser2.append(str(e)) @@ -687,18 +690,20 @@ def plot_raw_scan(self): # TODO test line scan plots intensities = self.intensities.T #this is only there because of how we are saving the data in the app - intensities = np.reshape(intensities, newshape=(2048,self.numb_x_pixels, self.numb_y_pixels)) - self.ui.raw_scan_viewbox.setImage(intensities, scale= + intensities = np.reshape(intensities, newshape=(2048,self.numb_x_pixels, self.numb_y_pixels)) + self.raw_scan_viewbox = pg.ImageView() + self.raw_scan_viewbox.setImage(intensities, scale= (self.x_step_size, self.y_step_size), xvals=self.wavelengths) #roi_plot = self.ui.raw_scan_viewBox.getRoiPlot() #roi_plot.plot(data['Wavelengths'], intensities) - self.ui.raw_scan_viewbox.view.invertY(False) + self.raw_scan_viewbox.view.invertY(False) scale = pg.ScaleBar(size=2,suffix='um') - scale.setParentItem(self.ui.raw_scan_viewbox.view) + scale.setParentItem(self.raw_scan_viewbox.view) scale.anchor((1, 1), (1, 1), offset=(-30, -30)) - self.ui.raw_scan_viewbox.view.sigRangeChanged.connect(lambda: updateDelay(scale, 10)) + self.raw_scan_viewbox.view.sigRangeChanged.connect(lambda: updateDelay(scale, 10)) + self.raw_scan_viewbox.show() except Exception as e: self.ui.result_textBrowser2.append(str(e)) @@ -711,16 +716,18 @@ def plot_intensity_sums(self): sums = np.sum(self.intensities, axis=-1) self.sums = np.reshape(sums, newshape=(self.numb_x_pixels, self.numb_y_pixels)) + self.intensity_sums_viewBox = pg.ImageView() - self.ui.intensity_sums_viewBox.setImage(self.sums, scale= + self.intensity_sums_viewBox.setImage(self.sums, scale= (self.x_step_size, self.y_step_size)) - self.ui.intensity_sums_viewBox.view.invertY(False) + self.intensity_sums_viewBox.view.invertY(False) scale = pg.ScaleBar(size=2,suffix='um') - scale.setParentItem(self.ui.intensity_sums_viewBox.view) + scale.setParentItem(self.intensity_sums_viewBox.view) scale.anchor((1, 1), (1, 1), offset=(-30, -30)) - self.ui.intensity_sums_viewBox.view.sigRangeChanged.connect(lambda: updateDelay(scale, 10)) + self.intensity_sums_viewBox.view.sigRangeChanged.connect(lambda: updateDelay(scale, 10)) + self.intensity_sums_viewBox.show() except Exception as e: self.ui.result_textBrowser2.append(str(e)) From 08af9592ea60747f4fa10f27f5200a07b9a33ba8 Mon Sep 17 00:00:00 2001 From: Sarthak Jariwala Date: Wed, 11 Mar 2020 23:12:18 -0700 Subject: [PATCH 49/63] some gui rearrangements --- .../Spectrum_analysis/Spectra_plot_fit_gui.ui | 517 +++++++++--------- 1 file changed, 246 insertions(+), 271 deletions(-) diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui index ac27289..fd2cf5b 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui @@ -6,8 +6,8 @@ 0 0 - 1728 - 1052 + 2284 + 1434 @@ -127,10 +127,13 @@ - - - - Peak Center 1 (nm) + + + + 9999.000000000000000 + + + 780.000000000000000 @@ -144,13 +147,10 @@ - - - - 9999.000000000000000 - - - 780.000000000000000 + + + + Peak Center 1 (nm) @@ -408,13 +408,10 @@ - - - - 9999.000000000000000 - - - 770.000000000000000 + + + + Sigma 1 (nm) @@ -425,10 +422,13 @@ - - - - Sigma 1 (nm) + + + + 9999.000000000000000 + + + 770.000000000000000 @@ -975,92 +975,126 @@ Ready Figure Scan Spectra Data - - - - - - - - - 15 - - - - For Raw Scan Data - - - - - - - - 12 - - - - Plot - - - - - - - - - - 0 - 0 - - - + + + + + - 0 - 300 + 210 + 16777215 + + + 12 + + + + Load Settings + + + + + + + 12 + + + + Spectra Scan +File + + + + + + + + 12 + + + + Background +File + + + + + + + + 12 + + + + Load Only + Fit File + + + + + + + + 12 + + + + For Scan Data + + + + - - - - - - + + - 15 + 12 - - - pk_pos - - - - - fwhm - - + + Intensity Sums + - - - - - 0 - 0 - + + + + + 12 + - - - 0 - 300 - + + For Raw Scan Data + + + + + + + + 12 + + + + # Y points + + + + + + + 2000 + + + 100 - + 2000 @@ -1070,44 +1104,61 @@ Ready Figure - + + + + 12 + + # X points - + + + + 12 + + - # Y points + After Fitting Scan Data - - + + 12 - Plot + For Fit Scale - - - - 2000 + + + + + 12 + - - 100 + + Plot - + + + + 12 + + Use Raw Scan Settings @@ -1116,19 +1167,26 @@ Ready Figure - - + + - 15 + 12 - - After Fitting Scan Data - + + + pk_pos + + + + + fwhm + + - + @@ -1140,161 +1198,65 @@ Ready Figure - - - - - - - - - - - 15 - - - - Intensity Sums - - - - - - - - 12 - - - - Plot - - - - + + + + + 12 + + + - - - - - 0 - 0 - + + + + + 12 + - - - 0 - 300 - + + Launch Data Viewer - - - - - - Qt::Horizontal - - - - - - - - 210 - 16777215 - - - - - 15 - - - - Load Settings - - - - - - - 12 - - - - For Scan Data - - - - - - - - 12 - - - - Launch Data Viewer - - - - - - - - 12 - - - - Spectra Scan -File - - - - - - - - 12 - - - - Background -File - - - - - - - - 12 - - - - Load Only - Fit File - - - - - - - - 12 - - - - Export Fitted + + + + + 12 + + + + Export Fitted Scan - - - - - - - - + + + + + + + + 12 + + + + Plot + + + + + + + + 12 + + + + Plot + + + + @@ -1390,6 +1352,24 @@ Scan Import .pkl file + + + + 390 + 20 + 327 + 43 + + + + + 12 + + + + Launch Data Viewer + + @@ -1400,19 +1380,14 @@ Scan 0 0 - 1728 - 21 + 2284 + 38 - - ImageView - QGraphicsView -
pyqtgraph
-
PlotWidget QGraphicsView From 74296f93e63730c083923d6e9da192d8c871f0e0 Mon Sep 17 00:00:00 2001 From: Sarthak Jariwala Date: Wed, 11 Mar 2020 23:35:21 -0700 Subject: [PATCH 50/63] initial attempts at sorting 'Analyse Spectra Fits' function --- PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py index 3c3bed6..da27751 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py @@ -243,6 +243,11 @@ def analyze_spectra_fits(self): if self.fit_scan_file is None: self.open_fit_scan_file() + #result_no = int(self.ui.result_spinBox.value()) + #self.matplotlibwidget = MatplotlibWidget(size=(12,8), dpi=300) + #self.fit_scan_file['result_'+str(0)].plot(fig=self.matplotlibwidget.getFigure().add_subplot(111)) + #self.matplotlibwidget.draw() + #self.matplotlibwidget.show() analyze_window = Analyze(scan_fit_file=self.fit_scan_file) analyze_window.run() From 947574181af5dae898b55ca321ecf88f746d8ac9 Mon Sep 17 00:00:00 2001 From: SarthakJariwala Date: Sun, 15 Mar 2020 14:57:16 -0700 Subject: [PATCH 51/63] modified spec file --- PythonGUI_apps/DataBrowser.spec | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/PythonGUI_apps/DataBrowser.spec b/PythonGUI_apps/DataBrowser.spec index 372f922..1c2b037 100644 --- a/PythonGUI_apps/DataBrowser.spec +++ b/PythonGUI_apps/DataBrowser.spec @@ -1,10 +1,10 @@ -# -*- mode: python -*- +# -*- mode: python ; coding: utf-8 -*- block_cipher = None -a = Analysis(['C:\\Users\\lindat18\\Dropbox\\Ginger_Lab\\Data_Analysis\\PythonGUI_apps\\DataBrowser.py'], - pathex=['C:\\Users\\lindat18\\Dropbox\\Ginger_Lab\\Data_Analysis\\PythonGUI_apps'], +a = Analysis(['DataBrowser.py'], + pathex=['E:\\QT_projects\\Python_GUI_apps\\PythonGUI_apps'], binaries=[], datas=[], hiddenimports=['ipykernel.datapub'], @@ -33,4 +33,5 @@ coll = COLLECT(exe, a.datas, strip=False, upx=True, + upx_exclude=[], name='DataBrowser') From d591cbc417030fc3378caad38f353829587fa4e5 Mon Sep 17 00:00:00 2001 From: Sarthak Jariwala Date: Sun, 15 Mar 2020 17:39:26 -0700 Subject: [PATCH 52/63] clean up --- .../Lifetime_analysis/read_ph_phd.py | 78 +++++++------------ 1 file changed, 30 insertions(+), 48 deletions(-) diff --git a/PythonGUI_apps/Lifetime_analysis/read_ph_phd.py b/PythonGUI_apps/Lifetime_analysis/read_ph_phd.py index 1c536a4..76ccd1b 100644 --- a/PythonGUI_apps/Lifetime_analysis/read_ph_phd.py +++ b/PythonGUI_apps/Lifetime_analysis/read_ph_phd.py @@ -14,56 +14,38 @@ def read_picoharp_phd(datafile): - parser = picoharp_phd.PicoharpParser(datafile) + parser = picoharp.PicoharpParser(datafile) return parser -def phd_to_csv(datafile): - parser = read_picoharp_phd(datafile) - name, ext = datafile.rsplit('.', 1) - - total_curves = parser.no_of_curves() - y = [] - for i in range(total_curves): - res, curve = parser.get_curve(i) - time_window = int(numpy.floor(parser.get_time_window_in_ns(curve_no))) - curve = curve[0:time_window] - y.append(curve) - -parser = picoharp_phd.PicoharpParser(datafile) -name, ext = datafile.rsplit('.', 1) - -#for i in range(parser.no_of_curves()): +#def phd_to_csv(datafile, return_df = False): +# parser = read_picoharp_phd(datafile) +# name, ext = datafile.rsplit('.', 1) # -# res, curve1 = parser.get_curve(0) -# res, curve2 = parser.get_curve(1) -# res, curve3 = parser.get_curve(2) -# res, curve4 = parser.get_curve(3) -# res, curve5 = parser.get_curve(4) -## res, curve2 = parser.get_curve(1) -# size = len(curve1) - -curve_no = 3 - -res, curve1 = parser.get_curve(curve_no) -time_window = int(numpy.floor(parser.get_time_window_in_ns(curve_no))) -curve1 = curve1[0:time_window] -size = len(curve1) -X = numpy.arange(0, size*res, res, numpy.float) - -plt.figure() -plt.plot(X,curve1) -plt.yscale('log') -plt.ylim([1,1e4]) -#csvname = '%s.csv' % name -#csv = open(csvname, 'w') -# -#for x, y1, y2, y3, y4, y5 in zip(X, curve1, curve2, curve3, curve4, curve5): -# csv.write('%f,%d,%d,%d,%d,%d\n' % (x, y1, y2, y3,y4,y5)) -# -#csv.close() -# -#print('Saved %s.' % csvname) +# total_curves = parser.no_of_curves() +# y = [] +# for i in range(total_curves): +# res, curve = parser.get_curve(i) +# time_window = int(np.floor(parser.get_time_window_in_ns(curve_no))) +# curve = curve[0:time_window] +# y.append(curve) +# +# df = pd.DataFrame(y) +# df.T.to_csv(name+".csv", index=False, header=False) +# if return_df == True: +# return df.T +def smooth(curve, boxwidth): + sm_curve = np.convolve(curve, np.ones(boxwidth)/boxwidth, mode="same") + return sm_curve -#if __name__ == '__main__': -# main() +def get_x_y(curve_no, parser, smooth_trace = False, boxwidth = 3): + + assert type(parser) == picoharp.PicoharpParser, 'must be picoharp parser' + res, curve = parser.get_curve(curve_no) + time_window = int(np.floor(parser.get_time_window_in_ns(curve_no))) + curve = curve[0:time_window] + size = len(curve) + x = np.arange(0, size*res, res, np.float) + if smooth_trace == True: + curve = smooth(curve, boxwidth=boxwidth) + return x,curve From 0c66cf3eb7b08bac9f0b8c11c82e19d9497e7c53 Mon Sep 17 00:00:00 2001 From: Sarthak Jariwala Date: Sun, 15 Mar 2020 17:44:55 -0700 Subject: [PATCH 53/63] clean up --- PythonGUI_apps/Lifetime_analysis/read_ph_phd.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/PythonGUI_apps/Lifetime_analysis/read_ph_phd.py b/PythonGUI_apps/Lifetime_analysis/read_ph_phd.py index 76ccd1b..6c35edc 100644 --- a/PythonGUI_apps/Lifetime_analysis/read_ph_phd.py +++ b/PythonGUI_apps/Lifetime_analysis/read_ph_phd.py @@ -6,7 +6,7 @@ """ import picoharp_phd -import numpy +import numpy as np import matplotlib.pyplot as plt #import sys @@ -14,7 +14,7 @@ def read_picoharp_phd(datafile): - parser = picoharp.PicoharpParser(datafile) + parser = picoharp_phd.PicoharpParser(datafile) return parser #def phd_to_csv(datafile, return_df = False): @@ -40,7 +40,7 @@ def smooth(curve, boxwidth): def get_x_y(curve_no, parser, smooth_trace = False, boxwidth = 3): - assert type(parser) == picoharp.PicoharpParser, 'must be picoharp parser' + assert type(parser) == picoharp_phd.PicoharpParser, 'must be picoharp parser' res, curve = parser.get_curve(curve_no) time_window = int(np.floor(parser.get_time_window_in_ns(curve_no))) curve = curve[0:time_window] From 027fec17c22308f419b5481f0c2498e4fbe7d70b Mon Sep 17 00:00:00 2001 From: Sarthak Jariwala Date: Sun, 15 Mar 2020 18:35:57 -0700 Subject: [PATCH 54/63] added TODO --- PythonGUI_apps/Lifetime_analysis/Lifetime_plot_fit.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/PythonGUI_apps/Lifetime_analysis/Lifetime_plot_fit.py b/PythonGUI_apps/Lifetime_analysis/Lifetime_plot_fit.py index 27b924d..fa7f67a 100644 --- a/PythonGUI_apps/Lifetime_analysis/Lifetime_plot_fit.py +++ b/PythonGUI_apps/Lifetime_analysis/Lifetime_plot_fit.py @@ -534,6 +534,9 @@ def export_window(self): self.exportplotwindow.export_fig_signal.connect(self.pub_ready_plot_export) def pub_ready_plot_export(self): + #TODO - get all curves from the plotwidget + #item = self.ui.plot.listDataItems()[0] + #print(self.ui.plot.getData(self)) try: filename = QtWidgets.QFileDialog.getSaveFileName(self,caption="Filename with EXTENSION") From d5166ba1cd5d6c1c77308daacf566feac3b72739 Mon Sep 17 00:00:00 2001 From: Sarthak Jariwala Date: Sun, 15 Mar 2020 18:59:52 -0700 Subject: [PATCH 55/63] adding multi-trace exporter for picoharp data --- PythonGUI_apps/DataBrowser.py | 8 +- .../Export_Windows/Multi_Trace_Exporter.py | 147 ++++++++++++++++++ .../Export_Windows/Multi_Trace_Exporter.ui | 85 ++++++++++ .../Lifetime_analysis/read_ph_phd.py | 5 +- 4 files changed, 243 insertions(+), 2 deletions(-) create mode 100644 PythonGUI_apps/Export_Windows/Multi_Trace_Exporter.py create mode 100644 PythonGUI_apps/Export_Windows/Multi_Trace_Exporter.ui diff --git a/PythonGUI_apps/DataBrowser.py b/PythonGUI_apps/DataBrowser.py index 5a276fc..3dea4ec 100644 --- a/PythonGUI_apps/DataBrowser.py +++ b/PythonGUI_apps/DataBrowser.py @@ -20,6 +20,8 @@ from H5_Pkl import h5_pkl_view, h5_view_and_plot from Image_analysis import Image_analysis from Table import Table_widget +from Export_Windows import Multi_Trace_Exporter + pg.mkQApp() #pg.setConfigOption('background', 'w') @@ -39,7 +41,8 @@ def __init__(self): self.ui = WindowTemplate() self.ui.setupUi(self) self.ui.select_comboBox.addItems(["Lifetime Analysis", "Spectrum Analysis", "FLIM Analysis", - "UV-Vis Analysis", "PLQE Analysis", "H5 View/Plot", "H5/PKL Viewer", "Image Analysis", "Table View"]) + "UV-Vis Analysis", "PLQE Analysis", "H5 View/Plot", "H5/PKL Viewer", "Image Analysis", "Table View", + "Mulit-Trace Exporter"]) self.ui.load_pushButton.clicked.connect(self.load_app) self.show() @@ -76,6 +79,9 @@ def load_app(self): elif analysis_software == "Table View": self.table_widget = Table_widget.MainWindow() self.table_widget.show() + elif analysis_software == "Mulit-Trace Exporter": + self.trace_exporter = Multi_Trace_Exporter.MainWindow() + self.trace_exporter.show() def run(): diff --git a/PythonGUI_apps/Export_Windows/Multi_Trace_Exporter.py b/PythonGUI_apps/Export_Windows/Multi_Trace_Exporter.py new file mode 100644 index 0000000..5d5555d --- /dev/null +++ b/PythonGUI_apps/Export_Windows/Multi_Trace_Exporter.py @@ -0,0 +1,147 @@ +import pyqtgraph as pg +from pathlib import Path +from pyqtgraph.Qt import QtCore, QtGui, QtWidgets +try: + from Lifetime_analysis.read_ph_phd import read_picoharp_phd, get_x_y +except Exception as e: + print(e) +import matplotlib.pyplot as plt + +"""Recylce params for plotting""" +plt.rc('xtick', labelsize = 20) +plt.rc('xtick.major', pad = 3) +plt.rc('ytick', labelsize = 20) +plt.rc('lines', lw = 2.5, markersize = 7.5) +plt.rc('legend', fontsize = 20) +plt.rc('axes', linewidth=3.5) + +pg.mkQApp() + +base_path = Path(__file__).parent +file_path = (base_path / "Multi_Trace_Exporter.ui").resolve() + +uiFile = file_path + +WindowTemplate, TemplateBaseClass = pg.Qt.loadUiType(uiFile) + +class MainWindow(TemplateBaseClass): + + def __init__(self): + super(TemplateBaseClass, self).__init__() + + # Create the main window + self.ui = WindowTemplate() + self.ui.setupUi(self) + + self.temp_layout = pg.GraphicsLayoutWidget() + + # file system tree + self.fs_model = QtWidgets.QFileSystemModel() + self.fs_model.setRootPath(QtCore.QDir.currentPath()) + self.ui.treeView.setModel(self.fs_model) + self.ui.treeView.setIconSize(QtCore.QSize(25,25)) + self.ui.treeView.setSortingEnabled(True) + + self.tree_selectionModel = self.ui.treeView.selectionModel() + self.tree_selectionModel.selectionChanged.connect(self.on_treeview_selection_change) + + self.ui.comboBox.currentIndexChanged.connect(self.add_trace_to_temp_plot) + self.ui.add_pushButton.clicked.connect(self.add_trace_to_mem) + self.ui.export_pushButton.clicked.connect(self.pub_ready_plot_export) + + self.x_i = [] + self.y_i = [] + self.x_mem = [] + self.y_mem = [] + self.legend = [] + + self.show() + + def on_treeview_selection_change(self): + try: + fname = self.fs_model.filePath(self.tree_selectionModel.currentIndex()) + _ , ext = fname.rsplit('.',1) + + self.ui.comboBox.clear() + self.ui.textBrowser.clear() + self.x_i = [] + self.y_i = [] + + if ext in ['phd']: + self.parser = read_picoharp_phd(fname) + curve_list = [] + + for i in range(self.parser.no_of_curves()): + curve_list.append("Curve "+str(i)) + x, y = get_x_y(i, self.parser, smooth_trace=self.ui.smooth_checkBox.isChecked(), boxwidth=self.ui.smooth_spinBox.value()) + self.x_i.append(x) + self.y_i.append(y) + + self.ui.comboBox.addItems(curve_list) + self.ui.textBrowser.setText(str(self.parser.info())) + + else: + self.ui.textBrowser.setText(str("Select a PicoHarp File")) + except Exception as e: + print(e) + + def add_trace_to_temp_plot(self): + try: + #self.temp_layout = pg.GraphicsLayoutWidget() + self.temp_layout.clear() + self.temp_plot = self.temp_layout.addPlot(title = "Current Selection") + self.temp_plot.plot(self.x_i[self.ui.comboBox.currentIndex()], self.y_i[self.ui.comboBox.currentIndex()], pen='r') + self.temp_plot.setLogMode(False, True) + self.temp_layout.show() + except Exception as e: + print(e) + + def add_trace_to_mem(self): + try: + self.x_mem.append(self.x_i[self.ui.comboBox.currentIndex()]) + self.y_mem.append(self.y_i[self.ui.comboBox.currentIndex()]) + self.legend.append(self.ui.lineEdit.text()) + except Exception as e: + print(e) + + def pub_ready_plot_export(self): + try: + filename = QtWidgets.QFileDialog.getSaveFileName(self,caption="Filename with EXTENSION") + + plt.figure(figsize=(8,6)) + plt.tick_params(direction='out', length=8, width=3.5) + for i in range(len(self.x_mem)): + if self.ui.Normalize_checkBox.isChecked(): + plt.plot(self.x_mem[i], self.y_mem[i]/max(self.y_mem[i]), label=str(self.legend[i])) + else: + plt.plot(self.x_mem[i], self.y_mem[i], label=str(self.legend[i])) + + plt.yscale('log') + plt.xlabel("Time (ns)", fontsize=20, fontweight='bold') + plt.ylabel("Intensity (norm.)", fontsize=20, fontweight='bold') + plt.legend() + plt.tight_layout() + + plt.savefig(filename[0],bbox_inches='tight', dpi=300) + plt.close() + + self.clear_memory() + + except Exception as e: + print(e) + pass + + def clear_memory(self): + self.x_mem = [] + self.y_mem = [] + self.legend = [] + + + + +def run(): + win = MainWindow() + QtGui.QApplication.instance().exec_() + return win + +#run() \ No newline at end of file diff --git a/PythonGUI_apps/Export_Windows/Multi_Trace_Exporter.ui b/PythonGUI_apps/Export_Windows/Multi_Trace_Exporter.ui new file mode 100644 index 0000000..7b59ef1 --- /dev/null +++ b/PythonGUI_apps/Export_Windows/Multi_Trace_Exporter.ui @@ -0,0 +1,85 @@ + + + MainWindow + + + + 0 + 0 + 1108 + 1063 + + + + MainWindow + + + + + + + + + + Smoothen Trace + + + + + + + Enter Trace Legend Here + + + + + + + Add + + + + + + + Normalize (for export) + + + + + + + 1 + + + + + + + Export + + + + + + + + + + + + + + + 0 + 0 + 1108 + 38 + + + + + + + + diff --git a/PythonGUI_apps/Lifetime_analysis/read_ph_phd.py b/PythonGUI_apps/Lifetime_analysis/read_ph_phd.py index 6c35edc..1d35203 100644 --- a/PythonGUI_apps/Lifetime_analysis/read_ph_phd.py +++ b/PythonGUI_apps/Lifetime_analysis/read_ph_phd.py @@ -5,7 +5,10 @@ @author: Sarthak """ -import picoharp_phd +try: + from Lifetime_analysis import picoharp_phd +except: + import picoharp_phd import numpy as np import matplotlib.pyplot as plt #import sys From 6580ad069a5f35ef55efb23e6aa504264576e888 Mon Sep 17 00:00:00 2001 From: Sarthak Jariwala Date: Mon, 16 Mar 2020 16:48:01 -0700 Subject: [PATCH 56/63] add multiple traces for export --- .../Spectrum_analysis/Spectra_plot_fit.py | 53 ++++++-- .../Spectrum_analysis/Spectra_plot_fit_gui.ui | 127 +++++++++++------- 2 files changed, 120 insertions(+), 60 deletions(-) diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py index da27751..d545f99 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py @@ -92,6 +92,7 @@ def __init__(self): self.ui.fit_scan_pushButton.clicked.connect(self.fit_and_plot_scan) # self.ui.config_fit_params_pushButton.clicked.connect(self.configure_fit_params) self.ui.clear_pushButton.clicked.connect(self.clear_plot) + self.ui.add_to_mem_pushButton.clicked.connect(self.add_trace_to_mem) self.ui.export_single_figure_pushButton.clicked.connect(self.pub_ready_plot_export) self.ui.export_scan_figure_pushButton.clicked.connect(self.export_window) self.ui.analyze_spectra_fits_pushButton.clicked.connect(self.analyze_spectra_fits) @@ -133,6 +134,13 @@ def __init__(self): #container for data to append to txt file self.data_list = [] + + #for adding traces to memory for plotting/exporting all at once + self.x_mem = [] + self.y_mem = [] + self.best_fit_mem = [] + self.legend = [] + self.single_spec_fit_called = False self.show() @@ -364,6 +372,8 @@ def plot(self): pass self.ui.plot.setLabel('left', 'Intensity', units='a.u.') self.ui.plot.setLabel('bottom', 'Wavelength (nm)') + + self.single_spec_fit_called = False def normalize(self): self.y = (self.y) / np.amax(self.y) @@ -505,6 +515,7 @@ def fit_and_plot(self): self.ui.result_textBrowser.setText(self.result.fit_report()) self.data_list.append(self.ui.result_textBrowser.toPlainText()) + self.single_spec_fit_called = True except Exception as e: self.ui.result_textBrowser.append(str(e)) @@ -546,16 +557,24 @@ def pub_ready_plot_export(self): plt.savefig(filename[0],bbox_inches='tight', dpi=300) plt.close() except: - plt.figure(figsize=(8,6)) - plt.tick_params(direction='out', length=8, width=3.5) - plt.plot(self.x, self.y) - plt.plot(self.x, self.result.best_fit,'k') - plt.xlabel("Wavelength (nm)", fontsize=20, fontweight='bold') - plt.ylabel("Intensity (a.u.)", fontsize=20, fontweight='bold') - plt.tight_layout() - - plt.savefig(filename[0],bbox_inches='tight', dpi=300) - plt.close() + if self.x_mem == []: + self.ui.result_textBrowser.setText("Add traces to memory first!") + else: + plt.figure(figsize=(8,6)) + plt.tick_params(direction='out', length=8, width=3.5) + for i in range(len(self.x_mem)): + plt.plot(self.x_mem[i], self.y_mem[i], label=str(self.legend[i])) + if self.single_spec_fit_called == True: + plt.plot(self.x_mem[i], self.best_fit_mem[i],'k') + #plt.plot(self.x, self.y) + #plt.plot(self.x, self.result.best_fit,'k') + plt.xlabel("Wavelength (nm)", fontsize=20, fontweight='bold') + plt.ylabel("Intensity (a.u.)", fontsize=20, fontweight='bold') + plt.legend() + plt.tight_layout() + + plt.savefig(filename[0],bbox_inches='tight', dpi=300) + plt.close() except AttributeError: self.ui.result_textBrowser.setText("Need to fit the data first!") @@ -580,6 +599,20 @@ def export_data(self): def clear_export_data(self): self.data_list = [] + self.x_mem = [] + self.y_mem = [] + self.legend = [] + self.best_fit_mem = [] + + def add_trace_to_mem(self): + try: + self.x_mem.append(self.x) + self.y_mem.append(self.y) + if self.single_spec_fit_called == True: + self.best_fit_mem.append(self.result.best_fit) + self.legend.append(self.ui.lineEdit.text()) + except Exception as e: + print(e) """ Scan spectra functions """ diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui index fd2cf5b..b76c670 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui @@ -772,124 +772,121 @@ Load Settings - - + + 10 - Background -File + Subtract Background + + + true - - + + 10 - Normalize + Background File - - + + 10 - Clear Plots Everytime - - - true + Correct for White Light - - + + 10 - Correct for White Light + White Light Ref File - - + + 10 - For Single Spectrum + Clear Plots Everytime + + + true - - + + 10 - White Light -Ref File + Export Fit Data - - + + 10 - Subtract Background - - - true + Spectrum File - - + + 10 - Spectrum -File + Normalize - - + + 10 - Export data + For Single Spectrum - + @@ -898,21 +895,19 @@ File - - + + 10 - 50 - false - Plot + Plot without Background - + @@ -920,20 +915,19 @@ File - Export Publication -Ready Figure + Export Figure - - + + 10 - Plot without Background + Clear Export Memory @@ -950,15 +944,48 @@ Ready Figure + + + + + 10 + 50 + false + + + + Plot + + + - + + + + 10 + + + + Add Trace to Memory + + + + + 10 - Clear export data + Enter Legend Here... + + + + + + + Export Settings From d97bcf7a80754bea781ac179ec22a6d93005a55e Mon Sep 17 00:00:00 2001 From: Sarthak Jariwala Date: Mon, 16 Mar 2020 21:04:54 -0700 Subject: [PATCH 57/63] export mulitple plots and fits to the same export plot w legend; can also do from multiple files --- .../Lifetime_analysis_gui_layout.ui | 54 +++++++---- .../Lifetime_analysis/Lifetime_plot_fit.py | 93 ++++++++++++------- 2 files changed, 97 insertions(+), 50 deletions(-) diff --git a/PythonGUI_apps/Lifetime_analysis/Lifetime_analysis_gui_layout.ui b/PythonGUI_apps/Lifetime_analysis/Lifetime_analysis_gui_layout.ui index 53f58dd..24b97b0 100644 --- a/PythonGUI_apps/Lifetime_analysis/Lifetime_analysis_gui_layout.ui +++ b/PythonGUI_apps/Lifetime_analysis/Lifetime_analysis_gui_layout.ui @@ -6,8 +6,8 @@ 0 0 - 1490 - 1583 + 2620 + 1676 @@ -1071,32 +1071,24 @@ Export Settings - - + + - Export data + For Figure: - - - - - 12 - - + + - Save with Fit - - - true + Export Fit Data - + - Clear export data + Clear Export Memory @@ -1114,6 +1106,27 @@ + + + + For Data: + + + + + + + Enter Legend Here... + + + + + + + Add trace to memory + + + @@ -1214,6 +1227,9 @@ + + false + 12 @@ -1324,7 +1340,7 @@ 0 0 - 1490 + 2620 38 diff --git a/PythonGUI_apps/Lifetime_analysis/Lifetime_plot_fit.py b/PythonGUI_apps/Lifetime_analysis/Lifetime_plot_fit.py index fa7f67a..9437f9f 100644 --- a/PythonGUI_apps/Lifetime_analysis/Lifetime_plot_fit.py +++ b/PythonGUI_apps/Lifetime_analysis/Lifetime_plot_fit.py @@ -81,6 +81,7 @@ def __init__(self): self.ui.FittingFunc_comboBox.currentTextChanged.connect(self.switch_function_tab) self.ui.FittingMethod_comboBox.currentTextChanged.connect(self.switch_init_params_groupBox) self.ui.separate_irf_checkBox.stateChanged.connect(self.switch_open_irf) + self.ui.add_to_mem_pushButton.clicked.connect(self.add_trace_to_mem) self.ui.export_data_pushButton.clicked.connect(self.export_data) self.ui.clear_export_data_pushButton.clicked.connect(self.clear_export_data) self.ui.smoothData_checkBox.stateChanged.connect(self.smooth_trace_enabled) @@ -94,6 +95,11 @@ def __init__(self): self.file = None self.out = None # output file after fitting self.data_list = [] + self.fit_lifetime_called = False + self.x_mem = [] # containers for adding x data to memory + self.y_mem = [] # containers for adding y data to memory + self.best_fit_mem = [] # containers for adding best fit data to memory + self.legend = [] # containers for adding legend to memory #variables accounting for data received from FLIM analysis self.opened_from_flim = False #switched to True in FLIM_plot when "analyze lifetime" clicked @@ -109,6 +115,7 @@ def open_file(self): if ".csv" in self.filename[0] or ".txt" in self.filename[0]: #if txt or csv, prompt user to enter # of rows to skip self.skip_rows_window = SkipRowsWindow() self.skip_rows_window.skip_rows_signal.connect(self.open_with_skip_rows_window) + self.ui.Res_comboBox.setEnabled(True) else: self.file = read_picoharp_phd(self.filename[0]) self.opened_from_flim = False @@ -130,6 +137,7 @@ def open_irf_file(self): if ".txt" in self.irf_filename[0] or ".csv" in self.irf_filename[0]: self.irf_skip_rows_window = SkipRowsWindow() self.irf_skip_rows_window.skip_rows_signal.connect(self.open_irf_with_skip_rows_window) + self.ui.Res_comboBox.setEnabled(True) else: self.irf_file = read_picoharp_phd(self.irf_filename[0]) except: @@ -207,7 +215,6 @@ def acquire_settings(self, mode="data"): mode -- string specifying whether to use data or irf channel (default "data") """ - self.resolution = float(self.ui.Res_comboBox.currentText()) if mode == "data": channel = int(self.ui.Data_channel_spinBox.value()) elif mode == "irf": @@ -221,17 +228,23 @@ def acquire_settings(self, mode="data"): y = self.irf_file.get_curve(channel)[1] else: #otherwise, get data/irf from data file y = self.file[:,channel] + + self.resolution = float(self.ui.Res_comboBox.currentText()) except: res, y = self.file.get_curve(channel) - # TO DO - check if res read in is the same as selected time_window = int(np.floor(self.file.get_time_window_in_ns(channel))) y = y[0:time_window] + self.resolution = res length = np.shape(y)[0] - x = np.arange(0, length, 1) * self.resolution + x = np.arange(0, length*self.resolution, self.resolution, np.float) if self.ui.smoothData_checkBox.isChecked() and mode=="data": y = np.convolve(y, np.ones(self.ui.smoothData_spinBox.value())/self.ui.smoothData_spinBox.value(), mode="same") + + if self.ui.normalize_checkBox.isChecked(): + y = y / np.amax(y) + return x,y except Exception as e: @@ -243,10 +256,9 @@ def plot(self): x, y = self.hist_data_from_flim else: x,y = self.acquire_settings() #get data - if self.ui.normalize_checkBox.isChecked(): - y = y / np.amax(y) self.ui.plot.plot(x, y, clear=self.ui.clear_plot_checkBox.isChecked(), pen=pg.mkPen(self.plot_color)) + self.fit_lifetime_called = False try: self.ui.Result_textBrowser.setText("Integral Counts :\n" "{:.2E}".format( @@ -335,7 +347,8 @@ def fit_and_plot(self): #add fit params to data_list self.data_list.append("Data Channel: " + str(self.ui.Data_channel_spinBox.value()) + "\n" + self.ui.Result_textBrowser.toPlainText()) - + self.fit_lifetime_called = True + self.ui.plot.setLabel('left', 'Intensity', units='a.u.') self.ui.plot.setLabel('bottom', 'Time (ns)') return self.out @@ -462,7 +475,7 @@ def fit_and_plot_with_irf(self): #add fit params to data_list self.data_list.append("Data Channel: " + str(self.ui.Data_channel_spinBox.value()) + "\n" + self.ui.Result_textBrowser.toPlainText()) - + self.fit_lifetime_called = True except Exception as e: self.ui.Result_textBrowser.append(format(e)) @@ -528,39 +541,57 @@ def export_data(self): def clear_export_data(self): self.data_list = [] + self.clean_up_after_fig_export() + + def clean_up_after_fig_export(self): + self.x_mem = [] + self.y_mem = [] + self.legend = [] + self.best_fit_mem = [] + + def add_trace_to_mem(self): + try: + if self.fit_lifetime_called == True: + self.x_mem.append(self.out[:,0]) + self.y_mem.append(self.out[:,1]) + self.best_fit_mem.append(self.out[:,2]) + else: + self.x_mem.append(self.acquire_settings()[0]) + self.y_mem.append(self.acquire_settings()[1]) + self.legend.append(self.ui.lineEdit.text()) + except Exception as e: + print(e) def export_window(self): self.exportplotwindow = ExportPlotWindow() self.exportplotwindow.export_fig_signal.connect(self.pub_ready_plot_export) def pub_ready_plot_export(self): - #TODO - get all curves from the plotwidget - #item = self.ui.plot.listDataItems()[0] - #print(self.ui.plot.getData(self)) try: - filename = QtWidgets.QFileDialog.getSaveFileName(self,caption="Filename with EXTENSION") + if self.x_mem == []: + self.ui.result_textBrowser.setText("Add traces to memory first!") - plt.figure(figsize=(8,6)) - plt.tick_params(direction='out', length=8, width=3.5) - if self.ui.save_w_fit_checkBox.isChecked(): - plt.plot(self.out[:,0],self.out[:,1]/np.max(self.out[:,1]),self.exportplotwindow.ui.traceColor_comboBox.currentText()) - plt.plot(self.out[:,0],self.out[:,2]/np.max(self.out[:,1]),self.exportplotwindow.ui.fitColor_comboBox.currentText()) - if self.exportplotwindow.ui.legend_checkBox.isChecked(): - plt.legend([self.exportplotwindow.ui.legend1_lineEdit.text(),self.exportplotwindow.ui.legend2_lineEdit.text()]) else: - plt.plot(self.acquire_settings()[0],self.acquire_settings()[1]/np.max(self.acquire_settings()[1]), - self.exportplotwindow.ui.traceColor_comboBox.currentText()) - if self.exportplotwindow.ui.legend_checkBox.isChecked(): - plt.legend([self.exportplotwindow.ui.legend1_lineEdit.text()]) - plt.yscale('log') - plt.xlabel("Time (ns)", fontsize=20, fontweight='bold') - plt.ylabel("Intensity (norm.)", fontsize=20, fontweight='bold') - plt.tight_layout() - plt.xlim([self.exportplotwindow.ui.lowerX_spinBox.value(),self.exportplotwindow.ui.upperX_spinBox.value()]) - plt.ylim([self.exportplotwindow.ui.lowerY_spinBox.value(),self.exportplotwindow.ui.upperY_doubleSpinBox.value()]) - - plt.savefig(filename[0],bbox_inches='tight', dpi=300) - plt.close() + filename = QtWidgets.QFileDialog.getSaveFileName(self,caption="Filename with EXTENSION") + + plt.figure(figsize=(8,6)) + plt.tick_params(direction='out', length=8, width=3.5) + for i in range(len(self.x_mem)): + plt.plot(self.x_mem[i], self.y_mem[i], label=str(self.legend[i])) + if self.fit_lifetime_called == True: + plt.plot(self.x_mem[i], self.best_fit_mem[i],'k--') + + plt.yscale('log') + plt.xlabel("Time (ns)", fontsize=20, fontweight='bold') + plt.ylabel("Intensity (norm.)", fontsize=20, fontweight='bold') + plt.legend() + plt.tight_layout() + plt.xlim([self.exportplotwindow.ui.lowerX_spinBox.value(),self.exportplotwindow.ui.upperX_spinBox.value()]) + plt.ylim([self.exportplotwindow.ui.lowerY_spinBox.value(),self.exportplotwindow.ui.upperY_doubleSpinBox.value()]) + + plt.savefig(filename[0],bbox_inches='tight', dpi=300) + plt.close() + self.clean_up_after_fig_export() except Exception as e: self.ui.Result_textBrowser.append(format(e)) From 3d5f2592f997d1a984944ba3c1eae3e4571c6769 Mon Sep 17 00:00:00 2001 From: Sarthak Jariwala Date: Mon, 16 Mar 2020 21:05:59 -0700 Subject: [PATCH 58/63] changes to export window --- .../Export_Windows/Export_window.py | 20 +- PythonGUI_apps/Export_Windows/export_plot.ui | 184 +++--------------- 2 files changed, 42 insertions(+), 162 deletions(-) diff --git a/PythonGUI_apps/Export_Windows/Export_window.py b/PythonGUI_apps/Export_Windows/Export_window.py index f5eccf6..0e5cc63 100644 --- a/PythonGUI_apps/Export_Windows/Export_window.py +++ b/PythonGUI_apps/Export_Windows/Export_window.py @@ -58,19 +58,19 @@ def __init__(self): self.ui = export_WindowTemplate() self.ui.setupUi(self) - self.ui.traceColor_comboBox.addItems(["C0","C1","C2","C3","C4","C5","C6","C7", "r", "g", "b", "y", "k"]) - self.ui.fitColor_comboBox.addItems(["k", "r", "b", "y", "g","C0","C1","C2","C3","C4","C5","C6","C7"]) + #self.ui.traceColor_comboBox.addItems(["C0","C1","C2","C3","C4","C5","C6","C7", "r", "g", "b", "y", "k"]) + #self.ui.fitColor_comboBox.addItems(["k", "r", "b", "y", "g","C0","C1","C2","C3","C4","C5","C6","C7"]) self.ui.export_pushButton.clicked.connect(self.export) - self.ui.legend_checkBox.stateChanged.connect(self.legend_title) + #self.ui.legend_checkBox.stateChanged.connect(self.legend_title) self.show() - def legend_title(self): - if self.ui.legend_checkBox.isChecked(): - self.ui.legend1_lineEdit.setEnabled(True) - self.ui.legend2_lineEdit.setEnabled(True) - else: - self.ui.legend1_lineEdit.setEnabled(False) - self.ui.legend2_lineEdit.setEnabled(False) + #def legend_title(self): + # if self.ui.legend_checkBox.isChecked(): + # self.ui.legend1_lineEdit.setEnabled(True) + # self.ui.legend2_lineEdit.setEnabled(True) + # else: + # self.ui.legend1_lineEdit.setEnabled(False) + # self.ui.legend2_lineEdit.setEnabled(False) def export(self): self.export_fig_signal.emit() diff --git a/PythonGUI_apps/Export_Windows/export_plot.ui b/PythonGUI_apps/Export_Windows/export_plot.ui index 31e3b40..7613a2b 100644 --- a/PythonGUI_apps/Export_Windows/export_plot.ui +++ b/PythonGUI_apps/Export_Windows/export_plot.ui @@ -6,7 +6,7 @@ 0 0 - 980 + 930 435 @@ -14,35 +14,11 @@ Form - - - - - 15 - - - - X limits - - - - - - - - 12 - - - - Upper - - - - 12 + 10 @@ -53,23 +29,11 @@ - - - - - 12 - - - - Lower - - - - 12 + 10 @@ -78,40 +42,19 @@ -100.000000000000000 + + 10000000000000000000000.000000000000000 + 1.500000000000000 - - - - - 15 - - - - Color - - - - - - - - 12 - - - - Trace - - - - - + + - 12 + 10 @@ -123,7 +66,7 @@ - 12 + 10 @@ -134,15 +77,15 @@ - - + + - 15 + 10 - Y limits + Lower @@ -150,7 +93,7 @@ - 12 + 10 @@ -158,11 +101,11 @@ - + - 17 + 15 @@ -170,105 +113,39 @@ - - - - - 12 - - - - Legend 2 - - - - - - - false - - - - 12 - - - - - - - - - 12 - - - - - - - - - 12 - - - - - - + + 12 - Fit - - - - - - - false - - - - 12 - + Y limits - - + + - 15 + 10 - Legends + Upper - - + + 12 - Legend 1 - - - - - - - - 15 - - - - Add Legends to the Plot + X limits @@ -276,14 +153,17 @@ - 12 + 10 4 - 0.000000000000000 + -10000.000000000000000 + + + 1000000000000000000.000000000000000 0.010000000000000 From 98ac680045eb1e4b3c826455bc02e35371dc567b Mon Sep 17 00:00:00 2001 From: Sarthak Jariwala Date: Mon, 16 Mar 2020 21:07:34 -0700 Subject: [PATCH 59/63] Export mulitple plots and fits w legends from multiple files, started fitting attempts in eV --- .../Spectrum_analysis/Spectra_plot_fit.py | 44 ++++-- .../Spectrum_analysis/Spectra_plot_fit_gui.ui | 137 ++++++++++-------- 2 files changed, 107 insertions(+), 74 deletions(-) diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py index d545f99..f8a5650 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py @@ -25,9 +25,9 @@ from H5_Pkl import h5_pkl_view sys.path.append(os.path.abspath('../Export_Windows')) try: - from Export_window import ExportFigureWindow + from Export_window import ExportFigureWindow, ExportPlotWindow except: - from Export_Windows.Export_window import ExportFigureWindow + from Export_Windows.Export_window import ExportFigureWindow, ExportPlotWindow # local modules try: from Spectra_fit_funcs import Spectra_Fit, Single_Gaussian, Single_Lorentzian, Double_Gaussian, Multi_Gaussian @@ -93,7 +93,7 @@ def __init__(self): # self.ui.config_fit_params_pushButton.clicked.connect(self.configure_fit_params) self.ui.clear_pushButton.clicked.connect(self.clear_plot) self.ui.add_to_mem_pushButton.clicked.connect(self.add_trace_to_mem) - self.ui.export_single_figure_pushButton.clicked.connect(self.pub_ready_plot_export) + self.ui.export_single_figure_pushButton.clicked.connect(self.export_plot_window) self.ui.export_scan_figure_pushButton.clicked.connect(self.export_window) self.ui.analyze_spectra_fits_pushButton.clicked.connect(self.analyze_spectra_fits) @@ -347,6 +347,7 @@ def plot(self): self.y = self.file[:,1] self.check_loaded_files() + self.check_eV_state() if self.check_loaded_files() == True: #check the following conditions if all required files have been provided if self.ui.subtract_bck_radioButton.isChecked() == True and self.ui.WLRef_checkBox.isChecked() == False: @@ -364,20 +365,29 @@ def plot(self): if self.ui.norm_checkBox.isChecked(): self.normalize() - + self.ui.plot.plot(self.x, self.y, clear=self.clear_check(), pen='r') except Exception as e: self.ui.result_textBrowser.append(str(e)) pass self.ui.plot.setLabel('left', 'Intensity', units='a.u.') - self.ui.plot.setLabel('bottom', 'Wavelength (nm)') + if self.ui.fit_in_eV.isChecked(): + self.ui.plot.setLabel('bottom', 'Energy (eV)') + else: + self.ui.plot.setLabel('bottom', 'Wavelength (nm)') self.single_spec_fit_called = False def normalize(self): self.y = (self.y) / np.amax(self.y) + def check_eV_state(self): + if self.ui.fit_in_eV.isChecked(): + self.x = 1240/self.file[:,0] + else: + self.x = self.file[:,0] + def clear_plot(self): self.ui.plot.clear() self.ui.result_textBrowser.clear() @@ -419,9 +429,9 @@ def fit_and_plot(self): elif self.opened_from_flim: pass else: - + self.check_eV_state() if fit_func == "Single Gaussian": #and self.ui.subtract_bck_radioButton.isChecked() == True: - single_gauss = Single_Gaussian(self.file, self.bck_file, wlref=self.wlref_file) + single_gauss = Single_Gaussian(self.file, self.bck_file, wlref=self.wlref_file, fit_in_eV=self.ui.fit_in_eV.isChecked()) if self.ui.adjust_param_checkBox.isChecked(): center1_min = self.ui.single_peakcenter1_min_spinBox.value() center1_max = self.ui.single_peakcenter1_max_spinBox.value() @@ -436,7 +446,7 @@ def fit_and_plot(self): self.ui.result_textBrowser.setText(self.result.fit_report()) elif fit_func == "Single Lorentzian": #and self.ui.subtract_bck_radioButton.isChecked() == True: - single_lorentzian = Single_Lorentzian(self.file, self.bck_file, wlref=self.wlref_file) + single_lorentzian = Single_Lorentzian(self.file, self.bck_file, wlref=self.wlref_file, fit_in_eV=self.ui.fit_in_eV.isChecked()) if self.ui.adjust_param_checkBox.isChecked(): center1_min = self.ui.single_peakcenter1_min_spinBox.value() @@ -452,7 +462,7 @@ def fit_and_plot(self): self.ui.result_textBrowser.setText(self.result.fit_report()) elif fit_func == "Double Gaussian": #and self.ui.subtract_bck_radioButton.isChecked() == True: - double_gauss = Double_Gaussian(self.file, self.bck_file, wlref=self.wlref_file) + double_gauss = Double_Gaussian(self.file, self.bck_file, wlref=self.wlref_file, fit_in_eV=self.ui.fit_in_eV.isChecked()) if self.ui.adjust_param_checkBox.isChecked(): center1_min = self.ui.double_peakcenter1_min_spinBox.value() center1_max = self.ui.double_peakcenter1_max_spinBox.value() @@ -482,7 +492,7 @@ def fit_and_plot(self): elif fit_func == "Triple Gaussian": #and self.ui.subtract_bck_radioButton.isChecked() == True: #currently only works for triple gaussian (n=3) - multiple_gauss = Multi_Gaussian(self.file, self.bck_file, 3, wlref=self.wlref_file) + multiple_gauss = Multi_Gaussian(self.file, self.bck_file, 3, wlref=self.wlref_file, fit_in_eV=self.ui.fit_in_eV.isChecked()) if self.ui.adjust_param_checkBox.isChecked(): center1_min = self.ui.multi_peakcenter1_min_spinBox.value() center1_max = self.ui.multi_peakcenter1_max_spinBox.value() @@ -523,6 +533,10 @@ def fit_and_plot(self): def export_window(self): self.export_window = ExportImages() self.export_window.export_fig_signal.connect(self.pub_ready_plot_export) + + def export_plot_window(self): + self.exportplotwindow = ExportPlotWindow() + self.exportplotwindow.export_fig_signal.connect(self.pub_ready_plot_export) def pub_ready_plot_export(self): filename = QtWidgets.QFileDialog.getSaveFileName(self,caption="Filename with EXTENSION") @@ -566,10 +580,14 @@ def pub_ready_plot_export(self): plt.plot(self.x_mem[i], self.y_mem[i], label=str(self.legend[i])) if self.single_spec_fit_called == True: plt.plot(self.x_mem[i], self.best_fit_mem[i],'k') - #plt.plot(self.x, self.y) - #plt.plot(self.x, self.result.best_fit,'k') - plt.xlabel("Wavelength (nm)", fontsize=20, fontweight='bold') + + if self.ui.fit_in_eV.isChecked(): + plt.xlabel("Energy (eV)", fontsize=20, fontweight='bold') + else: + plt.xlabel("Wavelength (nm)", fontsize=20, fontweight='bold') plt.ylabel("Intensity (a.u.)", fontsize=20, fontweight='bold') + plt.xlim([self.exportplotwindow.ui.lowerX_spinBox.value(),self.exportplotwindow.ui.upperX_spinBox.value()]) + plt.ylim([self.exportplotwindow.ui.lowerY_spinBox.value(),self.exportplotwindow.ui.upperY_doubleSpinBox.value()]) plt.legend() plt.tight_layout() diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui index b76c670..de5691b 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui @@ -612,6 +612,21 @@ + + + + + 10 + + + + Fit in eV + + + true + + + @@ -772,6 +787,15 @@ Load Settings + + + + + 10 + + + + @@ -787,160 +811,170 @@ - - + + 10 - Background File + Spectrum File - - + + 10 - Correct for White Light + Export Figure - - + + 10 - White Light Ref File + Clear Export Memory - - + + 10 - Clear Plots Everytime - - - true + Correct for White Light - - + + 10 - Export Fit Data + White Light Ref File - - + + 10 - Spectrum File + Enter Legend Here... - - + + 10 - Normalize + For Single Spectrum - - + + 10 - For Single Spectrum + Background File - - + + + + Export Settings + + + + + 10 + + Export Fit Data + - - + + 10 + false - Plot without Background + Clear Plot - - + + 10 - Export Figure + Normalize - - + + 10 - Clear Export Memory + Clear Plots Everytime + + + true - - + + 10 - false - Clear Plot + Plot without Background @@ -970,25 +1004,6 @@ - - - - - 10 - - - - Enter Legend Here... - - - - - - - Export Settings - - - From f102eacebf10544b9aac32ac8eebb73106ea15b9 Mon Sep 17 00:00:00 2001 From: Sarthak Jariwala Date: Mon, 16 Mar 2020 21:08:59 -0700 Subject: [PATCH 60/63] changes to include fit in eV instead of nm, lmfit not able to fit it and collect uncertainities --- .../Spectrum_analysis/Spectra_fit_funcs.py | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_fit_funcs.py b/PythonGUI_apps/Spectrum_analysis/Spectra_fit_funcs.py index fba0a86..47b9174 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_fit_funcs.py +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_fit_funcs.py @@ -23,10 +23,11 @@ class Spectra_Fit(object): ref: reference spectrum (both x and y-axis) for background correction """ - def __init__(self, data, ref, wlref = None): + def __init__(self, data, ref, wlref = None, fit_in_eV = True): self.data = data self.ref = ref self.wlref = wlref + self.fit_in_eV = fit_in_eV def background_correction(self): """Return the background corrected spectrum""" @@ -37,8 +38,10 @@ def background_correction(self): if self.wlref is not None: wlref = self.wlref[:,1] y = y/wlref - - # y = y - np.mean(y[(x>600) & (x<700)]) # removing any remaining bckgrnd + + if self.fit_in_eV is True: + x = 1240/x + return [x,y] class Single_Gaussian(Spectra_Fit): @@ -87,14 +90,6 @@ def lorentzian_model(self): pars = lmodel.guess(y, x=x) # parameters - center, width, height result = lmodel.fit(y, pars, x=x, nan_policy='propagate') return result - - # def lorentzian_model_w_lims(self, center_min = None, center_max = None): - # x,y = self.background_correction() - # lmodel = LorentzianModel(prefix = 'l1_') # calling lorentzian model - # pars = lmodel.guess(y, x=x) # parameters - center, width, height - # pars['l1_center'].set(min = center_min, max = center_max) - # result = lmodel.fit(y, pars, x=x, nan_policy='propagate') - # return result def lorentzian_model_w_lims(self, peak_pos, sigma, min_max_range): x,y = self.background_correction() @@ -155,8 +150,8 @@ class Multi_Gaussian(Spectra_Fit): # self.num_of_gaussians = num_of_gaussians # self.peak_pos = peak_pos # self.min_max_range = min_max_range - def __init__(self, data, ref, num_of_gaussians, wlref=None): - Spectra_Fit.__init__(self, data, ref, wlref) + def __init__(self, data, ref, num_of_gaussians, wlref=None, fit_in_eV = True): + Spectra_Fit.__init__(self, data, ref, wlref, fit_in_eV=True) self.num_of_gaussians = num_of_gaussians def gaussian_model(self): From 7da1bb4e632bb6e88e17e0eee0047a3ee4cbd1b1 Mon Sep 17 00:00:00 2001 From: Sarthak Jariwala Date: Tue, 17 Mar 2020 12:29:08 -0700 Subject: [PATCH 61/63] can now fit and plot spectra in eV, user bound inputs are still in nm but converted to eV in the backend --- .../Spectrum_analysis/Spectra_fit_funcs.py | 25 ++++++++++++++++--- .../Spectrum_analysis/Spectra_plot_fit.py | 21 ++++++++++------ .../Spectrum_analysis/Spectra_plot_fit_gui.ui | 4 +-- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_fit_funcs.py b/PythonGUI_apps/Spectrum_analysis/Spectra_fit_funcs.py index 47b9174..a96f782 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_fit_funcs.py +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_fit_funcs.py @@ -40,7 +40,9 @@ def background_correction(self): y = y/wlref if self.fit_in_eV is True: - x = 1240/x + x = np.sort(1240/self.data[:, 0]) # converting to eV and sorting in ascending order + y = [y[i] for i in np.argsort(1240/x)] # sorting argument of y acc to x sorting index + # need to do this because data is collected in wavelength return [x,y] @@ -69,12 +71,16 @@ def gaussian_model(self): # return result #770 760 780 sigma 15 def gaussian_model_w_lims(self, peak_pos, sigma, min_max_range): x,y = self.background_correction() + if self.fit_in_eV is True: + peak_pos = 1240/peak_pos + sigma = 1240/sigma + min_max_range = np.sort(1240/np.asarray(min_max_range)) gmodel = GaussianModel(prefix = 'g1_') # calling gaussian model pars = gmodel.guess(y, x=x) # parameters - center, width, height pars['g1_center'].set(peak_pos, min=min_max_range[0], max=min_max_range[1]) pars['g1_sigma'].set(sigma) result = gmodel.fit(y, pars, x=x, nan_policy='propagate') - return result #770 760 780 sigma 15 + return result class Single_Lorentzian(Spectra_Fit): """Fit a single Lorentzian to the spectrum @@ -93,6 +99,10 @@ def lorentzian_model(self): def lorentzian_model_w_lims(self, peak_pos, sigma, min_max_range): x,y = self.background_correction() + if self.fit_in_eV is True: + peak_pos = 1240/peak_pos + sigma = 1240/sigma + min_max_range = np.sort(1240/np.asarray(min_max_range)) lmodel = LorentzianModel(prefix = 'l1_') # calling lorentzian model pars = lmodel.guess(y, x=x) # parameters - center, width, height pars['l1_center'].set(peak_pos, min = min_max_range[0], max = min_max_range[1]) @@ -127,6 +137,10 @@ def gaussian_model_w_lims(self, peak_pos, sigma, min_max_range): #min_max_range - list containing lists of min and max for peak center. [ [min1, max1], [min2, max2] ] x,y = self.background_correction() + if self.fit_in_eV is True: + peak_pos = 1240/np.asarray(peak_pos) + sigma = 1240/np.asarray(sigma) + min_max_range = np.sort(1240/np.asarray(min_max_range)) gmodel_1 = GaussianModel(prefix='g1_') # calling gaussian model pars = gmodel_1.guess(y, x=x) # parameters - center, width, height pars['g1_center'].set(peak_pos[0], min = min_max_range[0][0], max = min_max_range[0][1]) @@ -136,7 +150,7 @@ def gaussian_model_w_lims(self, peak_pos, sigma, min_max_range): gmodel_2 = GaussianModel(prefix='g2_') pars.update(gmodel_2.make_params()) # update parameters - center, width, height pars['g2_center'].set(peak_pos[1], min = min_max_range[1][0], max = min_max_range[1][1]) - pars['g2_sigma'].set(sigma[1], min = composite_pars['g1_sigma'].value) + pars['g2_sigma'].set(sigma[1], min = pars['g1_sigma'].value) pars['g2_amplitude'].set(min = 0) gmodel = gmodel_1 + gmodel_2 @@ -192,6 +206,11 @@ def gaussian_model_w_lims(self, peak_pos, sigma, min_max_range): assert self.num_of_gaussians == len(self.peak_pos), ("Number of gaussians must be equal to the number of peak positions") assert len(self.min_max_range) == len(self.peak_pos), ("Number of bounds on the range must be equal to the number of peak positions") + if self.fit_in_eV is True: + peak_pos = 1240/np.asarray(peak_pos) + sigma = 1240/np.asarray(sigma) + min_max_range = np.sort(1240/np.asarray(min_max_range)) + for i in range(self.num_of_gaussians): diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py index f8a5650..e1cdd67 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py @@ -347,7 +347,6 @@ def plot(self): self.y = self.file[:,1] self.check_loaded_files() - self.check_eV_state() if self.check_loaded_files() == True: #check the following conditions if all required files have been provided if self.ui.subtract_bck_radioButton.isChecked() == True and self.ui.WLRef_checkBox.isChecked() == False: @@ -365,6 +364,8 @@ def plot(self): if self.ui.norm_checkBox.isChecked(): self.normalize() + + self.check_eV_state() self.ui.plot.plot(self.x, self.y, clear=self.clear_check(), pen='r') @@ -384,9 +385,11 @@ def normalize(self): def check_eV_state(self): if self.ui.fit_in_eV.isChecked(): - self.x = 1240/self.file[:,0] + self.x = np.sort(1240/self.file[:,0]) + self.y = [self.y[i] for i in np.argsort(1240/self.file[:,0])] else: self.x = self.file[:,0] + self.y = self.file[:,1] def clear_plot(self): self.ui.plot.clear() @@ -430,7 +433,7 @@ def fit_and_plot(self): pass else: self.check_eV_state() - if fit_func == "Single Gaussian": #and self.ui.subtract_bck_radioButton.isChecked() == True: + if fit_func == "Single Gaussian": single_gauss = Single_Gaussian(self.file, self.bck_file, wlref=self.wlref_file, fit_in_eV=self.ui.fit_in_eV.isChecked()) if self.ui.adjust_param_checkBox.isChecked(): center1_min = self.ui.single_peakcenter1_min_spinBox.value() @@ -441,7 +444,8 @@ def fit_and_plot(self): [center1_min, center1_max]) else: self.result = single_gauss.gaussian_model() - self.ui.plot.plot(self.x, self.y, clear=self.clear_check(), pen='r') + #self.ui.plot.plot(self.x, self.y, clear=self.clear_check(), pen='r') + self.plot() self.ui.plot.plot(self.x, self.result.best_fit, clear=False, pen='k') self.ui.result_textBrowser.setText(self.result.fit_report()) @@ -457,7 +461,8 @@ def fit_and_plot(self): [center1_min, center1_max]) else: self.result = single_lorentzian.lorentzian_model() - self.ui.plot.plot(self.x, self.y, clear=self.clear_check(), pen='r') + #self.ui.plot.plot(self.x, self.y, clear=self.clear_check(), pen='r') + self.plot() self.ui.plot.plot(self.x, self.result.best_fit, clear=False, pen='k') self.ui.result_textBrowser.setText(self.result.fit_report()) @@ -481,7 +486,8 @@ def fit_and_plot(self): else: self.result = double_gauss.gaussian_model() - self.ui.plot.plot(self.x, self.y, clear=self.clear_check(), pen='r') + #self.ui.plot.plot(self.x, self.y, clear=self.clear_check(), pen='r') + self.plot() self.ui.plot.plot(self.x, self.result.best_fit, clear=False, pen='k') if self.ui.plot_components_checkBox.isChecked(): comps = self.result.eval_components(x=self.x) @@ -515,7 +521,8 @@ def fit_and_plot(self): else: self.result = multiple_gauss.gaussian_model() - self.ui.plot.plot(self.x, self.y, clear=self.clear_check(), pen='r') + #self.ui.plot.plot(self.x, self.y, clear=self.clear_check(), pen='r') + self.plot() self.ui.plot.plot(self.x, self.result.best_fit, clear=False, pen='k') if self.ui.plot_components_checkBox.isChecked(): comps = self.result.eval_components(x=self.x) diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui index de5691b..e1fc8de 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui @@ -7,7 +7,7 @@ 0 0 2284 - 1434 + 1476 @@ -620,7 +620,7 @@ - Fit in eV + Fit/Plot in eV true From 4a5885699130c32723418e684ac10827e0857dad Mon Sep 17 00:00:00 2001 From: Sarthak Jariwala Date: Tue, 17 Mar 2020 12:30:14 -0700 Subject: [PATCH 62/63] add decimal and neg value input for x lims --- PythonGUI_apps/Export_Windows/export_plot.ui | 71 +++++++++++--------- 1 file changed, 40 insertions(+), 31 deletions(-) diff --git a/PythonGUI_apps/Export_Windows/export_plot.ui b/PythonGUI_apps/Export_Windows/export_plot.ui index 7613a2b..840264f 100644 --- a/PythonGUI_apps/Export_Windows/export_plot.ui +++ b/PythonGUI_apps/Export_Windows/export_plot.ui @@ -14,21 +14,6 @@ Form - - - - - 10 - - - - 3000000 - - - 1000 - - - @@ -37,7 +22,7 @@ - 1 + 4 -100.000000000000000 @@ -62,21 +47,6 @@ - - - - - 10 - - - - -10000 - - - 3000000 - - - @@ -170,6 +140,45 @@ + + + + + 10 + + + + 4 + + + -10000000.000000000000000 + + + 100000000000.000000000000000 + + + + + + + + 10 + + + + 4 + + + -1000000000.000000000000000 + + + 10000000000000.000000000000000 + + + 10000.000000000000000 + + + From c9487fdee375f2a65474d50557e0f8c74752557c Mon Sep 17 00:00:00 2001 From: Sarthak Jariwala Date: Tue, 17 Mar 2020 13:05:45 -0700 Subject: [PATCH 63/63] pop-up plot widget, expand textbrowser view --- .../Spectrum_analysis/Spectra_plot_fit.py | 6 +- .../Spectrum_analysis/Spectra_plot_fit_gui.ui | 295 ++++++++++-------- 2 files changed, 164 insertions(+), 137 deletions(-) diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py index e1cdd67..69f182b 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit.py @@ -113,6 +113,10 @@ def __init__(self): # for i in reversed(range(self.ui.bounds_groupBox.layout().count())): # self.ui.bounds_groupBox.layout().itemAt(i).widget().deleteLater() #self.ui.single_bounds_page.layout().addWidget(QtWidgets.QPushButton("test")) + + self.ui.plot = pg.PlotWidget() + self.ui.plot.setTitle(title="Spectrum Plot") + #self.ui.plot.show() self.file = None self.bck_file = None @@ -366,7 +370,7 @@ def plot(self): self.normalize() self.check_eV_state() - + self.ui.plot.show() self.ui.plot.plot(self.x, self.y, clear=self.clear_check(), pen='r') except Exception as e: diff --git a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui index e1fc8de..7e013d3 100644 --- a/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui +++ b/PythonGUI_apps/Spectrum_analysis/Spectra_plot_fit_gui.ui @@ -6,8 +6,8 @@ 0 0 - 2284 - 1476 + 2115 + 1483 @@ -787,30 +787,6 @@ Load Settings - - - - - 10 - - - - - - - - - 10 - - - - Subtract Background - - - true - - - @@ -823,7 +799,7 @@ - + @@ -835,7 +811,7 @@ - + @@ -871,7 +847,7 @@ - + @@ -895,63 +871,84 @@ - - + + 10 - Background File + Subtract Background + + + true - - + + + + + 10 + + - Export Settings + Export Fit Data - + 10 - Export Fit Data + Add Trace to Memory - - + + 10 - false - Clear Plot + Plot without Background - - + + + + + 10 + 50 + false + + + + Plot + + + + + 10 - Normalize + Background File - + @@ -966,41 +963,56 @@ - - + + 10 - Plot without Background + Normalize - - + + 10 - 50 - false + false - Plot + Clear Plot + + + + + + + Export Settings + + + + + + + For Data - - - - 10 - + + + For Figure + + + + - Add Trace to Memory + Plot Control @@ -1008,7 +1020,13 @@ - + + + + 10 + + + @@ -1019,7 +1037,7 @@ - + @@ -1090,100 +1108,78 @@ File - - + + 12 - - Intensity Sums - - - + + 12 - For Raw Scan Data + Export Fitted +Scan - - + + 12 - # Y points - - - - - - - 2000 - - - 100 - - - - - - - 2000 - - - 100 + Launch Data Viewer - - + + 12 - # X points + After Fitting Scan Data - - + + 12 - After Fitting Scan Data + Intensity Sums - - + + 12 - For Fit Scale + For Raw Scan Data - - + + 12 @@ -1194,22 +1190,19 @@ File - - + + 12 - Use Raw Scan Settings - - - true + Plot - + @@ -1228,73 +1221,110 @@ File - - + + 12 - Analyze Spectra Fits + Plot - - + + 12 + + Export Settings + - - + + 12 - Launch Data Viewer + Analyze Spectra Fits - - + + 12 - Export Fitted -Scan + For Fit Scale - - + + 12 - Plot + Use Raw Scan Settings + + + true - - + + 12 - Plot + # X points + + + + + + + + 12 + + + + # Y points + + + + + + + 2000 + + + 100 + + + + + + + 2000 + + + 100 @@ -1422,20 +1452,13 @@ Scan 0 0 - 2284 + 2115 38 - - - PlotWidget - QGraphicsView -
pyqtgraph
-
-