Exemplo n.º 1
0
def compareKien():
    """compare Kien 2013 Fig 4,5"""
    bprop =[880e-9,20e-3,1e-6]
    Cs = atom(atm = 'Cs133')
    Cs880 = dipole(Cs, (0,1/2.,3,3), bprop)
                    
    CsP = dipole(Cs, (1,3/2.,3,3), bprop)               
    
    wls = [np.linspace(680, 690, 200)*1e-9, np.linspace(930, 940, 200)*1e-9]
    ylims = [(-1200, 300), (-3000, 6000)]
    for ii in range(2):
        plt.figure()
        plt.title("Cs Polarisabilities. Red: 6S$_{1/2}$, Blue: 6P$_{3/2}$.\nscalar: solid, vector: dashed, tensor: dotted")
        a1 = Cs880.polarisability(wls[ii],mj=0.5,split=True)
        a2 = 0.5*(np.array(CsP.polarisability(wls[ii],mj=1.5, split=True))+
            np.array(CsP.polarisability(wls[ii],mj=0.5, split=True)))
        ls = ['-', '--', ':']
        for i in range(3):
            plt.plot(wls[ii]*1e9, a1[i]/au, 'r', linestyle=ls[i], label="Cs")
            plt.plot(wls[ii]*1e9, a2[i]/au, 'b', linestyle=ls[i], label="$P_{3/2}$")
        #plt.legend()
        plt.ylim(ylims[ii])
        plt.xlabel("Wavelength (nm)")
        plt.ylabel("Polarisablity (a.u.)")
        plt.show()
Exemplo n.º 2
0
def vmfSS(ATOM):
    """Return the Stark shifts of the MF states for Cs cooling/repump transitions"""
    
    plt.figure()
    
    if ATOM.atm == 'Cs133':
        Cs = ATOM
        F = 5
        bprop = [938e-9, 8e-3, 1.7e-6]      # wavelength, beam power, beam waist
        for MFp in range(-F, F+1, 1):
            P = dipole(Cs, (1,3/2.,F,MFp), bprop)
            Pshift = P.acStarkShift(0,0,0, bprop[0], HF=True)/h/1e6    # interested in how the EStates shift relative to each other
            plt.plot(MFp, Pshift, '_', markersize=15, linewidth=10, color = '#7E317B')
            print("|F' = "+str(F)+", m_F' = "+str(MFp)+"> : %.5g MHz"%Pshift)
        
    elif ATOM.atm == 'Rb87':
        Rb = ATOM
        F = 3
        bprop = [940e-9, 35e-3, 1.7e-6]      # wavelength, beam power, beam waist
        for MFp in range(-F, F+1, 1):
            P = dipole(Rb, (1,3/2.,F,MFp), bprop)
            Pshift = P.acStarkShift(0,0,0, bprop[0], HF=True)/h/1e6    # interested in how the EStates shift relative to each other
            s, v, t = P.polarisability(bprop[0], mj=3/2, HF=False, split=True)
           # print('split ',s/au, t/au)
            s, v, t = P.polarisability(bprop[0], mj=3/2, HF=True, split=True)
         #   print('avrge ',s/au, t/au)
            plt.plot(MFp, Pshift, '_', markersize=15, linewidth=10, color = '#7E317B')
            print("|F' = "+str(F)+", m_F' = "+str(MFp)+"> : %.5g MHz"%Pshift)
    
    plt.title('Stark Shifts of ' + ATOM.atm  + " |F' = " + str(F) + ', $M_F$> states' )            
    plt.xlabel("$M_F$")  
    plt.ylabel("AC Stark Shift (MHz)")
    plt.show()
Exemplo n.º 3
0
def getMFStarkShifts(
        wavelength=1064e-9,  # laser wavelength in m
        power=0.00906143,  # laser power in W
        beamwaist=1e-6,  # beam waist in m
        plotit=False):  # toggle to plot the results
    """Return the Stark shifts of the MF states for cooling/repump transitions.
    Units are MHz"""
    bprop = [wavelength, power, beamwaist]  # collect beam properties
    Fs = [1, 2]
    numstates = sum(2 * np.array(Fs) +
                    1) * 3  # total number of hyperfine transitions
    l1 = [6, 12]  # index of lines for making legend
    #
    states = np.zeros((numstates, 3), dtype=int)  # F, MF, MFprime
    shifts = np.zeros(numstates)  # differential ac Stark shifts
    i = 0  # index
    for F in Fs:
        for MF in range(-F, F + 1):
            for MFp in range(MF - 1, MF + 2):
                S = dipole(Rb, (0, 1 / 2., F, MF), bprop)
                P = dipole(Rb, (1, 3 / 2., F + 1, MFp), bprop)
                #
                states[i] = (F, MF, MFp)
                # units are MHz
                shifts[i] = (
                    S.acStarkShift(0, 0, 0, bprop[0], HF=True) -
                    P.acStarkShift(0, 0, 0, bprop[0], HF=True)) / h / 1e6
                i += 1
    #
    if plotit:
        plt.figure()
        colors = plt.rcParams['axes.prop_cycle'].by_key()['color']
        i = 0
        for F, MF, MFp in states:
            if MF != 0:
                deltaMF = (MFp - MF) * np.sign(MF)
            else:
                deltaMF = (MFp - MF)
            plt.plot(MF,
                     shifts[i],
                     '_',
                     color=colors[F - 1],
                     alpha=0.33 * (2 + deltaMF),
                     markersize=15,
                     linewidth=10)
            i += 1
        plt.xlabel("$M_F$")
        plt.ylabel("AC Stark Shift (MHz)")
        lines = plt.gca().lines
        plt.legend(lines[l1[0]:l1[1]], [
            'F=' + str(f) + r', $\Delta M_F=$' + str(-dmf)
            for f in range(min(Fs),
                           max(Fs) + 1) for dmf in range(-1, 2)
        ])
        plt.show()
    #
    return states, shifts
Exemplo n.º 4
0
def getMFStarkShifts():
    """Return the Stark shifts of the MF states for Cs cooling/repump transitions"""

    print(
        "stark shift of Cs 6S1/2 -> 6P3/2 for different MF states at 1064nm for beam power 6 mW, beam waist 1 micron, giving trap depth 1 mK"
    )
    bprop = [1064e-9, 6e-3, 1e-6]  # wavelength, beam power, beam waist

    plt.figure()
    # colors = plt.rcParams['axes.prop_cycle'].by_key()['color']
    colors = ['k', 'r']
    for F in [3, 4]:
        for MF in range(-F, F + 1):
            print(" ----- |F = " + str(F) + ", m_F = " + str(MF) + ">")
            for MFp in range(MF - 1, MF + 2):
                S = dipole(Cs.m, (0, 1 / 2., F, MF),
                           bprop,
                           Cs.D0S,
                           Cs.w0S,
                           Cs.lwS,
                           Cs.nljS,
                           nuclear_spin=Cs.I,
                           symbol=Cs.X)
                P = dipole(Cs.m, (1, 3 / 2., F + 1, MFp),
                           bprop,
                           Cs.D0P3,
                           Cs.w0P3,
                           Cs.lwP3,
                           Cs.nljP3,
                           nuclear_spin=Cs.I,
                           symbol=Cs.X)
                shift = (S.acStarkShift(0, 0, 0, bprop[0], HF=True) -
                         P.acStarkShift(0, 0, 0, bprop[0], HF=True)) / h / 1e6
                if MF != 0:
                    deltaMF = (MFp - MF) * np.sign(MF)
                else:
                    deltaMF = (MFp - MF)
                plt.plot(MF,
                         shift,
                         '_',
                         color=colors[F - 3],
                         alpha=0.33 * (2 + deltaMF),
                         markersize=15,
                         linewidth=10)
                print("|F' = " + str(F + 1) + ", m_F' = " + str(MFp) +
                      "> : %.5g MHz" % shift)

    plt.xlabel("$M_F$")
    plt.ylabel("AC Stark Shift (MHz)")
    lines = plt.gca().lines
    plt.legend(lines[18:24], [
        'F=' + str(f) + ', $\Delta M_F=$' + str(-dmf) for f in range(3, 5)
        for dmf in range(-1, 2)
    ])
    plt.show()
