Skip to main content

Python versions on PyPI CeNTREX-TlF version on PyPI

See the changelog for release notes and migration guidance.

Extensions

CeNTREX-TlF-julia-extension version on PyPI CeNTREX-TlF version on PyPI

CeNTREX-TlF

Code for generating the CeNTREX TlF States, Hamiltonians, Transitions, Couplings and Lindblad equations.

Consists of six modules:

  • states
  • hamiltonian
  • transitions
  • couplings
  • lindblad
  • utils

states has code to generate states and the classes that describe the CoupledBasisState, UncoupledBasisState and State; where State holds multiple CoupledBasisStates or UncoupledBasisStates with different amplitudes, i.e. when superpositions arise.

Lindblad Solver Performance Options

Rust-backed Lindblad solves default to execution_mode="expanded_sparse". This mode uses a packed Hermitian density matrix and, by default, groups diagonal-real and complex input terms in the RHS kernel. The grouping can be controlled with use_split_input_rhs on solve_lindblad, solve_lindblad_batch, parameter_scan, initial_condition_scan, and grid_scan.

result = solve_lindblad(
    prepared,
    rho0,
    (0.0, t_end),
    execution_mode="expanded_sparse",
    use_split_input_rhs=True,  # default
)

Set use_split_input_rhs=False to keep the same expanded-sparse coefficient representation while disabling input-term grouping. This is mainly useful for benchmarking or checking full-system performance regressions; compact systems usually benefit from the default grouped path.

Dependencies

  • numpy
  • scipy
  • sympy
  • pandas

Installation

python -m pip install .
where . is the path to the directory. To install directly from Github use:
python -m pip install git+https://github.com/ograsdijk/CeNTREX-TlF

states

states contains the functions and classes to represent the TlF states:
CoupledBasisState is a class representing a TlF state with coupled quantum numbers, i.e. F, mF, F1, J, I1, I2, Ω, P.
UncoupledBasisState is a class representing a TlF state with uncoupled quantum numbers, i.e. J, mJ, I1, m1, I2, m2, Ω, P.
Finally State is a class representing a collection of states, since in most cases the TlF molecules are in a superposition state.

from centrex_tlf import states
states.CoupledBasisState(F=1, mF=0, F1 = 1/2, J = 0, I1 = 1/2, I2 = 1/2, Omega = 0, P = 1)

or using some of the functions to generate all hyperfine substates in a given J level:

from centrex_tlf import states
QN = states.generate_uncoupled_states_ground(Js = [0,1])

which returns an array containing the UncoupledBasisStates

array([|X, J = 0, mJ = 0, I₁ = 1/2, m₁ = -1/2, I₂ = 1/2, m₂ = -1/2, P = +, Ω = 0>,
       |X, J = 0, mJ = 0, I₁ = 1/2, m₁ = -1/2, I₂ = 1/2, m₂ = 1/2, P = +, Ω = 0>,
       |X, J = 0, mJ = 0, I₁ = 1/2, m₁ = 1/2, I₂ = 1/2, m₂ = -1/2, P = +, Ω = 0>,
       |X, J = 0, mJ = 0, I₁ = 1/2, m₁ = 1/2, I₂ = 1/2, m₂ = 1/2, P = +, Ω = 0>,
       |X, J = 1, mJ = -1, I₁ = 1/2, m₁ = -1/2, I₂ = 1/2, m₂ = -1/2, P = -, Ω = 0>,
       |X, J = 1, mJ = -1, I₁ = 1/2, m₁ = -1/2, I₂ = 1/2, m₂ = 1/2, P = -, Ω = 0>,
       |X, J = 1, mJ = -1, I₁ = 1/2, m₁ = 1/2, I₂ = 1/2, m₂ = -1/2, P = -, Ω = 0>,
       |X, J = 1, mJ = -1, I₁ = 1/2, m₁ = 1/2, I₂ = 1/2, m₂ = 1/2, P = -, Ω = 0>,
       |X, J = 1, mJ = 0, I₁ = 1/2, m₁ = -1/2, I₂ = 1/2, m₂ = -1/2, P = -, Ω = 0>,
       |X, J = 1, mJ = 0, I₁ = 1/2, m₁ = -1/2, I₂ = 1/2, m₂ = 1/2, P = -, Ω = 0>,
       |X, J = 1, mJ = 0, I₁ = 1/2, m₁ = 1/2, I₂ = 1/2, m₂ = -1/2, P = -, Ω = 0>,
       |X, J = 1, mJ = 0, I₁ = 1/2, m₁ = 1/2, I₂ = 1/2, m₂ = 1/2, P = -, Ω = 0>,
       |X, J = 1, mJ = 1, I₁ = 1/2, m₁ = -1/2, I₂ = 1/2, m₂ = -1/2, P = -, Ω = 0>,
       |X, J = 1, mJ = 1, I₁ = 1/2, m₁ = -1/2, I₂ = 1/2, m₂ = 1/2, P = -, Ω = 0>,
       |X, J = 1, mJ = 1, I₁ = 1/2, m₁ = 1/2, I₂ = 1/2, m₂ = -1/2, P = -, Ω = 0>,
       |X, J = 1, mJ = 1, I₁ = 1/2, m₁ = 1/2, I₂ = 1/2, m₂ = 1/2, P = -, Ω = 0>],
      dtype=object)

