spinecho_sim package#

A set of tools for spin echo simulations.

class spinecho_sim.ExperimentalTrajectory(*, trajectory: Trajectory, positions: ndarray[Any, dtype[floating]])#

Bases: object

Represents the trajectory of a diatomic particle in a solenoid.

property displacement: ParticleDisplacement#

The displacement of the particle at the end of the trajectory.

positions: ndarray[Any, dtype[floating]]#
property rotational_angular_momentum: Spin[tuple[int, int]]#

The rotational angular momentum of the particle.

property spin: Spin[tuple[int, int]]#

The spin components from the simulation states.

trajectory: Trajectory#
class spinecho_sim.FieldSolver(*, region: FieldRegion, z_start: float | None = None, z_end: float | None = None)#

Bases: object

Dataclass representing a solenoid with its parameters.

property length: float#
region: FieldRegion#
simulate_diatomic_trajectories(initial_states: Sequence[StateVectorParticleState], n_steps: int = 100) StateVectorSimulationResult#

Run a solenoid simulation for multiple initial states.

simulate_diatomic_trajectory(initial_state: StateVectorParticleState, n_steps: int = 100) StateVectorExperimentalTrajectory#
simulate_monatomic_trajectories(initial_states: Sequence[ParticleState], n_steps: int = 100) MonatomicSimulationResult#

Run a solenoid simulation for multiple initial states.

simulate_monatomic_trajectory(initial_state: ParticleState, n_steps: int = 100) MonatomicExperimentalTrajectory#

Run the spin echo simulation using configured parameters.

z_end: float | None = None#
property z_span: tuple[float, float]#
z_start: float | None = None#
class spinecho_sim.MonatomicParticleState(*, displacement: 'ParticleDisplacement' = <factory>, parallel_velocity: 'float', _spin_angular_momentum: 'GenericSpin', coefficients: 'tuple[float, float, float, float]' = (267538030.37970677, 41919527.413910046, 715026.4879570369, 362414.1285181185), gyromagnetic_ratio: 'float' = -204000000.0)#

Bases: ParticleState

as_coherent() Sequence[CoherentMonatomicParticleState]#
gyromagnetic_ratio: float = -204000000.0#
property rotational_angular_momentum: GenericSpin#
property spin: GenericSpin#
class spinecho_sim.SimulationResult(*, trajectories: TrajectoryList, positions: ndarray[Any, dtype[floating]])#

Bases: object

Represents the result of a solenoid simulation.

property displacements: ParticleDisplacementList#

Extract the displacements from the simulation states.

positions: ndarray[Any, dtype[floating]]#
property rotational_angular_momentum: Spin[tuple[int, int, int]]#
property spin: Spin[tuple[int, int, int]]#
trajectories: TrajectoryList#
spinecho_sim.create_initial_states(*, spin: float = 0.5, num_spins: int, velocity: float, velocity_spread: float, initial_theta: float = 1.5707963267948966, initial_phi: float = 0, gyromagnetic_ratio: float = -204000000.0, beam_radius: float = 0.00116) list[MonatomicParticleState]#

Create a list of initial particle states with given parameters.

spinecho_sim.plot_sweep_results(sweep_result: SweepResult, parameter_name: str = 'Current (A)', save_path: str | None = None) tuple[Figure, Axes]#

Plot the results of a parameter sweep.

spinecho_sim.sweep_field_current(currents: ndarray, initial_states: list[MonatomicParticleState], solenoid_length: float = 0.75, magnetic_constant: float = 0.00396, n_steps: int = 1000) SweepResult#

Sweep over different magnetic field currents and record final spin states.

Subpackages#

Submodules#

spinecho_sim.parameter_sweep module#

class spinecho_sim.parameter_sweep.SweepResult(parameter_values: ndarray, results: ndarray[tuple[Literal[4], ...]])#

Bases: object

Results from a parameter sweep.

parameter_values: ndarray#
results: ndarray[tuple[Literal[4], ...]]#
spinecho_sim.parameter_sweep.create_initial_states(*, spin: float = 0.5, num_spins: int, velocity: float, velocity_spread: float, initial_theta: float = 1.5707963267948966, initial_phi: float = 0, gyromagnetic_ratio: float = -204000000.0, beam_radius: float = 0.00116) list[MonatomicParticleState]#

Create a list of initial particle states with given parameters.

spinecho_sim.parameter_sweep.plot_sweep_results(sweep_result: SweepResult, parameter_name: str = 'Current (A)', save_path: str | None = None) tuple[Figure, Axes]#

Plot the results of a parameter sweep.