Exemplo n.º 5
0
def compareArora():
    """Plot Fig. 5 - 8 in Arora et al 2007 to show that the polarisabilities 
    of Rb and Cs without hyperfine levels are correct"""
    # beam properties: wavelength, power, beam waist
    # intensity set to 1e10 MW/cm^2
    bprop = [1064e-9, np.pi*0.5e-2, 1e-6]
    
    for ATOM in [atom(atm = 'Rb87'), atom(atm = 'Cs133')]:
        if ATOM.X == 'Rb87':
            wavel1 = np.linspace(780, 800, 200)*1e-9
            Ylim1 = (-8000, 8000)
            wavel2 = np.linspace(787,794, 200)*1e-9 
            Ylim2 = (-1000, 1000)
            FS, FP = 1, 3
        elif ATOM.X == 'Cs133':
            wavel1 = np.linspace(925, 1000, 200)*1e-9
            Ylim1 = (-1000, 5000)
            wavel2 = np.linspace(927, 945, 200)*1e-9
            Ylim2 = (-100, 100)
            FS, FP = 3, 5
            
        S = dipole(ATOM, (0,1/2.,FS,FS), bprop)
        
        P3 = dipole(ATOM, (1,3/2.,FP,FP), bprop)
                        
        # compare polarisability of excited states
        plt.figure()
        plt.title("Polarisability of "+ATOM.X)
        plt.plot(wavel1*1e9, S.polarisability(wavel1)/au, 'r', label='s')
        plt.plot(wavel1*1e9, P3.polarisability(wavel1,mj=0.5)/au, 'g--', label='p$_{3/2}$, mj=1/2')
        plt.plot(wavel1*1e9, P3.polarisability(wavel1,mj=1.5)/au, 'm:', label='p$_{3/2}$, mj=3/2')
        plt.legend()
        plt.xlabel("Wavelength (nm)")
        plt.ylabel("Polarisability (a.u.)")
        plt.ylim(Ylim1)
        plt.xlim(wavel1[0]*1e9, wavel1[-1]*1e9)
        
        # calculate stark shifts between F, MF states
        mfLS = ['r', 'g--', 'm:', 'c-.', 'k-.', 'y']  # line styles
        plt.figure()
        plt.title("AC Stark Shifts for transitions from P$_{3/2}$ m$_F$ to \nthe groundstate in "+ATOM.X)
        dES = S.acStarkShift(0,0,0, wavel2, HF=True)   # ground state stark shift
        for MF in range(FP+1):
            P3.MF = MF
            dEPMF = P3.acStarkShift(0,0,0, wavel2, HF=True) # excited MF state stark shift
            plt.plot(wavel2*1e9, (dEPMF - dES)/h/1e6, mfLS[MF], label=r'm$_F$ = $\pm$'+str(MF))
        xlims = [wavel2[0]*1e9, wavel2[-1]*1e9]
        plt.plot(xlims, [0,0], 'k:', alpha=0.4)  #  show where zero is
        plt.ylim(Ylim2)
        plt.xlim(xlims)
        plt.xlabel("Wavelength (nm)")
        plt.ylabel("Stark Shift (MHz)")
        plt.legend()
        
    plt.show()
Exemplo n.º 6
0
def plotPolarisability():
    """Plot the polarisability of Rb 5S and Cs 6S states highlighting our laser wavelengths"""
    bprop = [1064e-9, 6e-3, 1e-6]  # wavelength, beam power, beam waist
    wavelengths = np.linspace(700, 1100, 500) * 1e-9  # in m
    ymax = 5000

    # groundstate rubidium
    Rb5S = dipole(Rb, (0, 1 / 2., 1, 1), bprop)
    alphaRb = Rb5S.polarisability(
        wavelengths) / au  # polarisability in atomic units

    # groundstate caesium
    Cs6S = dipole(Cs, (0, 1 / 2., 4, 4), bprop)
    alphaCs = Cs6S.polarisability(
        wavelengths) / au  # polarisability in atomic units

    plt.figure()
    # split up the plotting so as not to have lines at resonances:
    for v in [[alphaRb, DUsea_blue, 'Rb 5S$_{1/2}$'],
              [alphaCs, DUcherry_red, 'Cs 6S$_{1/2}$']]:
        plus = np.where(v[0] > 0)[0]  # where polarisability is positive
        ind1 = plus[np.where(plus > np.arange(len(plus)) +
                             plus[0])[0][0]]  # second positive region
        plt.plot(wavelengths[:plus[0] - 1] * 1e9,
                 v[0][:plus[0] - 1],
                 color=v[1],
                 label=v[2])
        plt.plot(wavelengths[plus[0] + 1:ind1 - 1] * 1e9,
                 v[0][plus[0] + 1:ind1 - 1],
                 color=v[1])
        plt.plot(wavelengths[ind1 + 1:] * 1e9, v[0][ind1 + 1:], color=v[1])

    # plot dotted lines to show where the resonances are
    plt.plot([780] * 2, [-ymax, ymax], '--', color=DUsea_blue)
    plt.plot([795] * 2, [-ymax, ymax], '--', color=DUsea_blue)
    plt.plot([852.3] * 2, [-ymax, ymax], '--', color=DUcherry_red)
    plt.plot([894.6] * 2, [-ymax, ymax], '--', color=DUcherry_red)

    # show zero crossing
    plt.plot([wavelengths[0] * 1e9, wavelengths[-1] * 1e9], [0, 0],
             'k--',
             alpha=0.4)
    # show laser wavelengths
    # plt.fill_between([1060,1070], ymax, -ymax, color=DUcherry_red, alpha=0.3)
    # plt.fill_between([935,945], ymax, -ymax, color=DUcherry_red, alpha=0.3)
    # plt.fill_between([878, 882], ymax, -ymax, color=DUsea_blue, alpha=0.3)
    # plt.fill_between([805,825], ymax, -ymax, color=DUsea_blue, alpha=0.3)
    plt.ylim((-ymax, ymax))
    plt.ylabel('Polarisability ($a_0^3$)')
    plt.xlim((wavelengths[0] * 1e9, wavelengths[-1] * 1e9))
    plt.xlabel('Wavelength (nm)')
    plt.legend()
    plt.tight_layout()
    plt.show()
