Skip to content

Transfocator Scan

transfocator_scan

Classes

gigE_camera_accessor

gigE_camera_accessor(camera_pv)
Source code in tfs/transfocator_scan.py
def __init__(self,camera_pv):
    self.camera_pv=camera_pv
    self.get_markers()
    self.check_color_mode()
    pass
Attributes
camera_pv instance-attribute
camera_pv = camera_pv
Functions
check_color_mode
check_color_mode()
Source code in tfs/transfocator_scan.py
def check_color_mode(self):
    color_mode = caget(self.camera_pv + ':ColorMode_RBV')
    if color_mode != 0:
        color = True
    else:
        color = False
    self.color=color
get_image
get_image()
Source code in tfs/transfocator_scan.py
def get_image(self):
    image = caget(self.camera_pv + ':IMAGE1:ArrayData')#some cameras can be image2 need to consider.
    if len(image)==0:
        print(" [!] Can't read camera", PV + ".", "Exiting...", '\n')
        sys.exit(1)
    if self.color:
        ArraySizeX=caget(self.camera_pv +':IMAGE1:ArraySize1_RBV')
        ArraySizeY=caget(self.camera_pv +':IMAGE1:ArraySize2_RBV')
        img=np.reshape(image,(ArraySizeY,ArraySizeX,3))
        img_array = np.array(img)
        grey_image=img_array[:,:,0]*299/1000+img_array[:,:,1]*587/1000+img_array[:,:,2]*114/1000
    else:
        ArraySizeX = caget(self.camera_pv + ':IMAGE1:ArraySize0_RBV')
        ArraySizeY = caget(self.camera_pv + ':IMAGE1:ArraySize1_RBV')
        grey_image = np.reshape(image, (ArraySizeY, ArraySizeX))
    return grey_image
get_image_old
get_image_old()
Source code in tfs/transfocator_scan.py
def get_image_old(self):
    image = caget(self.camera_pv + ':IMAGE1:ArrayData')#some cameras can be image2 need to consider.
    if len(image) == 0:
        print(" [!] Can't read camera", PV + ".", "Exiting...", '\n')
        sys.exit(1)
    else:
        ArraySizeX = caget(self.camera_pv + ':IMAGE1:ArraySize0_RBV')
        ArraySizeY = caget(self.camera_pv + ':IMAGE1:ArraySize1_RBV')
        image = np.reshape(image, (ArraySizeY, ArraySizeX))
        # image = ndimage.gaussian_filter(image, 0.1) # test gaussian filter denoising
        # image = ndimage.median_filter(image, 1) # test median filter denoising
    return image
get_image_roi
get_image_roi()
Source code in tfs/transfocator_scan.py
def get_image_roi(self):
    image = self.get_image()
    y_slice = slice(min(self.marker1Y, self.marker2Y), max(self.marker1Y, self.marker2Y))
    x_slice = slice(min(self.marker1X, self.marker2X), max(self.marker1X, self.marker2X))
    image = image[y_slice, x_slice]
    self.active_image=image
    #image = image[self.marker1Y:self.marker2Y, self.marker1X:self.marker2X]
    return image
get_markers
get_markers()
Source code in tfs/transfocator_scan.py
def get_markers(self):
    self.marker1X = caget(self.camera_pv + ':Cross1X')
    self.marker1Y = caget(self.camera_pv + ':Cross1Y')
    self.marker2X = caget(self.camera_pv + ':Cross2X')
    self.marker2Y = caget(self.camera_pv + ':Cross2Y')
    self.marker3X = caget(self.camera_pv + ':Cross3X')
    self.marker3Y = caget(self.camera_pv + ':Cross3Y')
    self.marker4X = caget(self.camera_pv + ':Cross4X')
    self.marker4Y = caget(self.camera_pv + ':Cross4Y')
    return self.marker1X, self.marker1Y, self.marker2X, self.marker2Y
get_projections
get_projections()
Source code in tfs/transfocator_scan.py
def get_projections(self):
    self.x_projection = np.sum(self.active_image, axis=0)
    self.y_projection = np.sum(self.active_image, axis=1)
    self.x_projection -= self.x_projection.min()
    self.y_projection -= self.y_projection.min()
    return self.x_projection, self.y_projection

transfocator_aligner

transfocator_aligner(camera_pv)

Bases: gigE_camera_accessor

Source code in tfs/transfocator_scan.py
def __init__(self,camera_pv):
    self.camera_pv=camera_pv
    self.get_markers()
    self.check_color_mode()
    pass
