class ScanningConfocalUI: def __del__(self): self.ui = None def show(self): #self.ui.exec_() self.ui.show() def __init__(self): ui_loader = QtUiTools.QUiLoader() print os.path.join(__file__, "scanning_confocal_mcl_ni.ui") ui_file = QtCore.QFile("scanning_confocal_mcl_ni.ui") ui_file.open(QtCore.QFile.ReadOnly) self.ui = ui_loader.load(ui_file) ui_file.close() self.HARDWARE_DEBUG = HARDWARE_DEBUG self.fig2d = Figure() self.ax2d = self.fig2d.add_subplot(111) self.ax2d.plot([0, 1]) self.canvas2d = FigureCanvas(self.fig2d) self.ui.plot2D_verticalLayout.addWidget(self.canvas2d) self.navtoolbar_plot2d = NavigationToolbar2(self.canvas2d, self.ui) self.ui.plot2D_verticalLayout.addWidget(self.navtoolbar_plot2d) self.fig_opt = Figure() self.ax_opt = self.fig_opt.add_subplot(111) self.canvas_opt = FigureCanvas(self.fig_opt) self.ui.plot_optimize_verticalLayout.addWidget(self.canvas_opt) self.navtoolbar_plot_opt = NavigationToolbar2(self.canvas_opt, self.ui) self.ui.plot_optimize_verticalLayout.addWidget( self.navtoolbar_plot_opt) self.optimize_history = np.zeros(OPTIMIZE_HISTORY_LEN, dtype=np.float) self.optimize_ii = 0 self.optimize_line, = self.ax_opt.plot(self.optimize_history) self.optimize_current_pos = self.ax_opt.axvline(self.optimize_ii, color='r') ##################### hardware ######################################### self.scanning = False ######## MCL NanoDrive Stage ########################################### self.nanodrive = MCLNanoDrive(debug=self.HARDWARE_DEBUG) try: self.hmax = self.nanodrive.cal[HAXIS_ID] self.vmax = self.nanodrive.cal[VAXIS_ID] self.ui.maxdim_label.setText("%s - %s scan. Max: %g x %g um" % (HAXIS, VAXIS, self.hmax, self.vmax)) except Exception as e: print e self.ui.maxdim_label.setText("max: ? x ? um") # Logged Quantities self.x_position = LoggedQuantity(name='x_position', dtype=np.float) self.y_position = LoggedQuantity(name='y_position', dtype=np.float) self.z_position = LoggedQuantity(name='z_position', dtype=np.float) #self.x_position.updated_value.connect(self.ui.cx_lcdNumber.display) self.x_position.updated_value.connect( self.ui.cx_doubleSpinBox.setValue) self.ui.x_set_lineEdit.returnPressed.connect( self.x_position.update_value) #self.y_position.updated_value.connect(self.ui.cy_lcdNumber.display) self.y_position.updated_value.connect( self.ui.cy_doubleSpinBox.setValue) self.ui.y_set_lineEdit.returnPressed.connect( self.y_position.update_value) #self.z_position.updated_value.connect(self.ui.cz_lcdNumber.display) self.z_position.updated_value.connect( self.ui.cz_doubleSpinBox.setValue) self.ui.z_set_lineEdit.returnPressed.connect( self.z_position.update_value) self.x_position.hardware_set_func = lambda x: self.nanodrive.set_pos_ax( x, MCL_AXIS_ID["X"]) self.y_position.hardware_set_func = lambda y: self.nanodrive.set_pos_ax( y, MCL_AXIS_ID["Y"]) self.z_position.hardware_set_func = lambda z: self.nanodrive.set_pos_ax( z, MCL_AXIS_ID["Z"]) ####### NI (apd) counter readout ################################## self.ni_counter = NI_FreqCounter(debug=self.HARDWARE_DEBUG) self.apd_count_rate = LoggedQuantity(name='apd_count_rate', dtype=np.float, fmt="%e") self.apd_count_rate.updated_text_value.connect( self.ui.apd_counter_output_lineEdit.setText) ######################################################################## self.read_stage_position() self.read_ni_countrate() self.update_display() # update figure self.ax2d.set_xlim(0, self.hmax) self.ax2d.set_ylim(0, self.vmax) # events self.ui.scan_start_pushButton.clicked.connect(self.on_scan_start) self.ui.scan_stop_pushButton.clicked.connect(self.on_scan_stop) self.ui.fast_update_checkBox.stateChanged.connect( self.on_fast_timer_checkbox) self.ui.clearfig_pushButton.clicked.connect(self.on_clearfig) ### timers self.slow_display_timer = QtCore.QTimer(self.ui) self.slow_display_timer.timeout.connect(self.on_slow_display_timer) self.slow_display_timer.start(TIMER_MS) self.fast_timer = QtCore.QTimer(self.ui) self.fast_timer.timeout.connect(self.on_fast_timer) self.display_update_when_scanning_timer = QtCore.QTimer(self.ui) self.display_update_when_scanning_timer.timeout.connect( self.on_display_update_when_scanning_timer) @QtCore.Slot() def on_clearfig(self): self.fig2d.clf() self.ax2d = self.fig2d.add_subplot(111) self.ax2d.plot([0, 1]) # update figure self.ax2d.set_xlim(0, self.hmax) self.ax2d.set_ylim(0, self.vmax) self.fig2d.canvas.draw() def read_stage_position(self): self.stage_pos = self.nanodrive.get_pos() return self.stage_pos def read_ni_countrate(self, int_time=0.01): try: self.ni_counter.start() time.sleep(int_time) self.c0_rate = self.ni_counter.read_average_freq_in_buffer() except Exception as E: print E #self.ni_counter.reset() finally: self.ni_counter.stop() def update_display(self): self.x_position.update_value(self.stage_pos[MCL_AXIS_ID["X"] - 1], update_hardware=False) self.y_position.update_value(self.stage_pos[MCL_AXIS_ID["Y"] - 1], update_hardware=False) self.z_position.update_value(self.stage_pos[MCL_AXIS_ID["Z"] - 1], update_hardware=False) self.apd_count_rate.update_value(self.c0_rate) @QtCore.Slot() def on_slow_display_timer(self): self.read_stage_position() self.read_ni_countrate(int_time=0.01) self.update_display() @QtCore.Slot() def on_fast_timer(self): try: self.c0_rate = self.ni_counter.read_average_freq_in_buffer() except Exception as E: self.c0_rate = -1 self.apd_count_rate.update_value(self.c0_rate) #print self.c0_rate self.optimize_ii += 1 self.optimize_ii %= OPTIMIZE_HISTORY_LEN ii = self.optimize_ii self.optimize_history[ii] = self.c0_rate self.optimize_line.set_ydata(self.optimize_history) self.optimize_current_pos.set_xdata((ii, ii)) if (ii % 10) == 0: self.ax_opt.relim() self.ax_opt.autoscale_view(scalex=False, scaley=True) #print "redraw" self.fig_opt.canvas.draw() @QtCore.Slot(bool) def on_fast_timer_checkbox(self, fast_timer_enable): if fast_timer_enable: self.fast_timer.start(100) print "fast timer start" else: self.fast_timer.stop() print "fast timer stop" @QtCore.Slot() def on_scan_start(self): print "start scan" self.scanning = True QtGui.QApplication.processEvents() #get scan parameters: self.h0 = self.ui.h0_doubleSpinBox.value() self.h1 = self.ui.h1_doubleSpinBox.value() self.v0 = self.ui.v0_doubleSpinBox.value() self.v1 = self.ui.v1_doubleSpinBox.value() self.dh = 1e-3 * self.ui.dh_spinBox.value() self.dv = 1e-3 * self.ui.dv_spinBox.value() self.h_array = np.arange(self.h0, self.h1, self.dh, dtype=float) self.v_array = np.arange(self.v0, self.v1, self.dv, dtype=float) self.Nh = len(self.h_array) self.Nv = len(self.v_array) self.pixel_time = self.ui.pixel_time_doubleSpinBox.value() self.extent = [self.h0, self.h1, self.v0, self.v1] ### create data arrays self.count_rate_map = np.zeros((self.Nv, self.Nh), dtype=np.float) print "shape:", self.count_rate_map.shape print "Nh, Nv", self.Nh, self.Nv ### update figure self.ax_2d_img = self.ax2d.imshow(self.count_rate_map, origin='lower', vmin=1e4, vmax=1e5, interpolation='nearest', extent=self.extent) self.fig2d.canvas.draw() self.slow_display_timer.stop() #stop the slow delay timer #display_timer_update = 0.5*self.pixel_time*1e3 #if display_timer_update < 200 self.display_update_when_scanning_timer.start(100) self.ni_counter.stop() self.ni_counter.start() # Scan! line_time0 = time.time() for i_v in range(self.Nv): if not self.scanning: break self.v_pos = self.v_array[i_v] self.nanodrive.set_pos_ax(self.v_pos, VAXIS_ID) self.read_stage_position() print "line time:", time.time() - line_time0 print "pixel time:", float(time.time() - line_time0) / self.Nh line_time0 = time.time() if i_v % 2: #odd lines h_line_indicies = range(self.Nh) else: #even lines -- traverse in oposite direction h_line_indicies = range(self.Nh)[::-1] for i_h in h_line_indicies: if not self.scanning: break self.h_pos = self.h_array[i_h] self.nanodrive.set_pos_ax(self.h_pos, HAXIS_ID) time0 = time.time() while time.time() - time0 < self.pixel_time: QtGui.QApplication.processEvents() #release self.c0_rate = self.ni_counter.read_average_freq_in_buffer() if np.isnan(self.c0_rate): self.c0_rate = 0 #self.count_rate_map[i_v,i_h] = counts[-1] # grab integration time for now self.count_rate_map[i_v, i_h] = self.c0_rate # grab count0 rate """self.ccd.start_acquisition() stat = "ACQUIRING" while stat!= "IDLE": wx_yielded_sleep(self.ccd.exposure_time * 0.25) stati, stat = self.ccd.get_status() self.ccd.get_acquired_data() spectrum = np.sum(self.ccd.buffer[ROW0:ROW1], axis=0) self.spectrum_map[jj,ii,:] = spectrum self.integrated_count_map[jj,ii] = sum(spectrum) """ self.on_scan_stop() @QtCore.Slot() def on_scan_stop(self): print "on_scan_stop" self.scanning = False self.ni_counter.stop() self.update_display() self.slow_display_timer.start() #restart the normal timer self.display_update_when_scanning_timer.stop() # clean up after scan self.ax_2d_img.set_data(self.count_rate_map) self.fig2d.canvas.draw() self.update_display() self.scanning = False print "scanning done" print "saving data..." t0 = time.time() np.savetxt("%i_confocal_scan.csv" % t0, self.count_rate_map, delimiter=',') save_params = [ "h0", "h1", "v0", "v1", "Nh", "Nv", "h_array", "v_array", "dh", "dv", "count_rate_map", "pixel_time" ] save_dict = dict() for key in save_params: save_dict[key] = getattr(self, key) for key in [ "HAXIS", "VAXIS", "HARDWARE_DEBUG", ]: save_dict[key] = globals()[key] # for key in ["wl", "gratings", "grating"]: # save_dict["spec_"+key] = getattr(self.spec, key) # for key in ["exposure_time", "em_gain", "temperature", "ad_chan", "ro_mode", "Nx", "Ny"]: # save_dict["andor_"+key] = getattr(self.ccd, key) save_dict["time_saved"] = t0 np.savez_compressed("%i_confocal_scan.npz" % t0, **save_dict) print "data saved" @QtCore.Slot() def on_display_update_when_scanning_timer(self): # update display try: self.update_display() except Exception, err: print "Failed to update_display", err try: #self.spec_plotline.set_ydata(spectrum) #self.ax_speclive.relim() #self.ax_speclive.autoscale_view(tight=None, scalex=False, scaley=True) #self.fig2.canvas.draw() pass except Exception as err: print "Failed to update spectrum plot", err try: #print "updating figure" #self.read_from_hardware() self.ax_2d_img.set_data(self.count_rate_map) try: count_min = np.min(self.count_rate_map[np.nonzero( self.count_rate_map)]) except Exception as err: count_min = 0 count_max = np.max(self.count_rate_map) self.ax_2d_img.set_clim(count_min, count_max + 1) self.fig2d.canvas.draw() except Exception, err: print "Failed to update figure:", err
class ScanningTRPLHistMapApp(wx.App): def OnInit(self): print "OnInit" self.HARDWARE_DEBUG = HARDWARE_DEBUG self.STORED_HISTCHAN = 4000 #65535 self.frame = ScanningTRPLControlFrame(None) # Logged Quantities self.x_position = LoggedQuantity( name='x_position', dtype=np.float, display_textctrl=self.frame.m_textCtrl_current_x, input_textctrl=self.frame.m_textCtrl_set_current_x) self.y_position = LoggedQuantity( name='y_position', dtype=np.float, display_textctrl=self.frame.m_textCtrl_current_y, input_textctrl=self.frame.m_textCtrl_set_current_y) # Figure self.wxfig = MPLFigureWithToolbarWX(self.frame.m_panel_plot) self.fig = self.wxfig.fig self.ax = self.fig.add_subplot(111) # Optimization Fig self.fig2 = pl.figure(2) self.ax2 = self.fig2.add_subplot(111) self.c0_hist_line, = self.ax2.plot(np.zeros(HIST_LEN, dtype=float)) self.c1_hist_line, = self.ax2.plot(np.zeros(HIST_LEN, dtype=float)) self.hist_vline = self.ax2.axvline(0) self.c0_hist = np.zeros(HIST_LEN, dtype=float) self.c1_hist = np.zeros(HIST_LEN, dtype=float) self.fig2.show() self.hist_i = 0 # hardware self.scanning = False # FOR DEPTH SCAN: MCL axis Y = plot X, MCL axis Z = plot Y self.nanodrive = MCLNanoDrive(debug=self.HARDWARE_DEBUG) try: self.frame.m_staticText_maxdim.SetLabel( "max: x %g x z %g um" % (self.nanodrive.cal_Y, self.nanodrive.cal_Z)) except Exception as e: print e self.frame.m_staticText_maxdim.SetLabel("max: ? x ? um") #self.frame.m_staticText_maxdim.SetLabel("max: 75 x 75 um") #self.srslockin = SRSlockin(port="COM5", gpibaddr=8) #self.lockinstage = LockinStage(srs=self.srslockin, # POSMIN=0, POSMAX=75, channels={'x':1, 'y':2, 'z':3}) self.picoharp = PicoHarp300(devnum=0, debug=self.HARDWARE_DEBUG) self.read_from_hardware() #self.x_position.hardware_set_func = lambda x: self.lockinstage.setx(x) #self.y_position.hardware_set_func = lambda y: self.lockinstage.sety(y) self.x_position.hardware_set_func = lambda x: self.nanodrive.set_pos_ax( x, YAXIS) self.y_position.hardware_set_func = lambda y: self.nanodrive.set_pos_ax( y, ZAXIS) # update figure self.ax.set_xlim(0, self.nanodrive.cal_Y) self.ax.set_ylim(0, self.nanodrive.cal_Z) #self.ax.set_xlim(0, 75) #self.ax.set_ylim(0, 75) # events self.frame.Bind(wx.EVT_BUTTON, self.on_start_scan, self.frame.m_button_start) self.frame.Bind(wx.EVT_BUTTON, self.on_stop_scan, self.frame.m_button_stop) self.timer = wx.Timer(id=2001) self.timer.Bind(wx.EVT_TIMER, self.on_timer) self.timer.Start(2000) self.fast_timer = wx.Timer(id=2002) self.fast_timer.Bind(wx.EVT_TIMER, self.on_fast_timer) self.frame.m_checkBox_picoharp_fastreadout.Bind( wx.EVT_CHECKBOX, self.on_fast_timer_checkbox) self.update_display() self.frame.Show() return True def on_timer(self, e): self.read_from_hardware() self.update_display() def on_fast_timer(self, e): self.picoharp.read_count_rates() self.frame.m_textCtrl_count0.SetValue(str(self.picoharp.Countrate0)) self.frame.m_textCtrl_count1.SetValue(str(self.picoharp.Countrate1)) self.c0_hist[self.hist_i] = self.picoharp.Countrate0 self.c1_hist[self.hist_i] = self.picoharp.Countrate1 #self.c0_hist_line.set_ydata(self.c0_hist) self.c1_hist_line.set_ydata(self.c1_hist) self.hist_vline.set_xdata([self.hist_i] * 2) self.hist_i += 1 self.hist_i %= HIST_LEN if (self.hist_i % 10) == 0: self.ax2.relim() self.ax2.autoscale_view(scalex=False, scaley=True) #self.ax2.autoscale() self.fig2.canvas.draw() def on_fast_timer_checkbox(self, e): fast_timer_enable = self.frame.m_checkBox_picoharp_fastreadout.GetValue( ) if fast_timer_enable: self.fast_timer.Start(100) else: self.fast_timer.Stop() def on_start_scan(self, e): print "start scan" self.scanning = True # get scan parameters: self.x0 = float(self.frame.m_textCtrl_x0.GetValue()) self.x1 = float(self.frame.m_textCtrl_x1.GetValue()) self.y0 = float(self.frame.m_textCtrl_y0.GetValue()) self.y1 = float(self.frame.m_textCtrl_y1.GetValue()) self.dx = float(self.frame.m_textCtrl_dx.GetValue()) / 1000. self.dy = float(self.frame.m_textCtrl_dy.GetValue()) / 1000. self.x_array = np.arange(self.x0, self.x1, self.dx, dtype=float) self.y_array = np.arange(self.y0, self.y1, self.dy, dtype=float) self.Nx = len(self.x_array) self.Ny = len(self.y_array) print "Nx, Ny", self.Nx, self.Ny self.tacq = int(float(self.frame.m_textCtrl_tacq.GetValue()) * 1000) self.phrange = int(self.frame.m_textCtrl_phrange.GetValue()) self.phoffset = int(self.frame.m_textCtrl_phoffset.GetValue()) self.syncdiv = int( self.frame.m_choice_syncdivider.GetString( self.frame.m_choice_syncdivider.GetSelection())) self.zerocross0 = int(self.frame.m_spinCtrl_zerocross0.GetValue()) self.zerocross1 = int(self.frame.m_spinCtrl_zerocross0.GetValue()) self.level0 = int(self.frame.m_textCtrl_level0.GetValue()) self.level1 = int(self.frame.m_textCtrl_level1.GetValue()) # create data arrays #self.integrated_count_map_c0 = np.zeros((self.Nx, self.Ny), dtype=int) self.integrated_count_map_c1 = np.zeros((self.Ny, self.Nx), dtype=int) self.time_trace_map = np.zeros( (self.Ny, self.Nx, self.STORED_HISTCHAN), dtype=int) print "shape:", self.integrated_count_map_c1.shape, self.time_trace_map.shape #update figure self.aximg = self.ax.imshow( self.integrated_count_map_c1, origin='lower', vmin=1e4, vmax=1e5, interpolation='nearest', extent=[self.x0, self.x1, self.y0, self.y1]) self.wxfig.redraw() # set up experiment self.picoharp.setup_experiment(Range=self.phrange, Offset=self.phoffset, Tacq=self.tacq, SyncDivider=self.syncdiv, CFDZeroCross0=self.zerocross0, CFDLevel0=self.level0, CFDZeroCross1=self.zerocross1, CFDLevel1=self.level1) self.resolution = self.picoharp.Resolution line_time0 = time.time() for jj in range(self.Ny): #self.nanodrive.SetY(self.y_array[j]) if not self.scanning: break y = self.y_array[jj] #self.lockinstage.sety(y) #self.read_from_hardware() self.nanodrive.set_pos_ax(y, ZAXIS) self.read_from_hardware() y = self.ypos print "line time:", time.time() - line_time0 print "pixel time:", float(time.time() - line_time0) / len( self.x_array) line_time0 = time.time() if jj % 2: #odd lines x_line_indicies = range(self.Nx) else: #even lines -- traverse in opposite direction x_line_indicies = range(self.Nx)[::-1] for ii in x_line_indicies: #for ii in range(self.Nx): if not self.scanning: break x = self.xpos = self.x_array[ii] wx.Yield() #self.nanodrive.SetX(self.x_array[i]) #self.nanodrive.set_pos(x, y) #print "nanodrive set_pos: ", x, y #self.lockinstage.setx(x) self.nanodrive.set_pos_ax(x, YAXIS) #if self.HARDWARE_DEBUG: print "lockin stage moved to ", x, y ph = self.picoharp ph.start_histogram(Tacq=self.tacq) while not ph.check_done_scanning(): wx.Yield() ph.stop_histogram() hist_data = ph.read_histogram_data() self.time_trace_map[jj, ii, :] = hist_data[0:self.STORED_HISTCHAN] self.integrated_count_map_c1[jj, ii] = sum(hist_data) #x1, y1 = self.nanodrive.get_pos() #print "get pos: ", x1,y1 # update display try: self.update_display() except Exception, err: print "Failed to update_display", err if not (ii % 5): #self.update_figure() try: #print "updating figure" #self.read_from_hardware() self.aximg.set_data(self.integrated_count_map_c1) try: count_min = np.min( self.integrated_count_map_c1[np.nonzero( self.integrated_count_map_c1)]) except Exception as err: count_min = 0 count_max = np.max(self.integrated_count_map_c1) self.aximg.set_clim(count_min, count_max + 1) self.wxfig.redraw() except Exception, err: print "Failed to update figure:", err
class Confocal3DScanNI(object): INPUT_PARAM_NAMES = """x0 x1 dx y0 y1 dy z0 z1 dz t_exposure axis_scan_order mcl_axis_translation""".split() def __init__(self, **params): for p in self.INPUT_PARAM_NAMES: setattr(self, p, params[p]) self.x_array = np.arange(self.x0, self.x1, self.dx, dtype=float) self.y_array = np.arange(self.y0, self.y1, self.dy, dtype=float) self.z_array = np.arange(self.z0, self.z1, self.dz, dtype=float) self.Nx = len(self.x_array) self.Ny = len(self.y_array) self.Nz = len(self.z_array) self.mcl_axis_translation = xyz_tuple(*self.mcl_axis_translation) self.HARDWARE_DEBUG = False #HARDWARE self.nanodrive = MCLNanoDrive(debug=self.HARDWARE_DEBUG) self.freq_counter = NI_FreqCounter(debug=self.HARDWARE_DEBUG) #DATA ARRAYS self.count_freq_map = np.zeros(( self.Nz, self.Ny, self.Nx, ), dtype=np.float64) def run_3d_scan(self): self.set_ijk = (-1, -1, -1) self.scanning = True time0 = time.time() self.freq_counter.read_freq_buffer() #flush buffer for iii, ijk in enumerate( ijk_generator((self.Nx, self.Ny, self.Nz), self.axis_scan_order)): #previous ijk ip, jp, kp = self.set_ijk # new ijk i, j, k = ijk # move stage if i != ip: x = self.x_array[i] self.nanodrive.set_pos_ax(x, self.mcl_axis_translation.x) if j != jp: y = self.y_array[j] self.nanodrive.set_pos_ax(y, self.mcl_axis_translation.y) if k != kp: z = self.z_array[k] self.nanodrive.set_pos_ax(z, self.mcl_axis_translation.z) self.set_ijk = ijk #t1 = time.time() self.read_from_hardware() #print "read_from_hardware (s)", time.time() - t1 #t1 = time.time() time.sleep(self.t_exposure) freq = self.freq_counter.read_average_freq_in_buffer() #print "counter acquire (s)", time.time() - t1 cts = self.count_freq_map[k, j, i] = freq REPORT_INTERVAL = 10 if ((i + j + k) % REPORT_INTERVAL) == 0: print ijk, cts t_now = time.time() pixel_time = (t_now - time0) / REPORT_INTERVAL print "sec per pixel:", pixel_time, "| time remaining (s)", (( (self.Nx * self.Ny * self.Nz) - iii) * pixel_time) time0 = t_now #Finish up after scan print "saving data..." save_params = self.INPUT_PARAM_NAMES + [ "count_freq_map", "Nx", "Ny", "Nz", "x_array", "y_array", "z_array" ] save_dict = dict() for key in save_params: save_dict[key] = getattr(self, key) t0 = time.time() save_fname = "%i_confocal3d.npz" % t0 np.savez_compressed(save_fname, **save_dict) print "data saved as %s" % save_fname def read_from_hardware(self): pos = self.nanodrive.get_pos() self.xpos = pos[self.mcl_axis_translation.x - 1] self.ypos = pos[self.mcl_axis_translation.y - 1] self.zpos = pos[self.mcl_axis_translation.z - 1]
class ScanningTRPLHistMapApp(wx.App): def OnInit(self): print "OnInit" self.HARDWARE_DEBUG = HARDWARE_DEBUG self.frame = ScanningSpectrumControlFrame(None) # Logged Quantities self.x_position = LoggedQuantity( name='x_position', dtype=np.float, display_textctrl=self.frame.m_textCtrl_current_x, input_textctrl=self.frame.m_textCtrl_set_current_x) self.y_position = LoggedQuantity( name='y_position', dtype=np.float, display_textctrl=self.frame.m_textCtrl_current_y, input_textctrl=self.frame.m_textCtrl_set_current_y) # Figure ############################################################### self.wxfig = MPLFigureWithToolbarWX(self.frame.m_panel_plot) self.fig = self.wxfig.fig self.ax = self.fig.add_subplot(111) # Spectrum Fig self.fig2 = pl.figure(2) self.ax_speclive = self.fig2.add_subplot(111) #self.c0_hist_line, = self.ax2.plot(np.zeros(HIST_LEN,dtype=float)) #self.c1_hist_line, = self.ax2.plot(np.zeros(HIST_LEN,dtype=float)) #self.hist_vline = self.ax2.axvline(0) #self.c0_hist = np.zeros(HIST_LEN,dtype=float) #self.c1_hist = np.zeros(HIST_LEN,dtype=float) self.fig2.show() #self.history_i = 0 self.spec_plotline, = self.ax_speclive.plot(range(0, 512), range(0, 512)) ##################### hardware ######################################### self.scanning = False ######## MCL NanoDrive Stage ########################################### self.nanodrive = MCLNanoDrive(debug=self.HARDWARE_DEBUG) try: self.frame.m_staticText_maxdim.SetLabel( "max: %g x %g um" % (self.nanodrive.cal[XAXIS_ID], self.nanodrive.cal[YAXIS_ID])) except Exception as e: print e self.frame.m_staticText_maxdim.SetLabel("max: ? x ? um") self.read_from_hardware() self.x_position.hardware_set_func = lambda x: self.nanodrive.set_pos_ax( x, XAXIS_ID) self.y_position.hardware_set_func = lambda y: self.nanodrive.set_pos_ax( y, YAXIS_ID) #Spectrometer ########################################################## self.spec = ActonSpectrometer(port=SPEC_COMM_PORT, debug=self.HARDWARE_DEBUG, dummy=False) print self.spec.read_grating_info() self.frame.m_choice_spec_grating.Clear() for gnum, gname in self.spec.gratings: self.frame.m_choice_spec_grating.Append("%i %s" % (gnum, gname)) print self.spec.gratings_dict self.spec.read_grating() self.frame.m_choice_spec_grating.SetSelection(self.spec.grating - 1) self.spec.read_wl() self.frame.m_textCtrl_current_spec_wl.SetValue("%f" % self.spec.wl) self.frame.m_textCtrl_set_spec_wl.Bind(wx.EVT_TEXT_ENTER, self.on_change_spec_wl) self.frame.m_choice_spec_grating.Bind(wx.EVT_CHOICE, self.on_change_spec_grating) #self.frame.m_button_spec_stop.Bind(wx.EVT_BUTTON, self.on_spec_stop_motion) ######################################################################## #Andor CCD############################################################## self.ccd = AndorCCD(debug=self.HARDWARE_DEBUG) print "Andor CCD" print "%g x %g" % (self.ccd.Nx, self.ccd.Ny) self.spectrum_length = self.ccd.Nx self.ccd.set_ro_image_mode() self.ccd.set_trigger_mode('internal') self.ccd.set_image_flip(ANDOR_HFLIP, ANDOR_VFLIP) print "flip", self.ccd.get_image_flip() self.ccd.set_ad_channel(ANDOR_AD_CHAN) self.ccd.set_exposure_time(1.0) self.ccd.set_EMCCD_gain(1) self.ccd.set_cooler_on() self.ccd.get_temperature() self.ccd.set_shutter_open() self.spec_fig = pl.figure(3) self.specimg_ax = self.spec_fig.add_subplot(111) self.spec_ax = self.spec_fig.add_subplot(611) self.spec_ax.set_xlim(0, 512) self.spec_fig.show() self.ccd_img = self.specimg_ax.imshow(np.zeros( (self.ccd.Nx, self.ccd.Ny), dtype=np.int32), origin='lower', interpolation='nearest') self.specimg_ax.axhline(ROW0, color='w') self.specimg_ax.axhline(ROW1, color='w') self.specimg_ax.axvline(256, color='w') self.spec_line, = self.spec_ax.plot( np.zeros(self.ccd.Nx, dtype=np.int32), 'k-') self.spec_line2, = self.spec_ax.plot( np.zeros(self.ccd.Nx, dtype=np.int32), 'g-') self.video_mode = False self.frame.m_button_video_mode_start.Bind(wx.EVT_BUTTON, self.on_start_video_mode) self.frame.m_button_video_mode_stop.Bind(wx.EVT_BUTTON, self.on_stop_video_mode) self.frame.m_textCtrl_andor_exposure.SetValue( str(ANDOR_DEFAULT_EXPOSURE)) self.frame.m_textCtrl_andor_em.SetValue(str(ANDOR_DEFAULT_EMGAIN)) # A/D rate choice_adc = self.frame.m_choice_andor_adc choice_adc.Clear() for speed in self.ccd.HSSpeeds[ANDOR_AD_CHAN]: choice_adc.Append("%g MHz" % (speed)) choice_adc.SetSelection(0) self.ccd.set_hs_speed(0) choice_adc.Bind(wx.EVT_CHOICE, self.on_change_andor_adc) ######################################################################## # update figure self.ax.set_xlim(0, self.nanodrive.cal[XAXIS_ID]) self.ax.set_ylim(0, self.nanodrive.cal[YAXIS_ID]) # events self.frame.Bind(wx.EVT_BUTTON, self.on_start_scan, self.frame.m_button_start) self.frame.Bind(wx.EVT_BUTTON, self.on_stop_scan, self.frame.m_button_stop) self.timer = wx.Timer(id=2001) self.timer.Bind(wx.EVT_TIMER, self.on_timer) self.timer.Start(2000) #self.fast_timer = wx.Timer(id=2002) #self.fast_timer.Bind(wx.EVT_TIMER, self.on_fast_timer) #self.frame.m_checkBox_picoharp_fastreadout.Bind( # wx.EVT_CHECKBOX, self.on_fast_timer_checkbox) self.update_display() self.frame.Show() return True def on_timer(self, e): self.read_from_hardware() self.update_display() # def on_fast_timer(self,e): # self.picoharp.read_count_rates() # self.frame.m_textCtrl_count0.SetValue(str(self.picoharp.Countrate0)) # self.frame.m_textCtrl_count1.SetValue(str(self.picoharp.Countrate1)) # self.c0_hist[self.hist_i] = self.picoharp.Countrate0 # self.c1_hist[self.hist_i] = self.picoharp.Countrate1 # # #self.c0_hist_line.set_ydata(self.c0_hist) # self.c1_hist_line.set_ydata(self.c1_hist) # self.hist_vline.set_xdata([self.hist_i]*2) # # self.history_i += 1 # self.history_i %= HISTORY_LEN # # if (self.hist_i % 10) == 0: # self.ax2.relim() # self.ax2.autoscale_view(scalex=False, scaley=True) # #self.ax2.autoscale() # # self.fig2.canvas.draw() def on_fast_timer_checkbox(self, e): fast_timer_enable = self.frame.m_checkBox_picoharp_fastreadout.GetValue( ) if fast_timer_enable: self.fast_timer.Start(100) else: self.fast_timer.Stop() def on_start_scan(self, e): print "start scan" self.scanning = True # get scan parameters: self.x0 = float(self.frame.m_textCtrl_x0.GetValue()) self.x1 = float(self.frame.m_textCtrl_x1.GetValue()) self.y0 = float(self.frame.m_textCtrl_y0.GetValue()) self.y1 = float(self.frame.m_textCtrl_y1.GetValue()) self.dx = float(self.frame.m_textCtrl_dx.GetValue()) / 1000. self.dy = float(self.frame.m_textCtrl_dy.GetValue()) / 1000. self.x_array = np.arange(self.x0, self.x1, self.dx, dtype=float) self.y_array = np.arange(self.y0, self.y1, self.dy, dtype=float) self.Nx = len(self.x_array) self.Ny = len(self.y_array) print "Nx, Ny", self.Nx, self.Ny self.andor_exposure = float( self.frame.m_textCtrl_andor_exposure.GetValue()) self.andor_em_gain = int(self.frame.m_textCtrl_andor_em.GetValue()) ### create data arrays self.integrated_count_map = np.zeros((self.Ny, self.Nx), dtype=int) self.spectrum_map = np.zeros((self.Ny, self.Nx, self.spectrum_length), dtype=int) print "shape:", self.integrated_count_map.shape, self.spectrum_map.shape ### update figure self.aximg = self.ax.imshow( self.integrated_count_map, origin='lower', vmin=1e4, vmax=1e5, interpolation='nearest', extent=[self.x0, self.x1, self.y0, self.y1]) self.wxfig.redraw() # set up experiment self.ccd.set_exposure_time(self.andor_exposure) self.ccd.set_EMCCD_gain(self.andor_em_gain) # Scan! line_time0 = time.time() for jj in range(self.Ny): if not self.scanning: break y = self.y_array[jj] self.nanodrive.set_pos_ax(y, YAXIS_ID) self.read_from_hardware() y = self.ypos print "line time:", time.time() - line_time0 print "pixel time:", float(time.time() - line_time0) / len( self.x_array) line_time0 = time.time() if jj % 2: #odd lines x_line_indicies = range(self.Nx) else: #even lines -- traverse in opposite direction x_line_indicies = range(self.Nx)[::-1] for ii in x_line_indicies: if not self.scanning: break x = self.xpos = self.x_array[ii] wx.Yield() self.nanodrive.set_pos_ax(x, XAXIS_ID) self.ccd.start_acquisition() stat = "ACQUIRING" while stat != "IDLE": wx_yielded_sleep(self.ccd.exposure_time * 0.25) stati, stat = self.ccd.get_status() self.ccd.get_acquired_data() spectrum = np.sum(self.ccd.buffer[ROW0:ROW1], axis=0) self.spectrum_map[jj, ii, :] = spectrum self.integrated_count_map[jj, ii] = sum(spectrum) # update display try: self.update_display() except Exception, err: print "Failed to update_display", err try: self.spec_plotline.set_ydata(spectrum) self.ax_speclive.relim() self.ax_speclive.autoscale_view(tight=None, scalex=False, scaley=True) self.fig2.canvas.draw() except Exception as err: print "Failed to update spectrum plot", err if not (ii % 5): #self.update_figure() try: #print "updating figure" #self.read_from_hardware() self.aximg.set_data(self.integrated_count_map) try: count_min = np.min( self.integrated_count_map[np.nonzero( self.integrated_count_map)]) except Exception as err: count_min = 0 count_max = np.max(self.integrated_count_map) self.aximg.set_clim(count_min, count_max + 1) self.wxfig.redraw() except Exception, err: print "Failed to update figure:", err
class ConfocalTRPL3DScan(object): INPUT_PARAM_NAMES = """x0 x1 dx y0 y1 dy z0 z1 dz tacq phrange phoffset syncdiv zerocross0 zerocross1 level0 level1 axis_scan_order mcl_axis_translation stored_histogram_chan""".split() def __init__(self, **params): for p in self.INPUT_PARAM_NAMES: setattr(self, p, params[p]) self.x_array = np.arange(self.x0, self.x1, self.dx, dtype=float) self.y_array = np.arange(self.y0, self.y1, self.dy, dtype=float) self.z_array = np.arange(self.z0, self.z1, self.dz, dtype=float) self.Nx = len(self.x_array) self.Ny = len(self.y_array) self.Nz = len(self.z_array) self.mcl_axis_translation = xyz_tuple(*self.mcl_axis_translation) self.HARDWARE_DEBUG = False #HARDWARE self.nanodrive = MCLNanoDrive(debug=self.HARDWARE_DEBUG) #try: # self.frame.m_staticText_maxdim.SetLabel("max: %g x %g um" % (self.nanodrive.cal_Y, self.nanodrive.cal_X) ) self.picoharp = PicoHarp300(devnum=0, debug=self.HARDWARE_DEBUG) #DATA ARRAYS self.integrated_count_map = np.zeros(( self.Nz, self.Ny, self.Nx, ), dtype=int) print "size of time_trace_map %e" % (self.Nx * self.Ny * self.Nz * self.stored_histogram_chan) self.time_trace_map = np.zeros( (self.Nz, self.Ny, self.Nx, self.stored_histogram_chan), dtype=np.uint16) def run_3d_scan(self): self.picoharp.setup_experiment(Binning=self.phrange, SyncOffset=self.phoffset, Tacq=self.tacq, SyncDivider=self.syncdiv, CFDZeroCross0=self.zerocross0, CFDLevel0=self.level0, CFDZeroCross1=self.zerocross1, CFDLevel1=self.level1) self.set_ijk = (-1, -1, -1) self.scanning = True time0 = time.time() for iii, ijk in enumerate( ijk_generator((self.Nx, self.Ny, self.Nz), self.axis_scan_order)): if iii == 0: i, j, k = ijk print "moving to start position" self.nanodrive.set_pos_ax_slow(self.x_array[i], self.mcl_axis_translation.x) self.nanodrive.set_pos_ax_slow(self.y_array[j], self.mcl_axis_translation.y) self.nanodrive.set_pos_ax_slow(self.z_array[k], self.mcl_axis_translation.z) #previous ijk ip, jp, kp = self.set_ijk # new ijk i, j, k = ijk # move stage if i != ip: x = self.x_array[i] self.nanodrive.set_pos_ax(x, self.mcl_axis_translation.x) if j != jp: y = self.y_array[j] self.nanodrive.set_pos_ax(y, self.mcl_axis_translation.y) if k != kp: z = self.z_array[k] self.nanodrive.set_pos_ax(z, self.mcl_axis_translation.z) self.set_ijk = ijk self.read_from_hardware() ph = self.picoharp ph.start_histogram(Tacq=self.tacq) while not ph.check_done_scanning(): time.sleep(0.01) ph.stop_histogram() hist_data = ph.read_histogram_data() self.time_trace_map[k, j, i, :] = hist_data[0:self.stored_histogram_chan] cts = self.integrated_count_map[k, j, i] = sum(hist_data) if ((i + j + k) % 10) == 0: print ijk, cts t_now = time.time() pixel_time = (t_now - time0) * 0.1 print "sec per pixel:", pixel_time, "| time remaining (s)", (( (self.Nx * self.Ny * self.Nz) - iii) * pixel_time) time0 = t_now #Finish up after scan print "saving data..." save_params = self.INPUT_PARAM_NAMES + [ "time_trace_map", "Nx", "Ny", "Nz", "x_array", "y_array", "z_array", "countrate0", "integrated_count_map" ] save_dict = dict() for key in save_params: save_dict[key] = getattr(self, key) t0 = time.time() save_fname = "%i_time_trace_map3d.npz" % t0 np.savez_compressed(save_fname, **save_dict) print "data saved as %s" % save_fname def read_from_hardware(self): print self.picoharp.read_count_rates() self.countrate0 = self.picoharp.Countrate0 pos = self.nanodrive.get_pos() self.xpos = pos[self.mcl_axis_translation.x - 1] self.ypos = pos[self.mcl_axis_translation.y - 1] self.zpos = pos[self.mcl_axis_translation.z - 1]