Skip to content
This repository was archived by the owner on Apr 1, 2026. It is now read-only.

Commit 2aaaf1b

Browse files
author
LAKESIDE\LindaT18
committed
added flim line profile
1 parent 87f0129 commit 2aaaf1b

3 files changed

Lines changed: 177 additions & 119 deletions

File tree

PythonGUI_apps/FLIM_analysis/FLIM_plot.py

Lines changed: 169 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -25,127 +25,178 @@
2525
WindowTemplate, TemplateBaseClass = pg.Qt.loadUiType(uiFile)
2626

2727
class MainWindow(TemplateBaseClass):
28-
29-
def __init__(self):
30-
super(TemplateBaseClass, self).__init__()
31-
32-
# Create the main window
33-
self.ui = WindowTemplate()
34-
self.ui.setupUi(self)
35-
36-
self.ui.load_scan_pushButton.clicked.connect(self.open_pkl_file)
37-
self.ui.plot_intensity_sums_pushButton.clicked.connect(self.plot_intensity_sums)
38-
self.ui.plot_raw_hist_data_pushButton.clicked.connect(self.plot_raw_scan)
39-
self.ui.save_intensities_image_pushButton.clicked.connect(self.save_intensities_image)
40-
self.ui.save_intensities_array_pushButton.clicked.connect(self.save_intensities_array)
41-
self.ui.compare_checkBox.stateChanged.connect(self.switch_compare)
42-
43-
self.show()
44-
45-
"""Open Scan Files"""
46-
def open_pkl_file(self):
47-
try:
48-
self.filename = QtWidgets.QFileDialog.getOpenFileName(self)
49-
self.pkl_file = pickle.load(open(self.filename[0], 'rb'))
50-
except Exception as err:
51-
print(format(err))
52-
53-
def plot_intensity_sums(self):
54-
try:
55-
data = self.pkl_file
56-
numb_pixels_X = int((data['Scan Parameters']['X scan size (um)'])/(data['Scan Parameters']['X step size (um)']))
57-
numb_pixels_Y = int((data['Scan Parameters']['Y scan size (um)'])/(data['Scan Parameters']['Y step size (um)']))
58-
# TODO test line scan plots
59-
60-
hist_data = data["Histogram data"]
61-
hist_data = np.reshape(hist_data, newshape=(hist_data.shape[0], numb_pixels_X*numb_pixels_Y))
62-
self.intensity_sums = np.sum(hist_data, axis=0)
63-
self.intensity_sums = np.reshape(self.intensity_sums, newshape=(numb_pixels_X, numb_pixels_Y))
64-
self.ui.intensity_sums_viewBox.view.invertY(False) # stop y axis invert
65-
self.ui.intensity_sums_viewBox.setImage(self.intensity_sums, scale=
66-
(data['Scan Parameters']['X step size (um)'],
67-
data['Scan Parameters']['Y step size (um)']))
68-
scale = pg.ScaleBar(size=1,suffix='um')
69-
scale.setParentItem(self.ui.intensity_sums_viewBox.view)
70-
scale.anchor((1, 1), (1, 1), offset=(-30, -30))
71-
except Exception as err:
72-
print(format(err))
73-
74-
def plot_raw_scan(self):
75-
try:
76-
data = self.pkl_file
77-
numb_pixels_X = int((data['Scan Parameters']['X scan size (um)'])/(data['Scan Parameters']['X step size (um)']))
78-
numb_pixels_Y = int((data['Scan Parameters']['Y scan size (um)'])/(data['Scan Parameters']['Y step size (um)']))
79-
# TODO test line scan plots
80-
hist_data = data['Histogram data']
81-
82-
self.hist_image = np.reshape(hist_data, newshape=(hist_data.shape[0],numb_pixels_X,numb_pixels_Y))
83-
84-
time_data = data['Time data']
85-
self.times = time_data[:, 0, 0]*1e-3
86-
self.ui.raw_hist_data_viewBox.view.invertY(False) # stops y-axis invert
87-
self.ui.raw_hist_data_viewBox.setImage(self.hist_image, scale=
88-
(data['Scan Parameters']['X step size (um)'],
89-
data['Scan Parameters']['Y step size (um)']), xvals=self.times)
90-
if self.ui.compare_checkBox.isChecked():
91-
self.ui.imv2.setImage(self.hist_image, scale= (data['Scan Parameters']['X step size (um)'],
92-
data['Scan Parameters']['Y step size (um)']), xvals=self.times)
93-
94-
scale = pg.ScaleBar(size=1,suffix='um')
95-
scale.setParentItem(self.ui.raw_hist_data_viewBox.view)
96-
scale.anchor((1, 1), (1, 1), offset=(-30, -30))
97-
98-
except Exception as err:
99-
print(format(err))
100-
101-
def switch_compare(self):
102-
"""
103-
Handles compare checkbox. If checked, show second ROI that user can use for comparison to first ROI.
104-
"""
105-
if self.ui.compare_checkBox.isChecked():
106-
self.imv2 = pg.ImageView()
107-
if hasattr(self, "hist_image"):
108-
self.imv2.setImage(self.hist_image, scale= (self.pkl_file['Scan Parameters']['X step size (um)'],
109-
self.pkl_file['Scan Parameters']['Y step size (um)']), xvals=self.times)
110-
self.imv2.view.invertY(False) # stop y-axis invert
111-
self.ui.gridLayout.addWidget(self.imv2, 10, 4)
112-
else:
113-
self.ui.gridLayout.removeWidget(self.imv2)
114-
self.imv2.hide()
115-
116-
def save_intensities_image(self):
117-
try:
118-
filename_ext = os.path.basename(self.filename[0])
119-
filename = os.path.splitext(filename_ext)[0] #get filename without extension
120-
save_to = os.getcwd() + "\\" + filename + "_intensity_sums.png"
121-
cpm.plot_confocal(self.intensity_sums, stepsize=np.abs(self.pkl_file['Scan Parameters']['X step size (um)']))
122-
cpm.plt.savefig(save_to, bbox_inches='tight', dpi=300)
123-
except:
124-
pass
125-
126-
def save_intensities_array(self):
127-
try:
128-
filename_ext = os.path.basename(self.filename[0])
129-
filename = os.path.splitext(filename_ext)[0] #get filename without extension
130-
save_to = os.getcwd() + "\\" + filename + "_intensity_sums.txt"
131-
np.savetxt(save_to, self.intensity_sums.T, fmt='%f') #save transpoed intensity sums, as original array handles x in cols and y in rows
132-
except:
133-
pass
134-
135-
def close_application(self):
136-
choice = QtGui.QMessageBox.question(self, 'EXIT!',
137-
"Do you want to exit the app?",
138-
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
139-
if choice == QtGui.QMessageBox.Yes:
140-
sys.exit()
141-
else:
142-
pass
28+
29+
def __init__(self):
30+
super(TemplateBaseClass, self).__init__()
31+
32+
# Create the main window
33+
self.ui = WindowTemplate()
34+
self.ui.setupUi(self)
35+
36+
self.ui.load_scan_pushButton.clicked.connect(self.open_pkl_file)
37+
self.ui.plot_intensity_sums_pushButton.clicked.connect(self.plot_intensity_sums)
38+
self.ui.plot_raw_hist_data_pushButton.clicked.connect(self.plot_raw_scan)
39+
self.ui.save_intensities_image_pushButton.clicked.connect(self.save_intensities_image)
40+
self.ui.save_intensities_array_pushButton.clicked.connect(self.save_intensities_array)
41+
self.ui.compare_checkBox.stateChanged.connect(self.switch_compare)
42+
self.ui.intensity_sums_viewBox.roi.sigRegionChanged.connect(self.line_profile_update_plot)
43+
self.show()
44+
45+
"""Open Scan Files"""
46+
def open_pkl_file(self):
47+
try:
48+
self.filename = QtWidgets.QFileDialog.getOpenFileName(self)
49+
self.pkl_file = pickle.load(open(self.filename[0], 'rb'))
50+
except Exception as err:
51+
print(format(err))
52+
53+
def plot_intensity_sums(self):
54+
try:
55+
data = self.pkl_file
56+
self.numb_pixels_X = int((data['Scan Parameters']['X scan size (um)'])/(data['Scan Parameters']['X step size (um)']))
57+
self.numb_pixels_Y = int((data['Scan Parameters']['Y scan size (um)'])/(data['Scan Parameters']['Y step size (um)']))
58+
self.x_step_size = float(data['Scan Parameters']['X step size (um)'])
59+
self.x_scan_size = float(data['Scan Parameters']['X scan size (um)'])
60+
self.y_step_size = float(data['Scan Parameters']['Y step size (um)'])
61+
self.y_scan_size = float(data['Scan Parameters']['Y scan size (um)'])
62+
# TODO test line scan plots
63+
64+
hist_data = data["Histogram data"]
65+
hist_data = np.reshape(hist_data, newshape=(hist_data.shape[0], self.numb_pixels_X*self.numb_pixels_Y))
66+
self.intensity_sums = np.sum(hist_data, axis=0)
67+
self.intensity_sums = np.reshape(self.intensity_sums, newshape=(self.numb_pixels_X, self.numb_pixels_Y))
68+
self.ui.intensity_sums_viewBox.view.invertY(False) # stop y axis invert
69+
self.ui.intensity_sums_viewBox.setImage(self.intensity_sums, scale=
70+
(data['Scan Parameters']['X step size (um)'],
71+
data['Scan Parameters']['Y step size (um)']))
72+
self.ui.intensity_sums_viewBox.roi.setSize([self.x_scan_size, self.y_scan_size])
73+
scale = pg.ScaleBar(size=1,suffix='um')
74+
scale.setParentItem(self.ui.intensity_sums_viewBox.view)
75+
scale.anchor((1, 1), (1, 1), offset=(-30, -30))
76+
except Exception as err:
77+
print(format(err))
78+
79+
def custom_round(self, a, round_step):
80+
#Round a to the nearest interval of round_step
81+
return round(float(a)/round_step) * round_step
82+
83+
def line_profile_update_plot(self):
84+
if self.ui.line_profile_checkBox.isChecked() and hasattr(self, "intensity_sums"):
85+
roiPlot = self.ui.intensity_sums_viewBox.getRoiPlot()
86+
roiPlot.clear()
87+
intensity_sums = self.intensity_sums
88+
roi = self.ui.intensity_sums_viewBox.roi
89+
90+
##select relevant data in x direction by looking at roi
91+
roi_width = roi.size()[0]
92+
x_roi_min = self.custom_round(roi.pos()[0], self.x_step_size)
93+
x_roi_max = self.custom_round(roi.pos()[0] + roi_width, self.x_step_size)
94+
x_values = np.arange(start=x_roi_min, stop=x_roi_max+self.x_step_size, step=self.x_step_size) #get x values within x range, in x_step_size increments
95+
x_index_min = 0
96+
if x_roi_min != 0: #to avoid divide by 0 error
97+
x_index_min = round(x_roi_min/self.x_step_size) -1
98+
x_index_max = round(x_roi_max/self.x_step_size)+1
99+
column_slice = intensity_sums[:, x_index_min:x_index_max] #get array of data in x range
100+
101+
##select relevant data in y direction by looking at roi
102+
roi_height = roi.size()[1]
103+
y_roi_min = self.custom_round(roi.pos()[1], self.y_step_size)
104+
y_roi_max = self.custom_round(roi.pos()[1] + roi_height, self.y_step_size)
105+
y_range = [y_roi_min, y_roi_max] #get y range of roi
106+
y_index_min = 0
107+
if y_range[0] != 0: #to avoid divide by 0 error
108+
y_index_min = round(y_roi_min/self.y_step_size) -1
109+
y_index_max = round(y_range[1]/self.y_step_size)+1
110+
row_slice = column_slice[y_index_min:y_index_max] #get array of data in y range
111+
112+
#sum intensities along columns
113+
sums_to_plot = np.sum(row_slice, axis=0)
114+
115+
#even with rounding, x_values and sums_to_plot sometimes have slightly uneven lengths
116+
#handle this issue here
117+
if x_values.shape[0] != sums_to_plot.shape[0]:
118+
newshape = min(x_values.shape[0], sums_to_plot.shape[0])
119+
x_values = x_values[0:newshape]
120+
sums_to_plot = sums_to_plot[0:newshape]
121+
122+
try:
123+
roiPlot.plot(x_values, sums_to_plot)
124+
except:
125+
pass
126+
127+
def plot_raw_scan(self):
128+
try:
129+
data = self.pkl_file
130+
self.numb_pixels_X = int((data['Scan Parameters']['X scan size (um)'])/(data['Scan Parameters']['X step size (um)']))
131+
self.numb_pixels_Y = int((data['Scan Parameters']['Y scan size (um)'])/(data['Scan Parameters']['Y step size (um)']))
132+
# TODO test line scan plots
133+
hist_data = data['Histogram data']
134+
135+
self.hist_image = np.reshape(hist_data, newshape=(hist_data.shape[0],self.numb_pixels_X,self.numb_pixels_Y))
136+
time_data = data['Time data']
137+
self.times = time_data[:, 0, 0]*1e-3
138+
self.ui.raw_hist_data_viewBox.view.invertY(False) # stops y-axis invert
139+
self.ui.raw_hist_data_viewBox.setImage(self.hist_image, scale=
140+
(data['Scan Parameters']['X step size (um)'],
141+
data['Scan Parameters']['Y step size (um)']), xvals=self.times)
142+
if self.ui.compare_checkBox.isChecked():
143+
self.ui.imv2.setImage(self.hist_image, scale= (data['Scan Parameters']['X step size (um)'],
144+
data['Scan Parameters']['Y step size (um)']), xvals=self.times)
145+
scale = pg.ScaleBar(size=1,suffix='um')
146+
scale.setParentItem(self.ui.raw_hist_data_viewBox.view)
147+
scale.anchor((1, 1), (1, 1), offset=(-30, -30))
148+
149+
except Exception as err:
150+
print(format(err))
151+
152+
def switch_compare(self):
153+
"""
154+
Handles compare checkbox. If checked, show second ROI that user can use for comparison to first ROI.
155+
"""
156+
if self.ui.compare_checkBox.isChecked():
157+
self.imv2 = pg.ImageView()
158+
if hasattr(self, "hist_image"):
159+
self.imv2.setImage(self.hist_image, scale= (self.pkl_file['Scan Parameters']['X step size (um)'],
160+
self.pkl_file['Scan Parameters']['Y step size (um)']), xvals=self.times)
161+
self.imv2.view.invertY(False) # stop y-axis invert
162+
self.ui.gridLayout.addWidget(self.imv2, 10, 4)
163+
else:
164+
self.ui.gridLayout.removeWidget(self.imv2)
165+
self.imv2.hide()
166+
167+
def save_intensities_image(self):
168+
try:
169+
filename_ext = os.path.basename(self.filename[0])
170+
filename = os.path.splitext(filename_ext)[0] #get filename without extension
171+
save_to = os.getcwd() + "\\" + filename + "_intensity_sums.png"
172+
cpm.plot_confocal(self.intensity_sums, stepsize=np.abs(self.pkl_file['Scan Parameters']['X step size (um)']))
173+
cpm.plt.savefig(save_to, bbox_inches='tight', dpi=300)
174+
except:
175+
pass
176+
177+
def save_intensities_array(self):
178+
try:
179+
filename_ext = os.path.basename(self.filename[0])
180+
filename = os.path.splitext(filename_ext)[0] #get filename without extension
181+
save_to = os.getcwd() + "\\" + filename + "_intensity_sums.txt"
182+
np.savetxt(save_to, self.intensity_sums.T, fmt='%f') #save transpoed intensity sums, as original array handles x in cols and y in rows
183+
except:
184+
pass
185+
186+
def close_application(self):
187+
choice = QtGui.QMessageBox.question(self, 'EXIT!',
188+
"Do you want to exit the app?",
189+
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
190+
if choice == QtGui.QMessageBox.Yes:
191+
sys.exit()
192+
else:
193+
pass
143194

144195
"""Run the Main Window"""
145196
def run():
146-
win = MainWindow()
147-
QtGui.QApplication.instance().exec_()
148-
return win
197+
win = MainWindow()
198+
QtGui.QApplication.instance().exec_()
199+
return win
149200

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

PythonGUI_apps/FLIM_analysis/flim_plot_gui.ui

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@
3232
</property>
3333
</widget>
3434
</item>
35+
<item>
36+
<widget class="QCheckBox" name="line_profile_checkBox">
37+
<property name="text">
38+
<string>Line profile</string>
39+
</property>
40+
</widget>
41+
</item>
3542
<item alignment="Qt::AlignLeft">
3643
<widget class="QPushButton" name="save_intensities_array_pushButton">
3744
<property name="text">

PythonGUI_apps/H5_Pkl/h5_pkl_view.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def setup(self):
4747

4848
self.settings.data_filename.add_listener(self.on_change_data_filename)
4949

50-
# UI Connections
50+
# UI Connections/
5151
self.settings.data_filename.connect_to_browse_widgets(self.ui.data_filename_lineEdit,
5252
self.ui.data_filename_browse_pushButton)
5353

0 commit comments

Comments
 (0)