ARC documentationÂ¶
ARC (Alkali Rydberg Calculator) is package of routines written in Python, using objectoriented programming (OOP) to make modular, reusable and extendable collection of routines and data for performing useful calculations of single atom and twoatom properties, like level diagrams, interactions and transition strengths for alkali metal atoms.
ContentsÂ¶
Installation instructionsÂ¶
Prerequisite: PythonÂ¶
Install Python and packages for scientific computing in Python (scipy, numpy, matplotlib). The package is tested and works with both Python 2.7 and Python 3.6. We recommend installing Python distributions that comes with Numpy that is connected to the optimized numeric libraries like ATLAS. One such distribution is Anaconda, that provides ATLAS support and optimized math kernel.
Recommended installation: via Python pipÂ¶
Users can simply install the package from command line:
pip install ARCAlkaliRydbergCalculator
This finishes installation. This should work on all operating systems (Linux, OSX, Windows) with Python 2.7 or Python 3.6. Note this is a new feature for Windows, so Windows users should contact developers if unexpected errors occur. Below we describe some old (legacy) installation methods.
Download the ARC library/packageÂ¶
Download latest release for your operating system, unzip the archive and set the folder somewhere within the Python package search path or directly in your project directory. Simply import and use the module:
from arc import *
# write your code that uses ARC then.
It is important that package is stored somewhere where user has write permissions, so that it can update the databases with atomic properties. This is the end of the standard installation for majority of the users.
Installation of the package globally with setup.pyÂ¶
This is tested on Linux so far
Do this only if you have Linux/UNIX (as it is tested on it) and you are sure that you donâ€™t want to change underlying ARC code. Make sure you have C compiler and python development headers installed. To compile and install for local user ARC call from terminal:
python setup.py build
python setup.py install
Databases that have to be changed with new values will be locally copied from package data location to ~.arcdata folder when arc is used for the first time.
Compiling C extensionÂ¶
If you do need to compile C extension yourself, this is how to do it without installing globally the package (as in the previos section â€śInstallation of the package globally with setup.pyâ€ť). Optimized version of the Numerov is provided as the C code arc_c_extensions.c. You donâ€™t need to perform this step of manual compilation of that code if you followed recommended installation instruction by downloading precompiled binary distribution for the latest release . Note that path to arc directory should not contain spaces in order to setupc.py script to work.
For Windows users
If precompiled binaries donâ€™t work, please contact developers. Compiling Numpy C extensions on Windows is a bit complicated due to use of C89 standard (instead of C99). Procedure is the following. One needs to use MSVC compiler in order to compile Numpy extension for Python 2.7 under Windows. For other Python versions (3.5) find correct compiler here . After installation of the compiler, find in Start menu â€śVisual C++ 2008 32bit Command Promptâ€ť (for 32bit Python) or â€śVisual C++ 2008 64bit Command Promptâ€ť (for 64bit Python). Set the following variables set in the command prompt environment:
SET DISTUTILS_USE_SDK=1
SET MSSdk=1
python setupc.py build_ext inplace
This should build C Numpy extension (implementing Numerov integration) under Windows. We recommend, however, using prebuild binaries available on the release page .
For Linux users
Download and install GNU C compiler. Then with terminal open, navigate to arc folder where setupc.py file is located execute:
python setupc.py build_ext inplace
For Mac users
Download and install GNU C compiler. Then with terminal open, navigate to arc folder where setupc.py file is located execute:
python setupc.py build_ext inplace
Slow alternative: Numerov implemented in pure Python
Alternative solution, if you donâ€™t want to compile anything, is to use pure Python implementation of the Numerov, provided in the package. This is done by passing cpp_numerov = False flag whenever atoms are initialized, e.g:
atom = Rubidium(cpp_numerov=False)
This is not recommended option for complex calculations, since it will run much more slowly then optimized C version, but is fine if you need just a few numbers.
Finallyâ€¦
That is all, enjoy using ARC package. Check IPython notebook with examples to see some ideas where to start.
Getting started with ARCÂ¶
IPython notebook with examplesÂ¶
Rydberg atoms  a primer introduces Rydberg atoms and ARC package, and is a good starting point to learn how to use ARC to get relevant information about alkali metal Rydberg atoms. Notebook can also be downloaded in .ipython format here
, and can be interactively then modified and used in a Jupyter.
On demand examples from online Atom calculatorÂ¶
You can try using the package without installing anything on your computer. Simply point your web browser from your computer, tablet or phone to atomcalc.jqc.org.uk and use ARC online.
Online version also generates the correct code necessary for answering the questions you ask, which can be downladed and used as a starting point for running the package locally on your computer.
Frequently asked questions (FAQ)Â¶
If you have a question how to do a common calculation, we recommend checking above mentioned Rydberg atoms  a primer IPython notebook. For general questions about the package usage check here:
1. How to save calculation (or matrix) for later use?
Calculations of pairstate interactions PairStateInteractions
and Stark maps StarkMap
can be easily saved at any point by calling alkali_atom_functions.saveCalculation
. This can be loaded later by using alkali_atom_functions.loadSavedCalculation
and calculation can be continued from that point.
2. How to export results?
If you want to export results e.g. for analysis and plotting in other programs, you can use calculations_atom_pairstate.PairStateInteractions.exportData
and calculations_atom_single.StarkMap.exportData
to export results of Stark map and Pairstate interaction calculations in .csv format. See documentation of corresponding functions for more details.
3. Calculation is not outputting anything? How long does it take for calculation to finish?
Most of the functions have progressOutput and debugOutput as an optional parameter (by default set to False)  check documentation of individual functions for details. We recommend setting at least progressOutput=True so that you have minimum output about the status of calculations. This often displays percentage of the current calculation that is finished, that you can use to estimate total time. Setting debugOutput=True outputs even more verbose output, like states in the selected basis, and individual coupling strengths etc.
Detailed documentation of functionsÂ¶
Alkali atom functionsÂ¶
OverviewÂ¶
Classes and global methods
AlkaliAtom ([preferQuantumDefects, cpp_numerov]) 
Implements general calculations for alkali atoms. 
NumerovBack (innerLimit, outerLimit, kfun, â€¦) 
Full Python implementation of Numerov integration 
saveCalculation (calculation, fileName) 
Saves calculation for future use. 
loadSavedCalculation (fileName) 
Loads previously saved calculation. 
printState (n, l, j) 
Prints state spectroscopic label for numeric \(n\), \(l\), \(s\) label of the state 
printStateString (n, l, j) 
Returns state spectroscopic label for numeric \(n\), \(l\), \(s\) label of the state 
AlkaliAtom Methods
AlkaliAtom.getDipoleMatrixElement (n1, l1, â€¦) 
Dipole matrix element \(\langle n_1 l_1 j_1 m_{j_1} e\mathbf{r}n_2 l_2 j_2 m_{j_2}\rangle\) in units of \(a_0 e\) 
AlkaliAtom.getTransitionWavelength (n1, l1, â€¦) 
Calculated transition wavelength (in vacuum) in m. 
AlkaliAtom.getTransitionFrequency (n1, l1, â€¦) 
Calculated transition frequency in Hz 
AlkaliAtom.getRabiFrequency (n1, l1, j1, mj1, â€¦) 
Returns a Rabi frequency for resonantly driven atom in a center of TEM00 mode of a driving field 
AlkaliAtom.getRabiFrequency2 (n1, l1, j1, â€¦) 
Returns a Rabi frequency for resonant excitation with a given electric field amplitude 
AlkaliAtom.getStateLifetime (n, l, j[, â€¦]) 
Returns the lifetime of the state (in s) 
AlkaliAtom.getTransitionRate (n1, l1, j1, n2, â€¦) 
Transition rate due to coupling to vacuum modes (black body included) 
AlkaliAtom.getReducedMatrixElementJ_asymmetric (n1, â€¦) 
Reduced matrix element in \(J\) basis, defined in asymmetric notation. 
AlkaliAtom.getReducedMatrixElementJ (n1, l1, â€¦) 
Reduced matrix element in \(J\) basis (symmetric notation) 
AlkaliAtom.getReducedMatrixElementL (n1, l1, â€¦) 
Reduced matrix element in \(L\) basis (symmetric notation) 
AlkaliAtom.getRadialMatrixElement (n1, l1, â€¦) 
Radial part of the dipole matrix element 
AlkaliAtom.getQuadrupoleMatrixElement (n1, â€¦) 
Radial part of the quadrupole matrix element 
AlkaliAtom.getPressure (temperature) 
Vapour pressure (in Pa) at given temperature 
AlkaliAtom.getNumberDensity (temperature) 
Atom number density at given temperature 
AlkaliAtom.getAverageInteratomicSpacing (â€¦) 
Returns average interatomic spacing in atomic vapour 
AlkaliAtom.corePotential (l, r) 
core potential felt by valence electron 
AlkaliAtom.effectiveCharge (l, r) 
effective charge of the core felt by valence electron 
AlkaliAtom.potential (l, s, j, r) 
returns total potential that electron feels 
AlkaliAtom.radialWavefunction (l, s, j, â€¦) 
Radial part of electron wavefunction 
AlkaliAtom.getEnergy (n, l, j) 
Energy of the level relative to the ionisation level (in eV) 
AlkaliAtom.getZeemanEnergyShift (l, j, mj, â€¦) 
Retuns linear (paramagnetic) Zeeman shift. 
AlkaliAtom.getQuantumDefect (n, l, j) 
Quantum defect of the level. 
AlkaliAtom.getC6term (n, l, j, n1, l1, j1, â€¦) 
C6 interaction term for the given two pairstates 
AlkaliAtom.getC3term (n, l, j, n1, l1, j1, â€¦) 
C3 interaction term for the given two pairstates 
AlkaliAtom.getEnergyDefect (n, l, j, n1, l1, â€¦) 
Energy defect for the given two pairstates (one of the state has two atoms in the same state) 
AlkaliAtom.getEnergyDefect2 (n, l, j, nn, ll, â€¦) 
Energy defect for the given two pairstates 
AlkaliAtom.updateDipoleMatrixElementsFile () 
Updates the file with precalculated dipole matrix elements. 
AlkaliAtom.getRadialCoupling (n, l, j, n1, l1, j1) 
Returns radial part of the coupling between two states (dipole and quadrupole interactions only) 
AlkaliAtom.getAverageSpeed (temperature) 
Average (mean) speed at a given temperature 
AlkaliAtom.getLiteratureDME (n1, l1, j1, n2, â€¦) 
Returns literature information on requested transition. 
Detailed documentationÂ¶
Implements general singleatom calculations
This module calculates single (isolated) atom properties of all alkali metals in general. For example, it calculates dipole matrix elements, quandrupole matrix elements, etc. Also, some helpful general functions are here, e.g. for saving and loading calculations (singleatom and pairstate based), printing state labels etc.

class
arc.alkali_atom_functions.
AlkaliAtom
(preferQuantumDefects=True, cpp_numerov=True)[source]Â¶ Implements general calculations for alkali atoms.
This abstract class implements general calculations methods.
Parameters:  preferQuantumDefects (bool) â€“ Use quantum defects for energy level calculations. If False,
uses NIST ASD values
where available. If True, uses quantum defects for energy calculations
for principal quantum numbers equal or above
minQuantumDefectN
which is specified for each element separately. For principal quantum numbers below this value, NIST ASD values are used, since quantum defects donâ€™t reproduce well lowlying states. Default is True.  cpp_numerov (bool) â€“ should the wavefunction be calculated with Numerov algorithm implemented in C++; if False, it uses pure Python implementation that is much slower. Default is True.

Z
= 0.0Â¶ Atomic number

a1
= [0]Â¶ Model potential parameters fitted from experimental observations for different l (electron angular momentum)

a2
= [0]Â¶ Model potential parameters fitted from experimental observations for different l (electron angular momentum)

a3
= [0]Â¶ Model potential parameters fitted from experimental observations for different l (electron angular momentum)

a4
= [0]Â¶ Model potential parameters fitted from experimental observations for different l (electron angular momentum)

