Skip to content

Commit d97bcf7

Browse files
export mulitple plots and fits to the same export plot w legend; can also do from multiple files
1 parent 6580ad0 commit d97bcf7

File tree

2 files changed

+97
-50
lines changed

2 files changed

+97
-50
lines changed

PythonGUI_apps/Lifetime_analysis/Lifetime_analysis_gui_layout.ui

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
<rect>
77
<x>0</x>
88
<y>0</y>
9-
<width>1490</width>
10-
<height>1583</height>
9+
<width>2620</width>
10+
<height>1676</height>
1111
</rect>
1212
</property>
1313
<property name="windowTitle">
@@ -1071,32 +1071,24 @@
10711071
<string>Export Settings</string>
10721072
</property>
10731073
<layout class="QGridLayout" name="gridLayout_3">
1074-
<item row="2" column="0">
1075-
<widget class="QPushButton" name="export_data_pushButton">
1074+
<item row="0" column="0">
1075+
<widget class="QLabel" name="label_47">
10761076
<property name="text">
1077-
<string>Export data</string>
1077+
<string>For Figure:</string>
10781078
</property>
10791079
</widget>
10801080
</item>
1081-
<item row="1" column="0">
1082-
<widget class="QCheckBox" name="save_w_fit_checkBox">
1083-
<property name="font">
1084-
<font>
1085-
<pointsize>12</pointsize>
1086-
</font>
1087-
</property>
1081+
<item row="6" column="0">
1082+
<widget class="QPushButton" name="export_data_pushButton">
10881083
<property name="text">
1089-
<string>Save with Fit</string>
1090-
</property>
1091-
<property name="checked">
1092-
<bool>true</bool>
1084+
<string>Export Fit Data</string>
10931085
</property>
10941086
</widget>
10951087
</item>
1096-
<item row="2" column="1">
1088+
<item row="6" column="1">
10971089
<widget class="QPushButton" name="clear_export_data_pushButton">
10981090
<property name="text">
1099-
<string>Clear export data</string>
1091+
<string>Clear Export Memory</string>
11001092
</property>
11011093
</widget>
11021094
</item>
@@ -1114,6 +1106,27 @@
11141106
</property>
11151107
</widget>
11161108
</item>
1109+
<item row="5" column="0">
1110+
<widget class="QLabel" name="label_50">
1111+
<property name="text">
1112+
<string>For Data:</string>
1113+
</property>
1114+
</widget>
1115+
</item>
1116+
<item row="1" column="0">
1117+
<widget class="QLineEdit" name="lineEdit">
1118+
<property name="text">
1119+
<string>Enter Legend Here...</string>
1120+
</property>
1121+
</widget>
1122+
</item>
1123+
<item row="1" column="1">
1124+
<widget class="QPushButton" name="add_to_mem_pushButton">
1125+
<property name="text">
1126+
<string>Add trace to memory</string>
1127+
</property>
1128+
</widget>
1129+
</item>
11171130
</layout>
11181131
</widget>
11191132
</item>
@@ -1214,6 +1227,9 @@
12141227
</item>
12151228
<item row="0" column="1">
12161229
<widget class="QComboBox" name="Res_comboBox">
1230+
<property name="enabled">
1231+
<bool>false</bool>
1232+
</property>
12171233
<property name="font">
12181234
<font>
12191235
<pointsize>12</pointsize>
@@ -1324,7 +1340,7 @@
13241340
<rect>
13251341
<x>0</x>
13261342
<y>0</y>
1327-
<width>1490</width>
1343+
<width>2620</width>
13281344
<height>38</height>
13291345
</rect>
13301346
</property>

PythonGUI_apps/Lifetime_analysis/Lifetime_plot_fit.py

Lines changed: 62 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ def __init__(self):
8181
self.ui.FittingFunc_comboBox.currentTextChanged.connect(self.switch_function_tab)
8282
self.ui.FittingMethod_comboBox.currentTextChanged.connect(self.switch_init_params_groupBox)
8383
self.ui.separate_irf_checkBox.stateChanged.connect(self.switch_open_irf)
84+
self.ui.add_to_mem_pushButton.clicked.connect(self.add_trace_to_mem)
8485
self.ui.export_data_pushButton.clicked.connect(self.export_data)
8586
self.ui.clear_export_data_pushButton.clicked.connect(self.clear_export_data)
8687
self.ui.smoothData_checkBox.stateChanged.connect(self.smooth_trace_enabled)
@@ -94,6 +95,11 @@ def __init__(self):
9495
self.file = None
9596
self.out = None # output file after fitting
9697
self.data_list = []
98+
self.fit_lifetime_called = False
99+
self.x_mem = [] # containers for adding x data to memory
100+
self.y_mem = [] # containers for adding y data to memory
101+
self.best_fit_mem = [] # containers for adding best fit data to memory
102+
self.legend = [] # containers for adding legend to memory
97103

