spinecho_sim.field package#

Module for flexible and extensible field representation framework.

class spinecho_sim.field.AnalyticFieldRegion(*, bz_axis: Callable[[float], float], length: float, z_start: float = 0.0, bz_axis_deriv: Callable[[float], float] | None = None, bz_axis_second_deriv: Callable[[float], float] | None = None, dz: float = 1e-05)#

Bases: FieldRegion

Analytic field region defined by an on-axis Bz(z) profile (axi-symmetric).

bz_axis: Callable[[float], float]#
bz_axis_deriv: Callable[[float], float] | None = None#
bz_axis_second_deriv: Callable[[float], float] | None = None#
dz: float = 1e-05#
property extent: AABB#

Override the extent property to define the region’s bounding box.

field_at(x: float, y: float, z: float) Vec3#

Compute the (Bx, By, Bz) field at coordinates (x, y, z).

field_at_many(xyz: Array3) Array3#
length: float#
z_start: float = 0.0#
class spinecho_sim.field.AxisDataFieldRegion(*, z_vals: ndarray, bz_vals: ndarray, bz_deriv_vals: ndarray | None = None, bz_second_deriv_vals: ndarray | None = None)#

Bases: FieldRegion

Field region defined by discrete on-axis data points with paraxial approximation.

bz_deriv_vals: ndarray | None = None#
bz_second_deriv_vals: ndarray | None = None#
bz_vals: ndarray#
property extent: AABB#

Override the extent property to define the region’s bounding box.

field_at(x: float, y: float, z: float) Vec3#

Compute the (Bx, By, Bz) field at coordinates (x, y, z).

field_at_many(xyz: Array3) Array3#

Compute the field at multiple points in one call.

classmethod from_measured_data(z_vals: ndarray, bz_vals: ndarray) AxisDataFieldRegion#

Create an AxisDataFieldRegion from measured z and Bz values.

z_vals: ndarray#
class spinecho_sim.field.DataFieldRegion(*, x_vals: ndarray, y_vals: ndarray, z_vals: ndarray, field_data: ndarray[tuple[int, int, int, int]])#

Bases: FieldRegion

Field region defined by discrete data on a 3D grid.

property extent: AABB#

Override the extent property to define the region’s bounding box.

field_at(x: float, y: float, z: float) Vec3#

Compute the (Bx, By, Bz) field at coordinates (x, y, z).

field_at_many(xyz: Array3) Array3#
field_data: ndarray[tuple[int, int, int, int]]#
validate() None#
x_vals: ndarray#
y_vals: ndarray#
z_vals: ndarray#
class spinecho_sim.field.FieldPlotConfig(*, cmap: 'str' = 'viridis', figsize: 'tuple[float, float]' = (12, 8), line_styles: 'PlotLineStyles | None' = None, show_magnitude: 'bool' = True, show_colorbar: 'bool' = True)#

Bases: object

cmap: str = 'viridis'#
figsize: tuple[float, float] = (12, 8)#
line_styles: PlotLineStyles | None = None#
show_colorbar: bool = True#
show_magnitude: bool = True#
class spinecho_sim.field.FieldRegion#

Bases: ABC

Abstract base class for a magnetic field region.

classmethod analytic(*, bz: Callable[[float], float], length: float, z_start: float = 0.0, bz_deriv: Callable[[float], float] | None = None, bz_second_deriv: Callable[[float], float] | None = None, dz: float = 1e-05) AnalyticFieldRegion#
contains(x: float, y: float, z: float) bool#
contains_many(xyz: Array3) np.ndarray#
property extent: AABB | None#
abstractmethod field_at(x: float, y: float, z: float) Vec3#

Compute the (Bx, By, Bz) field at coordinates (x, y, z).

field_at_many(xyz: Array3) Array3#
classmethod from_data(*, x_vals: ndarray, y_vals: ndarray, z_vals: ndarray, field_data: ndarray) DataFieldRegion#

Create a DataFieldRegion from explicit keyword arguments.

rotate(angle: float) RotatedFieldRegion#

Rotate the field by a constant angle (in radians).

scale(factor: float) ScaledFieldRegion#

Scale the field by a constant factor.

then(other: FieldRegion) FieldSequence#

Combine two regions sequentially along the z-axis.

translate(*, dx: float = 0.0, dy: float = 0.0, dz: float = 0.0) TranslatedFieldRegion#

Translate the field by a constant offset.

class spinecho_sim.field.FieldSequence(*, regions: list[FieldRegion])#

Bases: FieldRegion

Composite field region that concatenates multiple regions end-to-end along z.

contains(x: float, y: float, z: float) bool#

Check if any region contains the point.

property extent: AABB | None#

Compute the union of extents of all regions.

field_at(x: float, y: float, z: float) Vec3#

Compute the (Bx, By, Bz) field at coordinates (x, y, z).

field_at_many(xyz: Array3) Array3#
regions: list[FieldRegion]#
class spinecho_sim.field.FieldSuperposition(*, regions: list[FieldRegion])#

Bases: FieldRegion

Composite field region that superposes multiple regions (sums their fields).

contains(x: float, y: float, z: float) bool#

Check if any region contains the point.

