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.SystemType
System

Container 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 register
  • beams::Vector{AbstractBeam} – list of beams acting on the atoms
  • initial_state::Vector{AbstractLevel} – per-atom logical/physical levels used to prepare the initial many-body state
  • state::Ref{Union{Nothing,Array{ComplexF64}}} – current state (statevector or density matrix) in the chosen basis; nothing if uninitialized
  • basis::Union{Nothing,Basis} – Hilbert-space basis associated with atoms
  • nodes::Vector{AbstractNode} – DAG nodes encoding Hamiltonian terms, jump operators, and other system components. Each node holds its compiled output in node._field. Built by add_coupling!, add_detuning!, etc.
  • detector_specs::Vector{Dynamiq.DetectorSpec} – detector configuration used for measurement modelling
AtomTwin.getqstateFunction
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.getmatrixFunction
getmatrix(field::<:AbstractField)

Return the operator matrix for a field

AtomTwin.Dynamiq.BasisType
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.LevelType
Level <: AbstractLevel

Represents a generic atomic level without hyperfine structure (e.g., leak states).

Fields

  • label::String: Human-readable label
AtomTwin.FineLevelType
FineLevel <: AbstractLevel

Represents a specific fine-structure level with quantum numbers J, mJ, and Landé g-factor.

Fields

  • J::Rational{Int}: Total electronic angular momentum quantum number
  • mJ::Rational{Int}: Magnetic quantum number
  • g_J::Float64: Landé g-factor for this level
  • label::String: Human-readable label (e.g., "nS₁/₂")
AtomTwin.HyperfineLevelType
HyperfineLevel <: AbstractLevel

Represents a specific hyperfine level with quantum numbers F, mF and Landé g-factor.

Fields

  • F::Rational{Int}: Total angular momentum quantum number
  • J::Rational{Int}: Orbital angular momentum quantum number
  • mF::Rational{Int}: Magnetic quantum number
  • g_F::Float64: Landé g-factor for this level
  • label::String: Human-readable label (e.g., "³P₀")
AtomTwin.SuperpositionType
Superposition

Sparse 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.AbstractManifoldType
AbstractManifold

Abstract supertype for manifolds of atomic levels (e.g. FineManifold, HyperfineManifold). Provides a common interface for iteration and access to the underlying levels.

AtomTwin.FineManifoldType
FineManifold <: AbstractManifold

Container for all magnetic sublevels of a fine-structure manifold with quantum number J.

Fields

  • J::Rational{Int}: Total electronic angular momentum quantum number
  • label::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.HyperfineManifoldType
HyperfineManifold <: AbstractManifold

Container for all magnetic sublevels of a hyperfine manifold with quantum number F.

Fields

  • F::Rational{Int}: Total angular momentum quantum number
  • J::Rational{Int}: Orbital angular momentum quantum number
  • label::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.getindexFunction
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.iterateFunction

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
end
Base.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.AtomType
Atom

Generic neutral atom model used as the default species in AtomTwin. It wraps an internal NLevelAtom with reasonable generic defaults.

AtomTwin.Dynamiq.NLevelAtomType
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.PolarizabilityModelType
PolarizabilityModel

Empirical 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 has
    • freq_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.PolarizabilityCurveType
PolarizabilityCurve

Container 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_Wcm2Function
light_shift_coeff_Hz_per_Wcm2(model::PolarizabilityModel, λ_nm::Real) -> Float64

Light-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) * I

Arguments

  • model: Polarizability model for a single atomic state.
  • λ_nm: Laser wavelength in nanometres.
light_shift_coeff_Hz_per_Wcm2(atom::Ytterbium171Atom, state, λ_nm) -> Float64

Light-shift coefficient for a Yb-171 atom in the given state at wavelength λ_nm (nm).

Returns Δν/I in Hz/(W/cm²).

AtomTwin.polarizability_auFunction
polarizability_au(model::PolarizabilityModel, λ_nm::Real) -> Float64

Dynamic 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) -> Float64

Dynamic polarizability in atomic units for a Yb-171 atom in the given state at wavelength λ_nm (nm).

AtomTwin.polarizability_siFunction
polarizability_si(model::PolarizabilityModel, λ_nm::Real) -> Float64

Dynamic 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.AtomWrapperType
AtomWrapper{S} <: AbstractAtom

Low-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_DEFAULTSConstant
ATOM_DEFAULTS

Internal 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

  1. Position initialization: If atom.x_init is set:
    • If PositionSampler: draws random position from configured distribution
    • If Vector: sets position to fixed value
  2. Velocity initialization: If atom.v_init is set:
    • If VelocitySampler: draws random velocity (e.g., Maxwell-Boltzmann distribution)
    • If Vector: sets velocity to fixed value
  3. 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 properties
Ytterbium171Atom
├─ 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.GaussianBeamType
GaussianBeam <: AbstractBeam

Axis-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.GeneralGaussianBeamType
GeneralGaussianBeam <: AbstractBeam

Elliptical 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 to k).
  • v::Vector{Float64}: Local y axis (perpendicular to k and u).
  • 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.PlanarBeamType
PlanarBeam <: AbstractBeam

Plane-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.TweezerArrayType
TweezerArray

Array 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 axis
  • col_freqs::Vector{Float64} – AOD drive frequencies for the column axis
  • row_amplitudes::Vector{Float64} – relative amplitudes per row
  • col_amplitudes::Vector{Float64} – relative amplitudes per column
  • dx::Float64 – position-to-frequency factor along x (e.g. µm/MHz)
  • dy::Float64 – position-to-frequency factor along y
  • beams::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.PopulationDetectorSpecFunction
PopulationDetectorSpec(atom; level = 1, name = "", tspan = nothing) -> DetectorSpec

Create 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. If nothing, the time grid is supplied by the simulation.
PopulationDetectorSpec(atom, level::AbstractLevel; name = "") -> Dynamiq.DetectorSpec

AtomTwin convenience wrapper to define a population detector using level objects instead of integer indices.

Arguments

  • atom::AbstractAtom: atom whose population is to be monitored
  • level::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.CoherenceDetectorSpecFunction
CoherenceDetectorSpec(atom; levels = 1=>2, name = "", tspan = nothing) -> DetectorSpec

Create 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. If nothing, the time grid is taken from the simulation.
CoherenceDetectorSpec(atom, levels::Pair{<:AbstractLevel,<:AbstractLevel}; name = "") -> Dynamiq.DetectorSpec

AtomTwin convenience wrapper to define a coherence detector between two levels using AbstractLevel objects.

Arguments

  • atom::AbstractAtom: atom whose coherence is to be monitored
  • levels::Pair: pair ℓ1 => ℓ2 of 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.MotionDetectorSpecFunction
MotionDetectorSpec(atom; dims = [1, 2, 3], name = "") -> Dynamiq.DetectorSpec

AtomTwin 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.FieldDetectorSpecFunction
FieldDetectorSpec(obj; name = "", tspan = nothing) -> DetectorSpec

Inert 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. If nothing, the runtime supplies the segment or full-run tspan.

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.DetectorSpec

AtomTwin 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 instrument
  • detector_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}) -> System

Attach 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.PopulationDetectorType
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.CoherenceDetectorType
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.MotionDetectorType
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.FieldDetectorType
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.