Esempio n. 1
0
    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)
Esempio n. 2
0
    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)
Esempio n. 3
0
    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)
Esempio n. 4
0
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
Esempio n. 5
0
    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)
Esempio n. 6
0
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
Esempio n. 7
0
    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)