abundance
= 1.0Â¶ relative isotope abundance

alphaC
= 0.0Â¶ Core polarizability

corePotential
(l, r)[source]Â¶ core potential felt by valence electron
For more details about derivation of model potential see Ref. [2].
Parameters: Returns: core potential felt by valence electron (in a.u. ???)
Return type: References
[2] (1, 2) M. Marinescu, H. R. Sadeghpour, and A. Dalgarno PRA 49, 982 (1994), https://doi.org/10.1103/PhysRevA.49.982

cpp_numerov
= TrueÂ¶ swich  should the wavefunction be calculated with Numerov algorithm implemented in C++

dipoleMatrixElementFile
= ''Â¶ location of harddisk stored dipole matrix elements

effectiveCharge
(l, r)[source]Â¶ effective charge of the core felt by valence electron
For more details about derivation of model potential see Ref. [2].
Parameters: Returns: effective charge (in a.u.)
Return type:

elementName
= 'elementName'Â¶ Humanreadable element name

extraLevels
= []Â¶ levels that are for smaller principal quantum number (n) than ground level, but are above in energy due to angular part

getAverageInteratomicSpacing
(temperature)[source]Â¶ Returns average interatomic spacing in atomic vapour
See calculation of basic properties example snippet.
Parameters: temperature (float) â€“ temperature of the atomic vapour Returns: average interatomic spacing in m Return type: float

getAverageSpeed
(temperature)[source]Â¶ Average (mean) speed at a given temperature
Parameters: temperature (float) â€“ temperature (K) Returns: mean speed (m/s) Return type: float

getC3term
(n, l, j, n1, l1, j1, n2, l2, j2)[source]Â¶ C3 interaction term for the given two pairstates
Calculates \(C_3\) intaraction term for \(n,l,j,n,l,j\rangle \leftrightarrow n_1,l_1,j_1,n_2,l_2,j_2\rangle\)
Parameters:  n (int) â€“ principal quantum number
 l (int) â€“ orbital angular momenutum
 j (float) â€“ total angular momentum
 n1 (int) â€“ principal quantum number
 l1 (int) â€“ orbital angular momentum
 j1 (float) â€“ total angular momentum
 n2 (int) â€“ principal quantum number
 l2 (int) â€“ orbital angular momentum
 j2 (float) â€“ total angular momentum
Returns: \(C_3 = \frac{\langle n,l,j ern_1,l_1,j_1\rangle \langle n,l,j ern_2,l_2,j_2\rangle}{4\pi\varepsilon_0}\) (\(h\) Hz m \({}^3\)).
Return type:

getC6term
(n, l, j, n1, l1, j1, n2, l2, j2)[source]Â¶ C6 interaction term for the given two pairstates
Calculates \(C_6\) intaraction term for \(n,l,j,n,l,j\rangle \leftrightarrow n_1,l_1,j_1,n_2,l_2,j_2\rangle\). For details of calculation see Ref. [3].
Parameters:  n (int) â€“ principal quantum number
 l (int) â€“ orbital angular momenutum
 j (float) â€“ total angular momentum
 n1 (int) â€“ principal quantum number
 l1 (int) â€“ orbital angular momentum
 j1 (float) â€“ total angular momentum
 n2 (int) â€“ principal quantum number
 l2 (int) â€“ orbital angular momentum
 j2 (float) â€“ total angular momentum
Returns: \(C_6 = \frac{1}{4\pi\varepsilon_0} \frac{\langle n,l,j ern_1,l_1,j_1\rangle^2 \langle n,l,j ern_2,l_2,j_2\rangle^2} {E(n_1,l_1,j_2,n_2,j_2,j_2)E(n,l,j,n,l,j)}\) (\(h\) Hz m \({}^6\)).
Return type: Example
We can reproduce values from Ref. [3] for C3 coupling to particular channels. Taking for example channels described by the Eq. (50ac) we can get the values:
from arc import * channels = [[70,0,0.5, 70, 1,1.5, 69,1, 1.5],\ [70,0,0.5, 70, 1,1.5, 69,1, 0.5],\ [70,0,0.5, 69, 1,1.5, 70,1, 0.5],\ [70,0,0.5, 70, 1,0.5, 69,1, 0.5]] print(" = = = Caesium = = = ") atom = Caesium() for channel in channels: print("%.0f GHz (mu m)^6" % ( atom.getC6term(*channel) / C_h * 1.e27 )) print("\n = = = Rubidium = = =") atom = Rubidium() for channel in channels: print("%.0f GHz (mu m)^6" % ( atom.getC6term(*channel) / C_h * 1.e27 ))
Returns:
= = = Caesium = = = 722 GHz (mu m)^6 316 GHz (mu m)^6 383 GHz (mu m)^6 228 GHz (mu m)^6 = = = Rubidium = = = 799 GHz (mu m)^6 543 GHz (mu m)^6 589 GHz (mu m)^6 437 GHz (mu m)^6
which is in good agreement with the values cited in the Ref. [3]. Small discrepancies for Caesium originate from slightly different quantum defects used in calculations.
References
[3] (1, 2, 3) T. G. Walker, M. Saffman, PRA 77, 032723 (2008) https://doi.org/10.1103/PhysRevA.77.032723

getDipoleMatrixElement
(n1, l1, j1, mj1, n2, l2, j2, mj2, q)[source]Â¶ Dipole matrix element \(\langle n_1 l_1 j_1 m_{j_1} e\mathbf{r}n_2 l_2 j_2 m_{j_2}\rangle\) in units of \(a_0 e\)
Returns: dipole matrix element( \(a_0 e\)) Return type: float Example
For example, calculation of \(5 S_{1/2}m_j=\frac{1}{2} \rightarrow 5 P_{3/2}m_j=\frac{3}{2}\) transition dipole matrix element for laser driving \(\sigma^\) transition:
from arc import * atom = Rubidium() # transition 5 S_{1/2} m_j=0.5 > 5 P_{3/2} m_j=1.5 for laser # driving sigma transition print(atom.getDipoleMatrixElement(5,0,0.5,0.5,5,1,1.5,1.5,1))

getEnergy
(n, l, j)[source]Â¶ Energy of the level relative to the ionisation level (in eV)
Returned energies are with respect to the center of gravity of the hyperfinesplit states. If preferQuantumDefects =False (set during initialization) program will try use NIST energy value, if such exists, falling back to energy calculation with quantum defects if the measured value doesnâ€™t exist. For preferQuantumDefects =True, program will always calculate energies from quantum defects (useful for comparing quantum defect calculations with measured energy level values).
Parameters: Returns: state energy (eV)
Return type:

getEnergyDefect
(n, l, j, n1, l1, j1, n2, l2, j2)[source]Â¶ Energy defect for the given two pairstates (one of the state has two atoms in the same state)
Energy difference between the states \(E(n_1,l_1,j_1,n_2,l_2,j_2)  E(n,l,j,n,l,j)\)
Parameters:  n (int) â€“ principal quantum number
 l (int) â€“ orbital angular momenutum
 j (float) â€“ total angular momentum
 n1 (int) â€“ principal quantum number
 l1 (int) â€“ orbital angular momentum
 j1 (float) â€“ total angular momentum
 n2 (int) â€“ principal quantum number
 l2 (int) â€“ orbital angular momentum
 j2 (float) â€“ total angular momentum
Returns: energy defect (SI units: J)
Return type:

getEnergyDefect2
(n, l, j, nn, ll, jj, n1, l1, j1, n2, l2, j2)[source]Â¶ Energy defect for the given two pairstates
Energy difference between the states \(E(n_1,l_1,j_1,n_2,l_2,j_2)  E(n,l,j,nn,ll,jj)\)
See pairstate energy defects example snippet.
Parameters:  n (int) â€“ principal quantum number
 l (int) â€“ orbital angular momenutum
 j (float) â€“ total angular momentum
 nn (int) â€“ principal quantum number
 ll (int) â€“ orbital angular momenutum
 jj (float) â€“ total angular momentum
 n1 (int) â€“ principal quantum number
 l1 (int) â€“ orbital angular momentum
 j1 (float) â€“ total angular momentum
 n2 (int) â€“ principal quantum number
 l2 (int) â€“ orbital angular momentum
 j2 (float) â€“ total angular momentum
Returns: energy defect (SI units: J)
Return type:

getLiteratureDME
(n1, l1, j1, n2, l2, j2)[source]Â¶ Returns literature information on requested transition.
Parameters:  n1,l1,j1 â€“ one of the states we are coupling
 n2,l2,j2 â€“ the other state to which we are coupling
Returns: hasLiteratureValue?, dme, referenceInformation
If Boolean value is True, a literature value for dipole matrix element was found and reduced DME in J basis is returned as the number. Third returned argument (array) contains additional information about the literature value in the following order [ typeOfSource, errorEstimate , comment , reference, reference DOI] upon success to find a literature value for dipole matrix element:
 typeOfSource=1 if the value is theoretical calculation; otherwise, if it is experimentally obtained value typeOfSource=0
 comment details where within the publication the value can be found
 errorEstimate is absolute error estimate
 reference is humanreadable formatted reference
 reference DOI provides link to the publication.
Boolean value is False, followed by zero and an empty array if no literature value for dipole matrix element is found.
Return type: Note
The literature values are stored in /data folder in <element name>_literature_dme.csv files as a ; separated values. Each row in the file consists of one literature entry, that has information in the following order:
 n1
 l1
 j1
 n2
 l2
 j2
 dipole matrix element reduced l basis (a.u.)
 comment (e.g. where in the paper value appears?)
 value origin: 1 for theoretical; 0 for experimental values
 accuracy
 source (human readable formatted citation)
 doi number (e.g. 10.1103/RevModPhys.82.2313 )
If there are several values for a given transition, program will output the value that has smallest error (under column accuracy). The list of values can be expanded  every time program runs this file is read and the list is parsed again for use in calculations.

getNumberDensity
(temperature)[source]Â¶ Atom number density at given temperature
See calculation of basic properties example snippet.
Parameters: temperature (float) â€“ temperature in K Returns: atom concentration in \(1/m^3\) Return type: float

getPressure
(temperature)[source]Â¶ Vapour pressure (in Pa) at given temperature
Parameters: temperature (float) â€“ temperature in K Returns: vapour pressure in Pa Return type: float

getQuadrupoleMatrixElement
(n1, l1, j1, n2, l2, j2)[source]Â¶ Radial part of the quadrupole matrix element
Calculates \(\int \mathbf{d}r~R_{n_1,l_1,j_1}(r)\cdot R_{n_1,l_1,j_1}(r) \cdot r^4\). See Quadrupole calculation example snippet .
Parameters: Returns: quadrupole matrix element (\(a_0^2 e\)).
Return type:

getQuantumDefect
(n, l, j)[source]Â¶ Quantum defect of the level.
For an example, see Rydberg energy levels example snippet.
Parameters: Returns: quantum defect
Return type:

getRabiFrequency
(n1, l1, j1, mj1, n2, l2, j2, q, laserPower, laserWaist)[source]Â¶ Returns a Rabi frequency for resonantly driven atom in a center of TEM00 mode of a driving field
Parameters:  n1,l1,j1,mj1 â€“ state from which we are driving transition
 n2,l2,j2 â€“ state to which we are driving transition
 q â€“ laser polarization (1,0,1 correspond to \(\sigma^\), \(\pi\) and \(\sigma^+\) respectively)
 laserPower â€“ laser power in units of W
 laserWaist â€“ laser \(1/e^2\) waist (radius) in units of m
Returns: Frequency in rad \(^{1}\). If you want frequency in Hz, divide by returned value by \(2\pi\)
Return type:

getRabiFrequency2
(n1, l1, j1, mj1, n2, l2, j2, q, electricFieldAmplitude)[source]Â¶ Returns a Rabi frequency for resonant excitation with a given electric field amplitude
Parameters:  n1,l1,j1,mj1 â€“ state from which we are driving transition
 n2,l2,j2 â€“ state to which we are driving transition
 q â€“ laser polarization (1,0,1 correspond to \(\sigma^\), \(\pi\) and \(\sigma^+\) respectively)
 electricFieldAmplitude â€“ amplitude of electric field driving (V/m)