Exemplo n.º 7
0
def getMFStarkShifts(
        wavelength=1064e-9,  # laser wavelength in m
        power=0.00906143,  # laser power in W
        beamwaist=1e-6,  # beam waist in m
        ATOM=Cs):
    """Return the Stark shifts of the MF states for cooling/repump transitions"""
    bprop = [wavelength, power, beamwaist]  # collect beam properties
    if ATOM == Cs:  # assign the relevant hyperfine transitions
        Fs = [3, 4]
        l1 = [18, 24]  # index of lines for making legend
    elif ATOM == Rb:
        Fs = [1, 2]
        l1 = [6, 12]  # index of lines for making legend

    # print("Stark shift of "+ATOM.X+" S1/2 F = %s, %s -> P3/2 F' = %s, %s for different MF states."%(Fs[0],Fs[0]+1,Fs[1],Fs[1]+1))

    plt.figure()
    colors = plt.rcParams['axes.prop_cycle'].by_key()['color']
    for F in Fs:
        for MF in range(-F, F + 1):
            print(" ----- |F = " + str(F) + ", m_F = " + str(MF) + ">")
            for MFp in range(MF - 1, MF + 2):
                S = dipole(ATOM, (0, 1 / 2., F, MF), bprop)
                P = dipole(ATOM(1, 3 / 2., F + 1, MFp), bprop)
                shift = (S.acStarkShift(0, 0, 0, bprop[0], HF=True) -
                         P.acStarkShift(0, 0, 0, bprop[0], HF=True)) / h / 1e6
                if MF != 0:
                    deltaMF = (MFp - MF) * np.sign(MF)
                else:
                    deltaMF = (MFp - MF)
                plt.plot(MF,
                         shift,
                         '_',
                         color=colors[F - 1],
                         alpha=0.33 * (2 + deltaMF),
                         markersize=15,
                         linewidth=10)
                print("|F' = " + str(F + 1) + ", m_F' = " + str(MFp) +
                      "> : %.5g MHz" % shift)

    plt.xlabel("$M_F$")
    plt.ylabel("Differential AC Stark Shift (MHz)")
    lines = plt.gca().lines
    plt.legend(lines[l1[0]:l1[1]], [
        'F=' + str(f) + r', $\Delta M_F=$' + str(-dmf)
        for f in range(min(Fs),
                       max(Fs) + 1) for dmf in range(-1, 2)
    ])
    plt.show()
Exemplo n.º 8
0
    def showResult():
        wavelength = float(entrystrings[0].get())  # laser wavelength in nm
        beamwaist = float(entrystrings[1].get())  # beam waist in m
        power = float(entrystrings[2].get())  # power in Watts
        bprop = [wavelength, power, beamwaist]  # collect beam properties
        atomSymbol = entrystrings[3].get()  # choose Rb or Cs
        L = int(entrystrings[4].get())  # orbital angular momentum
        J = float(entrystrings[5].get())  # total angular momentum

        # choose element
        if atomSymbol == "Rb":
            atomObj = Rb
            F = 1
        elif atomSymbol == "Cs":
            atomObj = Cs
            F = 3
        else:
            messagebox.showinfo("Error", "You must choose Rb or Cs")
            return 0

        # get transition data for the given state
        if L == 0:
            D0, w0, lw, nlj = atomObj.D0S, atomObj.w0S, atomObj.lwS, atomObj.nljS
        elif L == 1 and J == 0.5:
            D0, w0, lw, nlj = atomObj.D0P1, atomObj.w0P1, atomObj.lwP1, atomObj.nljP1
        elif L == 1 and J == 1.5:
            D0, w0, lw, nlj = atomObj.D0P3, atomObj.w0P3, atomObj.lwP3, atomObj.nljP3

        # construct the instance of the dipole class
        dipoleObj = dipole(atomObj, (L, J, F, F), bprop)

        messagebox.showinfo("Calculation Result", getStarkShift(dipoleObj))
Exemplo n.º 9
0
def heatRate(wl, P, w0, trapfreq, X=Rb):
    """heating rate in units of vibrational quanta per second
    wl - wavelength (m)
    P  - beam power (W)
    w0 - beam waist (m)
    trapfreq - atomic trap frequency (rad/s)
    X  - instance of atom() class from AtomFieldInt_V3"""
    atom = dipole(X, (0,1/2.,1,1), [wl, P, w0])
    return atom.scatRate() * hbar * (2*np.pi/wl)**2 / 2 / X.m / trapfreq
Exemplo n.º 10
0

# compare trapping frequencies and Rabi frequencies between Rb/Cs
def wz(atom):
    """Axial trapping freq"""
    return np.sqrt(
        2 * np.abs(atom.acStarkShift(0, 0, 0) / atom.m / atom.field.zR**2))


def wr(atom):
    """Radial trap freq"""
    return np.sqrt(
        4 * np.abs(atom.acStarkShift(0, 0, 0) / atom.m / atom.field.w0**2))


rb5s = dipole(Rb, (0, 1 / 2., 1, 1), [814e-9, 1.46e-3, 1e-6])

print(rb5s.acStarkShift(0, 0, 0) / h / 1e6 / 20.7)
cs6s = dipole(Cs, (0, 1 / 2., 3, 3), [940e-9, 5.02e-3, 1.1e-6])

print(cs6s.acStarkShift(0, 0, 0) / h / 1e6 / 20.7)

print((wz(rb5s) / wz(cs6s))**2)
wl = 780.241209686e-9  # wavelength of D2 line in m  852.347065e-9
power = 100e-6  # in W
waist = 100e-6  # in m

# # calculate differential stark shifts for Raman transition
# X = Rb
# F, mF, Fp, mFp = 1, 1, 2, 2
# wl =  780.241209686e-9 # wavelength of D2 line in m  852.347065e-9
Exemplo n.º 11
0
Rbwl = 814e-9       # wavelength of the Rb tweezer trap in m
power = 8e-3       # power of Cs tweezer beam in W
Cswaist = 1.5e-6    # beam waist for Cs in m
Rbpower = power*0.43 # power of Rb tweezer beam in W 
Rbwaist = 1.5e-6    # beam waist fir Rb in m
minU0 = -0.6e-3*kB  # min acceptable combined trap depth for Cs
factorRb = 2        # how much deeper the Rb must be in its own trap
factorCs = 2        # how much deeper the Cs must be in its own trap
wavels = np.linspace(800, 840, 400) * 1e-9 # wavelengths to consider for Rb trap, in m

    
# For the 1064nm trap: at Cs wavelength with Cs power and Cs beam waist
# mass, (L,J,F,MF), bprop, dipole matrix elements (Cm), resonant frequencies (rad/s),
# linewidths (rad/s), state labels, nuclear spin, atomic symbol.
# groundstate rubidium 5 S 1/2
Rb1064 = dipole(Rb, (0,1/2.,1,1), [Cswl, power, Cswaist])
                
# groundstate caesium 6 S 1/2
Cs1064 = dipole(Cs, (0,1/2.,4,4), [Cswl, power, Cswaist])
                
print("Rb tweezer wavelength: %.0f nm\t\tCs tweezer wavelength: %.0f nm\n"%(Cswl*1e9, Rbwl*1e9))

# set the power of the traps so that the trap depth experienced by each 
# species in the overlapping trap is the same:
# Rbpower = (Cs1064.polarisability(Cswl,mj=0.5) - Rb1064.polarisability(Cswl, mj=0.5) 
#     )/ (Rb1064.polarisability(Rbwl, mj=0.5) - Cs1064.polarisability(Rbwl, mj=0.5)) * power