State objects, which are superpositions of BasisStates are also generated easily:

superposition = 1*QN[0] + 0.1j*QN[1]

which returns

1.00 x |X, J = 0, mJ = 0, I₁ = 1/2, m₁ = -1/2, I₂ = 1/2, m₂ = -1/2, P = +, Ω = 0>
0.00+0.10j x |X, J = 0, mJ = 0, I₁ = 1/2, m₁ = -1/2, I₂ = 1/2, m₂ = 1/2, P = +, Ω = 0>

A subset of State, CoupledBasisStates can be selected with the QuantumSelector as follows:

QN = states.generate_coupled_states_ground(Js = [0,1])
qn_select = states.QuantumSelector(J = 1, mF = 0, electronic = states.ElectronicState.X)
qn_select.get_indices(QN)

which returns all the indices with J=1 and mJ=0:

array([ 4,  6,  9, 13], dtype=int64)

hamiltonian

hamiltonian contains the functions to generate TlF hamiltonians in the X and B state in either coupled or uncoupled form.
Generating a ground state X hamiltonian can be accomplished easily using some convenience functions:

from centrex_tlf import states, hamiltonian

# generate the hyperfine sublevels in J=0 and J=1
QN = states.generate_uncoupled_states_ground(Js = [0,1])

# generate a dictionary with X hamiltonian terms
H = hamiltonian.generate_uncoupled_hamiltonian_X(QN)

# create a function outputting the hamiltonian as a function of E and B
Hfunc = hamiltonian.generate_uncoupled_hamiltonian_X_function(H)

All functions generating hamiltonians only require a list or array of TlF states. Generating the hamiltonian only for certain hyperfine sublevels is hence also straightforward. The function calculate_uncoupled_hamiltonian_X calculates the hamiltonians from scratch, whereas generate_uncoupled_hamiltonian_X pulls the non-zero elements from an sqlite database.

To convert a hamiltonian from one basis to another transformation matrices can be generated or calculated (generate_transform_matrix pulls non-zero matrix elements from an sqlite database, calculate_transform_matrix does the full element wise calculation):

from centrex_tlf import states, hamiltonian

# generate the hyperfine sublevels in J=0 and J=1
QN = states.generate_uncoupled_states_ground(Js = [0,1])
# generate the coupled hyperfine sublevels in J=0 and J=1
QNc = states.generate_coupled_states_ground(Js = [0,1])

# generate a dictionary with X hamiltonian terms
H = hamiltonian.generate_uncoupled_hamiltonian_X(QN)
Hfunc = hamiltonian.generate_uncoupled_hamiltonian_X_function(H)
H0 = Hfunc(E = [0,0,0], B = [0,0,1e-3])

# generate the transformation matrix
transform = hamiltonian.generate_transform_matrix(QN, QNc)

# calculate the transformed matrix
H0c = transform.conj().T@H0@transform

This is mostly used for optical bloch simulations where the coupled states representation is more convenient.

Stark Shift Example

To calculate the energy levels as a function of the electric field the following code can be used, which calculates all energies up to J=6 but only plots the |J=2, mJ=0> hyperfine levels. These are the states focussed by the electrostatic quadrupole lens in the CeNTREX experiment. Quadrupole Lens States

import numpy as np
import matplotlib.pyplot as plt

from centrex_tlf import states, hamiltonian

