Source code for SyMBac.PSF

import numpy as np
from scipy.special import jv

[docs]def get_fluorescence_kernel(Lambda,NA,n,radius,scale): """ Returns a 2D numpy array which is an airy-disk approximation of the fluorescence point spread function Parameters ---------- Lambda : float Wavelength of imaging light (micron) NA : float Numerical aperture of the objective lens n : float Refractive index of the imaging medium (~1 for air, ~1.4-1.5 for oil) radius : int The radius of the PSF to be rendered in pixels scale : float The pixel size of the image to be rendered (micron/pix) Returns ------- 2-D numpy array representing the fluorescence contrast PSF """ r = np.arange(-radius,radius+1) kaw = 2* NA/n * np.pi/Lambda xx,yy = np.meshgrid(r,r) xx, yy = xx*scale, yy*scale rr = np.sqrt(xx**2+yy**2) * kaw PSF = (2*jv(1,rr)/(rr))**2 PSF[radius,radius] = 1 return PSF, np.sqrt(xx**2+yy**2)
[docs]def somb(x): """ Returns the sombrero function of a 2D numpy array. """ z = np.zeros(x.shape) x = np.abs(x) idx = np.nonzero(x) z[idx] = 2*jv(1,np.pi*x[idx])/(np.pi*x[idx]) return z
[docs]def get_phase_contrast_kernel(R,W,radius,scale,NA,n,sigma,λ): """ Returns a 2D numpy array which is the phase contrast kernel based on microscope parameters Parameters ---------- R : float The radius of the phase contrast condenser (in mm) W : float The width of the phase contrast condenser opening (in mm) radius : int The radius of the PSF to be rendered in pixels scale : float The pixel size of the image to be rendered (micron/pix) NA : float Numerical aperture of the objective lens n : float Refractive index of the imaging medium (~1 for air, ~1.4-1.5 for oil) sigma : radius of a 2D gaussian of the same size as the PSF (in pixels) which is multiplied by the PSF to simulate apodisation of the PSF λ : The mean wavelength of the imaging light (in micron) Returns ------- 2-D numpy array representing the phase contrast PSF """ scale1 = 1000 # micron per millimeter #F = F * scale1 # to microm Lambda = λ # in micron % wavelength of light R = R * scale1 # to microm W = W * scale1 # to microm #The corresponding point spread kernel function for the negative phase contrast r = np.arange(-radius,radius+1) xx,yy = np.meshgrid(r,r) xx, yy = xx*scale, yy*scale kaw = 2* NA/n * np.pi/Lambda rr = np.sqrt(xx**2 + yy**2)*kaw kernel1 = 2*jv(1,rr)/(rr) kernel1[radius,radius] = 1 kernel2 = 2*(R-W)**2/R**2 * jv(1,(R-W)**2/R**2 * rr)/rr kernel2[radius,radius] = np.nanmax(kernel2) kernel = kernel1 - kernel2 kernel = kernel/np.max(kernel) kernel[radius,radius] = 1 kernel = -kernel/np.sum(kernel) gaussian = gaussian_2D(radius*2+1, sigma) kernel = kernel * gaussian return kernel
[docs]def gaussian_2D(size, σ): """Returns a 2D gaussian (numpy array) of size (pixels x pixels) and gaussian radius (σ)""" x = np.linspace(0,size,size) μ = np.mean(x) A = 1/(σ*np.sqrt(2*np.pi)) B = np.exp(-1/2 * (x-μ)**2/(σ**2)) _gaussian_1D = A*B _gaussian_2D = np.outer(_gaussian_1D,_gaussian_1D) return _gaussian_2D
[docs]def get_condensers(): """Returns a dictionary of common phase contrast condenser dimensions, where the numbers are W, R, diameter (in mm)""" condensers = { "Ph1": (0.45, 3.75, 24), "Ph2": (0.8, 5.0, 24), "Ph3": (1.0, 9.5, 24), "Ph4": (1.5, 14.0, 24), "PhF": (1.5, 19.0, 25) } #W, R, Diameter return condensers