Quick Start Guide
Installation
AtomTwin is a Julia package. The easiest way to use it is via the Julia package manager.
Requirements
- Julia 1.11 or later
- Internet access to download dependencies from the General registry
Install Julia with juliaup
juliaupis the recommended way to install and manage Julia on all major platforms.
- Windows: Install “Julia” from the Microsoft Store or via the Windows package manager (
winget), which also installsjuliaup. Then open a new terminal and runjuliato start the Julia REPL.- Linux: Use your distribution’s instructions for installing
juliaup(typically a single shell command from the official Julia download page), then open a terminal and runjulia.If you want Julia to use multiple CPU threads, start it with
julia --threads auto(or set theJULIA_NUM_THREADSenvironment variable), then follow the steps below to addAtomTwin.
Install AtomTwin from the registry
Start Julia, enter the package mode with ], and add AtomTwin:
julia> ]
pkg> add AtomTwinThen, in your code:
using AtomTwinYour first simulation: driven two‑level atom
An AtomTwin simulation usually follows three steps:
- Define the system (atoms, tweezers, interactions, noise, …)
- Build a sequence of operations and attach detectors
- Run the simulation with
playand inspect the outputs
1. Define a two‑level atom and system
using AtomTwin
g, e = Level(; label = "g"), Level(; label = "e")
atom = Atom(; levels = [g, e])
system = System(atom)AtomTwin.System
├─ Atoms (1): GenericAtom[g,e]
├─ Beams (0)
├─ Nodes (0)
├─ Detectors (0)
├─ Basis: dim = 2
└─ State: empty
2. Add physics and a detector
Add a resonant coupling between |g⟩ and |e⟩ with a Rabi frequency of 1 MHz:
add_coupling!(system, atom, g => e, 2π * 1e6)AtomTwin.GlobalCoupling(1→2, Ω=6.283185307179586e6 + 0.0im)
├─ Transition: 1 → 2
├─ Coefficient: 1.0 + 0.0im
└─ H: 2×2 operator (2 nonzero elements
Register a population detector on the excited state so we can plot the dynamics later:
add_detector!(system, PopulationDetectorSpec(atom, e; name = "P_e"))AtomTwin.System
├─ Atoms (1): GenericAtom[g,e]
├─ Beams (0)
├─ Nodes (1)
├─ Detectors (1): PopulationDetector
├─ Basis: dim = 2
└─ State: empty
Now define a simple sequence with a fixed time step of 1 ns and a 5 µs wait:
seq = Sequence(1e-9) # fixed time step of 1 nanosecond
@sequence seq begin
Wait(5e-6) # duration of 5 microseconds
endSequence(AbstractInstruction[Wait(5.0e-6)], 1.0e-9)3. Run the simulation
out = play(system, seq; initial_state = g)(detectors = Dict{String, Any}("P_e" => [9.869571931419052e-6, 3.947789809187577e-5, 8.882380959535094e-5, 0.00015790535834975207, 0.00024671981713382096, 0.0003552636797047994, 0.00048353266093685023, 0.0006315216969902259, 0.0007992249455111807, 0.0009866357858626174 … 0.0006315216976315857, 0.00048353266149810093, 0.0003552636801859175, 0.00024671981753478564, 0.000157905358670546, 8.882380983595985e-5, 3.94778982522886e-5, 9.869572011627851e-6, 1.629666288772325e-22, 9.869571851208647e-6]), times = [1.0e-9, 2.0e-9, 3.0000000000000004e-9, 4.0e-9, 5.0e-9, 6.0e-9, 7.000000000000001e-9, 8.0e-9, 9.000000000000001e-9, 1.0000000000000002e-8 … 4.992e-6, 4.993e-6, 4.994e-6, 4.995e-6, 4.996e-6, 4.997e-6, 4.998e-6, 4.999e-6, 4.9999999999999996e-6, 5.001e-6], final_states = Vector{ComplexF64}[])Detector outputs are stored in out.detectors by name. For the excited‑state population:
out.detectors["P_e"]5001-element Vector{Float64}:
9.869571931419052e-6
3.947789809187577e-5
8.882380959535094e-5
0.00015790535834975207
0.00024671981713382096
0.0003552636797047994
0.00048353266093685023
0.0006315216969902259
0.0007992249455111807
0.0009866357858626174
⋮
0.00048353266149810093
0.0003552636801859175
0.00024671981753478564
0.000157905358670546
8.882380983595985e-5
3.94778982522886e-5
9.869572011627851e-6
1.629666288772325e-22
9.869571851208647e-6You can now plot out.detectors["P_e"] against out.times using your plotting package of choice.
Using AtomTwin in a project environment
For a new project directory:
mkdir my_atom_project
cd my_atom_project
julia --project=.Then in the Julia REPL:
julia> ]
pkg> add AtomTwinYour Project.toml will now list AtomTwin as a dependency, and you can use it in any script inside this directory:
using AtomTwinExample workflows
Once AtomTwin is installed, you can:
- Explore more examples such as Rabi oscillations with noise and dissipation.
- Design and optimize your own sequences including quantum and classical dynamics of atoms in tweezer arrays.
- Prototype your own quantum instructions, estimate fidelities and error budgets.