class MicroscopeGUI(object): def __del__(self): self.ui = None def show(self): #self.ui.exec_() self.ui.show() def __init__(self): self.HARDWARE_DEBUG = HARDWARE_DEBUG self.scanning = False self.MCL_AXIS_ID = MCL_AXIS_ID self.HAXIS = HAXIS self.VAXIS = VAXIS self.HAXIS_ID = HAXIS_ID self.VAXIS_ID = VAXIS_ID self.logged_quantities = collections.OrderedDict() self.hardware_components = collections.OrderedDict() self.measurement_components = collections.OrderedDict() self.figs = collections.OrderedDict() # Load Qt UI from .ui file ui_loader = QtUiTools.QUiLoader() ui_file = QtCore.QFile("microscope_gui.ui") ui_file.open(QtCore.QFile.ReadOnly) self.ui = ui_loader.load(ui_file) ui_file.close() # Add hardware components print "Adding Hardware Components" self.picoharp_hc = self.add_hardware_component( PicoHarpHardwareComponent(self)) self.apd_counter_hc = self.add_hardware_component( APDCounterHardwareComponent(self)) self.andor_ccd_hc = self.add_hardware_component( AndorCCDHardwareComponent(self)) self.acton_spec_hc = self.add_hardware_component( ActonSpectrometerHardwareComponent(self)) self.flip_mirror_hc = self.add_hardware_component( FlipMirrorHardwareComponent(self)) self.setup_hardware() # Create the measurement objects print "Create Measurement objects" self.apd_optimizer_measure = self.add_measurement_component( APDOptimizerMeasurement(self)) self.apd_scan_measure = self.add_measurement_component( APDConfocalScanMeasurement(self)) self.ple_point_measure = self.add_measurement_component( PLEPointMeasurement(self)) self.ple2d_measure = self.add_measurement_component( PLE2DScanMeasurement(self)) self.picoharp_measure = self.add_measurement_component( PicoHarpMeasurement(self)) self.trpl_scan_measure = self.add_measurement_component( TRPLScanMeasurement(self)) self.andor_ro_measure = self.add_measurement_component( AndorCCDReadout(self)) self.andor_bg_measure = self.add_measurement_component( AndorCCDReadBackground(self)) self.spec_map_measure = self.add_measurement_component( SpectrumScan2DMeasurement(self)) self.power_scan_measure = self.add_measurement_component( PowerScanContinuous(self)) # Setup the figures for name, measure in self.measurement_components.items(): print "setting up figures for", name, "measurement", measure.name measure.setup_figure() self.setup_figures() print "figures:" for fig in self.figs: print "\t", fig print "measurement_components:" for m in self.measurement_components: print "\t", m # events self.ui.slow_display_timer_checkBox.stateChanged.connect( self.on_slow_display_timer_checkbox) self.ui.power_meter_acquire_cont_checkBox.stateChanged.connect( self.on_power_meter_acquire_cont_checkbox) self.ui.oo_spec_acquire_cont_checkBox.stateChanged.connect( self.on_oo_spec_acq_cont_checkbox) ### timers self.slow_display_timer = QtCore.QTimer(self.ui) self.slow_display_timer.timeout.connect(self.on_slow_display_timer) self.ui.slow_display_timer_checkBox.setChecked(True) self.power_meter_acq_cont_timer = QtCore.QTimer(self.ui) self.power_meter_acq_cont_timer.timeout.connect( self.on_power_meter_acq_cont_timer) self.oo_spec_acq_cont_timer = QtCore.QTimer(self.ui) self.oo_spec_acq_cont_timer.timeout.connect( self.on_oo_spec_acq_cont_timer) def start_display_timers(self): print "start_display_timers" @QtCore.Slot() def stop_display_timers(self): print "stop_display_timers" self.ui.slow_display_timer_checkBox.setChecked(False) self.ui.power_meter_acquire_cont_checkBox.setChecked(False) self.ui.oo_spec_acquire_cont_checkBox.setChecked(False) QtGui.QApplication.processEvents() def add_figure(self, name, widget): """creates a matplotlib figure attaches it to the qwidget specified (widget needs to have a layout set (preferably verticalLayout) adds a figure to self.figs""" print "---adding figure", name, widget if name in self.figs: return self.figs[name] else: fig = Figure() fig.patch.set_facecolor('w') canvas = FigureCanvas(fig) nav = NavigationToolbar2(canvas, self.ui) widget.layout().addWidget(canvas) widget.layout().addWidget(nav) canvas.setFocusPolicy(QtCore.Qt.ClickFocus) canvas.setFocus() self.figs[name] = fig return fig def add_logged_quantity(self, name, **kwargs): lq = LoggedQuantity(name=name, **kwargs) self.logged_quantities[name] = lq return lq def add_hardware_component(self, hc): self.hardware_components[hc.name] = hc return hc def add_measurement_component(self, measure): assert not measure.name in self.measurement_components.keys() self.measurement_components[measure.name] = measure return measure def setup_figures(self): ## OO Spec Figure ### F = self.fig_oo_spec = self.add_figure('oo_spec', self.ui.oo_spec_plot_widget) ax = self.oo_spec_ax = F.add_subplot(111) self.oo_spec_plotline, = ax.plot(self.oo_spectrometer.wavelengths, self.oo_spectrometer.spectrum) ax.set_xlabel("wavelengths (nm)") ax.set_ylabel("Laser Spectrum (counts)") def setup_hardware(self): ######## MCL NanoDrive Stage ########################################### print "Initializing MCL stage functionality" self.nanodrive = MCLNanoDrive(debug=True) 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)) # Logged Quantities self.x_position = self.add_logged_quantity(name='x_position', dtype=np.float) self.y_position = self.add_logged_quantity(name='y_position', dtype=np.float) self.z_position = self.add_logged_quantity(name='z_position', dtype=np.float) self.x_position.hardware_set_func = lambda x: self.nanodrive.set_pos_ax_slow( x, MCL_AXIS_ID["X"]) self.y_position.hardware_set_func = lambda y: self.nanodrive.set_pos_ax_slow( y, MCL_AXIS_ID["Y"]) self.z_position.hardware_set_func = lambda z: self.nanodrive.set_pos_ax_slow( z, MCL_AXIS_ID["Z"]) 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_doubleSpinBox.setValue) self.ui.y_set_lineEdit.returnPressed.connect( self.y_position.update_value) self.z_position.updated_value.connect( self.ui.cz_doubleSpinBox.setValue) self.ui.z_set_lineEdit.returnPressed.connect( self.z_position.update_value) self.nanodrive_move_speed = self.add_logged_quantity( name='nanodrive_move_speed', dtype=np.float, hardware_read_func=self.nanodrive.get_max_speed, hardware_set_func=self.nanodrive.set_max_speed) self.nanodrive_move_speed.updated_value[float].connect( self.ui.nanodrive_move_slow_doubleSpinBox.setValue) self.ui.nanodrive_move_slow_doubleSpinBox.valueChanged[float].connect( self.nanodrive_move_speed.update_value) self.nanodrive_move_speed.read_from_hardware() # read and initialize hardware control values self.read_stage_position() ### Power Meter ########################## print "Initializing power meter functionality" self.power_meter = ThorlabsPM100D(debug=self.HARDWARE_DEBUG) self.power_meter_wavelength = self.add_logged_quantity( 'power_meter_wavelength', dtype=int, hardware_read_func=self.power_meter.get_wavelength, hardware_set_func=self.power_meter.set_wavelength) self.power_meter_wavelength.updated_value[float].connect( self.ui.power_meter_wl_doubleSpinBox.setValue) self.ui.power_meter_wl_doubleSpinBox.valueChanged[float].connect( self.power_meter_wavelength.update_value) print "Reading initial wavelength" self.power_meter_wavelength.read_from_hardware() self.laser_power = self.add_logged_quantity( name='laser_in_power', fmt='%2.2e W', dtype=np.float, hardware_read_func=self.power_meter.measure_power) self.laser_power.updated_text_value.connect( self.ui.power_meter_power_label.setText) self.laser_power.read_from_hardware() ### AOTF ##################################### print "Initializing AOTF functionality" # self.dds = CrystalTechDDS(comm="serial", port="COM1", debug=self.HARDWARE_DEBUG) # Modulation property # self.aotf_modulation = self.add_logged_quantity(name="aotf_modulation", dtype=bool, hardware_set_func=self.dds.set_modulation) # self.aotf_modulation.updated_value[bool].connect(self.ui.aotf_mod_enable_checkBox.setChecked) # self.ui.aotf_mod_enable_checkBox.stateChanged.connect(self.aotf_modulation.update_value) # self.aotf_modulation.update_value(True) # Frequency property # TODO: only works on channel 0! # self.aotf_freq = self.add_logged_quantity(name="aotf_freq", # dtype=np.float, # hardware_read_func=self.dds.get_frequency, # hardware_set_func=self.dds.set_frequency, # fmt = '%f') # self.aotf_freq.updated_value[float].connect(self.ui.atof_freq_doubleSpinBox.setValue) # self.ui.atof_freq_doubleSpinBox.valueChanged[float].connect(self.aotf_freq.update_value) # self.ui.aotf_freq_set_lineEdit.returnPressed.connect(self.aotf_freq.update_value) # self.aotf_freq.read_from_hardware() # Power property # TODO: only works on channel 0! # self.aotf_power = self.add_logged_quantity(name="aotf_power", # dtype=np.int, # hardware_read_func=self.dds.get_amplitude, # hardware_set_func=self.dds.set_amplitude) # self.aotf_power.updated_value[float].connect(self.ui.aotf_power_doubleSpinBox.setValue) # self.ui.aotf_power_doubleSpinBox.valueChanged.connect(self.aotf_power.update_value) # self.aotf_power.read_from_hardware() ### OO Spec #################################### print "Initializing OceanOptics spectrometer functionality" self.oo_spectrometer = OceanOpticsSpectrometer( debug=self.HARDWARE_DEBUG) self.oo_spec_int_time = self.add_logged_quantity( name="oo_spec_int_time", dtype=float, hardware_set_func=self.oo_spectrometer.set_integration_time_sec) self.ui.oo_spec_int_time_doubleSpinBox.valueChanged[float].connect( self.oo_spec_int_time.update_value) self.oo_spec_int_time.updated_value[float].connect( self.ui.oo_spec_int_time_doubleSpinBox.setValue) self.oo_spec_int_time.update_value(0.1) self.oo_spectrometer.start_threaded_acquisition() # Hardware Read functions def read_stage_position(self): self.stage_pos = self.nanodrive.get_pos() 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) return self.stage_pos # GUI Functions @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() @QtCore.Slot() def on_slow_display_timer_checkbox(self, enable): if enable: self.slow_display_timer.start(TIMER_MS) else: self.slow_display_timer.stop() # Timer callbacks @QtCore.Slot() def on_slow_display_timer(self): self.read_stage_position() #self.read_ni_countrate(int_time = 0.01) #Update the temperature reading for the CCD if self.andor_ccd_hc.is_connected: ccd = self.andor_ccd_hc if (ccd.status.read_from_hardware() == 'IDLE'): ccd.temperature.read_from_hardware() @QtCore.Slot() def on_oo_spec_acq_cont_checkbox(self, enable): if enable: # limit update period to 50ms (in ms) or as slow as 1sec #timer_period = np.min(1.0,np.max(0.05*self.oo_spec_int_time.val,0.05)) * 1000. self.oo_spec_acq_cont_timer.start(0.050) else: self.oo_spec_acq_cont_timer.stop() @QtCore.Slot() def on_oo_spec_acq_cont_timer(self): # Check to see if a spectrum is available from the Ocean Optics spec if self.oo_spectrometer.is_threaded_acquisition_complete(): self.oospec_update_figure() self.oo_spectrometer.start_threaded_acquisition() def oospec_update_figure(self): F = self.fig_oo_spec ax = self.oo_spec_ax self.oo_spectrometer.spectrum[:10] = np.nan self.oo_spectrometer.spectrum[-10:] = np.nan self.oo_spec_plotline.set_ydata(self.oo_spectrometer.spectrum) ax.relim() ax.autoscale_view(scalex=False, scaley=True) F.canvas.draw() @QtCore.Slot(bool) def on_power_meter_acquire_cont_checkbox(self, enable): if enable: self.power_meter_acq_cont_timer.start(100) else: self.power_meter_acq_cont_timer.stop() @QtCore.Slot() def on_power_meter_acq_cont_timer(self): #read power self.laser_power.read_from_hardware()
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 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 MCLStage3DApp(wx.App): def OnInit(self): self.HARDWARE_DEBUG = HARDWARE_DEBUG self.frame = MCLStage3DFrame(None) self.nanodrive = MCLNanoDrive(debug=self.HARDWARE_DEBUG) try: self.frame.m_staticText_maxdim.SetLabel( "[ %g x %g x %g ]" % (self.nanodrive.cal_X, self.nanodrive.cal_Y, self.nanodrive.cal_Z)) except Exception as e: print e self.frame.m_staticText_maxdim.SetLabel("[ ? ? ? ]") y, x, z = self.nanodrive.get_pos() self.frame.m_scrollBar_x.SetScrollbar(100 * x / self.nanodrive.cal_Y, 1, 100, 1, refresh=True) self.frame.m_scrollBar_y.SetScrollbar(100 * y / self.nanodrive.cal_X, 1, 100, 1, refresh=True) self.frame.m_scrollBar_z.SetScrollbar(100 * z / self.nanodrive.cal_Z, 1, 100, 1, refresh=True) self.frame.m_textCtrl_x.SetValue("%02.3f" % x) self.frame.m_textCtrl_y.SetValue("%02.3f" % y) self.frame.m_textCtrl_z.SetValue("%02.3f" % z) self.frame.m_scrollBar_x.Bind(wx.EVT_SCROLL, self.on_scroll) self.frame.m_scrollBar_y.Bind(wx.EVT_SCROLL, self.on_scroll) self.frame.m_scrollBar_z.Bind(wx.EVT_SCROLL, self.on_scroll) self.frame.m_textCtrl_x.Bind(wx.EVT_TEXT_ENTER, self.on_change_text) self.frame.m_textCtrl_y.Bind(wx.EVT_TEXT_ENTER, self.on_change_text) self.frame.m_textCtrl_z.Bind(wx.EVT_TEXT_ENTER, self.on_change_text) # Figure self.wxfig = MPLFigureWithToolbarWX(self.frame.m_panel_plot) self.fig = self.wxfig.fig self.ax = self.fig.add_subplot(111) self.ax.set_xlim(0, self.nanodrive.cal_Y) self.ax.set_ylim(self.nanodrive.cal_X, 0) self.xypos_line, = self.ax.plot([x], [y], 'ro') self.frame.Show() return True def on_scroll(self, evt): self.frame.m_scrollBar_x.Refresh() self.frame.m_scrollBar_y.Refresh() self.frame.m_scrollBar_z.Refresh() new_x = self.frame.m_scrollBar_x.GetThumbPosition( ) * 0.01 * self.nanodrive.cal_Y new_y = self.frame.m_scrollBar_y.GetThumbPosition( ) * 0.01 * self.nanodrive.cal_X new_z = self.frame.m_scrollBar_z.GetThumbPosition( ) * 0.01 * self.nanodrive.cal_Z self.nanodrive.set_pos(new_y, new_x, new_z) y, x, z = self.nanodrive.get_pos() #self.frame.m_scrollBar_x.SetScrollbar(100*x/self.nanodrive.cal_X, 1, 100, 1, refresh=True) #self.frame.m_scrollBar_y.SetScrollbar(100*y/self.nanodrive.cal_Y, 1, 100, 1, refresh=True) #self.frame.m_scrollBar_z.SetScrollbar(100*z/self.nanodrive.cal_Z, 1, 100, 1, refresh=True) self.frame.m_textCtrl_x.SetValue("%02.3f" % x) self.frame.m_textCtrl_y.SetValue("%02.3f" % y) self.frame.m_textCtrl_z.SetValue("%02.3f" % z) self.xypos_line.set_xdata([x]) self.xypos_line.set_ydata([y]) self.wxfig.redraw() #self.frame.m_scrollBar_x.Refresh() #self.frame.m_scrollBar_y.Refresh() #self.frame.m_scrollBar_z.Refresh() def on_change_text(self, evt): new_x = float(self.frame.m_textCtrl_x.GetValue()) new_y = float(self.frame.m_textCtrl_y.GetValue()) new_z = float(self.frame.m_textCtrl_z.GetValue()) self.nanodrive.set_pos(new_y, new_x, new_z) y, x, z = self.nanodrive.get_pos() self.frame.m_textCtrl_x.SetValue("%02.3f" % x) self.frame.m_textCtrl_y.SetValue("%02.3f" % y) self.frame.m_textCtrl_z.SetValue("%02.3f" % z) self.frame.m_scrollBar_x.SetScrollbar(100 * x / self.nanodrive.cal_Y, 1, 100, 1, refresh=True) self.frame.m_scrollBar_y.SetScrollbar(100 * y / self.nanodrive.cal_X, 1, 100, 1, refresh=True) self.frame.m_scrollBar_z.SetScrollbar(100 * z / self.nanodrive.cal_Z, 1, 100, 1, refresh=True) self.wxfig.redraw()
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]