# Stability condition 1: 
def P1Rb(wlCs, wlRb, U0min=minU0, Cspower=power):
    """Condition 1: The combined trap depth must be > 0.6mK for Cs."""
    return abs((U0min*np.pi*eps0*c + Cs1064.polarisability(wlCs)*Cspower/Cswaist**2) 
Exemplo n.º 12
0
def combinedTrap(Cswl = 1064e-9, # wavelength of the Cs tweezer trap in m
                Rbwl = 880e-9, # wavelength of the Rb tweezer trap in m
                power = 6e-3, # power of Cs tweezer beam in W
                Rbpower = -1, # power of Rb tweezer beam in W 
                beamwaist = 1e-6): # beam waist in m
    """Model tweezer traps for Rb and Cs and find the potential each experiences
    when they're overlapping. Should fix the separate tweezer trap depths to >1mK.
    We also want Rb to experience a deeper trap from its tweezer than from the Cs
    tweezer so that there isn't too much heating during merging.
    args:
    Cswl = 1064e-9, # wavelength of the Cs tweezer trap in m
    Rbwl = 880e-9, # wavelength of the Rb tweezer trap in m
    power = 6e-3, # power of Cs tweezer beam in W
    Rbpower = -1, # power of Rb tweezer beam in W (if < 0 then choose a power
    such that both species experience the same trap depth when the tweezers are
    overlapping)
    beamwaist = 1e-6 # beam waist in m
    """
    bprop = [Cswl, power, beamwaist] # collect beam properties
    
    # For the 1064nm trap:
    # mass, (L,J,F,MF), bprop, dipole matrix elements (Cm), resonant frequencies (rad/s),
    # linewidths (rad/s), state labels, nuclear spin, atomic symbol.
    # groundstate rubidium
    Rb = atom(atm = 'Rb87')
    Rb1064 = dipole(Rb, (0,1/2.,1,1), bprop)
                    
    # groundstate caesium
    Cs = atom(atm = 'Cs133')
    Cs1064 = dipole(Cs, (0,1/2.,4,4), bprop)
                    
    CsP = dipole(Cs, (1,3/2.,5,5), bprop)
                    
    # set the power of the traps so that the trap depth experienced by each 
    # species in the overlapping trap is the same:
    if Rbpower < 0:
        Rbpower = (Cs1064.polarisability(Cswl,mj=0.5) - Rb1064.polarisability(Cswl, mj=0.5)) / (Rb1064.polarisability(Rbwl, mj=0.5) - Cs1064.polarisability(Rbwl, mj=0.5)) * power
    
    # for the 880nm trap:
    bprop = [Rbwl, abs(Rbpower), beamwaist]
    Rb880 = dipole(Rb, (0,1/2.,1,1), bprop)
                    
    Cs880 = dipole(Cs, (0,1/2.,3,3), bprop)
                    
    
    # in the trap with both tweezers overlapping: 
    U0 = abs(Rb1064.acStarkShift(0,0,0) + Rb880.acStarkShift(0,0,0))
    wrRb = np.sqrt(4*U0 / Rb.m / beamwaist**2) /2. /np.pi /1e3
    wrCs = np.sqrt(4*U0 / Cs.m / beamwaist**2) /2. /np.pi /1e3
    print("%.0f beam power: %.3g mW\t\t%.0f beam power: %.3g mW"%(Cswl*1e9, power*1e3, Rbwl*1e9, Rbpower*1e3))
    print("""In the combined %.0fnm and %.0fnm trap with a depth of %.3g mK the radial trapping frequencies are: 
Rubidium: %.0f kHz \nCaesium: %.0f kHz"""%(Rbwl*1e9, Cswl*1e9, U0/kB*1e3, wrRb, wrCs))
    
    # with just the Cs tweezer trap:
    URb =abs(Rb1064.acStarkShift(0,0,0))
    wrRb1064 = np.sqrt(4*URb / Rb.m / beamwaist**2) /2. /np.pi /1e3
    UCs = abs(Cs1064.acStarkShift(0,0,0))
    wrCs1064 = np.sqrt(4*UCs / Cs.m / beamwaist**2) /2. /np.pi /1e3
    print("""\nIn just the %.0fnm trap:
    Rubidium has trap depth %.3g mK
                 radial trapping frequency %.0f kHz
    Caesium has trap depth %.3g mK
                radial trapping frequency %.0f kHz"""%(Cswl*1e9, URb/kB*1e3, wrRb1064, UCs/kB*1e3, wrCs1064))
    
    print(getStarkShift(Cs1064))
    print(getStarkShift(CsP))
    
    # plot merging traps:
    n = 5   # number of time steps in merging to plot
    sep = np.linspace(0, 10e-6, n)     # initial separation of the tweezer traps
    zs = np.linspace(-2, 10, 200)*1e-6 # positions along the beam axis
    
    for atoms in [[Rb1064, Rb880], [Cs1064, Cs880]]:
        plt.figure()
        plt.subplots_adjust(hspace=0.01)
        
        for i in range(n):
            ax = plt.subplot2grid((n,1), (i,0))
            
            U = (atoms[0].acStarkShift(0,0,zs) + atoms[1].acStarkShift(0,0,zs-sep[n-i-1]))/kB*1e3 # combined potential along the beam axis
            U1064 = atoms[0].acStarkShift(0,0,zs)/kB*1e3         # potential in the 1064 trap
            U880 = atoms[1].acStarkShift(0,0,zs-sep[n-i-1])/kB*1e3 # potential in the 880 trap
            plt.plot(zs*1e6, U, 'k')
            plt.plot(zs*1e6, U1064, color='tab:orange', alpha=0.6)
            plt.plot(zs*1e6, U880, color='tab:blue', alpha=0.6)
            plt.plot([0]*2, [min(U),0], color='tab:orange', linewidth=10, label='%.0f'%(Cswl*1e9), alpha=0.4)
            plt.plot([sep[n-i-1]*1e6]*2, [min(U),0], color='tab:blue', linewidth=10, label='%.0f'%(Rbwl*1e9), alpha=0.4)
            ax.set_xticks([])
            ax.set_yticks([])

            if i == 0:
                ax.set_title("Optical potential experienced by "+atoms[0].X
        +"\n%.0f beam power: %.3g mW   %.0f beam power: %.3g mW"%(Cswl*1e9, power*1e3, Rbwl*1e9, Rbpower*1e3),
                    pad = 25)
                plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3, ncol=2, mode="expand", borderaxespad=0.)
        
            
        plt.xlabel(r'Position ($\mu$m)')
        ax.set_xticks(sep*1e6)
        plt.ylabel('Trap Depth (mK)')
        ax.yaxis.set_major_locator(AutoLocator())
        
    plt.show()