Returns: Frequency in rad \(^{1}\). If you want frequency in Hz, divide by returned value by \(2\pi\)
Return type:

getRadialCoupling
(n, l, j, n1, l1, j1)[source]Â¶ Returns radial part of the coupling between two states (dipole and quadrupole interactions only)
Parameters: Returns: radial coupling strength (in a.u.), or zero for forbidden transitions in dipole and quadrupole approximation.
Return type:

getRadialMatrixElement
(n1, l1, j1, n2, l2, j2, useLiterature=True)[source]Â¶ Radial part of the dipole matrix element
Calculates \(\int \mathbf{d}r~R_{n_1,l_1,j_1}(r)\cdot R_{n_1,l_1,j_1}(r) \cdot r^3\).
Parameters: Returns: dipole matrix element (\(a_0 e\)).
Return type:

getReducedMatrixElementJ
(n1, l1, j1, n2, l2, j2)[source]Â¶ Reduced matrix element in \(J\) basis (symmetric notation)
Parameters: Returns: reduced dipole matrix element in \(J\) basis \(\langle j  er  j' \rangle\) (\(a_0 e\)).
Return type:

getReducedMatrixElementJ_asymmetric
(n1, l1, j1, n2, l2, j2)[source]Â¶ Reduced matrix element in \(J\) basis, defined in asymmetric notation.
Note that notation for symmetric and asymmetricly defined reduced matrix element is not consistent in the literature. For example, notation is used e.g. in Steck [1] is precisely the oposite.
Note
Note that this notation is asymmetric: \(( je r j' ) \neq ( j'e r j )\). Relation between the two notation is \(\langle jerj'\rangle= \sqrt{2j+1} ( j er j')\). This function always returns value for transition from lower to higher energy state, independent of the order of states entered in the function call.
Parameters: Returns: reduced dipole matrix element in Steck notation \(( j  er  j' )\) (\(a_0 e\)).
Return type: [1] Daniel A. Steck, â€śCesium D Line Data,â€ť (revision 2.0.1, 2 May 2008). http://steck.us/alkalidata

getReducedMatrixElementL
(n1, l1, j1, n2, l2, j2)[source]Â¶ Reduced matrix element in \(L\) basis (symmetric notation)
Parameters: Returns: reduced dipole matrix element in \(L\) basis \(\langle l  er  l' \rangle\) (\(a_0 e\)).
Return type:

getStateLifetime
(n, l, j, temperature=0, includeLevelsUpTo=0)[source]Â¶ Returns the lifetime of the state (in s)
For nonzero temperatures, user must specify up to which principal quantum number levels, that is above the initial state, should be included in order to account for blackbody induced transitions to higher lying states. See Rydberg lifetimes example snippet.
Parameters:  l, j (n,) â€“ specifies state whose lifetime we are calculating
 temperature â€“ optional. Temperature at which the atom environment is, measured in K. If this parameter is nonzero, user has to specify transitions up to which state (due to blackbody decay) should be included in calculation.
 includeLevelsUpTo (int) â€“ optional and not needed for atom lifetimes calculated at zero temperature. At non zero temperatures, this specify maximum principal quantum number of the state to which blackbody induced transitions will be included. Minimal value of the parameter in that case is \(n+1\)
Returns: State lifetime in units of s (seconds)
Return type: See also
getTransitionRate
for calculating rates of individual transition rates between the two states

getTransitionFrequency
(n1, l1, j1, n2, l2, j2)[source]Â¶ Calculated transition frequency in Hz
Returned values is given relative to the centre of gravity of the hyperfinesplit states.
Parameters:  n1 (int) â€“ principal quantum number of the state from which we are going
 l1 (int) â€“ orbital angular momentum of the state from which we are going
 j1 (float) â€“ total angular momentum of the state from which we are going
 n2 (int) â€“ principal quantum number of the state to which we are going
 l2 (int) â€“ orbital angular momentum of the state to which we are going
 j2 (float) â€“ total angular momentum of the state to which we are going
Returns: transition frequency (in Hz). If the returned value is negative, level from which we are going is above the level to which we are going.
Return type:

getTransitionRate
(n1, l1, j1, n2, l2, j2, temperature=0.0)[source]Â¶ Transition rate due to coupling to vacuum modes (black body included)
Calculates transition rate from the first given state to the second given state \(n_1,l_1,j_1\rangle \rightarrow n_2,j_2,j_2\rangle\) at given temperature due to interaction with the vacuum field. For zero temperature this returns Einstein A coefficient. For details of calculation see Ref. [4] and Ref. [5]. See Blackbody induced population transfer example snippet.
Parameters: Returns: transition rate in s \({}^{1}\) (SI)
Return type: References
[4] C. E. Theodosiou, PRA 30, 2881 (1984) https://doi.org/10.1103/PhysRevA.30.2881 [5] I. I. Beterov, I. I. Ryabtsev, D. B. Tretyakov, and V. M. Entin, PRA 79, 052504 (2009) https://doi.org/10.1103/PhysRevA.79.052504

getTransitionWavelength
(n1, l1, j1, n2, l2, j2)[source]Â¶ Calculated transition wavelength (in vacuum) in m.
Returned values is given relative to the centre of gravity of the hyperfinesplit states.
Parameters:  n1 (int) â€“ principal quantum number of the state from which we are going
 l1 (int) â€“ orbital angular momentum of the state from which we are going
 j1 (float) â€“ total angular momentum of the state from which we are going
 n2 (int) â€“ principal quantum number of the state to which we are going
 l2 (int) â€“ orbital angular momentum of the state to which we are going
 j2 (float) â€“ total angular momentum of the state to which we are going
Returns: transition wavelength (in m). If the returned value is negative, level from which we are going is above the level to which we are going.
Return type:

getZeemanEnergyShift
(l, j, mj, magneticFieldBz)[source]Â¶ Retuns linear (paramagnetic) Zeeman shift.
\(\mathcal{H}_P=\frac{\mu_B B_z}{\hbar}(\hat{L}_{\rm z}+g_{\rm S}S_{\rm z})\)
Returns: energy offset of the state (in J) Return type: float

groundStateN
= 0Â¶ principal quantum number for the ground state

levelDataFromNIST
= ''Â¶ location of stored NIST values of measured energy levels in eV

literatureDMEfilename
= ''Â¶ Filename of the additional literature source values of dipole matrix elements.
These additional values should be saved as reduced dipole matrix elements in J basis.

mass
= 0.0Â¶ atomic mass in kg

minQuantumDefectN
= 0Â¶ minimal quantum number for which quantum defects can be used; uses measured energy levels otherwise

potential
(l, s, j, r)[source]Â¶ returns total potential that electron feels
Total potential = core potential + SpinOrbit interaction
Parameters: Returns: potential (in a.u.)
Return type:

quadrupoleMatrixElementFile
= ''Â¶ location of harddisk stored dipole matrix elements

quantumDefect
= [[[0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]], [[0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]]]Â¶ Contains list of modified RydbergRitz coefficients for calculating quantum defects for [[ \(S_{1/2},P_{1/2},D_{3/2},F_{5/2}\)], [ \(S_{1/2},P_{3/2},D_{5/2},F_{7/2}\)]].

radialWavefunction
(l, s, j, stateEnergy, innerLimit, outerLimit, step)[source]Â¶ Radial part of electron wavefunction
Calculates radial function with Numerov (from outside towards the core). Note that wavefunction might not be calculated all the way to the requested innerLimit if the divergence occurs before. In that case third returned argument gives nonzero value, corresponding to the first index in the array for which wavefunction was calculated. For quick example see Rydberg wavefunction calculation snippet.
Parameters:  l (int) â€“ orbital angular momentum
 s (float) â€“ spin angular momentum
 j (float) â€“ total angular momentum
 stateEnergy (float) â€“ state energy, relative to ionization threshold, should be given in atomic units (Hatree)
 innerLimit (float) â€“ inner limit at which wavefunction is requested
 outerLimit (float) â€“ outer limit at which wavefunction is requested
 step (flaot) â€“ radial step for integration mesh (a.u.)
Returns: \(r\)
\(R(r)\cdot r\)
Return type: Note
Radial wavefunction is not scaled to unity! This normalization condition means that we are using spherical harmonics which are normalized such that \(\int \mathrm{d}\theta~\mathrm{d}\psi~Y(l,m_l)^* \times Y(l',m_{l'}) = \delta (l,l') ~\delta (m_l, m_{l'})\).
Note
Alternative calculation methods can be added here (potenatial package expansion).

rc
= [0]Â¶ Model potential parameters fitted from experimental observations for different l (electron angular momentum)

scaledRydbergConstant
= 0Â¶ in eV
 preferQuantumDefects (bool) â€“ Use quantum defects for energy level calculations. If False,
uses NIST ASD values
where available. If True, uses quantum defects for energy calculations
for principal quantum numbers equal or above

arc.alkali_atom_functions.
NumerovBack
(innerLimit, outerLimit, kfun, step, init1, init2)[source]Â¶ Full Python implementation of Numerov integration
Calculates solution function \(rad(r)\) with descrete step in \(r\) size of step, integrating from outerLimit towards the innerLimit (from outside, inwards) equation \(\frac{\mathrm{d}^2 rad(r)}{\mathrm{d} r^2} = kfun(r)\cdot rad(r)\).
Parameters:  innerLimit (float) â€“ inner limit of integration
 outerLimit (flaot) â€“ outer limit of integration
 kfun (function(double)) â€“ pointer to function used in equation (see longer explanation above)
 step â€“ descrete step size for integration
 init1 (float) â€“ initial value, rad`(`outerLimit`+`step)
 init2 (float) â€“ initial value, rad`(`outerLimit`+:math:`2cdot step)
Returns: \(r\) (a.u), \(rad(r)\);
Return type: numpy array of float , numpy array of float, int
Note
Returned function is not normalized!
Note
If
AlkaliAtom.cpp_numerov
swich is set to True (default option), much faster C implementation of the algorithm will be used instead. That is recommended option. See documentation installation instructions for more details.

arc.alkali_atom_functions.
loadSavedCalculation
(fileName)[source]Â¶ Loads previously saved calculation.
Loads
calculations_atom_pairstate.PairStateInteractions
andcalculations_atom_single.StarkMap
calculation instance from file named filename where it was previously saved withsaveCalculation
.Example
See example for
saveCalculation
.Parameters: fileName â€“ name of the file where calculation will be saved Returns: saved calculation

arc.alkali_atom_functions.
printState
(n, l, j)[source]Â¶ Prints state spectroscopic label for numeric \(n\), \(l\), \(s\) label of the state
Parameters:

arc.alkali_atom_functions.
printStateString
(n, l, j)[source]Â¶ Returns state spectroscopic label for numeric \(n\), \(l\), \(s\) label of the state
Parameters: Returns: label for the state in standard spectroscopic notation
Return type: string

arc.alkali_atom_functions.
printStateStringLatex
(n, l, j)[source]Â¶ Returns latex code for spectroscopic label for numeric \(n\), \(l\), \(s\) label of the state
Parameters: Returns: label for the state in standard spectroscopic notation
Return type: string