spinecho_sim.parameter_sweep.sweep_field_current(currents: ndarray, initial_states: list[MonatomicParticleState], solenoid_length: float = 0.75, magnetic_constant: float = 0.00396, n_steps: int = 1000) SweepResult#

Sweep over different magnetic field currents and record final spin states.

spinecho_sim.util module#

class spinecho_sim.util.Arrow3D(xs: Sequence[float], ys: Sequence[float], zs: Sequence[float], *args: tuple[Any, ...], **kwargs: dict[str, Any])#

Bases: FancyArrowPatch

Custom class for 3D arrows.

do_3d_projection() float#

Handle 3D projection for the arrow.

draw(renderer: RendererBase) None#

Draw the Artist (and its children) using the given renderer.

This has no effect if the artist is not visible (.Artist.get_visible returns False).

Parameters#

renderer : ~matplotlib.backend_bases.RendererBase subclass.

Notes#

This method is overridden in the Artist subclasses.

set(*, agg_filter=<UNSET>, alpha=<UNSET>, animated=<UNSET>, antialiased=<UNSET>, arrowstyle=<UNSET>, capstyle=<UNSET>, clip_box=<UNSET>, clip_on=<UNSET>, clip_path=<UNSET>, color=<UNSET>, connectionstyle=<UNSET>, edgecolor=<UNSET>, facecolor=<UNSET>, fill=<UNSET>, gid=<UNSET>, hatch=<UNSET>, hatch_linewidth=<UNSET>, in_layout=<UNSET>, joinstyle=<UNSET>, label=<UNSET>, linestyle=<UNSET>, linewidth=<UNSET>, mouseover=<UNSET>, mutation_aspect=<UNSET>, mutation_scale=<UNSET>, patchA=<UNSET>, patchB=<UNSET>, path_effects=<UNSET>, picker=<UNSET>, positions=<UNSET>, rasterized=<UNSET>, sketch_params=<UNSET>, snap=<UNSET>, transform=<UNSET>, url=<UNSET>, visible=<UNSET>, zorder=<UNSET>)#

Set multiple properties at once.

Supported properties are

Properties:

agg_filter: a filter function, which takes a (m, n, 3) float array and a dpi value, and returns a (m, n, 3) array and two offsets from the bottom left corner of the image alpha: float or None animated: bool antialiased or aa: bool or None arrowstyle: [ ‘-’ | ‘<-’ | ‘->’ | ‘<->’ | ‘<|-' | '-|>’ | ‘<|-|>’ | ‘]-’ | ‘-[’ | ‘]-[’ | ‘|-|’ | ‘]->’ | ‘<-[’ | ‘simple’ | ‘fancy’ | ‘wedge’ ] capstyle: .CapStyle or {‘butt’, ‘projecting’, ‘round’} clip_box: ~matplotlib.transforms.BboxBase or None clip_on: bool clip_path: Patch or (Path, Transform) or None color: :mpltype:`color` connectionstyle: [ ‘arc3’ | ‘angle3’ | ‘angle’ | ‘arc’ | ‘bar’ ] edgecolor or ec: :mpltype:`color` or None facecolor or fc: :mpltype:`color` or None figure: ~matplotlib.figure.Figure or ~matplotlib.figure.SubFigure fill: bool gid: str hatch: {‘/’, ‘\’, ‘|’, ‘-’, ‘+’, ‘x’, ‘o’, ‘O’, ‘.’, ‘*’} hatch_linewidth: unknown in_layout: bool joinstyle: .JoinStyle or {‘miter’, ‘round’, ‘bevel’} label: object linestyle or ls: {‘-’, ‘–’, ‘-.’, ‘:’, ‘’, (offset, on-off-seq), …} linewidth or lw: float or None mouseover: bool mutation_aspect: float mutation_scale: float patchA: .patches.Patch patchB: .patches.Patch path_effects: list of .AbstractPathEffect picker: None or bool or float or callable positions: unknown rasterized: bool sketch_params: (scale: float, length: float, randomness: float) snap: bool or None transform: ~matplotlib.transforms.Transform url: str visible: bool zorder: float

class spinecho_sim.util.SolveIVPOptions#

Bases: TypedDict

Options for the ODE solver.

atol: float#
max_step: float#
rtol: float#
vectorized: bool#
class spinecho_sim.util.SolveIVPResult(*args, **kwargs)#

Bases: Protocol

Result of an ODE solve.

message: str#
status: int#
success: bool#
t: ndarray[tuple[Any, ...], dtype[float64]]#
y: ndarray[tuple[Any, ...], dtype[float64 | complex128]]#
spinecho_sim.util.check_normalization(psi: ndarray, tolerance: float = 1e-08) None#

Check if the state vector is normalized and issue a warning if not.