Exemplo n.º 13
0
def plotStarkShifts(
        wavelength=880e-9,  # laser wavelength in nm
        beamwaist=1e-6,  # beam waist in m
        power=20e-3):  # power in Watts
    """Find the ac Stark Shifts in Rb, Cs"""
    # typical optical tweezer parameters:
    bprop = [wavelength, power, beamwaist]  # collect beam properties

    # mass, (L,J,F,MF), bprop, dipole matrix elements (Cm), resonant frequencies (rad/s),
    # linewidths (rad/s), state labels, nuclear spin, atomic symbol.
    Rb5S = dipole(Rb.m, (0, 1 / 2., 1, 1),
                  bprop,
                  Rb.D0S,
                  Rb.w0S,
                  Rb.lwS,
                  Rb.nljS,
                  nuclear_spin=Rb.I,
                  symbol=Rb.X)

    Rb5P = dipole(Rb.m, (1, 3 / 2., 1, 1),
                  bprop,
                  Rb.D0P3,
                  Rb.w0P3,
                  Rb.lwP3,
                  Rb.nljP3,
                  nuclear_spin=Rb.I,
                  symbol=Rb.X)

    Cs6S = dipole(Cs.m, (0, 1 / 2., 3, 3),
                  bprop,
                  Cs.D0S,
                  Cs.w0S,
                  Cs.lwS,
                  Cs.nljS,
                  nuclear_spin=Cs.I,
                  symbol=Cs.X)

    Cs6P = dipole(Cs.m, (1, 3 / 2., 3, 3),
                  bprop,
                  Cs.D0P3,
                  Cs.w0P3,
                  Cs.lwP3,
                  Cs.nljP3,
                  nuclear_spin=Cs.I,
                  symbol=Cs.X)

    # need a small spacing to resolve the magic wavelengths - so it will run slow
    # to resolve magic wavelengths, take about 10,000 points.
    wavels = np.linspace(700e-9, 1100e-9, 500)

    # ac Stark Shift in Joules:
    dE6S = Cs6S.acStarkShift(0, 0, 0, wavels, mj=0.5, HF=False)
    dE6P = Cs6P.acStarkShift(0, 0, 0, wavels, mj=1.5, HF=False)
    dif6P = dE6P - dE6S

    magic6P = getMagicWavelengths(dif6P, dE6P, wavels)

    plt.figure()
    plt.title("AC Stark Shift in $^{133}$Cs")
    plt.plot(wavels * 1e9, dE6S / h * 1e-6, 'b--', label='Ground S$_{1/2}$')
    plt.plot(wavels * 1e9, dE6P / h * 1e-6, 'r-.', label='Excited P$_{3/2}$')
    plt.plot(wavels * 1e9, (dif6P) / h * 1e-6, 'k', label='Difference')
    plt.plot([magic6P[0] * 1e9] * 2,
             [min(dif6P / h / 1e6), max(dif6P / h / 1e6)],
             'm:',
             label='Magic Wavelength')
    plt.legend()
    for mw in magic6P[1:]:
        plt.plot(
            [mw * 1e9] * 2,
            [min(dif6P / h / 1e6), max(dif6P / h / 1e6)], 'm:')
    plt.ylabel("Stark Shift (MHz)")
    plt.xlabel("Wavelength (nm)")
    plt.xlim(wavels[0] * 1e9, wavels[-1] * 1e9)
    plt.ylim(-2200, 2200)
    plt.plot(wavels * 1e9, np.zeros(len(wavels)), 'k',
             alpha=0.25)  # show zero crossing
    plt.show()
    print("Magic wavelengths at:\n", magic6P)

    # ac Stark Shift in Joules:
    dE5S = Rb5S.acStarkShift(0, 0, 0, wavels, mj=0.5, HF=False)
    dE5P = Rb5P.acStarkShift(0, 0, 0, wavels, mj=1.5, HF=False)
    dif5P = dE5P - dE5S

    plt.figure()
    plt.title("AC Stark Shift in $^{87}$Rb")
    plt.plot(wavels * 1e9, dE5S / h * 1e-6, 'b--', label='Ground S$_{1/2}$')
    plt.plot(wavels * 1e9, dE5P / h * 1e-6, 'r-.', label='Excited P$_{3/2}$')
    plt.plot(wavels * 1e9, (dif5P) / h * 1e-6, 'k', label='Difference')
    plt.legend()
    plt.ylabel("Stark Shift (MHz)")
    plt.xlabel("Wavelength (nm)")
    plt.ylim(-500, 500)
    plt.plot(wavels * 1e9, np.zeros(len(wavels)), 'k',
             alpha=0.25)  # show zero crossing
    plt.show()
Exemplo n.º 14
0
def combinedTrap(
        Cswl=1064e-9,  # wavelength of the Cs tweezer trap in m
        Rbwl=880e-9,  # wavelength of the Rb tweezer trap in m
        power=20e-3,  # power in W
        beamwaist=1e-6):  # beam waist in m
    """Model tweezer traps for Rb and Cs and find the potential each experiences
    when they're overlapping"""
    bprop = [Cswl, power, beamwaist]  # collect beam properties

    # For the 1064nm trap:
    # mass, (L,J,F,MF), bprop, dipole matrix elements (Cm), resonant frequencies (rad/s),
    # linewidths (rad/s), state labels, nuclear spin, atomic symbol.
    # groundstate rubidium
    Rb1064 = dipole(Rb.m, (0, 1 / 2., 1, 1),
                    bprop,
                    Rb.D0S,
                    Rb.w0S,
                    Rb.lwS,
                    Rb.nljS,
                    nuclear_spin=Rb.I,
                    symbol=Rb.X)

    # groundstate caesium
    Cs1064 = dipole(Cs.m, (0, 1 / 2., 4, 4),
                    bprop,
                    Cs.D0S,
                    Cs.w0S,
                    Cs.lwS,
                    Cs.nljS,
                    nuclear_spin=Cs.I,
                    symbol=Cs.X)

    CsP = dipole(Cs.m, (1, 3 / 2., 5, 5),
                 bprop,
                 Cs.D0P3,
                 Cs.w0P3,
                 Cs.lwP3,
                 Cs.nljP3,
                 nuclear_spin=Cs.I,
                 symbol=Cs.X)

    # set the power of the traps so that the trap depth experienced by each
    # species in the overlapping trap is the same:
    P880 = (Cs1064.polarisability(Cswl, mj=0.5) - Rb1064.polarisability(
        Cswl, mj=0.5)) / (Rb1064.polarisability(Rbwl, mj=0.5) -
                          Cs1064.polarisability(Rbwl, mj=0.5)) * power

    # for the 880nm trap:
    bprop = [Rbwl, abs(P880), beamwaist]
    Rb880 = dipole(Rb.m, (0, 1 / 2., 1, 1),
                   bprop,
                   Rb.D0S,
                   Rb.w0S,
                   Rb.lwS,
                   Rb.nljS,
                   nuclear_spin=Rb.I,
                   symbol=Rb.X)

    Cs880 = dipole(Cs.m, (0, 1 / 2., 3, 3),
                   bprop,
                   Cs.D0S,
                   Cs.w0S,
                   Cs.lwS,
                   Cs.nljS,
                   nuclear_spin=Cs.I,
                   symbol=Cs.X)

    # in the trap with both tweezers overlapping:
    U0 = abs(Rb1064.acStarkShift(0, 0, 0) + Rb880.acStarkShift(0, 0, 0))
    wrRb = np.sqrt(4 * U0 / Rb.m / beamwaist**2) / 2. / np.pi / 1e3
    wrCs = np.sqrt(4 * U0 / Cs.m / beamwaist**2) / 2. / np.pi / 1e3
    print("%.0f beam power: %.3g mW\t\t%.0f beam power: %.3g mW" %
          (Cswl * 1e9, power * 1e3, Rbwl * 1e9, P880 * 1e3))
    print(
        """In the combined %.0fnm and %.0fnm trap with a depth of %.3g mK the radial trapping frequencies are: 
Rubidium: %.0f kHz \nCaesium: %.0f kHz""" %
        (Rbwl * 1e9, Cswl * 1e9, U0 / kB * 1e3, wrRb, wrCs))

    # with just the Cs tweezer trap:
    URb = abs(Rb1064.acStarkShift(0, 0, 0))
    wrRb1064 = np.sqrt(4 * URb / Rb.m / beamwaist**2) / 2. / np.pi / 1e3
    UCs = abs(Cs1064.acStarkShift(0, 0, 0))
    wrCs1064 = np.sqrt(4 * UCs / Cs.m / beamwaist**2) / 2. / np.pi / 1e3
    print("""\nIn just the %.0fnm trap:
    Rubidium has trap depth %.3g mK
                 radial trapping frequency %.0f kHz
    Caesium has trap depth %.3g mK
                radial trapping frequency %.0f kHz""" %
          (Cswl * 1e9, URb / kB * 1e3, wrRb1064, UCs / kB * 1e3, wrCs1064))

    print(getStarkShift(Cs1064))
    print(getStarkShift(CsP))

    # plot merging traps:
    n = 5  # number of time steps in merging to plot
    sep = np.linspace(0, 10e-6, n)  # initial separation of the tweezer traps
    zs = np.linspace(-2, 10, 200) * 1e-6  # positions along the beam axis

    for atoms in [[Rb1064, Rb880], [Cs1064, Cs880]]:
        plt.figure()
        plt.subplots_adjust(hspace=0.01)
        for i in range(n):
            ax = plt.subplot2grid((n, 1), (i, 0))
            if i == 0:
                ax.set_title(
                    "Optical potential experienced by " + atoms[0].X +
                    "\n%.0f beam power: %.3g mW   %.0f beam power: %.3g mW" %
                    (Cswl * 1e9, power * 1e3, Rbwl * 1e9, P880 * 1e3))

            U = (atoms[0].acStarkShift(0, 0, zs) +
                 atoms[1].acStarkShift(0, 0, zs - sep[n - i - 1])
                 ) / kB * 1e3  # combined potential along the beam axis
            U1064 = atoms[0].acStarkShift(
                0, 0, zs) / kB * 1e3  # potential in the 1064 trap
            U880 = atoms[1].acStarkShift(
                0, 0,
                zs - sep[n - i - 1]) / kB * 1e3  # potential in the 880 trap
            plt.plot(zs * 1e6, U, 'k')
            plt.plot(zs * 1e6, U1064, color='tab:orange', alpha=0.6)
            plt.plot(zs * 1e6, U880, color='tab:blue', alpha=0.6)
            plt.plot([0] * 2, [min(U), 0],
                     color='tab:orange',
                     linewidth=10,
                     label='%.0f' % (Cswl * 1e9),
                     alpha=0.4)
            plt.plot([sep[n - i - 1] * 1e6] * 2, [min(U), 0],
                     color='tab:blue',
                     linewidth=10,
                     label='%.0f' % (Rbwl * 1e9),
                     alpha=0.4)
            ax.set_xticks([])
            ax.set_yticks([])

        plt.xlabel('Position ($\mu$m)')
        ax.set_xticks(sep * 1e6)
        plt.ylabel('Trap Depth (mK)')
        ax.yaxis.set_major_locator(AutoLocator())

    plt.show()