arc.alkali_atom_functions.
saveCalculation
(calculation, fileName)[source]Â¶ Saves calculation for future use.
Saves
calculations_atom_pairstate.PairStateInteractions
andcalculations_atom_single.StarkMap
calculations in compact binary format in file named filename. It uses cPickle serialization library in Python, and also zips the final file.Calculation can be retrieved and used with
loadSavedCalculation
Parameters:  calculation â€“ class instance of calculations (instance of
calculations_atom_pairstate.PairStateInteractions
orcalculations_atom_single.StarkMap
) to be saved.  fileName â€“ name of the file where calculation will be saved
Example
Letâ€™s suppose that we did the part of the
calculation_atom_pairstate.PairStateInteractions
calculation that involves generation of the interaction matrix. After that we can save the full calculation in a single file:calc = PairStateInteractions(Rubidium(), 60,0,0.5,60,0,0.5, 0.5,0.5) calc.defineBasis(0,0, 5,5, 25.e9) calc.diagonalise(np.linspace(0.5,10.0,200),150) saveCalculation(calc, "mySavedCalculation.pkl")
Then, at a later time, and even on the another machine, we can load that file and continue with calculation. We can for example explore the calculated level diagram:
calc = loadSavedCalculation("mySavedCalculation.pkl") calc.plotLevelDiagram() calc.showPlot() rvdw = calc.getVdwFromLevelDiagram(0.5,14,minStateContribution=0.5,\ showPlot = True)
Or, we can do additional matrix diagonalization, in some new range, then and find C6 by fitting the obtained level diagram:
calc = loadSavedCalculation("mySavedCalculation.pkl") calc.diagonalise(np.linspace(3,6.0,200),20) calc.getC6fromLevelDiagram(3,6.0,showPlot=True)
Note that for all loading of saved calculations weâ€™ve been using function
loadSavedCalculation
.Note
This doesnâ€™t save results of
plotLevelDiagram
for the corresponding calculations. Call the plot function before callingshowPlot
function for the corresponding calculation. calculation â€“ class instance of calculations (instance of
Alkali atom dataÂ¶
Hydrogen ([preferQuantumDefects, cpp_numerov]) 
Properties of hydrogen atoms 
Lithium6 ([preferQuantumDefects, cpp_numerov]) 
Properties of lithium 6 atoms 
Lithium7 ([preferQuantumDefects, cpp_numerov]) 
Properties of lithium 7 atoms 
Sodium ([preferQuantumDefects, cpp_numerov]) 
Properties of sodium 23 atoms 
Potassium ([preferQuantumDefects, cpp_numerov]) 
backward compatibility: before only one class for Potassium existed and it corresponded to Potassium 39 
Potassium39 ([preferQuantumDefects, cpp_numerov]) 
Properties of potassium 39 atoms 
Potassium40 ([preferQuantumDefects, cpp_numerov]) 
Properties of potassium 40 atoms 
Potassium41 ([preferQuantumDefects, cpp_numerov]) 
Properties of potassium 41 atoms 
Rubidium ([preferQuantumDefects, cpp_numerov]) 
backward compatibility: before there was only one Rubidium class, and that one corresponded to Rubidium85 
Rubidium85 ([preferQuantumDefects, cpp_numerov]) 
Properites of rubidium 85 atoms 
Rubidium87 ([preferQuantumDefects, cpp_numerov]) 
Properites of rubidium 87 atoms 
Caesium ([preferQuantumDefects, cpp_numerov]) 
Properties of caesium atoms 
This module specifies properties of individual alkali metals.
If you want to change e.g. coefficients used for model potential, quantum defects, or other numerical values, this is the place to look at.
How to delete precalculated dipole/quadrupole matrix elements values and/or start a new database? To delete precalculated values, simply delete files, whose names are stated in dipoleMatrixElementFile, quadrupoleMatrixElementFile and precalculatedDB variables for the corresponding atom type, from data/ folder. Alternatively, if you want to keep old values, but want to also start completely new calculation of dipole matrix elements (e.g. because you changed parameters of energy levels significantly or model potential parameters), simply set new values for dipoleMatrixElementFile, quadrupoleMatrixElementFile and precalculatedDB variables.
Note that by default isotopes of Rubidium and Potassium are sharing precalculated dipole and quadrupole matrix elements. This is because the small energy level differences typically donâ€™t change this matrix elements within a typical accuracy.
Data sourcesÂ¶
[1]  (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54) M. Marinescu, H. R. Sadeghpour, and A. Dalgarno, Phys.Rev.A 49, 982 (1994) https://doi.org/10.1103/PhysRevA.49.982 
[2]  K.H. Weber and Craig J. Sansonetti, Phys.Rev.A 35, 4650 (1987) 
[3]  (1, 2, 3, 4, 5, 6, 7, 8, 9) C.B.Alcock, V.P.Itkin, M.K.Horrigan, Canadian Metallurgical Quarterly, 23, 309 (1984) http://dx.doi.org/10.1179/cmq.1984.23.3.309 
[4]  (1, 2) Wenhui Li, I. Mourachko, M. W. Noel, and T. F. Gallagher, Phys. Rev. A 67, 052502 (2003) https://doi.org/10.1103/PhysRevA.67.052502 
[5]  (1, 2) Jianing Han, Yasir Jamil, D. V. L. Norum, Paul J. Tanner, and T. F. Gallagher, Phys. Rev. A 74, 054502 (2006) https://doi.org/10.1103/PhysRevA.74.054502 
[6]  Markus Mack, Florian Karlewski, Helge Hattermann, Simone Hockh, Florian Jessen, Daniel Cano, and Jozsef Fortagh, Phys. Rev. A 83, 052515 (2011), https://doi.org/10.1103/PhysRevA.83.052515 
[7]  (1, 2) K. Afrousheh, P. BohlouliZanjani, J. A. Petrus, and J. D. D. Martin, Phys. Rev. A 74, 062712 (2006) https://doi.org/10.1103/PhysRevA.74.062712 
[8]  (1, 2) P. Goy, J. Liang, M. Gross, and S. Haroche, Phys. Rev. A 34, 2889 (1986) https://doi.org/10.1103/PhysRevA.34.2889 
[9]  Johannes Deiglmayr, Holger Herburger, Heiner Sassmannshausen, Paul Jansen, Hansjurg Schmutz, Frederic Merkt, Phys. Rev. A 93, 013424 (2016) https://doi.org/10.1103/PhysRevA.93.013424 
[10]  C. J. Lorenzen, and K. Niemax, Z. Phys. A 315, 127 (1984) dx.doi.org/ 10.1007/BF01419370 
[11]  (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)

[12]  NIST, P. Mohr and S. Kotochigova, unpublished calculations (2000). The wavelengths for the Balmeralpha and Balmerbeta transitions at 6563 and 4861 \(\unicode{xC5}\) include only the stronger components of more extensive fine structures. 
[13] 

[14]  (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17) J. S. Coursey, D. J. Schwab, J. J. Tsai, and R. A. Dragoset, (2015), Atomic Weights and Isotopic Compositions (version 4.1). Online Available: http://physics.nist.gov/Comp (2017, March, 14). National Institute of Standards and Technology, Gaithersburg, MD. 
[15]  B. Sanguinetti, H. O. Majeed, M. L. Jones and B. T. H. Varcoe, J. Phys. B 42, 165004 (2009) http://iopscience.iop.org/article/10.1088/09534075/42/16/165004/meta 
ModuleÂ¶

class
arc.alkali_atom_data.
Caesium
(preferQuantumDefects=True, cpp_numerov=True)[source]Â¶ Properties of caesium atoms

extraLevels
= [[5, 2, 2.5], [5, 2, 1.5], [5, 3, 3.5], [5, 3, 2.5], [5, 4, 4.5], [5, 4, 3.5], [4, 3, 3.5], [4, 3, 2.5]]Â¶ levels that are for smaller n than ground level, but are above in energy due to angular part

getPressure
(temperature)[source]Â¶ Pressure of atomic vapour at given temperature.
Uses equation and values from [3]. Values from table 2. (accuracy + 5%) are used for Cs in solid phase. Values from table 3. (accuracy +1 %) are used for Cs in liquid phase.

quantumDefect
= [[[4.04935665, 0.2377037, 0.255401, 0.00378, 0.25486, 0.0], [3.5915895, 0.360926, 0.41905, 0.64388, 1.45035, 0.0], [2.4754562, 0.00932, 0.43498, 0.76358, 18.0061, 0.0], [0.03341424, 0.198674, 0.28953, 0.2601, 0.0, 0.0], [0.00703865, 0.049252, 0.01291, 0.0, 0.0, 0.0]], [[4.04935665, 0.2377037, 0.255401, 0.00378, 0.25486, 0.0], [3.5589599, 0.392469, 0.67431, 22.3531, 92.289, 0.0], [2.46631524, 0.013577, 0.37457, 2.1867, 1.5532, 56.6739], [0.03341424, 0.198674, 0.28953, 0.2601, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]]]Â¶ quantum defects for \(S_{1/2}\), \(nP_{1/2}\), \(D_{5/2}\), \(F_{5/2}\) and \(G_{7/2}\) are from [2], while quantum defects for \(nP_{3/2}\),:math:D_{3/2} are from [10],
Note
f_7/2 quantum defects are PUT TO BE EXACTLY the same as f_5/2 (~10MHz difference?!)

scaledRydbergConstant
= 13.605636850154157Â¶ in eV


class
arc.alkali_atom_data.
Hydrogen
(preferQuantumDefects=True, cpp_numerov=True)[source]Â¶ Properties of hydrogen atoms

class
arc.alkali_atom_data.
Lithium6
(preferQuantumDefects=True, cpp_numerov=True)[source]Â¶ Properties of lithium 6 atoms

getPressure
(temperature)[source]Â¶ Pressure of atomic vapour at given temperature.
Uses equation and values from [3]. Values from table 3. (accuracy +1 %) are used both for liquid and solid phase of Li.

quantumDefect
= [[[0.3995101, 0.029, 0.0, 0.0, 0.0, 0.0], [0.0471835, 0.024, 0.0, 0.0, 0.0, 0.0], [0.002129, 0.01491, 0.1759, 0.8507, 0.0, 0.0], [7.7e05, 0.021856, 0.4211, 2.3891, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]], [[0.3995101, 0.029, 0.0, 0.0, 0.0, 0.0], [0.047172, 0.024, 0.0, 0.0, 0.0, 0.0], [0.002129, 0.01491, 0.1759, 0.8507, 0.0, 0.0], [7.7e05, 0.021856, 0.4211, 2.3891, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]]]Â¶ quantum defects for \(nS\) and \(nP\) are from Ref. [8] . Quantum defects for \(D_j\) and \(F_j\) are from Ref. [11] (note that this defects in Ref. [11] are for Li7, differences are expected not be too big).


class
arc.alkali_atom_data.
Lithium7
(preferQuantumDefects=True, cpp_numerov=True)[source]Â¶ Properties of lithium 7 atoms

getPressure
(temperature)[source]Â¶ Pressure of atomic vapour at given temperature (in K).
Uses equation and values from [3]. Values from table 3. (accuracy +1 %) are used for both liquid and solid phase of Li.

quantumDefect
= [[[0.3995101, 0.029, 0.0, 0.0, 0.0, 0.0], [0.047178, 0.024, 0.0, 0.0, 0.0, 0.0], [0.002129, 0.01491, 0.1759, 0.8507, 0.0, 0.0], [7.7e05, 0.021856, 0.4211, 2.3891, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]], [[0.3995101, 0.029, 0.0, 0.0, 0.0, 0.0], [0.0471665, 0.024, 0.0, 0.0, 0.0, 0.0], [0.002129, 0.01491, 0.1759, 0.8507, 0.0, 0.0], [7.7e05, 0.021856, 0.4211, 2.3891, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]]]Â¶ quantum defects for \(nS\) and \(nP\) states are from Ref. [8]. Quantum defects for \(D_j\) and \(F_j\) states are from [11].


class
arc.alkali_atom_data.
Potassium
(preferQuantumDefects=True, cpp_numerov=True)[source]Â¶ backward compatibility: before only one class for Potassium existed and it corresponded to Potassium 39

class
arc.alkali_atom_data.
Potassium39
(preferQuantumDefects=True, cpp_numerov=True)[source]Â¶ Properties of potassium 39 atoms

extraLevels
= [[3, 2, 2.5], [3, 2, 1.5]]Â¶ levels that are for smaller n than ground level, but are above in energy due to angular part

getPressure
(temperature)[source]Â¶ Pressure of atomic vapour at given temperature.
Uses equation and values from [3]. Values from table 2. (accuracy + 5%) are used for Na in solid phase. Values from table 3. (accuracy +1 %) are used for Na in liquid phase.

quantumDefect
= [[[2.1801985, 0.13558, 0.0759, 0.117, 0.206, 0.0], [1.713892, 0.233294, 0.16137, 0.5345, 0.234, 0.0], [0.27697, 1.024911, 0.709174, 11.839, 26.689, 0.0], [0.010098, 0.100224, 1.56334, 12.6851, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]], [[2.1801985, 0.13558, 0.0759, 0.117, 0.206, 0.0], [1.710848, 0.235437, 0.11551, 1.1015, 2.0356, 0.0], [0.277158, 1.025635, 0.59201, 10.0053, 19.0244, 0.0], [0.010098, 0.100224, 1.56334, 12.6851, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]]]Â¶ quantum defects from Ref. [11].


class
arc.alkali_atom_data.
Potassium40
(preferQuantumDefects=True, cpp_numerov=True)[source]Â¶ Properties of potassium 40 atoms

extraLevels
= [[3, 2, 2.5], [3, 2, 1.5]]Â¶ levels that are for smaller n than ground level, but are above in energy due to angular part

getPressure
(temperature)[source]Â¶ Pressure of atomic vapour at given temperature.
Uses equation and values from [3]. Values from table 2. (accuracy + 5%) are used for Na in solid phase. Values from table 3. (accuracy +1 %) are used for Na in liquid phase.

quantumDefect
= [[[2.1801985, 0.13558, 0.0759, 0.117, 0.206, 0.0], [1.713892, 0.233294, 0.16137, 0.5345, 0.234, 0.0], [0.27697, 1.024911, 0.709174, 11.839, 26.689, 0.0], [0.010098, 0.100224, 1.56334, 12.6851, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]], [[2.1801985, 0.13558, 0.0759, 0.117, 0.206, 0.0], [1.710848, 0.235437, 0.11551, 1.1015, 2.0356, 0.0], [0.277158, 1.025635, 0.59201, 10.0053, 19.0244, 0.0], [0.010098, 0.100224, 1.56334, 12.6851, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]]]Â¶ quantum defects from Ref. [11].

scaledRydbergConstant
= 13.6055062456062Â¶ in eV


class
arc.alkali_atom_data.
Potassium41
(preferQuantumDefects=True, cpp_numerov=True)[source]Â¶ Properties of potassium 41 atoms

extraLevels
= [[3, 2, 2.5], [3, 2, 1.5]]Â¶ levels that are for smaller n than ground level, but are above in energy due to angular part

getPressure
(temperature)[source]Â¶ Pressure of atomic vapour at given temperature.
Uses equation and values from [3]. Values from table 2. (accuracy + 5%) are used for Na in solid phase. Values from table 3. (accuracy +1 %) are used for Na in liquid phase.

quantumDefect
= [[[2.1801985, 0.13558, 0.0759, 0.117, 0.206, 0.0], [1.713892, 0.233294, 0.16137, 0.5345, 0.234, 0.0], [0.27697, 1.024911, 0.709174, 11.839, 26.689, 0.0], [0.010098, 0.100224, 1.56334, 12.6851, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]], [[2.1801985, 0.13558, 0.0759, 0.117, 0.206, 0.0], [1.710848, 0.235437, 0.11551, 1.1015, 2.0356, 0.0], [0.277158, 1.025635, 0.59201, 10.0053, 19.0244, 0.0], [0.010098, 0.100224, 1.56334, 12.6851, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]]]Â¶ quantum defects from Ref. [11].

scaledRydbergConstant
= 13.605510795147651Â¶ in eV


class
arc.alkali_atom_data.
Rubidium
(preferQuantumDefects=True, cpp_numerov=True)[source]Â¶ backward compatibility: before there was only one Rubidium class, and that one corresponded to Rubidium85

class
arc.alkali_atom_data.
Rubidium85
(preferQuantumDefects=True, cpp_numerov=True)[source]Â¶ Properites of rubidium 85 atoms

extraLevels
= [[4, 2, 2.5], [4, 2, 1.5], [4, 3, 3.5], [4, 3, 2.5]]Â¶ levels that are for smaller n than ground level, but are above in energy due to angular part

getPressure
(temperature)[source]Â¶ Pressure of atomic vapour at given temperature.
Uses equation and values from [3]. Values from table 2. (accuracy + 5%) are used for Rb in solid phase. Values from table 3. (accuracy +1 %) are used for Rb in liquid phase.

quantumDefect
= [[[3.1311804, 0.1784, 0.0, 0.0, 0.0, 0.0], [2.6548849, 0.29, 0.0, 0.0, 0.0, 0.0], [1.34809171, 0.60286, 0.0, 0.0, 0.0, 0.0], [0.0165192, 0.085, 0.0, 0.0, 0.0, 0.0], [0.00405, 0.0, 0.0, 0.0, 0.0, 0.0]], [[3.1311804, 0.1784, 0.0, 0.0, 0.0, 0.0], [2.6416737, 0.295, 0.0, 0.0, 0.0, 0.0], [1.34646572, 0.596, 0.0, 0.0, 0.0, 0.0], [0.0165437, 0.086, 0.0, 0.0, 0.0, 0.0], [0.00405, 0.0, 0.0, 0.0, 0.0, 0.0]]]Â¶ quantum defects for \(nF\) states are from [5]. Quantum defects for \(nG\) states are from [7]. All other quantum defects are from from [4]

scaledRydbergConstant
= 13.605605108199638Â¶ in eV


class
arc.alkali_atom_data.
Rubidium87
(preferQuantumDefects=True, cpp_numerov=True)[source]Â¶ Properites of rubidium 87 atoms

extraLevels
= [[4, 2, 2.5], [4, 2, 1.5], [4, 3, 3.5], [4, 3, 2.5]]Â¶ levels that are for smaller n than ground level, but are above in energy due to angular part

getPressure
(temperature)[source]Â¶ Pressure of atomic vapour at given temperature.
Uses equation and values from [3]. Values from table 2. (accuracy + 5%) are used for Rb in solid phase. Values from table 3. (accuracy +1 %) are used for Rb in liquid phase.

quantumDefect
= [[[3.1311804, 0.1784, 0.0, 0.0, 0.0, 0.0], [2.6548849, 0.29, 0.0, 0.0, 0.0, 0.0], [1.34809171, 0.60286, 0.0, 0.0, 0.0, 0.0], [0.0165192, 0.085, 0.0, 0.0, 0.0, 0.0], [0.00405, 0.0, 0.0, 0.0, 0.0, 0.0]], [[3.1311804, 0.1784, 0.0, 0.0, 0.0, 0.0], [2.6416737, 0.295, 0.0, 0.0, 0.0, 0.0], [1.34646572, 0.596, 0.0, 0.0, 0.0, 0.0], [0.0165437, 0.086, 0.0, 0.0, 0.0, 0.0], [0.00405, 0.0, 0.0, 0.0, 0.0, 0.0]]]Â¶ quantum defects for \(nF\) states are from [5]. Quantum defects for \(nG\) states are from [7]. All other quantum defects are from from [4]

scaledRydbergConstant
= 13.60560712837914Â¶ in eV (M_ion core = m_atomic  m_electron)


class
arc.alkali_atom_data.
Sodium
(preferQuantumDefects=True, cpp_numerov=True)[source]Â¶ Properties of sodium 23 atoms

getPressure
(temperature)[source]Â¶ Pressure of atomic vapour at given temperature.
Uses equation and values from [3]. Values from table 2. (accuracy + 5%) are used for Na in solid phase. Values from table 3. (accuracy +1 %) are used for Na in liquid phase.

quantumDefect
= [[[1.347964, 0.060673, 0.0233, 0.0085, 0.0, 0.0], [0.85538, 0.11363, 0.0384, 0.1412, 0.0, 0.0], [0.015543, 0.08535, 0.7958, 4.0513, 0.0, 0.0], [0.001453, 0.017312, 0.7809, 7.021, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]], [[1.347964, 0.060673, 0.0233, 0.0085, 0.0, 0.0], [0.854565, 0.114195, 0.0352, 0.1533, 0.0, 0.0], [0.015543, 0.08535, 0.7958, 4.0513, 0.0, 0.0], [0.001453, 0.017312, 0.7809, 7.021, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]]]Â¶ Quantum defects are from Ref. [11]. Note that we are using modified RydbergRitz formula. In literature both modified and nonmodified coefficients appear. For more details about the two equations see page 301. of Ref. [11].

scaledRydbergConstant
= 13.605368351064202Â¶ (eV)

Single atom calculationsÂ¶
OverviewÂ¶
StarkMap Methods
StarkMap.defineBasis (n, l, j, mj, nMin, â€¦) 
Initializes basis of states around state of interest 
StarkMap.diagonalise (eFieldList[, â€¦]) 
Finds atom eigenstates in a given electric field 
StarkMap.plotLevelDiagram ([units, â€¦]) 
Makes a plot of a stark map of energy levels 
StarkMap.showPlot ([interactive]) 
Shows plot made by plotLevelDiagram 
StarkMap.savePlot ([filename]) 
Saves plot made by plotLevelDiagram 
StarkMap.exportData (fileBase[, exportFormat]) 
Exports StarkMap calculation data. 
StarkMap.getPolarizability ([maxField, â€¦]) 
Returns the polarizability of the state (set during the initalization process) 
LevelPlot Methods
LevelPlot.makeLevels (nFrom, nTo, lFrom, lTo) 
Constructs energy level diagram in a given range 
LevelPlot.drawLevels () 
Draws a level diagram plot 
LevelPlot.showPlot () 
Shows a level diagram plot 
Detailed documentationÂ¶
This module provides calculations of singleatom properties.
Included calculations are Stark maps, level plot visualisations, lifetimes and radiative decays.

class
arc.calculations_atom_single.
LevelPlot
(atomType)[source]Â¶ Single atom level plots and decays
For an example see Rydberg energy levels example snippet.
Parameters: atom ( AlkaliAtom
) â€“ ={alkali_atom_data.Lithium6
,alkali_atom_data.Lithium7
,alkali_atom_data.Sodium
,alkali_atom_data.Potassium39
,alkali_atom_data.Potassium40
,alkali_atom_data.Potassium41
,alkali_atom_data.Rubidium85
,alkali_atom_data.Rubidium87
,alkali_atom_data.Caesium
} Alkali atom type whose levels we want to examine
makeLevels
(nFrom, nTo, lFrom, lTo)[source]Â¶ Constructs energy level diagram in a given range
Parameters:  nFrom (int) â€“ minimal principal quantum number of the states we are interested in
 nTo (int) â€“ maximal principal quantum number of the states we are interested in
 lFrom (int) â€“ minimal orbital angular momentum of the states we are interested in
 lTo (int) â€“ maximal orbital angular momentum of the states we are interested in


class
arc.calculations_atom_single.
StarkMap
(atom)[source]Â¶ Calculates Stark maps for single atom in a field
This initializes calculation for the atom of a given type. For details of calculation see Zimmerman [1]. For a quick working example see Stark map example snippet.
Parameters: atom ( AlkaliAtom
) â€“ ={alkali_atom_data.Lithium6
,alkali_atom_data.Lithium7
,alkali_atom_data.Sodium
,alkali_atom_data.Potassium39
,alkali_atom_data.Potassium40
,alkali_atom_data.Potassium41
,alkali_atom_data.Rubidium85
,alkali_atom_data.Rubidium87
,alkali_atom_data.Caesium
} Select the alkali metal for energy level diagram calculationExamples
State \(28~S_{1/2}~m_j=0.5\) polarizability calculation
>>> from arc import * >>> calc = StarkMap(Caesium()) >>> calc.defineBasis(28, 0, 0.5, 0.5, 23, 32, 20) >>> calc.diagonalise(np.linspace(00.,6000,600)) >>> print("%.5f MHz cm^2 / V^2 " % calc.getPolarizability()) 0.76705 MHz cm^2 / V^2
Stark map calculation
>>> from arc import * >>> calc = StarkMap(Caesium()) >>> calc.defineBasis(28, 0, 0.5, 0.5, 23, 32, 20) >>> calc.diagonalise(np.linspace(00.,60000,600)) >>> calc.plotLevelDiagram() >>> calc.showPlot() << matplotlib plot will open containing a Stark map >>
Examples
Advanced interfacing of Stark map calculations (StarkMap class) Here we show one easy way to obtain the Stark matrix (from diagonal
mat1
and offdiagonal partmat2
) and basis states (stored inbasisStates
), if this middleproduct of the calculation is needed for some code build on top of the existing ARC package.>>> from arc import * >>> calc = StarkMap(Caesium()) >>> calc.defineBasis(28, 0, 0.5, 0.5, 23, 32, 20) >>> # Now we have matrix and basis states, that we can used in our own code >>> # Let's say we want Stark map at electric field of 0.2 V/m >>> eField = 0.2 # V/m >>> # We can easily extract Stark matrix >>> # as diagonal matrix (state detunings) >>> # + offdiagonal matrix (propotional to electric field) >>> matrix = calc.mat1+calc.mat2*eField >>> # and the basis states as array [ [n,l,j,mj] , ...] >>> basisStates = calc.basisStates >>> # you can do your own calculation now...
References
[1] M. L. Zimmerman et.al, PRA 20:2251 (1979) https://doi.org/10.1103/PhysRevA.20.2251 
basisStates
= NoneÂ¶ List of basis states for calculation in the form [ [n,l,j,mj], â€¦]. Calculated by
defineBasis
.

defineBasis
(n, l, j, mj, nMin, nMax, maxL, Bz=0, progressOutput=False, debugOutput=False)[source]Â¶ Initializes basis of states around state of interest
Defines basis of states for further calculation. \(n,l,j,m_j\) specify state whose neighbourhood and polarizability we want to explore. Other parameters specify basis of calculations. This method stores basis in
basisStates
, while corresponding interaction matrix is stored in two parts. First part is diagonal electricfield independent part stored inmat1
, while the second partmat2
corresponds to offdiagonal elements that are propotional to electric field. Overall interaction matrix for electric field eField can be then obtained as fullStarkMatrix =mat1
+mat2
*eFieldParameters:  n (int) â€“ principal quantum number of the state
 l (int) â€“ angular orbital momentum of the state
 j (flaot) â€“ total angular momentum of the state
 mj (float) â€“ projection of total angular momentum of the state
 nMin (int) â€“ minimal principal quantum number of the states to be included in the basis for calculation
 nMax (int) â€“ maximal principal quantum number of the states to be included in the basis for calculation
 maxL (int) â€“ maximal value of orbital angular momentum for the states to be included in the basis for calculation
 Bz (float) â€“ optional, magnetic field directed along zaxis in units of Tesla. Calculation will be correct only for weak magnetic fields, where paramagnetic term is much stronger then diamagnetic term. Diamagnetic term is neglected.
 progressOutput (
bool
, optional) â€“ if True prints the progress of calculation; Set to false by default.  debugOutput (
bool
, optional) â€“ if True prints additional information usefull for debuging. Set to false by default.

diagonalise
(eFieldList, drivingFromState=[0, 0, 0, 0, 0], progressOutput=False, debugOutput=False)[source]Â¶ Finds atom eigenstates in a given electric field
Eigenstates are calculated for a list of given electric fields. To extract polarizability of the originaly stated state see
getPolarizability
method. Results are saved ineFieldList
,y
andhighlight
.Parameters:  eFieldList (array) â€“ array of electric field strength (in V/m) for which we want to know energy eigenstates
 progressOutput (
bool
, optional) â€“ if True prints the progress of calculation; Set to false by default.  debugOutput (
bool
, optional) â€“ if True prints additional information usefull for debuging. Set to false by default.

eFieldList
= NoneÂ¶ Saves electric field (in units of V/m) for which energy levels are calculated
See also

exportData
(fileBase, exportFormat='csv')[source]Â¶ Exports StarkMap calculation data.
Only supported format (selected by default) is .csv in a humanreadable form with a header that saves details of calculation. Function saves three files: 1) filebase _eField.csv; 2) filebase _energyLevels 3) filebase _highlight
For more details on the format, see header of the saved files.
Parameters:  filebase (string) â€“ filebase for the names of the saved files without format extension. Add as a prefix a directory path if necessary (e.g. saving outside the current working directory)
 exportFormat (string) â€“ optional. Format of the exported file. Currently only .csv is supported but this can be extended in the future.