property extent: AABB | None#

Compute the union of extents of all regions.

field_at(x: float, y: float, z: float) Vec3#

Compute the (Bx, By, Bz) field at coordinates (x, y, z).

field_at_many(xyz: Array3) Array3#
regions: list[FieldRegion]#
class spinecho_sim.field.HeatmapConfig(*, cmap: 'str' = 'viridis', figsize: 'tuple[float, float]' = (12, 8), show_colorbar: 'bool' = True, n_contours: 'int | None' = 10, show_field_lines: 'bool' = False, field_line_density: 'float' = 1.0, field_line_color: 'str' = 'w', field_line_width: 'float' = 0.5, symmetric_scale: 'bool' = False)#

Bases: object

cmap: str = 'viridis'#
field_line_color: str = 'w'#
field_line_density: float = 1.0#
field_line_width: float = 0.5#
figsize: tuple[float, float] = (12, 8)#
n_contours: int | None = 10#
show_colorbar: bool = True#
show_field_lines: bool = False#
symmetric_scale: bool = False#
class spinecho_sim.field.RotatedFieldRegion(*, base_region: FieldRegion, angle: float)#

Bases: FieldRegion

Field region that rotates another region about the z-axis by a given angle.

angle: float#
base_region: FieldRegion#
property extent: AABB | None#
field_at(x: float, y: float, z: float) Vec3#

Compute the (Bx, By, Bz) field at coordinates (x, y, z).

field_at_many(xyz: Array3) Array3#
class spinecho_sim.field.ScaledFieldRegion(*, base_region: 'FieldRegion', factor: 'float')#

Bases: FieldRegion

base_region: FieldRegion#
property extent: AABB | None#
factor: float#
field_at(x: float, y: float, z: float) Vec3#

Compute the (Bx, By, Bz) field at coordinates (x, y, z).

field_at_many(xyz: Array3) Array3#
class spinecho_sim.field.SolenoidRegion(*, bz_axis: Callable[[float], float], length: float, z_start: float = 0.0, bz_axis_deriv: Callable[[float], float] | None = None, bz_axis_second_deriv: Callable[[float], float] | None = None, dz: float = 1e-05)#

Bases: AnalyticFieldRegion

Ergonomic builders that mirror the old Solenoid constructors.

classmethod from_experimental_parameters(*, length: float, magnetic_constant: float, current: float, z_start: float = 0.0) SolenoidRegion#

Build a solenoid from an experimental magnetic constant and current.

classmethod with_nonuniform_z(*, length: float, strength: Callable[[float], float], z_start: float = 0.0) SolenoidRegion#

Build a solenoid with a non-uniform field along the z-axis.

classmethod with_uniform_z(*, length: float, strength: float, z_start: float = 0.0) SolenoidRegion#

Bz is constant; AnalyticFieldRegion enforces 0 outside z-span.

class spinecho_sim.field.TranslatedFieldRegion(*, base_region: 'FieldRegion', dx: 'float' = 0.0, dy: 'float' = 0.0, dz: 'float' = 0.0)#

Bases: FieldRegion

base_region: FieldRegion#
dx: float = 0.0#
dy: float = 0.0#
dz: float = 0.0#
property extent: AABB | None#
field_at(x: float, y: float, z: float) ndarray#

Compute the (Bx, By, Bz) field at coordinates (x, y, z).

field_at_many(xyz: Array3) Array3#
class spinecho_sim.field.UniformFieldRegion(*, B: 'np.ndarray', region_extent: 'AABB | None' = None)#

Bases: FieldRegion

B: ndarray#
property extent: AABB | None#

Override the extent property to define the region’s bounding box.

field_at(x: float, y: float, z: float) ndarray#

Compute the (Bx, By, Bz) field at coordinates (x, y, z).

region_extent: AABB | None = None#
class spinecho_sim.field.ZeroField#

Bases: FieldRegion

A field region that always returns zero field.

field_at(x: float, y: float, z: float) Vec3#

Compute the (Bx, By, Bz) field at coordinates (x, y, z).

field_at_many(xyz: Array3) Array3#
spinecho_sim.field.plot_field_along_axis(field_region: FieldRegion, z_range: tuple[float | None, float | None] = (None, None), num_points: int = 1000, *, config: FieldPlotConfig = FieldPlotConfig(cmap='viridis', figsize=(12, 8), line_styles=None, show_magnitude=True, show_colorbar=True)) tuple[Figure, Axes]#

Plot magnetic field components along the z-axis (at x=0, y=0).

spinecho_sim.field.plot_field_heatmap(field_region: FieldRegion, component: Literal['Bx', 'By', 'Bz', 'magnitude'] = 'Bz', x_max: float = 0.00116, z_range: tuple[float | None, float | None] = (None, None), n_x: int = 100, n_z: int = 500, config: HeatmapConfig = HeatmapConfig(cmap='viridis', figsize=(12, 8), show_colorbar=True, n_contours=10, show_field_lines=False, field_line_density=1.0, field_line_color='w', field_line_width=0.5, symmetric_scale=False)) tuple[Figure, Axes]#

Create a heatmap of the magnetic field in the x-z plane (at y=0).