Functions
fit_2d_gaussian_fixed_angle
fit_2d_gaussian_fixed_angle(image)
Source code in tfs/transfocator_scan.py
def fit_2d_gaussian_fixed_angle(image):
    x = np.arange(image.shape[1])
    y = np.arange(image.shape[0])
    x, y = np.meshgrid(x, y)
    initial_guess = (image.max(), image.shape[1]//2, image.shape[0]//2, 10, 10, np.min(image))
    try:
        popt, _ = curve_fit(twoD_gaussian_fixed_angle, (x, y), image.ravel(), p0=initial_guess)
        return popt  # amplitude, xo, yo, sigma_x, sigma_y, offset
    except RuntimeError:
        print("Fit failed.")
        return None
fit_scan
fit_scan(x, y)
Source code in tfs/transfocator_scan.py
def fit_scan(self,x,y):
    maxi = np.percentile(y,95)
    mean_ind = np.argmin(y-maxi/2)
    guess = [maxi, x[mean_ind], np.std(x)]
    try:
        popt, pcov = curve_fit(gaussian, x, y,np.array(guess),maxfev=999999)
    except RuntimeError:
        guess_width_high=np.percentile(y,75)
        guess_width_low=np.percentile(y,25)
        print('bad fit')
        return [0,0,0,0]
    return popt 
scan_transfocator
scan_transfocator(transfocator_motor, positions, image_sec)
Source code in tfs/transfocator_scan.py
def scan_transfocator(self, transfocator_motor,positions, image_sec):
    wid_x=[]
    wid_y=[]
    fig, ax=plt.subplots(2,1,sharex=True)
    fig.suptitle('Transfocator Optimization Plot')
    line1, = ax[0].plot([],[],'ro-') 
    line2, = ax[1].plot([],[],'ro-') 
    ax[0].set_ylabel('FWHM_x')
    ax[1].set_ylabel('FWHM_y')
    ax[1].set_xlabel('Transfocator Z-position')
    plt.ion()
    for idx,pos in enumerate(positions):
        transfocator_motor.umv(pos)
        #transfocator_motor.mv(pos, wait = True)
        timeout = time.time()+image_sec
        img_count=0
        collect=True
        while collect==True:
            img=self.get_image_roi()
            #if np.sum(img-np.min(img))<np.shape(img)[0]*np.shape(img)[1]:
            #    print('bad shot!')
            #    continue
            #print('shot okay!')
            if img_count==0:
                images=img
                img_count+=1
            else:
                images+=img
                img_count+=1
            if time.time()>timeout and img_count>=10:
                collect=False
        images=images/img_count
        self.active_image=images-np.min(images)
        x,y=self.get_projections()
        opt_x=self.fit_scan(np.arange(0,len(x),1),x)
        opt_y=self.fit_scan(np.arange(0,len(y),1),y)
        wid_x.append(np.abs(opt_x[2]))
        wid_y.append(np.abs(opt_y[2]))
        if idx%5==0:
            line1.set_data(positions[:idx+1], wid_x)
            line2.set_data(positions[:idx+1], wid_y)
            ax[0].relim()  # Recalculate the data limits
            ax[1].relim()
            ax[0].autoscale_view()  
            ax[1].autoscale_view()
            fig.canvas.draw()  
            fig.canvas.flush_events()  
            plt.pause(0.1)  
    line1.set_data(positions,wid_x)
    line2.set_data(positions,wid_y)
    ax[0].relim()
    ax[1].relim()
    ax[0].autoscale_view()
    ax[1].autoscale_view()
    fig.canvas.draw()
    fig.canvas.flush_events()
    plt.show()
    plt.ioff()
scan_transfocator_jb
scan_transfocator_jb(transfocator_motor, positions, image_sec)
Source code in tfs/transfocator_scan.py
def scan_transfocator_jb(self, transfocator_motor, positions, image_sec):
    pos_list = []
    fwhm_x_list = []
    fwhm_y_list = []

    fig, ax = plt.subplots(2, 1, sharex=True)
    fig.suptitle('2D Gaussian FWHM Scatter per Image')
    ax[0].set_ylabel('FWHM_x')
    ax[1].set_ylabel('FWHM_y')
    ax[1].set_xlabel('Transfocator Z-position')
    plt.ion()

    for idx, pos in enumerate(positions):
        transfocator_motor.umv(pos)
        timeout = time.time() + image_sec
        img_count = 0
        collect = True

        while collect:
            img = self.get_image_roi() 
            fit_result = fit_2d_gaussian_fixed_angle(img)
            if fit_result is not None:
                _, _, _, sigma_x, sigma_y, _ = fit_result
                pos_list.append(pos)
                fwhm_x_list.append(sigma_x)
                fwhm_y_list.append(sigma_y)
            else:
                pos_list.append(pos)
                fwhm_x_list.append(0)
                fwhm_y_list.append(0)
            img_count += 1
            if time.time() > timeout or img_count >= 20:
                collect = False

        # Live update plot
        ax[0].scatter(pos_list[-img_count:], fwhm_x_list[-img_count:], color='red')
        ax[1].scatter(pos_list[-img_count:], fwhm_y_list[-img_count:], color='blue')
        for a in ax:
            a.relim()
            a.autoscale_view()
        fig.canvas.draw()
        fig.canvas.flush_events()
        plt.pause(0.1)

    plt.ioff()
    plt.show()
twoD_gaussian_fixed_angle
twoD_gaussian_fixed_angle(xy, amplitude, xo, yo, sigma_x, sigma_y, offset)
Source code in tfs/transfocator_scan.py
def twoD_gaussian_fixed_angle(xy, amplitude, xo, yo, sigma_x, sigma_y, offset):
    x, y = xy
    theta = 0  # Fixed angle in radians could optimize on tnis
    a = (np.cos(theta)**2)/(2*sigma_x**2) + (np.sin(theta)**2)/(2*sigma_y**2)
    b = -(np.sin(2*theta))/(4*sigma_x**2) + (np.sin(2*theta))/(4*sigma_y**2)
    c = (np.sin(theta)**2)/(2*sigma_x**2) + (np.cos(theta)**2)/(2*sigma_y**2)
    g = offset + amplitude * np.exp(- (a*((x - xo)**2) + 2*b*(x - xo)*(y - yo) + c*((y - yo)**2)))
    return g.ravel()

Functions

gaussian

gaussian(x, amplitude, mean, stddev)
Source code in tfs/transfocator_scan.py
def gaussian(x, amplitude, mean, stddev):
	return amplitude * np.exp(-((x - mean) / 4 / stddev)**2)