2525WindowTemplate , TemplateBaseClass = pg .Qt .loadUiType (uiFile )
2626
2727class 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"""
145196def 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()
0 commit comments