getPolarizability
(maxField=10000000000.0, showPlot=False, debugOutput=False, minStateContribution=0.0)[source]Â¶ Returns the polarizability of the state (set during the initalization process)
Parameters:  maxField (
float
, optional) â€“ maximum field (in V/m) to be used for fitting the polarizability. By default, max field is very large, so it will use eigenvalues calculated in the whole range.  showPlot (
bool
, optional) â€“ shows plot of calculated eigenValues of the given state (dots), and the fit (solid line) for extracting polarizability  debugOutput (
bool
, optional) â€“ if True prints additional information usefull for debuging. Set to false by default.
Returns: scalar polarizability in units of MHz cm \(^2\) / V \(^2\)
Return type:  maxField (

highlight
= NoneÂ¶ highlight[i] is an array of values measuring highlighted feature in the eigenstates at electric field intensity eFieldList[i]. E.g. highlight[i][j] measures highlighted feature of the state with energy y[i][j] at electric field eFieldList[i]. What will be highlighted feature is defined in the call of
diagonalise
(see that part of documentation for details).See also

indexOfCoupledState
= NoneÂ¶ Index of coupled state (initial state passed to
defineBasis
) inbasisStates
list of basis states

mat1
= NoneÂ¶ diagonal elements of Starkmatrix (detuning of states) calculated by
defineBasis
in the basisbasisStates
.

mat2
= NoneÂ¶ offdiagonal elements of Starkmatrix divided by electric field value. To get off diagonal elemements multiply this matrix with electric field value. Full Stark matrix is obtained as fullStarkMatrix =
mat1
+mat2
*eField. Calculated bydefineBasis
in the basisbasisStates
.

plotLevelDiagram
(units=1, highlighState=True, progressOutput=False, debugOutput=False, highlightColour='red', addToExistingPlot=False)[source]Â¶ Makes a plot of a stark map of energy levels
To save this plot, see
savePlot
. To print this plot seeshowPlot
.Parameters:  units (
int
,optional) â€“ possible values {1,2} ; if the value is 1 (default) Stark diagram will be plotted in energy units cm \({}^{1}\); if value is 2, Stark diagram will be plotted as energy \(/h\) in units of GHz  highlightState (
bool
, optional) â€“ False by default. If True, scatter plot colour map will map in red amount of original state for the given eigenState  progressOutput (
bool
, optional) â€“ if True prints the progress of calculation; Set to False by default.  debugOutput (
bool
, optional) â€“ if True prints additional information usefull for debuging. Set to False by default.  addToExistingPlot (
bool
, optional) â€“ if True adds points to existing old plot. Note that then interactive plotting doesnâ€™t work. False by default.
 units (

savePlot
(filename='StarkMap.pdf')[source]Â¶ Saves plot made by
plotLevelDiagram
Parameters: filename ( str
, optional) â€“ file location where the plot should be saved

showPlot
(interactive=True)[source]Â¶ Shows plot made by
plotLevelDiagram

y
= NoneÂ¶ y[i] is an array of eigenValues corresponding to the energies of the atom states at the electric field eFieldList[i]. For example y[i][j] is energy of the j eigenvalue (energy of the state) measured in cm \({}^{1}\) relative to the ionization threshold.
See also


arc.calculations_atom_single.
printState
(n, l, j)[source]Â¶ Prints state spectroscopic label for numeric \(n\), \(l\), \(s\) label of the state
Parameters:
Pairstate basis calculationsÂ¶
PreliminariesÂ¶
Relative orientation of the two atoms can be described with polar angle \(\theta\) (range \(0\pi\)) and azimuthal angle \(\phi\) (range \(02\pi\)). The \(\hat{z}\) axis is here specified relative to the laser driving. For circularly polarized laser light, this is the direction of laser beam propagation. For linearly polarized light, this is the plane of the electric field polarization, perpendicular to the laser direction.
Internal coupling between the two atoms in \(n,l,j,m_1\rangle\) and \(nn,ll,jj,m_2\rangle\) is calculated easily for the two atoms positioned so that \(\theta = 0\), and for other angles wignerD matrices are used to change a basis and perform calculation in the basis where couplings are more clearly seen.
OverviewÂ¶
PairStateInteractions Methods
PairStateInteractions.defineBasis (theta, â€¦) 
Finds relevant states in the vicinity of the given pairstate 
PairStateInteractions.getC6perturbatively (â€¦) 
Calculates \(C_6\) from second order perturbation theory. 
PairStateInteractions.getLeRoyRadius () 
Returns Le Roy radius for initial pairstate. 
PairStateInteractions.diagonalise (rangeR, â€¦) 
Finds eigenstates in atom pair basis. 
PairStateInteractions.plotLevelDiagram ([â€¦]) 
Plots pair state level diagram 
PairStateInteractions.showPlot ([interactive]) 
Shows level diagram printed by PairStateInteractions.plotLevelDiagram 
PairStateInteractions.exportData (fileBase[, â€¦]) 
Exports PairStateInteractions calculation data. 
PairStateInteractions.getC6fromLevelDiagram (â€¦) 
Finds \(C_6\) coefficient for original pair state. 
PairStateInteractions.getC3fromLevelDiagram (â€¦) 
Finds \(C_3\) coefficient for original pair state. 
PairStateInteractions.getVdwFromLevelDiagram (â€¦) 
Finds \(r_{\rm vdW}\) coefficient for original pair state. 
StarkMapResonances Methods
StarkMapResonances.findResonances (nMin, â€¦) 
Finds nearresonant dipolecoupled pairstates 
StarkMapResonances.showPlot ([interactive]) 
Plots initial state Stark map and its dipolecoupled resonances 
Detailed documentationÂ¶
Pairstate basis level diagram calculations
Calculates Rydberg spaghetti of level diagrams, as well as pertubative C6 and similar properties. It also allows calculation of Foster resonances tuned by DC electric fields.
Example
Calculation of the Rydberg eigenstates in pairstate basis for Rubidium in the vicinity of the \(60~S_{1/2}~m_j=1/2,~60~S_{1/2}~m_j=1/2\rangle\) state. Colour highlights coupling strength from state \(6~P_{1/2}~m_j=1/2\) with \(\pi\) (\(q=0\)) polarized light. eigenstates:
from arc import *
calc1 = PairStateInteractions(Rubidium(), 60, 0, 0.5, 60, 0, 0.5,0.5, 0.5)
calc1.defineBasis( 0., 0., 4, 5,10e9)
# optionally we can save now results of calculation for future use
saveCalculation(calc1,"mycalculation.pkl")
calculation1.diagonalise(linspace(1,10.0,30),250,progressOutput = True,drivingFromState=[6,1,0.5,0.5,0])
calc1.plotLevelDiagram()
calc1.ax.set_xlim(1,10)
calc1.ax.set_ylim(2,2)
calc1.showPlot()

class
arc.calculations_atom_pairstate.
PairStateInteractions
(atom, n, l, j, nn, ll, jj, m1, m2, interactionsUpTo=1)[source]Â¶ Calculates Rydberg level diagram (spaghetti) for the given pair state
Initializes Rydberg level spaghetti calculation for the given atom in the vicinity of the given pair state. For details of calculation see Ref. [1]. For a quick start point example see interactions example snippet.
Parameters:  atom (
AlkaliAtom
) â€“ ={alkali_atom_data.Lithium6
,alkali_atom_data.Lithium7
,alkali_atom_data.Sodium
,alkali_atom_data.Potassium39
,alkali_atom_data.Potassium40
,alkali_atom_data.Potassium41
,alkali_atom_data.Rubidium85
,alkali_atom_data.Rubidium87
,alkali_atom_data.Caesium
} Select the alkali metal for energy level diagram calculation  n (int) â€“ principal quantum number for the first atom
 l (int) â€“ orbital angular momentum for the first atom
 j (float) â€“ total angular momentum for the first atom
 nn (int) â€“ principal quantum number for the second atom
 ll (int) â€“ orbital angular momentum for the second atom
 jj (float) â€“ total angular momentum for the second atom
 m1 (float) â€“ projection of the total angular momentum on zaxis for the first atom
 m2 (float) â€“ projection of the total angular momentum on zaxis for the second atom
 interactionsUpTo (int) â€“ Optional. If set to 1, includes only dipoledipole interactions. If set to 2 includes interactions up to quadrupolequadrupole. Default value is 1.
References
[1] T. G Walker, M. Saffman, PRA 77, 032723 (2008) https://doi.org/10.1103/PhysRevA.77.032723 Examples
Advanced interfacing of pairstate interactions calculations (PairStateInteractions class). This is an advanced example intended for building up extensions to the existing code. If you want to directly access the pairstate interaction matrix, constructed by
defineBasis
, you can assemble it easily from diagonal part (stored inmatDiagonal
) and offdiagonal matrices whose spatial dependence is \(R^{3},R^{4},R^{5}\) stored in that order inmatR
. Basis states are stored inbasisStates
array.>>> from arc import * >>> calc = PairStateInteractions(Rubidium(), 60,0,0.5, 60,0,0.5, 0.5,0.5,interactionsUpTo = 1) >>> # theta=0, phi = 0, range of pqn, range of l, deltaE = 25e9 >>> calc.defineBasis(0 ,0 , 5, 5, 25e9, progressOutput=True) >>> # now calc stores interaction matrix and relevant basis >>> # we can access this directly and generate interaction matrix >>> # at distance rval : >>> rval = 4 # in mum >>> matrix = calc.matDiagonal >>> rX = (rval*1.e6)**3 >>> for matRX in self.matR: >>> matrix = matrix + matRX/rX >>> rX *= (rval*1.e6) >>> # matrix variable now holds full interaction matrix for >>> # interacting atoms at distance rval calculated in >>> # pairstate basis states can be accessed as >>> basisStates = calc.basisStates

atom
= NoneÂ¶ atom type

basisStates
= NoneÂ¶ List of pairstates for calculation. In the form [[n1,l1,j1,mj1,n2,l2,j2,mj2], â€¦]. Each state is an array [n1,l1,j1,mj1,n2,l2,j2,mj2] corresponding to \(n_1,l_1,j_1,m_{j1},n_2,l_2,j_2,m_{j2}\rangle\) state. Calculated by
defineBasis
.

channel
= NoneÂ¶ states relevant for calculation, defined in J basis (not resolving \(m_j\). Used as intermediary for full interaction matrix calculation by
defineBasis
.

coupling
= NoneÂ¶ List of matrices defineing coupling strengths between the states in J basis (not resolving \(m_j\) ). Basis is given by
channel
. Used as intermediary for full interaction matrix calculation bydefineBasis
.

defineBasis
(theta, phi, nRange, lrange, energyDelta, Bz=0, progressOutput=False, debugOutput=False)[source]Â¶ Finds relevant states in the vicinity of the given pairstate
Finds relevant pairstate basis and calculates interaction matrix. Pairstate basis is saved in
basisStates
. Interaction matrix is saved in parts depending on the scaling with distance. Diagonal elementsmatDiagonal
, correponding to relative energy defects of the pairstates, donâ€™t change with interatomic separation. Off diagonal elements can depend on distance as \(R^{3}, R^{4}\) or \(R^{5}\), corresponding to dipoledipole (\(C_3\) ), dipolequdrupole (\(C_4\) ) and quadrupolequadrupole coupling (\(C_5\) ) respectively. These parts of the matrix are stored inmatR
in that order. I.e.matR[0]
stores dipoledipole coupling (\(\propto R^{3}\)),matR[0]
stores dipolequadrupole couplings etc.Parameters:  theta (float) â€“ relative orientation of the two atoms (see figure on top of the page), range 0 to \(\pi\)
 phi (float) â€“ relative orientation of the two atoms (see figure on top of the page), range 0 to \(2\pi\)
 nRange (int) â€“ how much below and above the given principal quantum number of the pair state we should be looking?
 lrange (int) â€“ what is the maximum angular orbital momentum state that we are including in calculation
 energyDelta (float) â€“ what is maximum energy difference ( \(\Delta E/h\) in Hz) between the original pair state and the other pair states that we are including in calculation
 Bz (float) â€“ optional, magnetic field directed along zaxis in units of Tesla. Calculation will be correct only for weak magnetic fields, where paramagnetic term is much stronger then diamagnetic term. Diamagnetic term is neglected.
 progressOutput (bool) â€“ optional, False by default. If true, prints information about the progress of the calculation.
 debugOutput (bool) â€“ optional, False by default. If true, similar to progressOutput=True, this will print information about the progress of calculations, but with more verbose output.
See also
alkali_atom_functions.saveCalculation
andalkali_atom_functions.loadSavedCalculation
for information on saving intermediate results of calculation for later use.

diagonalise
(rangeR, noOfEigenvectors, drivingFromState=[0, 0, 0, 0, 0], eigenstateDetuning=0.0, sortEigenvectors=False, progressOutput=False, debugOutput=False)[source]Â¶ Finds eigenstates in atom pair basis.
ARPACK (
scipy.sparse.linalg.eigsh
) calculation of the noOfEigenvectors eigenvectors closest to the original state. If drivingFromState is specified as [n,l,j,mj,q] coupling between the pairstates and the situation where one of the atoms in the pair state basis is in \(n,l,j,m_j\rangle\) state due to driving with a laser field that drives \(q\) transition (+1,0,1 for \(\sigma^\), \(\pi\) and \(\sigma^+\) transitions respectively) is calculated and marked by the colourmaping these values on the obtained eigenvectors.Parameters:  rangeR (
array
) â€“ Array of values for distance between the atoms (in \(\mu\) m) for which we want to calculate eigenstates.  noOfEigenvectors (int) â€“ number of eigen vectors closest to the energy of the original (unperturbed) pair state. Has to be smaller then the total number of states.
 eigenstateDetuning (float, optional) â€“ Default is 0. This specifies detuning from the initial pairstate (in Hz) around which we want to find noOfEigenvectors eigenvectors. This is useful when looking only for couple of offresonant features.
 drivingFromState ([int,int,float,float,int]) â€“ Optional. State of the one of the atoms from the original pairstate basis from which we try to dribe to the excited pairbasis manifold. By default, program will calculate just contribution of the original pairstate in the eigenstates obtained by diagonalization, and will highlight itâ€™s admixure by colour mapping the obtained eigenstates plot.
 sortEigenvectors (bool) â€“ optional, False by default. Tries to sort eigenvectors so that given eigen vector index corresponds to adiabatically changing eigenstate, as detirmined by maximising overlap between old and new eigenvectors.
 progressOutput (bool) â€“ optional, False by default. If true, prints information about the progress of the calculation.
 debugOutput (bool) â€“ optional, False by default. If true, similar to progressOutput=True, this will print information about the progress of calculations, but with more verbose output.
 rangeR (

exportData
(fileBase, exportFormat='csv')[source]Â¶ Exports PairStateInteractions calculation data.
Only supported format (selected by default) is .csv in a humanreadable form with a header that saves details of calculation. Function saves three files: 1) filebase _r.csv; 2) filebase _energyLevels 3) filebase _highlight
For more details on the format, see header of the saved files.
Parameters:  filebase (string) â€“ filebase for the names of the saved files without format extension. Add as a prefix a directory path if necessary (e.g. saving outside the current working directory)
 exportFormat (string) â€“ optional. Format of the exported file. Currently only .csv is supported but this can be extended in the future.

getC3fromLevelDiagram
(rStart, rStop, showPlot=False, minStateContribution=0.0, resonantBranch=1)[source]Â¶ Finds \(C_3\) coefficient for original pair state.
Function first finds for each distance in the range [rStart , rStop] the eigen state with highest contribution of the original state. One can set optional parameter minStateContribution to value in the range [0,1), so that function finds only states if they have contribution of the original state that is bigger then minStateContribution.
Once original pairstate is found in the range of interatomic distances, from smallest rStart to the biggest rStop, function will try to perform fitting of the corresponding state energy \(E(R)\) at distance \(R\) to the function \(A+C_3/R^3\) where \(A\) is some offset.
Parameters:  rStart (float) â€“ smallest interatomic distance to be used for fitting
 rStop (float) â€“ maximum interatomic distance to be used for fitting
 showPlot (bool) â€“ If set to true, it will print the plot showing fitted energy level and the obtained best fit. Default is False
 minStateContribution (float) â€“ valid values are in the range [0,1). It specifies minimum amount of the original state in the given energy state necessary for the state to be considered for the adiabatic continuation of the original unperturbed pair state.
 resonantBranch (int) â€“ optional, default +1. For resonant interactions we have two branches with identical state contributions. In this case, we will select only positively detuned branch (for resonantBranch = +1) or negatively detuned branch (fore resonantBranch = 1) depending on the value of resonantBranch optional parameter
Returns: \(C_3\) measured in \(\text{GHz }\mu\text{m}^6\) on success; If unsuccessful returns False.
Return type: Note
In order to use this functions, highlighting in
diagonalise
should be based on the original pair state contribution of the eigenvectors (that this, drivingFromState parameter should not be set, which corresponds to drivingFromState = [0,0,0,0,0]).

getC6fromLevelDiagram
(rStart, rStop, showPlot=False, minStateContribution=0.0)[source]Â¶ Finds \(C_6\) coefficient for original pair state.
Function first finds for each distance in the range [ rStart , rStop ] the eigen state with highest contribution of the original state. One can set optional parameter minStateContribution to value in the range [0,1), so that function finds only states if they have contribution of the original state that is bigger then minStateContribution.
Once original pairstate is found in the range of interatomic distances, from smallest rStart to the biggest rStop, function will try to perform fitting of the corresponding state energy \(E(R)\) at distance \(R\) to the function \(A+C_6/R^6\) where \(A\) is some offset.
Parameters:  rStart (float) â€“ smallest interatomic distance to be used for fitting
 rStop (float) â€“ maximum interatomic distance to be used for fitting
 showPlot (bool) â€“ If set to true, it will print the plot showing fitted energy level and the obtained best fit. Default is False
 minStateContribution (float) â€“ valid values are in the range [0,1). It specifies minimum amount of the original state in the given energy state necessary for the state to be considered for the adiabatic continuation of the original unperturbed pair state.
Returns: \(C_6\) measured in \(\text{GHz }\mu\text{m}^6\) on success; If unsuccessful returns False.
Return type: Note
In order to use this functions, highlighting in
diagonalise
should be based on the original pair state contribution of the eigenvectors (that this, drivingFromState parameter should not be set, which corresponds to drivingFromState = [0,0,0,0,0]).

getC6perturbatively
(theta, phi, nRange, energyDelta)[source]Â¶ Calculates \(C_6\) from second order perturbation theory.
Calculates \(C_6=\sum_{\rm r',r''}\langle {\rm r',r''}V {\rm r1,r2}\rangle^2/\Delta_{\rm r',r''}\), where \(\Delta_{\rm r',r''}\equiv E({\rm r',r''})E({\rm r1, r2})\)
This calculation is faster then full diagonalization, but it is valid only far from the so called spaghetti region that occurs when atoms are close to each other. In that region multiple levels are strongly coupled, and one needs to use full diagonalization. In region where perturbative calculation is correct, energy level shift can be obtained as \(V(R)=C_6/R^6\)
See perturbative C6 calculations example snippet.
Parameters:  theta (float) â€“ orientation of interatomic axis with respect to quantization axis (\(z\)) in Euler coordinates (measured in units of radian)
 phi (float) â€“ orientation of interatomic axis with respect to quantization axis (\(z\)) in Euler coordinates (measured in units of radian)
 nRange (int) â€“ how much below and above the given principal quantum number of the pair state we should be looking
 energyDelta (float) â€“ what is maximum energy difference ( \(\Delta E/h\) in Hz) between the original pair state and the other pair states that we are including in calculation
Returns: \(C_6\) measured in \(\text{GHz }\mu\text{m}^6\)
Return type: Example
If we want to quickly calculate \(C_6\) for two Rubidium atoms in state \(62 D_{3/2} m_j=3/2\), positioned in space along the shared quantization axis:
from arc import * calculation = PairStateInteractions(Rubidium(), 62, 2, 1.5, 62, 2, 1.5, 1.5, 1.5) c6 = calculation.getC6perturbatively(0,0, 5, 25e9) print "C_6 = %.0f GHz (mu m)^6" % c6
Which returns:
C_6 = 767 GHz (mu m)^6
Quick calculation of angular anisotropy of for Rubidium \(D_{2/5},m_j=5/2\) states:
# Rb 60 D_{2/5}, mj=2.5 , 60 D_{2/5}, mj=2.5 pair state calculation1 = PairStateInteractions(Rubidium(), 60, 2, 2.5, 60, 2, 2.5, 2.5, 2.5) # list of atom orientations thetaList = np.linspace(0,pi,30) # do calculation of C6 pertubatively for all atom orientations c6 = [] for theta in thetaList: value = calculation1.getC6perturbatively(theta,0,5,25e9) c6.append(value) print ("theta = %.2f * pi C6 = %.2f GHz mum^6" % (theta/pi,value)) # plot results plot(thetaList/pi,c6,"b") title("Rb, pairstate 60 $D_{5/2},m_j = 5/2$, 60 $D_{5/2},m_j = 5/2$") xlabel(r"$\Theta /\pi$") ylabel(r"$C_6$ (GHz $\mu$m${}^6$") show()

getLeRoyRadius
()[source]Â¶ Returns Le Roy radius for initial pairstate.
Le Roy radius [2] is defined as \(2(\langle r_1^2 \rangle^{1/2} + \langle r_2^2 \rangle^{1/2})\), where \(r_1\) and \(r_2\) are electron coordinates for the first and the second atom in the initial pairstate. Below this radius, calculations are not valid since electron wavefunctions start to overlap.
Returns: LeRoy radius measured in \(\mu m\) Return type: float References
[2] R.J. Le Roy, Can. J. Phys. 52, 246 (1974) http://www.nrcresearchpress.com/doi/abs/10.1139/p74035

getVdwFromLevelDiagram
(rStart, rStop, showPlot=False, minStateContribution=0.0)[source]Â¶ Finds \(r_{\rm vdW}\) coefficient for original pair state.
Function first finds for each distance in the range [rStart,`rStop`] the eigen state with highest contribution of the original state. One can set optional parameter minStateContribution to value in the range [0,1), so that function finds only states if they have contribution of the original state that is bigger then minStateContribution.
Once original pairstate is found in the range of interatomic distances, from smallest rStart to the biggest rStop, function will try to perform fitting of the corresponding state energy \(E(R)\) at distance \(R\) to the function \(A+B\frac{1\sqrt{1+(r_{\rm vdW}/r)^6}}{1\sqrt{1+r_{\rm vdW}^6}}\)
where \(A\) and \(B\) are some offset.Parameters:  rStart (float) â€“ smallest interatomic distance to be used for fitting
 rStop (float) â€“ maximum interatomic distance to be used for fitting
 showPlot (bool) â€“ If set to true, it will print the plot showing fitted energy level and the obtained best fit. Default is False
 minStateContribution (float) â€“ valid values are in the range [0,1). It specifies minimum amount of the original state in the given energy state necessary for the state to be considered for the adiabatic continuation of the original unperturbed pair state.
Returns: \(r_{\rm vdW}\) measured in \(\mu\text{m}\) on success; If unsuccessful returns False.
Return type: Note
In order to use this functions, highlighting in
diagonalise
should be based on the original pair state contribution of the eigenvectors (that this, drivingFromState parameter should not be set, which corresponds to drivingFromState = [0,0,0,0,0]).

interactionsUpTo
= NoneÂ¶ â€ť Specifies up to which approximation we include in pairstate interactions. By default value is 1, corresponding to pairstate interactions up to dipoledipole coupling. Value of 2 is also supported, corresponding to pairstate interactions up to quadrupolequadrupole coupling.

j
= NoneÂ¶ pairstate definition â€“ total angular momentum of the first atom

jj
= NoneÂ¶ pairstate definition â€“ total angular momentum of the second atom

l
= NoneÂ¶ pairstate definition â€“ orbital angular momentum of the first atom

ll
= NoneÂ¶ pairstate definition â€“ orbital angular momentum of the second atom

m1
= NoneÂ¶ pairstate definition â€“ projection of the total ang. momentum for the first atom

m2
= NoneÂ¶ pairstate definition â€“ projection of the total angular momentum for the second atom

matDiagonal
= NoneÂ¶ Part of interaction matrix in pairstate basis that doesnâ€™t depend on interatomic distance. E.g. diagonal elements of the interaction matrix, that describe energies of the pair states in unperturbed basis, will be stored here. Basis states are stored in
basisStates
. Calculated bydefineBasis
.

matR
= NoneÂ¶ Stores interaction matrices in pairstate basis that scale as \(1/R^3\), \(1/R^4\) and \(1/R^5\) with distance in
matR[0]
,matR[1]
andmatR[2]
respectively. These matrices correspond to dipoledipole ( \(C_3\)), dipolequadrupole ( \(C_4\)) and quadrupolequadrupole ( \(C_5\)) interactions coefficients. Basis states are stored inbasisStates
. Calculated bydefineBasis
.

matrixElement
= NoneÂ¶ matrixElement[i] gives index of state in
channel
basis (that doesnâ€™t resolvem_j
states), for the given index i of the state inbasisStates
( \(m_j\) resolving) basis.

n
= NoneÂ¶ pairstate definition â€“ principal quantum number of the first atom

nn
= NoneÂ¶ pairstate definition â€“ principal quantum number of the second atom

originalPairStateIndex
= NoneÂ¶ index of the original n,l,j,m1,nn,ll,jj,m2 pairstate in the
basisStates
basis.

plotLevelDiagram
(highlightColor='red', highlightScale='linear')[source]Â¶ Plots pair state level diagram
Call
showPlot
if you want to display a plot afterwards.Parameters:  highlightColor (string) â€“ optional, specifies the colour used for state highlighting
 highlightScale (string) â€“ optional, specifies scaling of state highlighting. Default is â€linearâ€™. Use â€log2â€™ or â€log3â€™ for logarithmic scale going down to 1e2 and 1e3 respectively. Logarithmic scale is useful for spotting weakly admixed states.

savePlot
(filename='PairStateInteractions.pdf')[source]Â¶ Saves plot made by
plotLevelDiagram
Parameters: filename ( str
, optional) â€“ file location where the plot should be saved

showPlot
(interactive=True)[source]Â¶ Shows level diagram printed by
PairStateInteractions.plotLevelDiagram
By default, it will output interactive plot, which means that clicking on the state will show the composition of the clicked state in original basis (dominant elements)
Parameters: interactive (bool) â€“ optional, by default it is True. If true, plotted graph will be interactive, i.e. users can click on the state to identify the state composition Note
interactive=True has effect if the graphs are explored in usual matplotlib popup windows. It doesnâ€™t have effect on inline plots in Jupyter (IPython) notebooks.
 atom (

class
arc.calculations_atom_pairstate.
StarkMapResonances
(atom1, state1, atom2, state2)[source]Â¶ Calculates pair state Stark maps for finding resonances
Tool for finding conditions for Foster resonances. For a given pair state, in a given range of the electric fields, looks for the pairstate that are close in energy and coupled via dipoledipole interactions to the original pairstate.
See Stark resonances example snippet.
Parameters:  atom (
AlkaliAtom
) â€“={
alkali_atom_data.Lithium6
,alkali_atom_data.Lithium7
,alkali_atom_data.Sodium
,alkali_atom_data.Potassium39
,alkali_atom_data.Potassium40
,alkali_atom_data.Potassium41
,alkali_atom_data.Rubidium85
,alkali_atom_data.Rubidium87
,alkali_atom_data.Caesium
}the first atom in the pairstate  state1 ([int,int,float,float]) â€“ specification of the state of the first state as an array of values \([n,l,j,m_j]\)
 atom â€“
={
alkali_atom_data.Lithium6
,alkali_atom_data.Lithium7
,alkali_atom_data.Sodium
,alkali_atom_data.Potassium39
,alkali_atom_data.Potassium40
,alkali_atom_data.Potassium41
,alkali_atom_data.Rubidium85
,alkali_atom_data.Rubidium87
,alkali_atom_data.Caesium
}the second atom in the pairstate  state2 ([int,int,float,float]) â€“ specification of the state of the first state as an array of values \([n,l,j,m_j]\)
Note
In checking if certain state is dipole coupled to the original state, only the highest contributing state is checked for dipole coupling. This should be fine if one is interested in resonances in weak fields. For stronger fields, one might want to include effect of coupling to other contributing base states.

findResonances
(nMin, nMax, maxL, eFieldList, energyRange=[5000000000.0, 5000000000.0], Bz=0, progressOutput=False)[source]Â¶ Finds nearresonant dipolecoupled pairstates
For states in range of principal quantum numbers [nMin,`nMax`] and orbital angular momentum [0,`maxL`], for a range of electric fields given by eFieldList function will find nearresonant pair states.
Only states that are in the range given by energyRange will be extracted from the pairstate Stark maps.
Parameters:  nMin (int) â€“ minimal principal quantum number of the state to be included in the StarkMap calculation
 nMax (int) â€“ maximal principal quantum number of the state to be included in the StarkMap calculation
 maxL (int) â€“ maximum value of orbital angular momentum for the states to be included in the calculation
 eFieldList ([float]) â€“ list of the electric fields (in V/m) for which to calculate level diagram (StarkMap)
 Bz (float) â€“ optional, magnetic field directed along zaxis in units of Tesla. Calculation will be correct only for weak magnetic fields, where paramagnetic term is much stronger then diamagnetic term. Diamagnetic term is neglected.
 energyRange ([float,float]) â€“ optinal argument. Minimal and maximal energy of that some dipolecoupled state should have in order to keep it in the plot (in units of Hz). By default it finds states that are \(\pm 5\) GHz
 progressOutput (
bool
, optional) â€“ if True prints the progress of calculation; Set to false by default.
 atom (
How to contribute to the projectÂ¶
Ideally, this package/library will grow into a community project, as a communitymaintained resource for atomic physics community. Full code will be accessible from GitHub, so please fork the project, and submit improvements, additional modules, new features, or just suggest ideas. We have a list of features that can be potentially included.
Ideas for developmentÂ¶
This is incomplete list of some of the modules that can be added to the library:
 Dressing potentials
 Magic wavelengths
 Atomwall interactions
 Photoionization
 Collisional crosssections
 Tensor polarisability
 â€¦ (add your own ideas)
Naming conventionsÂ¶
For the sake of consistency, readability and crosslinking with the written literature, please follow the following for contributions:
 Names and method/subdivision should reflect structure of knowledge in atomic physics, NOT lowlevel implementation structure.
 Names should be sensible to atomic physicists (even if they are not familiar with coding).
 Use long selfdescriptive variable names (so that the code is selfdocumented and readable in itself) and write short comment on functions of code subsections.
 Use Google style docstrings for code documentation (we are using Sphinx Napoleon extension for generating documentation)
 Add references to original papers in comments and docstrings.
Finally, this is the naming convention. of the original package. For consistency, we suggest following the same naming convention.
Submodules are lower case, separated by underscore. Example:
import my_module_nameClasses are named in CamelCase, for example:
class MyNewClass: ...Class methods that return a value start with get in their name, and follow camelCase convention, for example:
def getSumOfTwoNumbers(a,b): return a+bClass methods donâ€™t return a value are named in camelCase, for example:
def defineBasis(): ...
Package structureÂ¶
Indices and tablesÂ¶
CreditsÂ¶
Authors:  Nikola Ĺ ibaliÄ‡, Jonathan D. Pritchard, Charles S. Adams, Kevin J. Weatherill 

Licence:  BSD 3Clause 
Version:  1.2.0 of 2017/06/10 