Exemplo n.º 15
0
        'F=' + str(f) + ', $\Delta M_F=$' + str(-dmf) for f in range(3, 5)
        for dmf in range(-1, 2)
    ])
    plt.show()


if __name__ == "__main__":
    wavelength = 1064e-9  # wavelength in m
    power = 6e-3  # beam power in W
    beamwaist = 1e-6  # beam waist in m
    bprop = [wavelength, power, beamwaist]

    Rb5P1 = dipole(Rb.m, (1, 1 / 2., 1, 1),
                   bprop,
                   Rb.D0P1,
                   Rb.w0P1,
                   Rb.lwP1,
                   Rb.nljP1,
                   nuclear_spin=Rb.I,
                   symbol=Rb.X)
    Rb5P3 = dipole(Rb.m, (1, 3 / 2., 1, 1),
                   bprop,
                   Rb.D0P3,
                   Rb.w0P3,
                   Rb.lwP3,
                   Rb.nljP3,
                   nuclear_spin=Rb.I,
                   symbol=Rb.X)

    # print(getStarkShift(Rb5P1))
    print(getStarkShift(Rb5P3))
    print(np.array(Rb5P3.polarisability(795e-9, HF=True, split=True)) / au)
Exemplo n.º 16
0
from AtomFieldInt_V3 import (dipole, atom, c, eps0, h, hbar, a0, e, me, kB,
                             amu, Eh, au, atom)

Rb = atom(atm='Rb87')
Cs = atom(atm='Cs133')
Na = atom(atm='Na23')

Cswl = 976e-9  # wavelength of the Cs tweezer trap in m
Nawl = 700e-9  # wavelength of the Rb tweezer trap in m
Cspower = 5e-3  # power of Cs tweezer beam in W
Napower = 5e-3  # power of Rb tweezer beam in W
Cswaist = 0.8e-6  # beam waist for Cs in m
Nawaist = 0.7e-6  # beam waist fir Na in m

# Cs in its own tweezer
Cs976 = dipole(Cs, (0, 1 / 2., 4, 4), [Cswl, Cspower, Cswaist])
# Cs in the Na tweezer
Cs700 = dipole(Cs, (0, 1 / 2., 4, 4), [Nawl, Napower, Nawaist])
# Na in the Cs tweezer
Na976 = dipole(Na, (0, 1 / 2., 1, 1), [Cswl, Cspower, Cswaist])
# Na in its own tweezer
Na700 = dipole(Na, (0, 1 / 2., 1, 1), [Nawl, Napower, Nawaist])

# separated tweezer trap depths in mK:
U_cs_976 = Cs976.acStarkShift(0, 0, 0) / kB * 1e3
U_cs_700 = Cs700.acStarkShift(0, 0, 0) / kB * 1e3
U_na_976 = Na976.acStarkShift(0, 0, 0) / kB * 1e3
U_na_700 = Na700.acStarkShift(0, 0, 0) / kB * 1e3