# generate states up to J=6
QN = states.generate_uncoupled_states_ground(Js=np.arange(7))

# generate the X hamiltonian terms
H = hamiltonian.generate_uncoupled_hamiltonian_X(QN)

# create a function outputting the hamiltonian as a function of E and B
Hfunc = hamiltonian.generate_uncoupled_hamiltonian_X_function(H)

# V/cm
Ez = np.linspace(0, 50e3, 101)

# generate the Hamiltonian for (almost) zero field, add a small field to make states
# non-degenerate
Hi = Hfunc(E=[0, 0, 1e-3], B=[0, 0, 1e-3])
E, V = np.linalg.eigh(Hi)

# get the true superposition-states of the system
QN_states = hamiltonian.matrix_to_states(V, QN)

# original eigenvectors used in tracking states as energies change order
V_track = V.copy()

# indices of the J=2, mJ=0 states focused by the lens
indices_J2_mJ0 = [
    idx
    for idx, s in enumerate(QN_states)
    if s.largest.J == 2 and s.largest.mJ == 0
]

indices_J012 = [
    idx for idx, s in enumerate(QN_states) if s.largest.J in [0, 1, 2]
]

# empty array for storing energies
energy = np.empty([Ez.size, len(QN)], dtype=np.complex128)

# iterate over the electric field values
for idx, Ei in enumerate(Ez):
    Hi = Hfunc(E=[0, 0, Ei], B=[0, 0, 1e-3])
    E, V = np.linalg.eigh(Hi)

    # sort indices to keep the state order the same
    indices = np.argmax(np.abs(V_track.conj().T @ V), axis=1)
    energy[idx, :] = E[indices]
    V_track[:, :] = V[:, indices]

# plot the J=2, mJ=0 Stark curves
fig, ax = plt.subplots(figsize=(12, 8))
ax.plot(
    Ez,
    (energy.real[:, indices_J2_mJ0] - energy.real[:, indices_J2_mJ0][0, 0])
    / (2 * np.pi * 1e9),
)
ax.set_xlabel("E [V/cm]")
ax.set_ylabel("Energy [GHz]")
ax.set_title("|J=2, mJ=0> Stark Curve")
ax.grid(True)
plt.show()

couplings

Code for generating the CeNTREX TlF couplings. Includes code for generating branching ratios, electric dipole coupling elements and coupling fields

Generating branching ratios

The code below generates branching ratios from |J'=1, F1'=1/2, mF=0> to all states in the J=1 manifold.

from centrex_tlf import states, couplings

excited_state = states.CoupledBasisState(
    J=1, F1=1 / 2, F=1, mF=0, I1=1 / 2, I2=1 / 2, Omega=1, P=1
)
qn_select = states.QuantumSelector(J=1)
ground_states = [1*s for s in states.generate_coupled_states_X(qn_select)]
br = couplings.calculate_br(1 * excited_state, ground_states)

Generating couplings

The code below generates the coupling fields for the J=1 manifold to the J'=1, F1'=1/2, F'=1 manifold. The returned value is a dataclass CouplingFields containing the following fields:

  • ground_main
  • excited_main
  • main_coupling: the electric dipole coupling between ground_main and excited_main
  • ground_states: list of all ground states
  • excited_states: list of all excited states
  • fields: a list of CouplingField dataclasses with the following fields:
    • polarization: polarization vector
    • field: coupling field in the ground_states + excited_states basis
from centrex_tlf import states, couplings

qn_select = states.QuantumSelector(J=1)
ground_states = states.generate_coupled_states_X(qn_select)

qn_select = states.QuantumSelector(J=1, F1=1 / 2, F=1, P=1, Ω=1)
excited_states = states.generate_coupled_states_B(qn_select)

# the generate_coupling_field_* functions requires lists as inputs, not np.ndarrays
QN = list(1 * np.append(ground_states, excited_states))
ground_states = [1*s for s in  ground_states]
excited_states = [1*s for s in excited_states]

H_rot = np.eye(len(QN), dtype=complex) * np.arange(len(QN))
V_ref = np.eye(len(QN))
pol_vecs = [np.array([0.0, 0.0, 1.0]), np.array([1.0, 0.0, 0.0])]
normalize_pol = True

