Skip to content

Commit

Permalink
Merge pull request #1 from SarthakJariwala/lifetime_irf
Browse files Browse the repository at this point in the history
Lifetime irf
  • Loading branch information
ltaing27 committed Aug 6, 2019
2 parents 36e3dcd + 5beda08 commit cca80ed
Show file tree
Hide file tree
Showing 24 changed files with 6,634 additions and 640 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.pyc
77 changes: 47 additions & 30 deletions PythonGUI_apps/DataBrowser.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,18 @@
"""

# system imports
import sys
from pathlib import Path

import pyqtgraph as pg
from pyqtgraph.Qt import QtGui

from Lifetime_analysis import Lifetime_plot_fit
from Spectrum_analysis import Spectra_plot_fit
from FLIM_analysis import FLIM_plot
from UV_Vis_analysis import uv_vis_analysis
from PLQE_analysis import plqe_analysis
from H5_Pkl import h5_pkl_view, h5_view_and_plot

pg.mkQApp()
pg.setConfigOption('background', 'w')
Expand All @@ -25,37 +30,49 @@
WindowTemplate, TemplateBaseClass = pg.Qt.loadUiType(uiFile)

class MainWindow(TemplateBaseClass):

def __init__(self):
TemplateBaseClass.__init__(self)

# Create the main window
self.ui = WindowTemplate()
self.ui.setupUi(self)
self.ui.select_comboBox.addItems(["Lifetime Analysis", "Spectrum Analysis", "UV-Vis Analysis"])
self.ui.load_pushButton.clicked.connect(self.load_app)

self.show()


def load_app(self):

analysis_software = self.ui.select_comboBox.currentText()

if analysis_software == "Lifetime Analysis":
self.lifetime_window = Lifetime_plot_fit.MainWindow()
self.lifetime_window.show()

elif analysis_software == "Spectrum Analysis":
self.spectrum_window = Spectra_plot_fit.MainWindow()
self.spectrum_window.show()

else:
print("not yet linked -- coming soon")

def __init__(self):
TemplateBaseClass.__init__(self)

# Create the main window
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"])
self.ui.load_pushButton.clicked.connect(self.load_app)

self.show()


def load_app(self):

analysis_software = self.ui.select_comboBox.currentText()

if analysis_software == "Lifetime Analysis":
self.lifetime_window = Lifetime_plot_fit.MainWindow()
self.lifetime_window.show()
elif analysis_software == "Spectrum Analysis":
self.spectrum_window = Spectra_plot_fit.MainWindow()
self.spectrum_window.show()
elif analysis_software == "FLIM Analysis":
self.flim_window = FLIM_plot.MainWindow()
self.flim_window.show()
elif analysis_software == "UV-Vis Analysis":
self.uv_vis_window = uv_vis_analysis.MainWindow()
self.uv_vis_window.show()
elif analysis_software == "PLQE Analysis":
self.plqe_window = plqe_analysis.MainWindow()
self.plqe_window.show()
elif analysis_software == "H5 View/Plot":
app = h5_view_and_plot.H5ViewPlot(sys.argv)
#sys.exit(app.exec_())
elif analysis_software == "H5/PKL Viewer":
app = h5_pkl_view.H5PklView(sys.argv)
#sys.exit(app.exec_())

def run():
win = MainWindow()
QtGui.QApplication.instance().exec_()
return
win = MainWindow()
QtGui.QApplication.instance().exec_()
return

run()
36 changes: 36 additions & 0 deletions PythonGUI_apps/DataBrowser.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# -*- mode: python -*-

block_cipher = None


a = Analysis(['DataBrowser.py'],
pathex=['C:\\Users\\lindat18\\Dropbox\\Ginger_Lab\\Data_Analysis\\PythonGUI_apps'],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
[],
exclude_binaries=True,
name='DataBrowser',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
name='DataBrowser')
251 changes: 251 additions & 0 deletions PythonGUI_apps/FLIM_analysis/FLIM_plot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
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 pickle
import time
from lmfit.models import GaussianModel
import customplotting.mscope as cpm
# local modules

pg.mkQApp()
pg.setConfigOption('background', 'w')
pg.setConfigOption('imageAxisOrder', 'row-major')

base_path = Path(__file__).parent
file_path = (base_path / "flim_plot_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)

#set up ui signals
self.ui.load_scan_pushButton.clicked.connect(self.open_pkl_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_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)
self.ui.import_pkl_pushButton.clicked.connect(self.import_pkl_to_convert)
self.ui.pkl_to_h5_pushButton.clicked.connect(self.pkl_to_h5)

self.show()

def open_pkl_file(self):
""" Open FLIM scan file """
try:
self.filename = QtWidgets.QFileDialog.getOpenFileName(self)
self.pkl_file = pickle.load(open(self.filename[0], 'rb'))
except Exception as err:
print(format(err))

def import_pkl_to_convert(self):
""" Open pkl file to convert to h5 """
try:
self.pkl_to_convert = QtWidgets.QFileDialog.getOpenFileName(self)
self.ui.result_textBrowser.append("Done Loading - .pkl to convert")
except:
pass

def plot_intensity_sums(self):
try:
data = self.pkl_file
self.numb_pixels_X = int((data['Scan Parameters']['X scan size (um)'])/(data['Scan Parameters']['X step size (um)']))
self.numb_pixels_Y = int((data['Scan Parameters']['Y scan size (um)'])/(data['Scan Parameters']['Y step size (um)']))
self.x_step_size = float(data['Scan Parameters']['X step size (um)'])
self.x_scan_size = float(data['Scan Parameters']['X scan size (um)'])
self.y_step_size = float(data['Scan Parameters']['Y step size (um)'])
self.y_scan_size = float(data['Scan Parameters']['Y scan size (um)'])

hist_data = data["Histogram data"]
hist_data = np.reshape(hist_data, newshape=(hist_data.shape[0], self.numb_pixels_X*self.numb_pixels_Y))
self.intensity_sums = np.sum(hist_data, axis=0) #sum intensities for each pixel
self.intensity_sums = np.reshape(self.intensity_sums, newshape=(self.numb_pixels_X, self.numb_pixels_Y))
self.ui.intensity_sums_viewBox.view.invertY(False) # stop y axis invert
self.ui.intensity_sums_viewBox.setImage(self.intensity_sums, scale=
(data['Scan Parameters']['X step size (um)'],
data['Scan Parameters']['Y step size (um)']))
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))
except Exception as err:
print(format(err))

def line_profile_update_plot(self):
""" Handle line profile for intensity sum viewbox """
if hasattr(self, "intensity_sums"):
roiPlot = self.ui.intensity_sums_viewBox.getRoiPlot()
roiPlot.clear()
roi = self.ui.intensity_sums_viewBox.roi

image = self.ui.intensity_sums_viewBox.getProcessedImage()

# Extract image data from ROI
axes = (self.ui.intensity_sums_viewBox.axes['x'], self.ui.intensity_sums_viewBox.axes['y'])
data, coords = roi.getArrayRegion(image.view(np.ndarray), self.ui.intensity_sums_viewBox.imageItem, axes, returnMappedCoords=True)

#calculate sums along columns in region
sums_to_plot = np.sum(data, axis=0)

#get scan x-coordinates in region
x_values = coords[1][0]

try:
roiPlot.plot(x_values, sums_to_plot)
except:
pass

def plot_raw_scan(self):
try:
data = self.pkl_file
self.numb_pixels_X = int((data['Scan Parameters']['X scan size (um)'])/(data['Scan Parameters']['X step size (um)']))
self.numb_pixels_Y = int((data['Scan Parameters']['Y scan size (um)'])/(data['Scan Parameters']['Y step size (um)']))
self.x_step_size = float(data['Scan Parameters']['X step size (um)'])
self.x_scan_size = float(data['Scan Parameters']['X scan size (um)'])
self.y_step_size = float(data['Scan Parameters']['Y step size (um)'])
self.y_scan_size = float(data['Scan Parameters']['Y scan size (um)'])
# TODO test line scan plots
hist_data = data['Histogram data']

self.hist_image = np.reshape(hist_data, newshape=(hist_data.shape[0],self.numb_pixels_X,self.numb_pixels_Y))
time_data = data['Time data']
self.times = time_data[:, 0, 0]*1e-3
self.ui.raw_hist_data_viewBox.view.invertY(False) # stops y-axis invert
self.ui.raw_hist_data_viewBox.setImage(self.hist_image, scale=
(data['Scan Parameters']['X step size (um)'],
data['Scan Parameters']['Y step size (um)']), xvals=self.times)
self.ui.raw_hist_data_viewBox.roi.setSize([self.x_scan_size, self.y_scan_size])
# if self.ui.compare_checkBox.isChecked():
# self.ui.imv2.setImage(self.hist_image, scale= (data['Scan Parameters']['X step size (um)'],
# data['Scan Parameters']['Y step size (um)']), xvals=self.times)
self.switch_compare()
self.ui.raw_hist_data_viewBox.ui.roiBtn.clicked.connect(self.switch_compare)
scale = pg.ScaleBar(size=1,suffix='um')
scale.setParentItem(self.ui.raw_hist_data_viewBox.view)
scale.anchor((1, 1), (1, 1), offset=(-30, -30))

except Exception as err:
print(format(err))

def switch_compare(self):
"""
Handles compare checkbox. If checked, show second ROI on raw histogram data that user can use for comparison to first ROI.
"""
if self.ui.compare_checkBox.isChecked() and hasattr(self, "hist_image"):
if not hasattr(self, "roi2"): #create roi if doesn't exist yet
self.roi2 = pg.ROI(pos=[0,0], size=[int(self.x_scan_size/2), int(self.y_scan_size/2)], movable=True, pen='r')
self.roi2.addScaleHandle([1, 1], [0, 0])
self.roi2.addRotateHandle([0, 0], [1, 1])
self.roi2.sigRegionChanged.connect(self.update_roi2_plot)
self.ui.raw_hist_data_viewBox.addItem(self.roi2)
self.update_roi2_plot()
self.roi2.hide()
self.roi2_plot.hide()
if self.ui.raw_hist_data_viewBox.ui.roiBtn.isChecked():
self.roi2.show()
self.roi2_plot.show()
else:
self.roi2.hide()
self.roi2_plot.hide()
else: #if not checked, hide roi
if hasattr(self, "roi2"):
self.roi2.hide()
self.roi2_plot.hide()

def update_roi2_plot(self):
""" Update plot corresponding to second roi """
#Adapted from pyqtgraph imageview sourcecode

image = self.ui.raw_hist_data_viewBox.getProcessedImage()

# Extract image data from ROI
axes = (self.ui.raw_hist_data_viewBox.axes['x'], self.ui.raw_hist_data_viewBox.axes['y'])
data, coords = self.roi2.getArrayRegion(image.view(np.ndarray), self.ui.raw_hist_data_viewBox.imageItem, axes, returnMappedCoords=True)
if data is None:
return

# Average data within entire ROI for each frame
data = data.mean(axis=max(axes)).mean(axis=min(axes))
xvals = self.ui.raw_hist_data_viewBox.tVals
if hasattr(self, "roi2_plot"):
self.roi2_plot.clear()
self.roi2_plot = self.ui.raw_hist_data_viewBox.getRoiPlot().plot(xvals, data, pen='r')

def save_intensities_image(self):
try:
filename_ext = os.path.basename(self.filename[0])
filename = os.path.splitext(filename_ext)[0] #get filename without extension
save_to = os.getcwd() + "\\" + filename + "_intensity_sums.png"
cpm.plot_confocal(self.intensity_sums, stepsize=np.abs(self.pkl_file['Scan Parameters']['X step size (um)']))
cpm.plt.savefig(save_to, bbox_inches='tight', dpi=300)
except:
pass

def save_intensities_array(self):
try:
filename_ext = os.path.basename(self.filename[0])
filename = os.path.splitext(filename_ext)[0] #get filename without extension
save_to = os.getcwd() + "\\" + filename + "_intensity_sums.txt"
np.savetxt(save_to, self.intensity_sums.T, fmt='%f') #save transposed intensity sums, as original array handles x in cols and y in rows
except:
pass

def pkl_to_h5(self):
#Convert scan .pkl file into h5
try:
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)
except Exception as err:
print(format(err))

def traverse_dict_into_h5(self, dictionary, h5_output):
#Create an h5 file using .pkl with scan data and params
for key in dictionary:
if type(dictionary[key]) == dict: #if subdictionary, create a group
group = h5_output.create_group(key)
previous_dict = dictionary[key]
self.traverse_dict_into_h5(dictionary[key], group) #traverse subdictionary
else:
if key == "Histogram data" or key == "Time data":
h5_output.create_dataset(key, data=dictionary[key])
else:
h5_output.attrs[key] = dictionary[key] #if not dataset, create attribute

def close_application(self):
choice = QtGui.QMessageBox.question(self, 'EXIT!',
"Do you want to exit the app?",
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
if choice == QtGui.QMessageBox.Yes:
sys.exit()
else:
pass

"""Run the Main Window"""
def run():
win = MainWindow()
QtGui.QApplication.instance().exec_()
return win

#Uncomment below if you want to run this as standalone
#run()
Loading

0 comments on commit cca80ed

Please sign in to comment.