def control_for_registration(self, wavelength, value): value = int(value) daq = DAQmission() if value == 0: switch = False else: switch = True if wavelength == '640': print(wavelength + ':' + str(value)) print(str(switch)) daq.sendSingleAnalog('640AO', value) daq.sendSingleDigital('640blanking', switch) elif wavelength == '532': print(wavelength + ':' + str(value)) print(str(switch)) daq.sendSingleAnalog('532AO', value) daq.sendSingleDigital('640blanking', switch) else: print(wavelength + ':' + str(value)) print(str(switch)) daq.sendSingleAnalog('488AO', value) daq.sendSingleDigital('640blanking', switch)
def control_for_registration(self, wavelength, value): value = int(value) daq = DAQmission() if value == 0: switch = False else: switch = True if wavelength == "640": print(wavelength + ":" + str(value)) print(str(switch)) daq.sendSingleAnalog("640AO", value) daq.sendSingleDigital("640blanking", switch) elif wavelength == "532": print(wavelength + ":" + str(value)) print(str(switch)) daq.sendSingleAnalog("532AO", value) daq.sendSingleDigital("640blanking", switch) else: print(wavelength + ":" + str(value)) print(str(switch)) daq.sendSingleAnalog("488AO", value) daq.sendSingleDigital("640blanking", switch)
def control_for_registration(self, wavelength, value): value = int(value) daq = DAQmission() if value == 0: switch = False else: switch = True if wavelength == '640': print(wavelength + ':' + str(value)) print(str(switch)) daq.sendSingleAnalog('640AO', value) # execute_tread_singlesample_AOTF_analog = execute_tread_singlesample_analog() # execute_tread_singlesample_AOTF_analog.set_waves('640AO', value) # execute_tread_singlesample_AOTF_analog.start() daq.sendSingleDigital('640blanking', switch) # execute_tread_singlesample_AOTF_digital = execute_tread_singlesample_digital() # execute_tread_singlesample_AOTF_digital.set_waves('640blanking', switch) # execute_tread_singlesample_AOTF_digital.start() elif wavelength == '532': print(wavelength + ':' + str(value)) print(str(switch)) daq.sendSingleAnalog('532AO', value) daq.sendSingleDigital('640blanking', switch) # execute_tread_singlesample_AOTF_analog = execute_tread_singlesample_analog() # execute_tread_singlesample_AOTF_analog.set_waves('532AO', value) # execute_tread_singlesample_AOTF_analog.start() # execute_tread_singlesample_AOTF_digital = execute_tread_singlesample_digital() # execute_tread_singlesample_AOTF_digital.set_waves('640blanking', switch) # execute_tread_singlesample_AOTF_digital.start() else: print(wavelength + ':' + str(value)) print(str(switch)) daq.sendSingleAnalog('488AO', value) daq.sendSingleDigital('640blanking', switch)
class Servo: def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.sampling_rate = 10000 self.PWM_frequency = 50 self.mission = DAQmission() def power_on(self): self.mission.sendSingleDigital(channel='servo_power_1', value=True) # time.sleep(1.5) def power_off(self): self.mission.sendSingleDigital(channel='servo_power_1', value=False) def rotate(self, degree): # Convert degree to duty cycle in PWM. if degree >= 0 and degree <= 360: dutycycle = 0.02 #round((degree/180) * 0.05 + 0.05, 6) PWM_wave = self.blockWave(self.sampling_rate, self.PWM_frequency, dutycycle, repeats=50) PWM_wave = np.where(PWM_wave == 0, False, True) # plt.figure() # plt.plot(PWM_wave) # plt.show() PWM_wave_organized = np.array( [('servo_modulation_1', PWM_wave), ('servo_power_1', np.ones(len(PWM_wave), dtype=bool))], dtype=[('Sepcification', 'U20'), ('Waveform', bool, (len(PWM_wave), ))]) self.mission.runWaveforms(clock_source = "DAQ", sampling_rate = self.sampling_rate, analog_signals = {},\ digital_signals = PWM_wave_organized, readin_channels = {}) else: print('Rotation degree out of range!') def blockWave(self, sampleRate, frequency, dutycycle, repeats, voltMin=0, voltMax=5): """ Generates a one period blockwave. sampleRate samplerate set on the DAQ (int) frequency frequency you want for the block wave (int) voltMin minimum value of the blockwave (float) voltMax maximum value of the blockwave (float) dutycycle duty cycle of the wave (wavelength at voltMax) (float) """ wavelength = int(sampleRate / frequency) #Wavelength in number of samples #The high values high = np.ones(math.ceil(wavelength * dutycycle)) * voltMax #Low values low = np.ones(math.floor(wavelength * (1 - dutycycle))) * voltMin #Adding them single_period = np.append(high, low) """ Repeats the wave a set number of times and returns a new repeated wave. """ extendedWave = np.array([]) for i in range(repeats): extendedWave = np.append(extendedWave, single_period) return extendedWave
def execute_tread_single_sample_digital(self, channel): daq = DAQmission() if channel == '640blanking': if self.switchbutton_blankingAll.isChecked(): self.lasers_status['640'][0] = True daq.sendSingleDigital(channel, True) else: self.lasers_status['640'][0] = False daq.sendSingleDigital(channel, False) elif channel == '532blanking': if self.switchbutton_532.isChecked(): self.lasers_status['532'][0] = True daq.sendSingleDigital(channel, True) else: self.lasers_status['532'][0] = False daq.sendSingleDigital(channel, False) elif channel == '488blanking': if self.switchbutton_488.isChecked(): self.lasers_status['488'][0] = True daq.sendSingleDigital(channel, True) else: self.lasers_status['488'][0] = False daq.sendSingleDigital(channel, False) self.sig_lasers_status_changed.emit(self.lasers_status)
class FocusFinder(): def __init__(self, source_of_image = "PMT", init_search_range = 0.010, total_step_number = 5, imaging_conditions = {'edge_volt':5}, \ motor_handle = None, camera_handle = None, twophoton_handle = None, *args, **kwargs): """ Parameters ---------- source_of_image : string, optional The input source of image. The default is PMT. init_search_range : int, optional The step size when first doing coarse searching. The default is 0.010. total_step_number : int, optional Number of steps in total to find optimal focus. The default is 5. imaging_conditions : list Parameters for imaging. For PMT, it specifies the scanning voltage. For camera, it specifies the AOTF voltage and exposure time. motor_handle : TYPE, optional Handle to control PI motor. The default is None. twophoton_handle : TYPE, optional Handle to control Insight X3. The default is None. Returns ------- None. """ super().__init__(*args, **kwargs) # The step size when first doing coarse searching. self.init_search_range = init_search_range # Number of steps in total to find optimal focus. self.total_step_number = total_step_number # Parameters for imaging. self.imaging_conditions = imaging_conditions if motor_handle == None: # Connect the objective if the handle is not provided. self.pi_device_instance = PIMotor() else: self.pi_device_instance = motor_handle # Current position of the focus. self.current_pos = self.pi_device_instance.GetCurrentPos() # Number of steps already tried. self.steps_taken = 0 # The focus degree of previous position. self.previous_degree_of_focus = 0 # Number of going backwards. self.turning_point = 0 # The input source of image. self.source_of_image = source_of_image if source_of_image == "PMT": self.galvo = RasterScan(Daq_sample_rate = 500000, edge_volt = self.imaging_conditions['edge_volt']) elif source_of_image == "Camera": if camera_handle == None: # If no camera instance fed in, initialize camera. self.HamamatsuCam_ins = CamActuator() self.HamamatsuCam_ins.initializeCamera() else: self.HamamatsuCam_ins = camera_handle def gaussian_fit(self, move_to_focus = True): # The upper edge. upper_position = self.current_pos + self.init_search_range # The lower edge. lower_position = self.current_pos - self.init_search_range # Generate the sampling positions. sample_positions = np.linspace(lower_position, upper_position, self.total_step_number) degree_of_focus_list = [] for each_pos in sample_positions: # Go through each position and write down the focus degree. degree_of_focus = self.evaluate_focus(round(each_pos, 6)) degree_of_focus_list.append(degree_of_focus) print(degree_of_focus_list) try: interpolated_fitted_curve = ProcessImage.gaussian_fit(degree_of_focus_list) # Generate the inpterpolated new focus position axis. x_axis_new = np.linspace(lower_position, upper_position, len(interpolated_fitted_curve)) # Generate a dictionary and find the position where has the highest focus degree. max_focus_pos = dict(zip(interpolated_fitted_curve, x_axis_new))[np.amax(interpolated_fitted_curve)] if True: # Plot the fitting. plt.plot(sample_positions, np.asarray(degree_of_focus_list),'b+:',label='data') plt.plot(x_axis_new, interpolated_fitted_curve,'ro:',label='fit') plt.legend() plt.title('Fig. Fit for focus degree') plt.xlabel('Position') plt.ylabel('Focus degree') plt.show() max_focus_pos = round(max_focus_pos, 6) print(max_focus_pos) self.pi_device_instance.move(max_focus_pos) # max_focus_pos_focus_degree = self.evaluate_focus(round(max_focus_pos, 6)) except: print("Fitting failed. Find max in the list.") max_focus_pos = sample_positions[degree_of_focus_list.index(max(degree_of_focus_list))] print(max_focus_pos) if move_to_focus == True: self.pi_device_instance.move(max_focus_pos) return max_focus_pos def bisection(self): """ Bisection way of finding focus. Returns ------- mid_position : float DESCRIPTION. """ # The upper edge in which we run bisection. upper_position = self.current_pos + self.init_search_range # The lower edge in which we run bisection. lower_position = self.current_pos - self.init_search_range for step_index in range(1, self.total_step_number + 1): # In each step of bisection finding. # In the first round, get degree of focus at three positions. if step_index == 1: # Get degree of focus in the mid. mid_position = (upper_position + lower_position)/2 degree_of_focus_mid = self.evaluate_focus(mid_position) print("mid focus degree: {}".format(round(degree_of_focus_mid, 5))) # Break the loop if focus degree is below threshold which means # that there's no cell in image. if not ProcessImage.if_theres_cell(self.galvo_image.astype('float32')): print('no cell') mid_position = False break # Move to top and evaluate. degree_of_focus_up = self.evaluate_focus(obj_position = upper_position) print("top focus degree: {}".format(round(degree_of_focus_up, 5))) # Move to bottom and evaluate. degree_of_focus_low = self.evaluate_focus(obj_position = lower_position) print("bot focus degree: {}".format(round(degree_of_focus_low, 5))) # Sorting dicitonary of degrees in ascending. biesection_range_dic = {"top":[upper_position, degree_of_focus_up], "bot":[lower_position, degree_of_focus_low]} # In the next rounds, only need to go to center and update boundaries. elif step_index > 1: # The upper edge in which we run bisection. upper_position = biesection_range_dic["top"][0] # The lower edge in which we run bisection. lower_position = biesection_range_dic["bot"][0] # Get degree of focus in the mid. mid_position = (upper_position + lower_position)/2 degree_of_focus_mid = self.evaluate_focus(mid_position) print("Current focus degree: {}".format(round(degree_of_focus_mid, 5))) # If sits in upper half, make the middle values new bottom. if biesection_range_dic["top"][1] > biesection_range_dic["bot"][1]: biesection_range_dic["bot"] = [mid_position, degree_of_focus_mid] else: biesection_range_dic["top"] = [mid_position, degree_of_focus_mid] print("The upper pos: {}; The lower: {}".format(biesection_range_dic["top"][0], biesection_range_dic["bot"][0])) return mid_position def evaluate_focus(self, obj_position = None): """ Evaluate the focus degree of certain objective position. Parameters ---------- obj_position : float, optional The target objective position. The default is None. Returns ------- degree_of_focus : float Degree of focus. """ if obj_position != None: self.pi_device_instance.move(obj_position) # Get the image. if self.source_of_image == "PMT": self.galvo_image = self.galvo.run() plt.figure() plt.imshow(self.galvo_image) plt.show() if False: with skimtiff.TiffWriter(os.path.join(r'M:\tnw\ist\do\projects\Neurophotonics\Brinkslab\Data\Xin\2020-11-17 gaussian fit auto-focus cells\trial_11', str(obj_position).replace(".", "_")+ '.tif')) as tif: tif.save(self.galvo_image.astype('float32'), compress=0) degree_of_focus = ProcessImage.local_entropy(self.galvo_image.astype('float32')) elif self.source_of_image == "Camera": # First configure the AOTF. self.AOTF_runner = DAQmission() # Find the AOTF channel key for key in self.imaging_conditions: if 'AO' in key: # like '488AO' AOTF_channel_key = key # Set the AOTF first. self.AOTF_runner.sendSingleDigital('blankingall', True) self.AOTF_runner.sendSingleAnalog(AOTF_channel_key, self.imaging_conditions[AOTF_channel_key]) # Snap an image from camera self.camera_image = self.HamamatsuCam_ins.SnapImage(self.imaging_conditions['exposure_time']) time.sleep(0.5) # Set back AOTF self.AOTF_runner.sendSingleDigital('blankingall', False) self.AOTF_runner.sendSingleAnalog(AOTF_channel_key, 0) plt.figure() plt.imshow(self.camera_image) plt.show() if False: with skimtiff.TiffWriter(os.path.join(r'M:\tnw\ist\do\projects\Neurophotonics\Brinkslab\Data\Xin\2021-03-06 Camera AF\beads', str(obj_position).replace(".", "_")+ '.tif')) as tif: tif.save(self.camera_image.astype('float32'), compress=0) degree_of_focus = ProcessImage.variance_of_laplacian(self.camera_image.astype('float32')) time.sleep(0.2) return degree_of_focus
def execute_tread_single_sample_digital(self, channel): daq = DAQmission() if channel == '640blanking': if self.switchbutton_640.isChecked(): self.lasers_status['640'][0] = True daq.sendSingleDigital(channel, True) # execute_tread_singlesample_AOTF_digital = execute_tread_singlesample_digital() # execute_tread_singlesample_AOTF_digital.set_waves(channel, 1) # execute_tread_singlesample_AOTF_digital.start() else: self.lasers_status['640'][0] = False daq.sendSingleDigital(channel, False) # execute_tread_singlesample_AOTF_digital = execute_tread_singlesample_digital() # execute_tread_singlesample_AOTF_digital.set_waves(channel, 0) # execute_tread_singlesample_AOTF_digital.start() elif channel == '532blanking': if self.switchbutton_532.isChecked(): self.lasers_status['532'][0] = True daq.sendSingleDigital(channel, True) # execute_tread_singlesample_AOTF_digital = execute_tread_singlesample_digital() # execute_tread_singlesample_AOTF_digital.set_waves(channel, 1) # execute_tread_singlesample_AOTF_digital.start() else: self.lasers_status['532'][0] = False daq.sendSingleDigital(channel, False) # execute_tread_singlesample_AOTF_digital = execute_tread_singlesample_digital() # execute_tread_singlesample_AOTF_digital.set_waves(channel, 0) # execute_tread_singlesample_AOTF_digital.start() elif channel == '488blanking': if self.switchbutton_488.isChecked(): self.lasers_status['488'][0] = True daq.sendSingleDigital(channel, True) # execute_tread_singlesample_AOTF_digital = execute_tread_singlesample_digital() # execute_tread_singlesample_AOTF_digital.set_waves(channel, 1) # execute_tread_singlesample_AOTF_digital.start() else: self.lasers_status['488'][0] = False daq.sendSingleDigital(channel, False) # execute_tread_singlesample_AOTF_digital = execute_tread_singlesample_digital() # execute_tread_singlesample_AOTF_digital.set_waves(channel, 0) # execute_tread_singlesample_AOTF_digital.start() elif channel == 'LED': if self.switchbutton_LED.isChecked(): execute_tread_singlesample_AOTF_digital = execute_tread_singlesample_digital( ) execute_tread_singlesample_AOTF_digital.set_waves(channel, 1) execute_tread_singlesample_AOTF_digital.start() else: execute_tread_singlesample_AOTF_digital = execute_tread_singlesample_digital( ) execute_tread_singlesample_AOTF_digital.set_waves(channel, 0) execute_tread_singlesample_AOTF_digital.start() self.sig_lasers_status_changed.emit(self.lasers_status)