# combined trap depths in mK:
U_cs = U_cs_976 + U_cs_700
Exemplo n.º 17
0
def plotScatRate():
    """Plot the polarisability of Rb 5S and Cs 6S states and the scattering
    rates within a given wavelength range (given in metres)"""
    bprop = [1064e-9, 6e-3, 1e-6]  # wavelength, beam power, beam waist
    wl1 = np.linspace(795e-9, Cs.rwS[0],
                      200)  # wavelength below Cs D1 line (m)
    wl2 = np.linspace(Cs.rwS[0], 1100e-9,
                      200)  # wavelength below Cs D1 line (m)

    # groundstate rubidium
    Rb5S = dipole(Rb, (0, 1 / 2., 1, 1), bprop)

    # below Cs D1 line, use intensities such that the Rb trap depth is 1mK
    I1 = 2 * kB * 1e-3 * eps0 * c / Rb5S.polarisability(wl1)

    # groundstate caesium
    Cs6S = dipole(Cs, (0, 1 / 2., 4, 4), bprop)

    # above Cs D1 line, use intensities such that the Cs trap depth is 1mK
    I2 = 2 * kB * 1e-3 * eps0 * c / Cs6S.polarisability(wl2)

    fig, ax = plt.subplots(2,
                           2,
                           gridspec_kw={
                               'height_ratios': [3, 2],
                               'hspace': 0,
                               'wspace': 0.02
                           },
                           sharex='col')
    for i, wl, I in [[0, wl1, I1], [1, wl2, I2]]:
        # plot scattering rates for fixed trap depth
        ax[0][i].semilogy(wl * 1e9,
                          Rb5S.scatRate(wl, I),
                          color=DUsea_blue,
                          label='Rb 5S$_{1/2}$')  # Rb
        ax[0][i].semilogy(wl * 1e9,
                          Cs6S.scatRate(wl, I),
                          color=DUcherry_red,
                          label='Cs 6S$_{1/2}$')  # Cs
        ax[0][i].plot([min(wl) * 1e9, max(wl) * 1e9], [100] * 2,
                      'k:')  # show acceptable limit
        ax[0][i].set_ylim((2, 10000))
        # plot polarisability in the same wavelength range
        ax[1][i].plot(wl * 1e9,
                      Rb5S.polarisability(wl) / au,
                      color=DUsea_blue,
                      label='Rb 5S$_{1/2}$')
        ax[1][i].plot(wl * 1e9,
                      Cs6S.polarisability(wl) / au,
                      color=DUcherry_red,
                      label='Cs 6S$_{1/2}$')
        ax[1][i].set_ylim((-6000, 6000))

        if not i:  # only have y label on the lhs
            ax[0][i].set_ylabel('Scattering Rate (s$^{-1}$)')
            ax[1][i].set_ylabel('Polarisability ($a_0^3$)')
        else:  # remove ticks
            ax[0][i].set_yticks([])
            ax[1][i].set_yticks([])

        ax[1][i].set_xlim((wl[0] * 1e9, wl[-1] * 1e9))
        ax[1][i].set_xlabel('Wavelength (nm)')

    # calculate trap depth
    # Rbdepths, Csdepths = np.zeros(len(wavelengths)), np.zeros(len(wavelengths))
    # for i in range(len(wavelengths)): # power changes to keep trap depth fixed
    #     Rb5S.field.E0 = np.sqrt(2 * abs(Is[i]) / eps0 / c)
    #     Cs6S.field.E0 = np.sqrt(2 * abs(Is[i]) / eps0 / c)
    #     Rbdepths[i] = Rb5S.acStarkShift(0,0,0, wavelengths[i])/kB*1e3 # in mK
    #     Csdepths[i] = Cs6S.acStarkShift(0,0,0, wavelengths[i])/kB*1e3 # in mK
    #
    # ax1 = ax[0].twinx() # plot trap depth
    # l3 = ax1.plot(wavelengths*1e9, Rbdepths, '--', color=DUsea_blue, label='Trap Depth', alpha=0.5)
    # l4 = ax1.plot(wavelengths*1e9, Csdepths, '--', color=DUcherry_red, label='Trap Depth', alpha=0.5)
    # ax1.set_ylabel('Trap Depth (mK)')
    # ax1.set_ylim((-3, 3))
    # lines = l1+l2+l3+l4 # order lines so that they appear next to each other in the legend
    # ax[0].legend(lines, [l.get_label() for l in lines], ncol=2, fontsize=11)

    plt.subplots_adjust(left=0.17, right=0.95, top=0.93, bottom=0.13)
    ax[0][1].legend()
    ax[0][0].set_title('Rb Trap Depth 1 mK')
    ax[0][1].set_title('Cs Trap Depth 1 mK')
    plt.show()
Exemplo n.º 18
0
def check880Trap(wavelength = 880e-9,     # wavelength in m
                 wavels = np.linspace(795,930,500)*1e-9, # wavelengths in m to plot
                 power = 5e-3,            # beam power in W
                 beamwaist = 1e-6,        # beam waist in m
                 species = 'Rb'):         # which species to set a 1mK trap for
    """Plot graphs of the trap depth experienced by Cs around 880nm when 
    the ground state Rb trap depth is fixed at 1mK. Look at the scattering
    rates and hence trap lifetimes that are possible."""
    bprop = [wavelength, power, beamwaist]
    Rb = atom(atm = 'Rb87')
    Rb5S = dipole(Rb, (0,1/2.,1,1), bprop)
    
    Rb5P = dipole(Rb, (1,3/2.,1,1), bprop)
    
    Cs = atom(atm = 'Cs133')                
    Cs6S = dipole(Cs, (0,1/2.,3,3), bprop)
                    
    Cs6P = dipole(Cs, (1,3/2.,3,3), bprop)               
    
    # choose power so that Rb trap depth is fixed at 1 mK:
    if species == Cs.X:
        Powers = abs(1e-3*kB * np.pi * eps0 * c * beamwaist**2 / Cs6S.polarisability(wavels)) # in Watts
    else:
        Powers = abs(1e-3*kB * np.pi * eps0 * c * beamwaist**2 / Rb5S.polarisability(wavels)) # in Watts
    _, ax1 = plt.subplots()
    ax1.set_title('Fixing the trap depth of ground state '+species+' at 1 mK')
    ax1.set_xlabel('Wavelength (nm)')
    ax1.plot(wavels*1e9, Powers*1e3, color='tab:blue')
    ax1.set_ylabel('Power (mW)', color='tab:blue')
    ax1.tick_params(axis='y', labelcolor='tab:blue')
    ax1.set_xlim(wavels[0]*1e9, wavels[-1]*1e9)
    # ax1.set_ylim(min(Powers)*1e3-0.5, 15)

    ax2 = ax1.twinx()
    # now the power and the wavelength are varied:
    Llabels = ['$S_{1/2}$', '$P_{3/2}$']
    if species == Cs.X:
        colors = ['k', 'tab:orange', 'tab:orange', 'tab:orange']
        linestyles = ['--', '-.', '-', ':']
    else:
        colors = ['tab:orange', 'tab:orange', 'k', 'tab:orange']
        linestyles = ['-', '-.', '--', ':']
    
    trapdepths = []
    for obj in [Cs6S, Cs6P, Rb5S, Rb5P]:
        res = np.zeros(len(Powers))
        for i in range(len(Powers)):
            obj.field.E0 = 2 * np.sqrt(Powers[i] / eps0 / c / np.pi)/beamwaist
            # average mj states (doesn't have any effect on j=1/2 states)
            res[i] = 0.5*(obj.acStarkShift(0,0,0, wavels[i], mj=1.5) + 
                    obj.acStarkShift(0,0,0, wavels[i], mj=0.5))
        color = colors.pop(0)
        ls = linestyles.pop(0)
        ax2.plot(wavels*1e9, res*1e3/kB, color=color, label=obj.X+" "+Llabels[obj.L], linestyle=ls)
        trapdepths.append(res)

    ax2.plot(wavels*1e9, np.zeros(len(wavels)), 'k', alpha=0.1) # show zero crossing    
    ax2.set_ylabel('Trap Depth (mK)', color='tab:orange')
    ax2.legend()
    ax2.set_ylim(-3, 3)
    ax2.tick_params(axis='y', labelcolor='tab:orange')
    plt.tight_layout()

    I = 2*Powers / np.pi / beamwaist**2
    # scattering rate of Cs from the D2 line:
    deltaCsD1 = 2*np.pi*c * (1/wavels - 1/Cs.rwS[0]) # detuning from D1 (rad/s)
    deltaCsD2 = 2*np.pi*c * (1/wavels - 1/Cs.rwS[35]) # detuning from D2 (rad/s)
    IsatCsD1 = 2.4981 *1e-3 *1e4 # saturation intensity for D1 transition, sigma polarised
    IsatCsD2 = 1.1023 *1e-3 *1e4 # saturation intensity for D2 transition, pi polarised
    CsRsc = 0
    for vals in [[Cs.lwS[0], deltaCsD1, IsatCsD1], [Cs.lwS[35], deltaCsD2, IsatCsD2]]:
        CsRsc += vals[0]/2. * I/vals[2] / (1 + 4*(vals[1]/vals[0])**2 + I/vals[2])
    # Cstau = 1e-3*kB / (hbar*(2*np.pi/wavels))**2 * 2.*Cs.m / CsRsc # the lifetime is the trap depth / recoil energy / scattering rate
    Cst = 4*np.sqrt(Cs.m*abs(trapdepths[0])) / (2*np.pi/wavels)**2 /hbar /beamwaist /CsRsc # duration in vibrational ground state (s) = 1/Lamb-Dicke^2 /Rsc

    # scattering rate of Rb from the D1 line:
    deltaRbD1 = 2*np.pi*c * (1/wavels - 1/Rb.rwS[0]) # detuning from D1 (rad/s)
    IsatRbD1 = 4.484 *1e-3 *1e4 # saturation intensity for D1 transition, pi polarised
    RbRsc = Rb.lwS[0]/2. * I/IsatRbD1 / (1 + 4*(deltaRbD1/Rb.lwS[0])**2 + I/IsatRbD1) # per second
    # Rbtau = 1e-3*kB / (hbar*(2*np.pi/wavels))**2 * 2.*Rb.m / RbRsc # the lifetime is the trap depth / recoil energy / scattering rate
    Rbt = 4*np.sqrt(Rb.m*abs(trapdepths[2])) / (2*np.pi/wavels)**2 /hbar /beamwaist /RbRsc # duration in vibrational ground state (s) = 1/Lamb-Dicke^2 /Rsc

    # plot lifetime and scattering rate on the same axis:
    for Rsc, ts, X in [[RbRsc, Rbt, Rb.X], [CsRsc, Cst, Cs.X]]:
        fig, ax3 = plt.subplots()
        ax3.set_title('Scattering rate and lifetime of ground state '+X+' in a 1 mK trap (for '+species+')')
        ax3.set_xlabel('Wavelength (nm)')
        ax3.semilogy(wavels*1e9, Rsc, color='tab:blue')
        ax3.plot(wavels*1e9, np.zeros(len(wavels))+100, '--', color='tab:blue', alpha=0.25) # show acceptable region
        ax3.set_ylabel('Scattering rate ($s^{-1}$)', color='tab:blue')
        ax3.tick_params(axis='y', labelcolor='tab:blue')
        ax3.set_xlim(wavels[0]*1e9, wavels[-1]*1e9)
        ax3.set_ylim(1, 1e5)

        ax4 = ax3.twinx()
        ax4.semilogy(wavels*1e9, ts, color='tab:orange')
        ax4.plot(wavels*1e9, np.ones(len(wavels))/2., '--', color='tab:orange', alpha=0.25) # show acceptable region
        ax4.set_ylabel('Time in the vibrational ground state (s)', color='tab:orange')
        ax4.tick_params(axis='y', labelcolor='tab:orange')
        ax4.set_ylim(0.001,10)
        plt.tight_layout()
    
    plt.show()