coupling = couplings.generate_coupling_field_automatic(
    ground_states_approx = ground_states, 
    excited_states_approx = excited_states, 
    QN_basis = QN,
    H_rot = H_rot, 
    QN = QN, 
    V_ref = V_ref, 
    pol_vecs = pol_vecs, 
    normalize_pol = normalize_pol
)

Metadata

Release files for centrex-tlf 0.2.9

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for centrex-tlf 0.2.9
File
centrex_tlf-0.2.9-cp313-cp313-win_amd64.whl CPython 3.13 CPython 3.13 Windows x86-64 Details
centrex_tlf-0.2.9-cp313-cp313-manylinux_2_28_x86_64.whl CPython 3.13 CPython 3.13 Linux glibc 2.28+ x86-64 Details
centrex_tlf-0.2.9-cp313-cp313-macosx_11_0_arm64.whl CPython 3.13 CPython 3.13 macOS 11.0+ ARM64 Details
centrex_tlf-0.2.9-cp312-cp312-win_amd64.whl CPython 3.12 CPython 3.12 Windows x86-64 Details
centrex_tlf-0.2.9-cp312-cp312-manylinux_2_28_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.28+ x86-64 Details
centrex_tlf-0.2.9-cp312-cp312-macosx_11_0_arm64.whl CPython 3.12 CPython 3.12 macOS 11.0+ ARM64 Details
centrex_tlf-0.2.9-cp311-cp311-win_amd64.whl CPython 3.11 CPython 3.11 Windows x86-64 Details
centrex_tlf-0.2.9-cp311-cp311-manylinux_2_28_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.28+ x86-64 Details
centrex_tlf-0.2.9-cp311-cp311-macosx_11_0_arm64.whl CPython 3.11 CPython 3.11 macOS 11.0+ ARM64 Details
centrex_tlf-0.2.9-cp310-cp310-win_amd64.whl CPython 3.10 CPython 3.10 Windows x86-64 Details
centrex_tlf-0.2.9-cp310-cp310-manylinux_2_28_x86_64.whl CPython 3.10 CPython 3.10 Linux glibc 2.28+ x86-64 Details
centrex_tlf-0.2.9-cp310-cp310-macosx_11_0_arm64.whl CPython 3.10 CPython 3.10 macOS 11.0+ ARM64 Details

Total release size: 11.3 MB

Release files / centrex_tlf-0.2.9-cp313-cp313-win_amd64.whl

Download URL centrex_tlf-0.2.9-cp313-cp313-win_amd64.whl
Size 909.6 kB
Tags CPython 3.13 Windows x86-64
SHA-256 checksum
How to use checksums
33bdb0364347118fce5d042642994afb5b43167d33598fed42d8b86bda26d8ce
BLAKE2b-256 checksum
How to use checksums
02d13e4a621fbb720fda66df6f61e8d55c00b1c8809797a52c276995ff21ad18
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / centrex_tlf-0.2.9-cp313-cp313-manylinux_2_28_x86_64.whl

Download URL centrex_tlf-0.2.9-cp313-cp313-manylinux_2_28_x86_64.whl
Size 998.2 kB
Tags CPython 3.13 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
d77b7db0aa6c4466555655c8961dda82ffb814a8af1c097713bd8e628e79da60
BLAKE2b-256 checksum
How to use checksums
f230776abf065573e0f85aa26edffe933847eb656c718cec26620d09be8d8253
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / centrex_tlf-0.2.9-cp313-cp313-macosx_11_0_arm64.whl

Download URL centrex_tlf-0.2.9-cp313-cp313-macosx_11_0_arm64.whl
Size 914.7 kB
Tags CPython 3.13 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
9ed1e92a9c445139353fbed6e889f865ace9605c50791c55bfe88743af75ab5e
BLAKE2b-256 checksum
How to use checksums
0e23b149c61db51e7564ffcc09acbf6df64069d63d63f6d2af70ee2bca0b9cf7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / centrex_tlf-0.2.9-cp312-cp312-win_amd64.whl

Download URL centrex_tlf-0.2.9-cp312-cp312-win_amd64.whl
Size 907.5 kB
Tags CPython 3.12 Windows x86-64
SHA-256 checksum
How to use checksums
2e6cc975ff1c8fda11812159f46e719d9c81f46d2fa718b5f3bceee8559ec035
BLAKE2b-256 checksum
How to use checksums
2baffb4407c7e7e2890a435d2f098543593364d8215cc421cdc26c92a3eaab5d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / centrex_tlf-0.2.9-cp312-cp312-manylinux_2_28_x86_64.whl

