Status: Alpha - usable, but still in early development.
Xscript is a Python toolkit that simplifies writing physics scripts.
Goal: Instead of switching between unrelated Python libraries, describe your physical system directly and let Xscript handle the underlying calculations.
Xscript requires Python 3.9 or newer and Git.
ARC is optional. The ARC backend requires Python 3.10 or newer.
Install Xscript directly from GitHub without ARC:
python -m pip install "xscript @ git+https://github.com/TU-Darmstadt-APQ/Xscript.git"This installs Xscript and its core dependencies: NumPy, SciPy, and Matplotlib.
ARC is not installed with the standard installation.
To include the ARC backend:
python -m pip install "xscript[arc] @ git+https://github.com/TU-Darmstadt-APQ/Xscript.git"The ARC backend requires Python 3.10 or newer.
Clone the repository and install Xscript in editable mode with the development tools:
git clone https://github.com/TU-Darmstadt-APQ/Xscript.git
cd Xscript
python -m pip install -e ".[dev]"To also install the ARC backend:
python -m pip install -e ".[dev,arc]"The ARC backend requires Python 3.10 or newer.
Example scripts are available in the examples/ directory.
Physical constants should be easy to recognize, easy to read, and easy to inspect.
Xscript uses clear uppercase names and includes descriptions, values, and units that appear when you hover over a constant in your editor.
from xscript.constants import C, HBAR, K_BValues come from scipy.constants, so Xscript keeps the familiar scientific foundation while making your scripts easier to read.
Physics scripts constantly jump between wavelengths, frequencies, energies, temperatures, and power units.
Instead of remembering conversion factors or rewriting the same expressions, start typing convert_ and let your editor show the available functions.
from xscript.convert import *
frequency_hz = convert_nm_to_hz(780.0)
energy_ev = convert_hz_to_ev(frequency_hz)Each function name tells you what goes in and what comes out.
Do not waste time manually creating figures, axes, labels, and layouts.
from xscript.tools import plot_line, plot_show
wavelength_nm = [780, 800, 820]
trap_depth_mk = [1.2, 1.0, 0.8]
plot_line(
wavelength_nm,
trap_depth_mk,
xlabel="Wavelength (nm)",
ylabel="Trap depth (mK)",
)
plot_show()Xscript handles the common Matplotlib setup for you. Direct Matplotlib access remains available when you need more control.
Xscript includes practical tools for common physics calculations and data analysis.
Import the tools once:
from xscript.tools import *Then start typing a prefix and let your editor suggest the available functions:
extract_: Extract peaks and other features from data.fit_: Fit data without dealing with the underlying SciPy syntax.func_: Access common mathematical and physical functions.plot_: Create plots without manually configuring Matplotlib.random_: Generate random samples and simulated data.scan_: Run parameter scans with minimal setup.
Each function name describes what it does, making the available tools easy to discover through autocomplete.
Define an atom once, then access its physical properties, transitions, quantum states, and atomic calculations through one consistent interface.
from xscript.atoms import AtomicTransition, RB85,RB87
atom = RB85()
print(atom.mass_kg)
# 1.40999344065e-25
print(atom.D1.wavelength_nm)
# 794.979014933
print(atom.D2.linewidth_hz)
# 6066600.0Describe atomic levels using their quantum numbers:
ground = atom.level(n=5, l=0, j=0.5)
excited = atom.level(n=5, l=1, j=1.5)
transition = AtomicTransition(
name="D2 transition",
initial=ground,
final=excited,
)Xscript provides the allowed magnetic and hyperfine quantum numbers:
print(ground.label)
# 5S1/2
print(ground.allowed_mj_values)
# [-0.5, 0.5]
print(ground.allowed_f_values)
# [2.0, 3.0]Generate the corresponding states directly:
hyperfine_ground = ground.levels_f[3]
print(hyperfine_ground.label)
# 5S1/2, F=3
stretched_ground = hyperfine_ground.levels_mf[3]
print(stretched_ground.label)
# 5S1/2, F=3, mF=3Or define a state explicitly:
stretched_ground = atom.level(
n=5,
l=0,
j=0.5,
f=3,
mf=3,
)The same atom provides direct access to atomic calculations:
atom.energy_ev(ground)
atom.hfs_coefficients_hz(ground)
atom.hyperfine_shift_hz(hyperfine_ground)
atom.lifetime_s(excited)Instead of scattering laser parameters across unrelated variables, define the instrument once:
from xscript.devices import DeviceLaserGaussian
laser = DeviceLaserGaussian(
name="Optical tweezer",
wavelength_nm=852.0,
power_mw=20.0,
waist_um=1.2,
polarization=0,
)Its relevant properties are immediately available:
laser.frequency_hz
laser.omega
laser.waist_m
laser.rayleigh_range_m
laser.intensity_peak_w_m2
laser.electric_field_amplitude_v_mEvaluate the beam away from its focus:
intensity = laser.intensity_w_m2(
rho_m=0.5e-6,
z_m=2.0e-6,
)
radial_gradient, axial_gradient = (
laser.intensity_gradient_cylindrical_w_m3(
rho_m=0.5e-6,
z_m=2.0e-6,
)
)Build an optical tweezer from the physical objects you already defined:
from xscript.devices import DeviceOpticalTweezer
tweezer = DeviceOpticalTweezer(
laser=laser,
atom=atom,
)Use the atom's D1 and D2 lines to calculate the trapping potential:
trap_minimum_j = tweezer.trap_potential_minimum_alkali_j()Calculate the trapping force at another position:
radial_force_n, axial_force_n = tweezer.trap_force_alkali_n(
(0.5e-6, 2.0e-6)
)For a stable red-detuned trap, obtain the approximate radial and axial angular trap frequencies:
radial_frequency_rad_s = tweezer.trap_frequency_radial()
axial_frequency_rad_s = tweezer.trap_frequency_axial()Xscript lets you describe a simulation in terms of the physics itself: initial conditions, accelerations, conditional effects, stopping rules, and recorded quantities.
model = VerletModel(
position_fn=get_init_position,
velocity_fn=get_init_velocity,
accelerations=[
duffing,
damping,
external_force,
when(is_too_fast, high_speed_damping),
],
actions=[
when(has_escaped, verlet_escape()),
],
)
result = verlet_run_sim(config, model)The simulation loop, state updates, data recording, stopping logic, and particle lifecycle are handled by the framework, so the user can focus on the model instead of control flow.
Velocity-Verlet is the first implementation built on top of the simulation core, with the framework designed so additional numerical methods and simulation types can be added without changing the way simulations are composed.
xscript.convert: Unit conversion functions.xscript.constants: Physical and mathematical constants.xscript.atoms: Atomic species, levels, transitions, and matrix elements.xscript.backends: Backend interfaces, registration, and implementations (dev mode).xscript.devices: Lasers, optical tweezers, and laboratory devices.xscript.simulations: Simulation framework and numerical integration tools for physical systems.xscript.tools: Plotting, fitting, analysis, validation, and mathematical helpers.
Atomic models define the user-facing interface. Backend implementations provide the underlying atomic data and calculations.
The backend registry connects each atomic species to a compatible implementation. ARC is the current backend for supported rubidium isotopes.
Additional backends can be added by implementing the backend protocol and registering a factory for the relevant atomic species.
Public methods include units in their names wherever practical:
_m: Meters._nm: Nanometers._um: Micrometers._hz: Hertz._rad_s: Radians per second._j: Joules._ev: Electronvolts._w: Watts._mw: Milliwatts._n: Newtons._w_m2: Watts per square meter.
Laser inputs commonly use nanometers, milliwatts, and micrometers, while calculated quantities generally use SI units.
laser.omega, trap_frequency_radial, and trap_frequency_axial return angular frequencies in radians per second.
Xscript is licensed under the PolyForm Noncommercial License 1.0.0.
Academic, educational, and other permitted noncommercial use is free. Commercial use requires a separate license.
For commercial licensing inquiries, contact the project maintainer through the repository.


