System and device model
Construct full neutral-atom device models by combining atoms, levels, tweezers, static fields, and detectors into a single System object.
AtomTwin.System — Type
SystemContainer for the full physical model of an atomic quantum processor.
A System bundles the atoms, beams (or tweezer arrays), basis, static fields, and detector specifications required to simulate dynamics with play and related routines. The quantum state is stored internally in state and is typically initialized lazily by the simulator.
Fields
atoms::Vector{AbstractAtom}– list of atoms in the registerbeams::Vector{AbstractBeam}– list of beams acting on the atomsinitial_state::Vector{AbstractLevel}– per-atom logical/physical levels used to prepare the initial many-body statestate::Ref{Union{Nothing,Array{ComplexF64}}}– current state (statevector or density matrix) in the chosen basis;nothingif uninitializedbasis::Union{Nothing,Basis}– Hilbert-space basis associated withatomsnodes::Vector{AbstractNode}– DAG nodes encoding Hamiltonian terms, jump operators, and other system components. Each node holds its compiled output innode._field. Built byadd_coupling!,add_detuning!, etc.detector_specs::Vector{Dynamiq.DetectorSpec}– detector configuration used for measurement modelling
AtomTwin.getqstate — Function
getqstate(system::System, state::Vector; density_matrix = false)Construct a many-body quantum state for system from a per-atom specification state.
Each entry of state is either an AbstractLevel or a Superposition for the corresponding atom. The function expands these into all product basis components using productstate(system.basis, ...), normalizes the resulting statevector, and returns either:
- the normalized statevector (default,
density_matrix = false), or - the corresponding pure-state density matrix (
density_matrix = true).
This is typically used to prepare initial states for simulations and analysis routines such as tomography.
getqstate(sys::System)Return the current quantum state stored in sys.
The state is populated by play / play!. If the system has not been simulated yet (i.e. sys.state[] is nothing), an error is thrown to signal that no state is available.
AtomTwin.gethamiltonian — Function
gethamiltonian(sys::System)Return the system Hamiltonian
AtomTwin.getmatrix — Function
getmatrix(field::<:AbstractField)Return the operator matrix for a field
AtomTwin.getbasis — Function
getbasis(sys:System)AtomTwin.Dynamiq.Basis — Type
Basis{N}Tensor-product basis for N atoms.
Each basis element is an N-tuple of internal level indices, one per atom. The full Hilbert-space dimension is stored in dim.
Levels
Specify internal energy levels and state manifolds for building atomic models.
AtomTwin.Level — Type
Level <: AbstractLevelRepresents a generic atomic level without hyperfine structure (e.g., leak states).
Fields
label::String: Human-readable label
AtomTwin.FineLevel — Type
FineLevel <: AbstractLevelRepresents a specific fine-structure level with quantum numbers J, mJ, and Landé g-factor.
Fields
J::Rational{Int}: Total electronic angular momentum quantum numbermJ::Rational{Int}: Magnetic quantum numberg_J::Float64: Landé g-factor for this levellabel::String: Human-readable label (e.g., "nS₁/₂")
AtomTwin.HyperfineLevel — Type
HyperfineLevel <: AbstractLevelRepresents a specific hyperfine level with quantum numbers F, mF and Landé g-factor.
Fields
F::Rational{Int}: Total angular momentum quantum numberJ::Rational{Int}: Orbital angular momentum quantum numbermF::Rational{Int}: Magnetic quantum numberg_F::Float64: Landé g-factor for this levellabel::String: Human-readable label (e.g., "³P₀")
AtomTwin.Superposition — Type
SuperpositionSparse linear combination of atomic levels.
Superposition stores a dictionary coeffs mapping each AbstractLevel to a complex amplitude. It is constructed implicitly using arithmetic on levels, for example 2 * ℓ1 - ℓ2 or ℓ1 + ℓ2.
Manifold types
AtomTwin.AbstractManifold — Type
AbstractManifoldAbstract supertype for manifolds of atomic levels (e.g. FineManifold, HyperfineManifold). Provides a common interface for iteration and access to the underlying levels.
AtomTwin.FineManifold — Type
FineManifold <: AbstractManifoldContainer for all magnetic sublevels of a fine-structure manifold with quantum number J.
Fields
J::Rational{Int}: Total electronic angular momentum quantum numberlabel::String: Manifold label (e.g., "nS₁/₂ Rydberg", "P₃/₂")g_J::Float64: Landé g-factor (common for all levels in manifold)Γ::Float64: Natural linewidth in rad/s (for excited states)levels::Vector{FineLevel}: All magnetic sublevels mJ = -J, -J+1, ..., +J
Constructor
FineManifold(J; label="", g_J=1.0, Γ=0.0)Automatically creates all 2J+1 magnetic sublevels.
AtomTwin.HyperfineManifold — Type
HyperfineManifold <: AbstractManifoldContainer for all magnetic sublevels of a hyperfine manifold with quantum number F.
Fields
F::Rational{Int}: Total angular momentum quantum numberJ::Rational{Int}: Orbital angular momentum quantum numberlabel::String: Manifold label (e.g., "³P₀", "³D₁")g_F::Float64: Landé g-factor (common for all levels in manifold)Γ::Float64: Natural linewidth in rad/s (for excited states)levels::Vector{HyperfineLevel}: All magnetic sublevels mF = -F, -F+1, ..., +F
Constructor
HyperfineManifold(F, J; label="", g_F=1.0, Γ=0.0)Automatically creates all 2F+1 magnetic sublevels.
Iteration and access
These methods let you iterate over levels and select sublevels:
Base.getindex — Function
manifold[mF]Access specific magnetic sublevel by mF quantum number.
Base.getindex(t::TweezerArray, i...)Index into the underlying beams vector.
This allows TweezerArray to be used like a 1D collection of GaussianBeam objects, e.g. ta[1] returns the first beam in the flattened row–major ordering.
Base.getindex(t::TweezerArray, i, j)Index into the underlying beams vector.
This allows TweezerArray to be used like a 2D collection of GaussianBeam objects, e.g. ta[1,2] returns the beam in the first row and the second column.
Beam at (row=i, col=j) has linear index (i-1)*nrow + j
Base.getindex(seq::Sequence, i...)Index into the underlying instruction list of seq.
This allows Sequence to be used like a vector of AbstractInstruction, e.g. seq[1] returns the first instruction in the sequence.
Base.getindex(sys::System, idx::Int)Return the idx-th DAG node in sys.nodes.
Base.iterate — Function
Iterator interface for manifolds (allows for level in manifold)
Base.iterate(t::TweezerArray, state...)Iterate over the beams in a TweezerArray.
Enables idioms such as
for beam in ta
# do something with each GaussianBeam
endBase.iterate(seq::Sequence, state...)Iterate over the instructions in seq.
Enables use of for inst in seq and other iterator-based patterns, treating Sequence as a collection of AbstractInstruction objects.
Example: building a hyperfine manifold
using AtomTwin
# Hyperfine manifold with F = 3/2, J=1/2 and a simple label
manifold = HyperfineManifold(3//2, 1//2; label = "6S1/2", g_F = 0.5)
#Iterate over all mF sublevels
for level in manifold
@show level.F, level.mF
end(level.F, level.mF) = (3//2, -3//2)
(level.F, level.mF) = (3//2, -1//2)
(level.F, level.mF) = (3//2, 1//2)
(level.F, level.mF) = (3//2, 3//2)Atoms
Define the internal structure of each atom by choosing species and setting properties like the levels, position, and velocity.
AtomTwin.Atom — Type
AtomGeneric neutral atom model used as the default species in AtomTwin. It wraps an internal NLevelAtom with reasonable generic defaults.
AtomTwin.Ytterbium171Atom — Type
Ytterbium171AtomConvenience type for a Yb-171 atom with built-in polarizability models.
AtomTwin.Rubidium87Atom — Type
Rubidium87AtomConvenience alias for an Rb-87 atom with default species parameters.
AtomTwin.Strontium88Atom — Type
Strontium88AtomConvenience alias for an Sr-88 atom with default species parameters.
AtomTwin.Potassium39Atom — Type
Potassium39AtomConvenience alias for a K-39 atom with default species parameters.
AtomTwin.Dynamiq.NLevelAtom — Type
NLevelAtom(n; x = [0, 0, 0], v = [0, 0, 0],
m = 1amu, alphas = Dict(), lambdas = Dict())Minimal n-level atomic model with classical center-of-mass motion.
x,v: position and velocity vectors in real space.m: atomic mass.alphas: dictionary of scalar or tensor polarizabilities keyed by wavelength.lambdas: dictionary of transition wavelengths keyed by level pairs.
Additional internal fields _P and _pidx are used for caching populations and basis-dependent index mappings during simulations.
These aliases all wrap the same low‑level constructor AtomWrapper{S} with different species labels and default parameters.
Atomic Data
AtomTwin.PolarizabilityModel — Type
PolarizabilityModelEmpirical polarizability model for an atomic state, defined by a set of discrete transitions and an optional offset.
Fields
state::String: Electronic state label (e.g."1S0","3P0").transitions::Vector{NamedTuple}: List of transitions; each entry hasfreq_THz::Float64: Transition frequency in THz (linear).gamma_MHz::Float64: Linewidth in MHz (linear).
offset_Hz_per_Wm2::Float64: Empirical offset in Hz/(W/m²).reference::String: Bibliographic reference for the data.
AtomTwin.PolarizabilityCurve — Type
PolarizabilityCurveContainer for plotting polarizability curves with an optional inset zoom.
Fields
models::Vector{PolarizabilityModel}: List of polarizability models to plot.λ_main: Wavelength range for main plot in nm (default:420:0.1:800).λ_inset: Wavelength range for inset zoom in nm (default:550.5:0.1:556.2).ylim_main: y-axis limits for main plot (default:(-30, 10)).ylim_inset: y-axis limits for inset (default:(-8, 3.5)).unit::Symbol: Plot unit, either:Hz_per_Wcm2(default) or:au.
Usage
using Plots
Default plot with inset
curve = PolarizabilityCurve([model1S0, model3P0]) plot(curve)
Custom ranges
curve = PolarizabilityCurve([model1S0, model3P0], λmain = 400:0.2:900, λinset = 555:0.05:556, yliminset = (-5, 2)) plot(curve) No inset (set λinset = nothing)
curve = PolarizabilityCurve([model1S0, model3P0], λ_inset = nothing) plot(curve)
AtomTwin.light_shift_coeff_Hz_per_Wcm2 — Function
light_shift_coeff_Hz_per_Wcm2(model::PolarizabilityModel, λ_nm::Real) -> Float64Light-shift coefficient Δν/I in Hz/(W/cm²) for the given model and wavelength.
Definition
For a beam intensity I in W/cm², the light shift is
Δν = light_shift_coeff_Hz_per_Wcm2(model, λ_nm) * IArguments
model: Polarizability model for a single atomic state.λ_nm: Laser wavelength in nanometres.
light_shift_coeff_Hz_per_Wcm2(atom::Ytterbium171Atom, state, λ_nm) -> Float64Light-shift coefficient for a Yb-171 atom in the given state at wavelength λ_nm (nm).
Returns Δν/I in Hz/(W/cm²).
AtomTwin.polarizability_au — Function
polarizability_au(model::PolarizabilityModel, λ_nm::Real) -> Float64Dynamic electric polarizability α in atomic units (a₀³) for the given model and wavelength.
Definition
Converts from SI units via
α_au = α_SI / (4π ε₀ a₀³)polarizability_au(atom::Ytterbium171Atom, state, λ_nm) -> Float64Dynamic polarizability in atomic units for a Yb-171 atom in the given state at wavelength λ_nm (nm).
AtomTwin.polarizability_si — Function
polarizability_si(model::PolarizabilityModel, λ_nm::Real) -> Float64Dynamic electric polarizability α in SI units (C·m²·V⁻¹) for the given model and wavelength.
Definition
Uses the relation
U/I = -α_SI / (c ε₀)which gives
α_SI = -c ε₀ (U/I)where U/I is the light shift per intensity in J/(W/m²).
Units
Returns polarizability in C·m²·V⁻¹ (or equivalently F·m²), which is the standard SI unit for electric polarizability.
Utilities
AtomTwin.AtomWrapper — Type
AtomWrapper{S} <: AbstractAtomLow-level, species-parametric atom wrapper providing NLevelAtom compatibility. The type parameter S is a Symbol, e.g. AtomWrapper{:Ytterbium171}.
Users are encouraged to use the convenience aliases Atom, Ytterbium171Atom, etc. instead of constructing AtomWrapper directly, unless fine-grained control is needed.
AtomTwin.ATOM_DEFAULTS — Constant
ATOM_DEFAULTSInternal dictionary of default species parameters keyed by a Symbol. Each entry stores a named tuple (mass, polarizabilities, I) used by AtomWrapper{S} when explicit values are not provided.
AtomTwin.initialize! — Function
initialize!(atom::AtomWrapper, inner::NLevelAtom; rng=Random.default_rng(), beams=AbstractBeam[])Initialize an atom's position, velocity, and species-specific data based on its configuration.
Arguments
atom::AtomWrapper: Wrapper containing initialization configuration (position/velocity samplers or fixed values)inner::NLevelAtom: The underlying NLevelAtom object to be initialized
Keyword Arguments
rng::AbstractRNG: Random number generator for stochastic sampling (default:Random.default_rng())beams::Vector{AbstractBeam}: Beams for computing wavelength-dependent polarizabilities
Behavior
- Position initialization: If
atom.x_initis set:- If
PositionSampler: draws random position from configured distribution - If
Vector: sets position to fixed value
- If
- Velocity initialization: If
atom.v_initis set:- If
VelocitySampler: draws random velocity (e.g., Maxwell-Boltzmann distribution) - If
Vector: sets velocity to fixed value
- If
- Polarizability initialization: For species with polarizability models, computes α values for all beam wavelengths and stores in
inner.alpha
Returns
inner::NLevelAtom: The initialized atom (modified in-place and returned)
Examples
```julia
Initialize with thermal velocity distribution
atom = Ytterbium171Atom( levels = [g, e], vinit = maxwellboltzmann(T=1e-6) # 1 μK ) inner = NLevelAtom(2) initialize!(atom, inner; beams=[tweezerbeam])
Initialize with fixed position
atom = Atom( levels = [g, e], x_init = [0.0, 0.0, 5e-6] # 5 μm above origin ) initialize!(atom, inner)
initalize!(atom::AbstractAtom)Convenience wrapper that initializes an AbstractAtom in place using its inner NLevelAtom.
This forwards to initialize!(::AtomWrapper, ::NLevelAtom), passing atom.inner and the supplied beams and rng.
Use these when you need fine control over species parameters or when integrating AtomTwin with other simulation layers. Position and velocity samplers (GaussianPosition, MaxwellBoltzmann) are documented in the DAG system section.
Example
using AtomTwin
# Create a single ytterbium-171 atom at rest
yb = Ytterbium171Atom()
# Attach a thermal velocity sampler at 5 µK
yb = Ytterbium171Atom(; v_init = maxwellboltzmann(T = 5e-6))
# Draw a random velocity and initialize the wrapped NLevelAtom
initialize!(yb)
yb # show its basic propertiesYtterbium171Atom
├─ Position: [0.0, 0.0, 0.0]
├─ Velocity: [-0.012414984643155292, 0.016603816202142598, -0.02807018538885928]
Beams
Define beam objects for producing forces on atoms or driving transitions between internal states
AtomTwin.Dynamiq.GaussianBeam — Type
GaussianBeam <: AbstractBeamAxis-aligned (z-propagating) Gaussian beam with a 3D harmonic envelope.
Fields:
λ::Float64: Wavelength in meters.w0::Float64: Transverse beam waist (radius) in meters.P::Float64: Optical power in watts.I0::Float64: Peak intensity at the waist.w0z::Float64: Effective axial waist (harmonic approximation) in meters.r0::Vector{Float64}: Beam center position ((x0, y0, z_0))._coeff::Base.RefValue{ComplexF64}: Complex amplitude envelope used by time-dependent modifiers.
The axial waist w0z is chosen such that the simple 3D Gaussian intensity (I \propto \exp[-2(x^2/w0^2 + y^2/w0^2 + z^2/w_{0z}^2)]) matches the quadratic expansion of a paraxial Gaussian near the focus.
AtomTwin.Dynamiq.GeneralGaussianBeam — Type
GeneralGaussianBeam <: AbstractBeamElliptical paraxial Gaussian beam with arbitrary propagation direction.
Fields:
λ::Float64: Wavelength in meters.w0x::Float64: Waist along local x (m).w0y::Float64: Waist along local y (m).P::Float64: Optical power (W).I0::Float64: Peak intensity.r0::Vector{Float64}: Waist center in global coordinates.k::Vector{Float64}: Propagation direction (normalized).u::Vector{Float64}: Local x axis (perpendicular tok).v::Vector{Float64}: Local y axis (perpendicular tokandu).pol::Vector{complexF64}: complex polarization vector in global coordinates_coeff::Base.RefValue{ComplexF64}: Complex amplitude envelope.
The beam profile is elliptical in the transverse plane spanned by u and v.
AtomTwin.Dynamiq.PlanarBeam — Type
PlanarBeam <: AbstractBeamPlane-wave beam with fixed intensity, propagation direction, and polarization.
Fields:
λ::Float64: Wavelength in meters.I::Float64: Intensity in (\mathrm{W/m^2}).E_field::Float64: Electric-field amplitude in natural units (scaled by (\hbar)).k::NTuple{3,Float64}: Wavevector components in (\mathrm{m^{-1}}).unit_k::NTuple{3,Float64}: Normalized propagation direction.polarization::NTuple{3,ComplexF64}: Polarization in the spherical q-basis (q = -1, 0, 1)._coeff::Base.RefValue{ComplexF64}: Complex amplitude envelope used by time-dependent modifiers.
The constructor takes a Cartesian propagation direction and a Jones polarization vector and converts them into the q-basis via BasisPolarization.
Tweezers
Configure 2D AOD-driven tweezer arrays, including spot positions and power distribution, to specify how atoms are trapped in space.
AtomTwin.TweezerArray — Type
TweezerArrayArray of optical tweezers generated by a two-dimensional acousto-optic deflector (AOD).
A TweezerArray represents a rectangular grid of Gaussian beams addressing an atomic register. The grid is parameterized by AOD drive frequencies and amplitudes in two orthogonal directions (“rows” and “columns”), from which individual beam positions and powers are derived.
Fields
λ::Float64– wavelength of each beam (m)w0::Float64– 1/e² waist of each beam at focus (m)P_total::Float64– total optical power distributed across the array (W)r0::Tuple{Float64,Float64}– transverse offset of the AOD reference spot (m)row_freqs::Vector{Float64}– AOD drive frequencies for the row axiscol_freqs::Vector{Float64}– AOD drive frequencies for the column axisrow_amplitudes::Vector{Float64}– relative amplitudes per rowcol_amplitudes::Vector{Float64}– relative amplitudes per columndx::Float64– position-to-frequency factor along x (e.g. µm/MHz)dy::Float64– position-to-frequency factor along ybeams::Vector{GaussianBeam}– flattened list of Gaussian beam objects
Detectors
Attach population, coherence, motion, and field detectors to a System so simulations produce the observables you need.
AtomTwin.Dynamiq.PopulationDetectorSpec — Function
PopulationDetectorSpec(atom; level = 1, name = "", tspan = nothing) -> DetectorSpecCreate a detector specification for a population detector.
Only the atom is required here; the quantum state and basis are retrieved from the system at build time via build_detectors.
Arguments
atom::AbstractAtom: Atom to observe (will be resolved when building).
Keywords
level::Int = 1: Level index to monitor.name::AbstractString = "": Optional detector name.tspan::Union{Nothing,Vector{Float64}} = nothing: Optional time vector. Ifnothing, the time grid is supplied by the simulation.
PopulationDetectorSpec(atom, level::AbstractLevel; name = "") -> Dynamiq.DetectorSpecAtomTwin convenience wrapper to define a population detector using level objects instead of integer indices.
Arguments
atom::AbstractAtom: atom whose population is to be monitoredlevel::AbstractLevel: target level (e.g.g,e,r)
Keyword arguments
name::String: optional detector name; defaults to the empty string
This converts level to its integer index via atom.level_indices and constructs a Dynamiq.PopulationDetectorSpec with that index.
AtomTwin.Dynamiq.CoherenceDetectorSpec — Function
CoherenceDetectorSpec(atom; levels = 1=>2, name = "", tspan = nothing) -> DetectorSpecCreate a detector specification for a coherence detector.
Only the atom is required here; the quantum state and basis will be retrieved from the system at build time via build_detectors.
Arguments
atom::AbstractAtom: Atom to observe (will be resolved when building).
Keywords
levels::Pair{Int,Int}: Pair of levels whose coherence is monitored.name::AbstractString: Optional detector name.tspan::Union{Nothing,Vector{Float64}}: Optional time vector. Ifnothing, the time grid is taken from the simulation.
CoherenceDetectorSpec(atom, levels::Pair{<:AbstractLevel,<:AbstractLevel}; name = "") -> Dynamiq.DetectorSpecAtomTwin convenience wrapper to define a coherence detector between two levels using AbstractLevel objects.
Arguments
atom::AbstractAtom: atom whose coherence is to be monitoredlevels::Pair: pairℓ1 => ℓ2of levels defining the coherence
Keyword arguments
name::String: optional detector name; defaults to the empty string
The levels are mapped to their integer indices via atom.level_indices and passed to Dynamiq.CoherenceDetectorSpec.
AtomTwin.MotionDetectorSpec — Function
MotionDetectorSpec(atom; dims = [1, 2, 3], name = "") -> Dynamiq.DetectorSpecAtomTwin wrapper for Dynamiq's motion detector specification.
Arguments
atom::AbstractAtom: atom whose motional degrees of freedom are monitored
Keyword arguments
dims: list of coordinate indices to monitor (default[1,2,3]for x,y,z)name::String: optional detector name
This is a thin wrapper around Dynamiq.MotionDetectorSpec, re-exported for a uniform AtomTwin-facing detector API.
AtomTwin.Dynamiq.FieldDetectorSpec — Function
FieldDetectorSpec(obj; name = "", tspan = nothing) -> DetectorSpecInert spec for constructing a FieldDetector at runtime.
Arguments
obj: Target object to monitor (e.g. coupling or detuning).
Keywords
name::AbstractString = "": Logical name used to group outputs.tspan::Union{Nothing,Vector{Float64}} = nothing: Optional time vector to attach to the spec. Ifnothing, the runtime supplies the segment or full-runtspan.
Specs are declarative and do not allocate buffers. At runtime, a resolver binds obj to either the original (persistent run) or a per-run copy (stateless run), and the detector is instantiated with the appropriate tspan.
FieldDetectorSpec(field; name = "") -> Dynamiq.DetectorSpecAtomTwin wrapper for Dynamiq's field detector specification.
Arguments
field::AbstractField: field instance to be monitored
Keyword arguments
name::String: optional detector name
Constructs and returns a Dynamiq.FieldDetectorSpec(field; ...).
AtomTwin.add_detector! — Function
add_detector!(system::System, detector_spec::DetectorSpec)Register an observable detector to record during simulation.
Arguments
system::System: The quantum system to instrumentdetector_spec::DetectorSpec: Detector specification (population, coherence, motion, field)
Detector Types
- PopulationDetectorSpec: Track occupation probability of atomic level
- CoherenceDetectorSpec: Track off-diagonal density matrix element
- MotionDetectorSpec: Track atomic position and velocity
- FieldDetectorSpec: Track electromagnetic field amplitude/phase
Returns
nothing(modifies system in-place)
Examples
```julia
Monitor ground state population
adddetector!(sys, PopulationDetectorSpec(atom, g; name="Pg"))
Monitor Rabi oscillation coherence
adddetector!(sys, CoherenceDetectorSpec(atom, g=>e; name="rhoge"))
Monitor atomic trajectory
add_detector!(sys, MotionDetectorSpec(atom; dims=[1,2,3], name="position"))
Monitor Rabi field strength
adddetector!(sys, FieldDetectorSpec(rabibeam; name="Omega")) function adddetector!(sys::System, spec::Dynamiq.DetectorSpec) push!(sys.detectorspecs, spec) return sys end
add_detector!(sys::System, specs::Vector{<:Dynamiq.DetectorSpec}) -> SystemAttach multiple detector specifications to a System.
Each element of specs is appended to sys.detector_specs. The modified system is returned.
Actual detector objects are constructed by `play' as Dynamiq objects.
AtomTwin.Dynamiq.PopulationDetector — Type
PopulationDetector{S,V,T} <: AbstractDetector{A,S}Detector that measures the population of a specific quantum level over time.
Detectors trigger at the end of each time step, so tspan[i] corresponds to the state after evolving to time tspan[i].
Fields
qstate::S: Quantum state representation (Vector{ComplexF64} or Matrix{ComplexF64}).atom::NLevelAtom: Atom being observed.level::Int: Level index (i) to monitor.vals::V: Recorded population values (P_i(t)).tspan::T: Time vector, Vector{Float} or SubArray.O::Op: Projection operator onto the chosen level.name::String: Optional detector name.
Constructor
PopulationDetector(qstate, basis, atom, level, tspan; name = "")
AtomTwin.Dynamiq.CoherenceDetector — Type
CoherenceDetector{A,S} <: AbstractDetector{A}Detector that measures the coherence between two specific quantum levels of an atom over time.
Detectors trigger at the end of each time step, so tspan[i] corresponds to the state after evolving to time tspan[i].
Fields
qstate::S: Reference to the quantum system (Vector{ComplexF64} or Matrix{ComplexF64}).atom::A: Atom being observed.levels::Pair{Int,Int}: Pair of level indices ((i, j)) that define the coherence.vals::Vector{ComplexF64}: Recorded coherence values as a function of time.tspan::Vector{Float64}: Time vector.O::Op: Operator that projects onto the (|i\rangle\langle j|) coherence.name::String: Optional detector name.
Constructor
CoherenceDetector(qstate, basis, atom, levels, tspan; name = "")
AtomTwin.Dynamiq.MotionDetector — Type
MotionDetector{A} <: AbstractDetector{A}Detector that records selected coordinates of a target object obj::A over time.
Fields
obj::A: Target being observed (e.g. an atom or a beam).dims::Vector{Int}: 1-based component indices to record at each time step.vals::Matrix{Float64}: Recorded samples, of size(length(tspan), length(dims)).tspan::Vector{Float64}: Time vector associated with the samples.name::String: Logical name used to group outputs.
Constructors
MotionDetector(obj, dim::Int, tspan; name = "")MotionDetector(obj, dims::Vector{Int}, tspan; name = "")
The detector preallocates its vals buffer according to tspan. Use write!(det, i) to sample the source object at time step i.
AtomTwin.Dynamiq.FieldDetector — Type
FieldDetector{A} <: AbstractDetector{A}Detector that records the complex amplitude of a field obj::A over time.
Typical use is to monitor the scalar coefficient _coeff[] of an AbstractField (e.g. a coupling or detuning) during a simulation.
Fields
obj::A: Target field being observed (e.g. coupling or detuning).vals::Vector{ComplexF64}: Per-timestep samples of the complex amplitude.tspan::Vector{Float64}: Time vector associated with the recorded samples.name::String: Logical name used to group outputs.
Constructor
FieldDetector(obj, tspan; name = "")
The detector stores its own vals buffer sized to tspan. Use write!(det, i) to sample the field at time step i.