Download URL centrex_tlf-0.2.9-cp312-cp312-manylinux_2_28_x86_64.whl
Size 997.0 kB
Tags CPython 3.12 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
5490b339a8b47f30820fb77c28c39d567124dcc0481baded081eb7ac1da33d15
BLAKE2b-256 checksum
How to use checksums
30600a5284fbb1f93dd24d674d6d0a68999ed28aded4f6e75ac1adba68a1b7c2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / centrex_tlf-0.2.9-cp312-cp312-macosx_11_0_arm64.whl

Download URL centrex_tlf-0.2.9-cp312-cp312-macosx_11_0_arm64.whl
Size 912.7 kB
Tags CPython 3.12 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
2e49b075301606fdac3f2b907b597c324014aa086658b5dfb5d0e62bb9269671
BLAKE2b-256 checksum
How to use checksums
316b556748cd2da4c844f2b887e82669ceddb3caa48715953c3fb02a96f1ec6e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / centrex_tlf-0.2.9-cp311-cp311-win_amd64.whl

Download URL centrex_tlf-0.2.9-cp311-cp311-win_amd64.whl
Size 911.0 kB
Tags CPython 3.11 Windows x86-64
SHA-256 checksum
How to use checksums
502fea7aaa2cc3c457a23f7287f9420b5481a24066332b1ab509e37a51548c74
BLAKE2b-256 checksum
How to use checksums
8d8b37f75a2d6a352ded493ed6222c896d5690e853c0404894e6c830f8f58d34
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / centrex_tlf-0.2.9-cp311-cp311-manylinux_2_28_x86_64.whl

Download URL centrex_tlf-0.2.9-cp311-cp311-manylinux_2_28_x86_64.whl
Size 998.7 kB
Tags CPython 3.11 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
27102dd2ac712dc9c5dd12ab9fb492436a10cdabd74f1ecd5359a40625db75b0
BLAKE2b-256 checksum
How to use checksums
8a846589938ec7f41ebd1c5c65467d41814b8e679ad7a871bc5c32381bcda9b8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / centrex_tlf-0.2.9-cp311-cp311-macosx_11_0_arm64.whl

Download URL centrex_tlf-0.2.9-cp311-cp311-macosx_11_0_arm64.whl
Size 914.7 kB
Tags CPython 3.11 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
95a62c91059b62f2c4c948f7a646f0997c9cea65a25bd5c7a67fc29e627e7524
BLAKE2b-256 checksum
How to use checksums
0fa00b2d7b52c9cae0664b42dab872d924f32cd3b5fbbc78e4fb63a9682e530e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / centrex_tlf-0.2.9-cp310-cp310-win_amd64.whl

Download URL centrex_tlf-0.2.9-cp310-cp310-win_amd64.whl
Size 911.2 kB
Tags CPython 3.10 Windows x86-64
SHA-256 checksum
How to use checksums
a877b31a09b24b27708aad1cea1728f53444fc754a9b672c2c94d3793623ebea
BLAKE2b-256 checksum
How to use checksums
7581938c43c2492fa42319547a62b22755104e36931e1e91d5cd47b5ecf95ca5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / centrex_tlf-0.2.9-cp310-cp310-manylinux_2_28_x86_64.whl

Download URL centrex_tlf-0.2.9-cp310-cp310-manylinux_2_28_x86_64.whl
Size 998.9 kB
Tags CPython 3.10 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
a02aed137c8015b301c604959e23a17772f52af81d3d9dc22590c2e188f0dcbd
BLAKE2b-256 checksum
How to use checksums
11a383f6b0f307e754615b2f3de02b07123d1f00ec899e87d1a2b0a0c18af2c9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / centrex_tlf-0.2.9-cp310-cp310-macosx_11_0_arm64.whl

Download URL centrex_tlf-0.2.9-cp310-cp310-macosx_11_0_arm64.whl
Size 914.7 kB
Tags CPython 3.10 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
4dc32f44fc15f3a587598c3a641201df80bd1190f079e2eaa23ff4e1965cfaa9
BLAKE2b-256 checksum
How to use checksums
297f65ebf330e84a2eb992f09fdcc8f5a7e7f28b16cb169dabefd26fb81b7ff7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page