from ColdTOFU import ShadowImage, numAtomsBlue, update_progress, rcParams, temperature
import numpy as np
from scipy.constants import *
import matplotlib.pyplot as plt
from IPython.display import display
from scipy.optimize import curve_fit
from pandas import DataFrame
%matplotlib inline
First and foremost thing to modify is the resource parameter dictionary that holds the details of the imaging system, including the camera specs, that is used to extract the time of flight images. These details are used all over the package to convert the pixel units of the image to the real units to extract size of the atomic cloud in real units. To check the default parameters, one could see the "params" attribute of the rcParams class as shown below. To update these parameters, use "update" method passing the property as a string and its corresponding value.
params = rcParams().params
print(params)
#Example to update magnification: rcParams().update('magnification', 3)
{'binning': 2, 'magnification': 2.07, 'pixelSize': 6.5e-06, 'quantum efficiency': 0.85, 'mass number': 87}
Number of atoms is estimated by extracting extracting the optical thickness from the image sequence. Once optical thickness is obtained from ShadowImage class, this is fit to a 2D gaussian and volume under the 2D gaussian is calculated. Number of atoms is estimated by dividing this volume with the scattering cross section. In this example, the atoms used are fermionic strontium 87 atoms and probe targeting $^1S_0 \rightarrow ^1P_1$ transition at 461 nm is used. In case you are using a different species of atoms, this function needs to be modified to use the scattering cross section of the that atom with the probe laser.
pathOfImage = '../Image Data/20211127/shadow_imag_#3150.tif'
averaging = 3
im = ShadowImage(pathOfImage)
od = im.averagedSignalOD(averaging, truncate=[])
start = 7*milli
step = 2*milli
timeStamps = start + np.arange(0, im.nSamples, 1)*step
# use ROIUpdater.ipynb to create an ROI file
# choose ROI such that the atomic cloud is at the center of the ROI
roi = np.loadtxt('ROIs/roi_#3146.txt', dtype=int)
n = np.zeros((im.nSamples,8)) #numAtomsReturnValues
x = np.zeros(im.nSamples) #x centers (along free fall direction) of the cloud
for i in range(im.nSamples):
update_progress(i)
j = i
n[i] = numAtomsBlue(od[i][roi[j,0]:roi[j,1], roi[j,2]:roi[j,3]], 0, plot=True)[:8]
x[i] = (n[i, 6] + roi[j, 2])*6.5*micro*params['binning']/params['magnification']
DataFrame(n, timeStamps, ['$N_{GaussFit}$', '$N_{Pixel Sum}$', '$n (m^{-3})$', '$\sigma_x(pix)$', '$\sigma_y(pix)$', '$OD^{max}$', '$x_0$', '$y_0$'])
Progress : [##################################################] 100.0%
$N_{GaussFit}$ | $N_{Pixel Sum}$ | $n (m^{-3})$ | $\sigma_x(pix)$ | $\sigma_y(pix)$ | $OD^{max}$ | $x_0$ | $y_0$ | |
---|---|---|---|---|---|---|---|---|
0.007 | 53926.872009 | 49713.785500 | 5.066690e+17 | 2.890528 | 3.135337 | 1.465715 | 19.900446 | 16.905352 |
0.009 | 58555.309082 | 28815.755149 | 3.051281e+17 | 3.588050 | 3.741724 | 1.074340 | 14.963922 | 16.195200 |
0.011 | 60786.298588 | 4999.340707 | 1.773953e+17 | 4.164575 | 4.744741 | 0.757754 | 18.392828 | 20.492358 |
0.013 | 62478.065419 | -2497.043558 | 1.205500e+17 | 4.851972 | 5.366150 | 0.591088 | 21.295724 | 19.763900 |
To extract the temperature, call the temperature function with sizes of the clouds obtained from numAtomsBlue function and corresponding times of flight as shown below.
sizes = n[:,3:5] #sizes from the 2D Gaussian fit
Tx, Ty = temperature(sizes, timeStamps)
# free fall equation of motion
def func(t, g, y0):
return y0-0.5*g*t**2
popt, pcov = curve_fit(func, timeStamps, x, p0=[9.8, 0.002])
plt.plot(timeStamps, x, 'o')
plt.plot(timeStamps, func(timeStamps, *popt))
print('acc. due to gravity:'+str(popt[0]))
acc. due to gravity:9.807112897427652