spinecho_sim.util.csr_add(a: csr_matrix, b: csr_matrix) csr_matrix#

Typed sp.csr_matrix + sp.csr_matrix → sp.csr_matrix.

spinecho_sim.util.csr_diags(diagonals: ndarray | list[ndarray] | list[float], offsets: int = 0, shape: tuple[int, int] | None = None, dtype: dtype | None = None) csr_matrix#

Typed version of sp.diags that guarantees a csr_matrix.

spinecho_sim.util.csr_eye(n: int, dtype: type = <class 'complex'>) csr_matrix#

Typed identity matrix in sp.csr_matrix format.

spinecho_sim.util.csr_hermitian(a: csr_matrix) csr_matrix#

Typed sp.csr_matrix† → sp.csr_matrix.

spinecho_sim.util.csr_kron(a: csr_matrix, b: csr_matrix) csr_matrix#

Typed Kronecker product returning sp.csr_matrix.

spinecho_sim.util.csr_scale(a: csr_matrix, scale: complex) csr_matrix#

Typed sp.csr_matrix * float → sp.csr_matrix.

spinecho_sim.util.csr_subtract(a: csr_matrix, b: csr_matrix) csr_matrix#

Typed sp.csr_matrix - sp.csr_matrix → sp.csr_matrix.

spinecho_sim.util.csr_to_array(sparse_matrix: csr_matrix) ndarray#

Convert a sparse matrix to a dense numpy array.

spinecho_sim.util.get_figure(ax: Axes | None = None) tuple[Figure | SubFigure, Axes]#

Get a figure and axes for plotting.

spinecho_sim.util.get_measure_label(measure: Literal['real', 'imag', 'abs', 'arg']) str#

Get the specified measure of an array.

spinecho_sim.util.kronecker_n(operator_list: list[csr_matrix]) csr_matrix#

Compute the Kronecker product of a list of sparse matrices.

spinecho_sim.util.make_bx_blob(*, x_half: float = 0.1, y_half: float = 0.1, z0: float = 0.0, z1: float = 1.0, nx: int = 21, ny: int = 21, nz: int = 11, r_scale: float = 0.1, z_center: float | None = None, z_width: float = 0.2, amplitude: float = 0.1) DataFieldRegion#

Create a localized Bx ‘blob’ with Gaussian radial and axial profiles.

spinecho_sim.util.make_linear_bz_data(z0: float, z1: float, bz0: float, bz1: float, *, x_half: float = 0.1, y_half: float = 0.1, nx: int = 5, ny: int = 5, nz: int = 6) DataFieldRegion#

Create a DataFieldRegion where Bz varies linearly from bz0 at z0 to bz1 at z1.

spinecho_sim.util.measure_data(arr: ndarray, measure: Literal['real', 'imag', 'abs', 'arg']) ndarray#

Get the specified measure of an array.

spinecho_sim.util.plot_complex_heatmap(arr: np.ndarray) tuple[Figure, Axes]#

Plot a complex-valued array as a heatmap with phase and magnitude.

spinecho_sim.util.product_state(stars: ndarray) ndarray#

Create a product state from a list of majorana stars.

spinecho_sim.util.solve_ivp_typed(fun: Callable[[float, ndarray[tuple[Any, ...], dtype[float64 | complex128]]], ndarray[tuple[Any, ...], dtype[float64 | complex128]]], t_span: tuple[float, float], y0: ndarray[tuple[Any, ...], dtype[float64 | complex128]], *, t_eval: ndarray[tuple[Any, ...], dtype[float64]] | None = None, method: Literal['RK45', 'RK23', 'DOP853', 'Radau', 'BDF', 'LSODA'] = 'RK45', vectorized: bool = False, rtol: float = 0.001, **kwargs: SolveIVPOptions) SolveIVPResult#

Typed wrapper around scipy.integrate.solve_ivp.

spinecho_sim.util.sparse_apply(a: csr_matrix, b: ndarray) ndarray#

Matrix multiplication for a sparse matrix and a dense vector, returning a dense vector.

spinecho_sim.util.sparse_matmul(a: csr_matrix, b: csr_matrix) csr_matrix#

Matrix multiplication for two sparse matrices, returning a sparse matrix.

spinecho_sim.util.symmetrize(n_stars: int) csr_matrix#

(2^N x 2^N) projector onto the totally-symmetric subspace.

spinecho_sim.util.timed(f: Callable[[P], R]) Callable[[P], R]#

Log the time taken for f to run.

Parameters#

fCallable[P, R]

The function to time

Returns#

Callable[P, R]

The decorated function

spinecho_sim.util.verify_hermitian(matrix: csr_matrix) bool#

Check if a sparse matrix is Hermitian.