Exemplo n.º 19
0
    # ax[0].legend(lines, [l.get_label() for l in lines], ncol=2, fontsize=11)

    plt.subplots_adjust(left=0.17, right=0.95, top=0.93, bottom=0.13)
    ax[0][1].legend()
    ax[0][0].set_title('Rb Trap Depth 1 mK')
    ax[0][1].set_title('Cs Trap Depth 1 mK')
    plt.show()


if __name__ == "__main__":
    wavelength = 1064e-9  # wavelength in m
    power = 6e-3  # beam power in W
    beamwaist = 1e-6  # beam waist in m
    bprop = [wavelength, power, beamwaist]

    Rb5P1 = dipole(Rb, (1, 1 / 2., 1, 1), bprop)
    Rb5P3 = dipole(Rb, (1, 3 / 2., 1, 1), bprop)

    # print(getStarkShift(Rb5P1))
    # print(getStarkShift(Rb5P3))
    # print(np.array(Rb5P3.polarisability(795e-9, HF=True, split=True))/au)

    # combinedTrap(power=6e-3)
    # getMFStarkShifts()
    # plotPolarisability()
    plotScatRate()

    # compare Kien 2013 Fig 4,5:
    # wls = [np.linspace(680, 690, 200)*1e-9, np.linspace(930, 940, 200)*1e-9]
    # ylims = [(-1200, 300), (-3000, 6000)]
    # for ii in range(2):
Exemplo n.º 20
0
import matplotlib.pyplot as plt
import sys
sys.path.append(r'Y:\Tweezer\Code\Python 3.5\polarisability')
sys.path.append(r'Z:\Tweezer\Code\Python 3.5\polarisability')
from AtomFieldInt_V3 import dipole, atom, c, eps0, h, hbar, a0, e, me, kB, amu, Eh, au

Rb = atom(atm='Rb87')
Cs = atom(atm='Cs133')
# from scipy.constants import physical_constants
# muB = physical_constants['Bohr magneton']

wavelength = 1064e-9  # wavelength in m
power = 5e-3  # beam power in W
waist = 1.2e-6  # beam waist of tweezer in m
ehat = (2**(-0.5), 1j * 2**(-0.5), 0)  # E field circular polarisation

# create dipole objects for ground state Rb / Cs
bprop = [wavelength, power, waist, ehat]
Rb5S = dipole(Rb, (0, 1 / 2., 1, 1), bprop)
# Rb5S.gJ = 2.00233113 # Fine structure Lande g-factor (from Steck)

Cs6S = dipole(Cs, (0, 1 / 2., 3, 3), bprop)
# Cs6S.gJ = 2.00254032 # Fine structure Lande g-factor (from Steck)


def get_sep(atom=Rb5S, wl=wavelength):
    """Calculate the displacement of the trap centre due to the fictitious field"""
    aS, aV, aT = atom.polarisability(
        wl, split=True, HF=True)  # vector polarisability for |F,MF>
    return aV / aS * atom.MF / atom.F * wl / 4. / np.pi  # displacement of potential min.
Exemplo n.º 21
0
    Fs, occs = np.unique(states[:, 0], return_counts=True)  # F states
    if not weights:  # probability of being in each MF state
        weights = np.concatenate([np.ones(o) / o
                                  for o in occs])  # equal distribution
    weighted_shift = shifts * weights
    aveShifts = [np.sum(weighted_shift[np.where(Fs == F)])
                 for F in Fs]  # average
    return aveShifts


if __name__ == "__main__":
    # calculate the stark shifts for trap depths 0 - 2 mK
    beamwaist = 1.2e-6  # beam waist of tweezer in m
    wavelength = 1064e-9  # wavelength of tweezer beam in m
    # make an object to calculate the groundstate polarisability
    G = dipole(Rb, (0, 1 / 2., 1, 1), [wavelength, 1e-3, beamwaist])
    powers = abs(
        np.linspace(0, 2, 200) * 1e-3 * kB / G.polarisability(wavelength) *
        np.pi * eps0 * c * beamwaist**2)

    shifts = np.zeros((len(powers), 2))  # AC Stark shifts in MHz
    for i in range(len(powers)):
        mfstates, mfshifts = getMFStarkShifts(wavelength, powers[i], beamwaist)
        shifts[i] = aveShift(mfstates, mfshifts)

    plt.figure()
    ax1 = plt.gca()
    ax2 = ax1.twiny()
    plt.title('Averaging over the hyperfine transitions of Rb D2 line')
    ax1.plot(powers * 1e3, shifts[:, 0], label="F=1 $\rightarrow$ F'=2")
    ax1.plot(powers * 1e3, shifts[:, 1], label="F=2 $\rightarrow$ F'=3")