laser_err = laser.laser_on(freq) print('Laser error: %d' % laser_err) laser.read_error() time.sleep(1) if laser_err == Laser.NOERROR: laser.clean_sweep_prep(5, 5000) laser.clean_sweep_start() laser.clean_sweep_pause(-5) offset_GHz = laser.offset() wait_time = time.perf_counter() + 10 while time.perf_counter() < wait_time: offset_GHz = laser.offset() print('Clean sweep offset: %d GHz' % offset_GHz) print("NOP: %d" % laser.check_nop()) time.sleep(0.2) laser.clean_sweep_start() laser.clean_sweep_pause(-4) offset_GHz = laser.offset() while time.perf_counter() < wait_time + 5:
class Model: def __init__(self): self.frequency = Observable() self.power = Observable(0) self.offset = Observable(0) self.on = Observable(False) self.connected = Observable(False) self.clean_jump_active = Observable(False) self.clean_scan_active = Observable(False) self.clean_scan_progress = Observable() self.clean_sweep_state = Observable() self.scan_data = Observable({ 't_laser': [], 'f': [], 'p_in': [], 't_pm': [], 'p_out': [] }) self.scan_data_old = Observable({'f': [], 't': []}) self.scan_time_remaining = Observable() self.scan_update_active = Observable(False) self.lock = Lock() self.data_lock = Lock() self.laser = None self.power_meter = None self.power_meter_connected = Event() self.power_meter_connected.clear() self.power_meter_thread = None self.power_meter_stop = Event() def set_startup_frequency(self, frequency): self.frequency.set(frequency) def connect_laser(self): with self.lock: self.laser = Laser() self.connected.set(True) def connect_pm(self): rm = visa.ResourceManager() resources = rm.list_resources() print(resources) inst = rm.open_resource(resources[0]) inst.timeout = 5000 print(inst.query('*IDN?')) self.power_meter = ThorlabsPM100(inst=inst) self.power_meter_connected.set() def laser_on(self): with self.lock: self.laser.startup_begin(self.frequency.get()) while self.laser.check_nop() > 16: self.power.set(self.laser.check_power()) self.on.set(True) def laser_off(self): # with self.lock: self.laser.laser_off() self.power.set(0) self.on.set(False) def disconnect(self): with self.lock: if self.laser: self.laser.itla_disconnect() self.connected.set(False) def standard_update(self, gui_lock: Lock, update_stop_event: Event): while not update_stop_event.is_set(): time.sleep(0.01) with self.lock: if not update_stop_event.is_set(): self.power.set(self.laser.check_power()) freq_thz = self.laser.read(Laser.REG_FreqTHz) freq_ghz = self.laser.read(Laser.REG_FreqGHz) self.frequency.set(freq_thz + freq_ghz / 10000) self.offset.set(self.laser.offset()) def scan_update(self, end_event: Event, take_data: Event): self.power_meter_connected.wait() print('PM connected') t_prev = None p_prev = None f_prev = None stop_pm_event = Event() power_queue = Queue() time_queue = Queue() pm_read_thread = Thread(target=self.pm_read, args=(time_queue, power_queue, stop_pm_event)) pm_read_thread.start() self.scan_update_active.set(True) while not end_event.is_set(): queue = Queue(maxsize=1) laser_read_thread = Thread(target=self.laser_read, args=(queue, )) laser_read_thread.start() output_powers_list = [] measured_time_list = [] laser_read_thread.join() stop_pm_event.set() pm_read_thread.join() while not time_queue.empty(): measured_time_list.append(time_queue.get()) while not power_queue.empty(): output_powers_list.append(power_queue.get()) pm_read_thread = Thread(target=self.pm_read, args=(time_queue, power_queue, stop_pm_event)) stop_pm_event.clear() pm_read_thread.start() output_powers = np.array(output_powers_list) measured_time = np.array(measured_time_list) p_new, offset, t_end = queue.get() self.power.set(p_new) self.offset.set(offset) f_new = self.frequency.get() + offset / 1000 if t_prev and f_prev and p_prev: assert isinstance(f_prev, float) assert isinstance(p_prev, float) t_duration = t_end - t_prev interpolation = ((measured_time - t_prev) / t_duration) frequencies = list(interpolation * f_new + (1 - interpolation) * f_prev) input_powers = interpolation * p_new + (1 - interpolation) * p_prev input_powers_watts = np.power(10, input_powers / 10) / 1000 relative_powers = list(output_powers / input_powers_watts) if abs(offset) < 20 and abs(p_new - 10) < 0.03 and abs( f_prev - f_new) < 0.1 and take_data.is_set(): with self.data_lock: data = self.scan_data_old.get() data['f'] += frequencies data['t'] += relative_powers self.scan_data_old.set(data) t_prev = t_end f_prev = f_new p_prev = p_new self.scan_update_active.set(False) def laser_read(self, queue: Queue): with self.lock: input_power = self.laser.check_power() offset = self.laser.offset() t = time.perf_counter() results = input_power, offset, t queue.put(results) def pm_read(self, time_queue: Queue, power_queue: Queue, stop: Event): while not stop.is_set(): power_queue.put(self.power_meter.read) time_queue.put(time.perf_counter()) def pm_update(self, end_event: Event, take_data: Event): self.power_meter_connected.wait() while not end_event.is_set(): if take_data.is_set(): power_out = self.power_meter.read with self.data_lock: data = self.scan_data.get() if len(data['t_laser']) > 1 and abs( data['t_laser'][-1] - time.perf_counter()) < 2E-1: data['t_pm'].append(time.perf_counter()) data['p_out'].append(power_out) self.scan_data.set(data) def clean_jump(self, frequency): self.clean_jump_active.set(True) self.clean_sweep_stop() with self.lock: self.laser.wait_nop() power_reference = self.power.get() with self.lock: self.laser.clean_jump_start(frequency) # Read the frequency error and wait until it is below a threshold or 2 seconds passes wait_time = time.perf_counter() + 2 with self.lock: error_read = self.laser.read(Laser.REG_Cjumpoffset) freq_error = error_read / 10.0 self.offset.set(freq_error) while abs(freq_error) > 0.1 and time.perf_counter() < wait_time: with self.lock: error_read = self.laser.read(Laser.REG_Cjumpoffset) freq_error = error_read / 10.0 self.offset.set(freq_error) with self.lock: self.laser.wait_nop() # Read out the laser's claimed frequency with self.lock: claim_thz = self.laser.read(Laser.REG_GetFreqTHz) claim_ghz = self.laser.read(Laser.REG_GETFreqGHz) / 10 claim_freq = claim_thz + claim_ghz / 1000.0 self.frequency.set(claim_freq) print('Laser\'s claimed frequency: %f' % claim_freq) with self.lock: self.laser.clean_jump_finish() time_wait = time.perf_counter() + 1 while self.power.get() < 0.8 * power_reference and time.perf_counter( ) < time_wait: time.sleep(.1) self.clean_sweep_start(0, 1) self.clean_jump_active.set(False) def clean_sweep_start(self, frequency, speed): self.clean_sweep_state.set("Preparing for clean sweep...") with self.lock: self.laser.clean_sweep_prep(frequency, int(speed * 1000)) time.sleep(1) self.clean_sweep_state.set("Running clean sweep.") with self.lock: self.laser.clean_sweep_start() def clean_sweep_stop(self): with self.lock: self.laser.clean_sweep_stop() self.clean_sweep_state.set(None) def clean_sweep_to_offset(self, offset): self.clean_sweep_state.set( "Sweeping to offset of {} GHz".format(offset)) with self.lock: self.laser.clean_sweep_to_offset(offset) while abs(self.offset.get() - offset) > 0.1: time.sleep(0.1) self.clean_sweep_state.set( "Pausing sweep at offset of {} GHz".format(offset)) def clean_scan(self, start_frequency: float, stop_frequency: float, speed: float, stop: Event, take_data: Event): assert stop_frequency > start_frequency if not self.power_meter_connected.is_set(): self.connect_pm() jump_frequency = start_frequency self.clean_scan_active.set(True) self.clean_scan_progress.set(0) self.scan_data.set({ 't_laser': [], 'f': [], 'p_in': [], 't_pm': [], 'p_out': [] }) self.scan_data_old.set({'f': [], 't': []}) take_data.clear() # self.power_meter_thread = Thread(target=self.pm_update, args=(stop, take_data)) # self.power_meter_thread.start() scan_start_time = time.perf_counter() scan_count = 0 while jump_frequency < stop_frequency + 0.03 and not stop.is_set(): power_reference = self.power.get() with self.lock: self.laser.clean_jump(jump_frequency) freq_thz = self.laser.read(Laser.REG_FreqTHz) freq_ghz = self.laser.read(Laser.REG_FreqGHz) frequency = freq_thz + freq_ghz / 10000 self.frequency.set(frequency) with self.lock: self.laser.wait_nop() time_wait = time.perf_counter() + 1 while self.power.get( ) < 0.8 * power_reference and time.perf_counter() < time_wait: time.sleep(.1) time.sleep(0.5) power_reference = self.power.get() self.clean_sweep_start(50, speed) time.sleep(.1) take_data.set() while self.offset.get() < 10 and not stop.is_set(): time.sleep(.1) while self.offset.get() > -10 and not stop.is_set(): time.sleep(.1) while self.offset.get() < -1 and not stop.is_set(): time.sleep(0.1) take_data.clear() time.sleep(0.5) with self.lock: self.laser.clean_sweep_stop() with self.lock: self.laser.wait_nop() time_wait = time.perf_counter() + 5 while self.power.get( ) < 0.95 * power_reference and time.perf_counter() < time_wait: time.sleep(.1) jump_frequency += 0.04 progress = (jump_frequency - start_frequency) / (stop_frequency - start_frequency) self.clean_scan_progress.set((jump_frequency - start_frequency) / (stop_frequency - start_frequency)) time_elapsed = time.perf_counter() - scan_start_time scan_count += 1 average_time_elapsed = time_elapsed / scan_count self.scan_time_remaining.set( round(average_time_elapsed / progress / 60)) time.sleep(1) # self.power_meter_thread.join() self.clean_scan_active.set(False)