98104
#variables accounting for data received from FLIM analysis
99105
self.opened_from_flim = False #switched to True in FLIM_plot when "analyze lifetime" clicked
@@ -109,6 +115,7 @@ def open_file(self):
109115
if ".csv" in self.filename[0] or ".txt" in self.filename[0]: #if txt or csv, prompt user to enter # of rows to skip
110116
self.skip_rows_window = SkipRowsWindow()
111117
self.skip_rows_window.skip_rows_signal.connect(self.open_with_skip_rows_window)
118+
self.ui.Res_comboBox.setEnabled(True)
112119
else:
113120
self.file = read_picoharp_phd(self.filename[0])
114121
self.opened_from_flim = False
@@ -130,6 +137,7 @@ def open_irf_file(self):
130137
if ".txt" in self.irf_filename[0] or ".csv" in self.irf_filename[0]:
131138
self.irf_skip_rows_window = SkipRowsWindow()
132139
self.irf_skip_rows_window.skip_rows_signal.connect(self.open_irf_with_skip_rows_window)
140+
self.ui.Res_comboBox.setEnabled(True)
133141
else:
134142
self.irf_file = read_picoharp_phd(self.irf_filename[0])
135143
except:
@@ -207,7 +215,6 @@ def acquire_settings(self, mode="data"):
207215
208216
mode -- string specifying whether to use data or irf channel (default "data")
209217
"""
210-
self.resolution = float(self.ui.Res_comboBox.currentText())
211218
if mode == "data":
212219
channel = int(self.ui.Data_channel_spinBox.value())
213220
elif mode == "irf":
@@ -221,17 +228,23 @@ def acquire_settings(self, mode="data"):
221228
y = self.irf_file.get_curve(channel)[1]
222229
else: #otherwise, get data/irf from data file
223230
y = self.file[:,channel]
231+
232+
self.resolution = float(self.ui.Res_comboBox.currentText())
224233
except:
225234
res, y = self.file.get_curve(channel)
226-
# TO DO - check if res read in is the same as selected
227235
time_window = int(np.floor(self.file.get_time_window_in_ns(channel)))
228236
y = y[0:time_window]
237+
self.resolution = res
229238

230239
length = np.shape(y)[0]
231-
x = np.arange(0, length, 1) * self.resolution
240+
x = np.arange(0, length*self.resolution, self.resolution, np.float)
232241

233242
if self.ui.smoothData_checkBox.isChecked() and mode=="data":
234243
y = np.convolve(y, np.ones(self.ui.smoothData_spinBox.value())/self.ui.smoothData_spinBox.value(), mode="same")
244+
245+
if self.ui.normalize_checkBox.isChecked():
246+
y = y / np.amax(y)
247+
235248
return x,y
236249

237250
except Exception as e:
@@ -243,10 +256,9 @@ def plot(self):
243256
x, y = self.hist_data_from_flim
244257
else:
245258
x,y = self.acquire_settings() #get data
246-
if self.ui.normalize_checkBox.isChecked():
247-
y = y / np.amax(y)
248259

249260
self.ui.plot.plot(x, y, clear=self.ui.clear_plot_checkBox.isChecked(), pen=pg.mkPen(self.plot_color))
261+
self.fit_lifetime_called = False
250262

251263
try:
252264
self.ui.Result_textBrowser.setText("Integral Counts :\n" "{:.2E}".format(
@@ -335,7 +347,8 @@ def fit_and_plot(self):
335347

336348
#add fit params to data_list
337349
self.data_list.append("Data Channel: " + str(self.ui.Data_channel_spinBox.value()) + "\n" + self.ui.Result_textBrowser.toPlainText())
338-
350+
self.fit_lifetime_called = True
351+
339352
self.ui.plot.setLabel('left', 'Intensity', units='a.u.')
340353
self.ui.plot.setLabel('bottom', 'Time (ns)')
341354
return self.out
@@ -462,7 +475,7 @@ def fit_and_plot_with_irf(self):
462475

463476
#add fit params to data_list
464477
self.data_list.append("Data Channel: " + str(self.ui.Data_channel_spinBox.value()) + "\n" + self.ui.Result_textBrowser.toPlainText())
465-
478+
self.fit_lifetime_called = True
466479
except Exception as e:
467480
self.ui.Result_textBrowser.append(format(e))
468481

@@ -528,39 +541,57 @@ def export_data(self):
528541

529542
def clear_export_data(self):
530543
self.data_list = []
544+
self.clean_up_after_fig_export()
545+
546+
def clean_up_after_fig_export(self):
547+
self.x_mem = []
548+
self.y_mem = []
549+
self.legend = []
550+
self.best_fit_mem = []
551+
552+
def add_trace_to_mem(self):
553+
try:
554+
if self.fit_lifetime_called == True:
555+
self.x_mem.append(self.out[:,0])
556+
self.y_mem.append(self.out[:,1])
557+
self.best_fit_mem.append(self.out[:,2])
558+
else:
559+
self.x_mem.append(self.acquire_settings()[0])
560+
self.y_mem.append(self.acquire_settings()[1])
561+
self.legend.append(self.ui.lineEdit.text())
562+
except Exception as e:
563+
print(e)
531564

532565
def export_window(self):
533566
self.exportplotwindow = ExportPlotWindow()
534567
self.exportplotwindow.export_fig_signal.connect(self.pub_ready_plot_export)
535568

536569
def pub_ready_plot_export(self):
537-
#TODO - get all curves from the plotwidget
538-
#item = self.ui.plot.listDataItems()[0]
539-
#print(self.ui.plot.getData(self))
540570
try:
541-
filename = QtWidgets.QFileDialog.getSaveFileName(self,caption="Filename with EXTENSION")
571+
if self.x_mem == []:
572+
self.ui.result_textBrowser.setText("Add traces to memory first!")
542573

543-
plt.figure(figsize=(8,6))
544-
plt.tick_params(direction='out', length=8, width=3.5)
545-
if self.ui.save_w_fit_checkBox.isChecked():
546-
plt.plot(self.out[:,0],self.out[:,1]/np.max(self.out[:,1]),self.exportplotwindow.ui.traceColor_comboBox.currentText())
547-
plt.plot(self.out[:,0],self.out[:,2]/np.max(self.out[:,1]),self.exportplotwindow.ui.fitColor_comboBox.currentText())
548-
if self.exportplotwindow.ui.legend_checkBox.isChecked():
549-
plt.legend([self.exportplotwindow.ui.legend1_lineEdit.text(),self.exportplotwindow.ui.legend2_lineEdit.text()])
550574
else:
551-
plt.plot(self.acquire_settings()[0],self.acquire_settings()[1]/np.max(self.acquire_settings()[1]),
552-
self.exportplotwindow.ui.traceColor_comboBox.currentText())
553-
if self.exportplotwindow.ui.legend_checkBox.isChecked():
554-
plt.legend([self.exportplotwindow.ui.legend1_lineEdit.text()])
555-
plt.yscale('log')
556-
plt.xlabel("Time (ns)", fontsize=20, fontweight='bold')
557-
plt.ylabel("Intensity (norm.)", fontsize=20, fontweight='bold')
558-
plt.tight_layout()
559-
plt.xlim([self.exportplotwindow.ui.lowerX_spinBox.value(),self.exportplotwindow.ui.upperX_spinBox.value()])
560-
plt.ylim([self.exportplotwindow.ui.lowerY_spinBox.value(),self.exportplotwindow.ui.upperY_doubleSpinBox.value()])
561-
562-
plt.savefig(filename[0],bbox_inches='tight', dpi=300)
563-
plt.close()
575+
filename = QtWidgets.QFileDialog.getSaveFileName(self,caption="Filename with EXTENSION")
576+
577+
plt.figure(figsize=(8,6))
578+
plt.tick_params(direction='out', length=8, width=3.5)
579+
for i in range(len(self.x_mem)):
580+
plt.plot(self.x_mem[i], self.y_mem[i], label=str(self.legend[i]))
581+
if self.fit_lifetime_called == True:
582+
plt.plot(self.x_mem[i], self.best_fit_mem[i],'k--')
583+
584+
plt.yscale('log')
585+
plt.xlabel("Time (ns)", fontsize=20, fontweight='bold')
586+
plt.ylabel("Intensity (norm.)", fontsize=20, fontweight='bold')
587+
plt.legend()
588+
plt.tight_layout()
589+
plt.xlim([self.exportplotwindow.ui.lowerX_spinBox.value(),self.exportplotwindow.ui.upperX_spinBox.value()])
590+
plt.ylim([self.exportplotwindow.ui.lowerY_spinBox.value(),self.exportplotwindow.ui.upperY_doubleSpinBox.value()])
591+
592+
plt.savefig(filename[0],bbox_inches='tight', dpi=300)
593+
plt.close()
594+
self.clean_up_after_fig_export()
564595

565596
except Exception as e:
566597
self.ui.Result_textBrowser.append(format(e))

0 commit comments

Comments
 (0)