Skip to content

API Reference

Every public class, method, and function in aleathor, grouped by what you're trying to do.

Conventions: - All geometry operations require the C extension (_alea). If not installed, RuntimeError is raised. - Cell IDs are MCNP-numbered (positive integers). Cell indices are 0-based internal positions. - Methods that query the geometry automatically rebuild the internal C system if changes are pending.


Loading Models

ath.load

ath.load(filename: str) -> Model

Load a geometry file, auto-detecting format from extension. .xml files are read as OpenMC. Everything else is read as MCNP (.inp, .i, .mcnp, or no extension).

ath.read_mcnp

ath.read_mcnp(filename: str) -> Model

Parse an MCNP input file. Handles cell cards, surface cards, data cards (materials, transforms), LIKE BUT, cell complements (#cell), macrobodies, universe fills, and lattices.

ath.read_mcnp_string

ath.read_mcnp_string(content: str) -> Model

Parse MCNP input from a string instead of a file.

ath.read_openmc

ath.read_openmc(filename: str) -> Model

Parse an OpenMC XML geometry file.

ath.read_openmc_string

ath.read_openmc_string(content: str) -> Model

Parse OpenMC XML input from a string instead of a file.


Model

Constructor

Model(title: str = "aleathor Model")

Create an empty model. Cells, materials, and surfaces are added programmatically.

Properties

model.title         # str: Model title
model.cells         # CellCollection: all cells, with filtering support
model.surfaces      # Dict[int, Surface]: all surfaces by ID
model.materials     # List[Material]: all materials
model.universes     # List[Universe]: all universes
model.backend.config        # Dict[str, Any]: system configuration (getter/setter)
model.backend.spatial_index_instance_count  # int: cell instances in spatial index

Cell Management

model.add_cell

model.add_cell(
    region: Region,
    cell_id: int = None,      # Auto-assigned if None
    material: int = 0,         # 0 = void
    density: float = 0.0,
    density_unit: str = "g/cm3",
    name: str = None,
    universe: int = 0,
    fill: int = None,          # Universe to fill with
    importance: float = 1.0,
) -> Cell

Add a cell to the model and push it to the C backend. density is passed as a positive magnitude; density_unit controls whether it is stored as mass density ("g/cm3", negative in MCNP syntax) or atom density ("atoms/b-cm", positive in MCNP syntax). Returns a Cell view.

model.get_cell

model.get_cell(cell_id: int) -> Cell
model[cell_id] -> Cell    # Subscript notation

Get cell by MCNP cell ID. Returns a Cell. Raises KeyError if not found.

model.update_cell

model.update_cell(
    cell_id: int,
    material: int = None,     # None = keep current
    density: float = None,
    density_unit: str = None,
    importance: float = None,
) -> Cell

Update cell properties in the C backend. Only provided fields are changed. Returns a fresh Cell. Raises KeyError if not found.

model.remove_cell

model.remove_cell(cell_id: int) -> None

Remove cell by ID. No-op if not found.


Material Management

model.add_material

model.add_material(
    material_id: int,
    name: str = None,
    density: float = None,
) -> Material

Add a material. Raises ValueError if ID already exists.

model.get_material

model.get_material(material_id: int) -> Material

Get material by ID. Raises KeyError if not found.

model.create_mixture

model.create_mixture(
    material_ids: List[int],
    fractions: List[float],
    new_id: int = 0,          # 0 = auto-assign
    name: str = None,
) -> int

Create a weighted mixture of existing materials. Fractions are normalized automatically. Returns the assigned material ID.


Universe Management

model.add_universe

model.add_universe(universe_id: int, name: str = None) -> Universe

model.get_universe

model.get_universe(universe_id: int) -> Universe

Point Queries

Most code should use cell_at(). Use cell_path_at() only when you need to inspect the nested universe path that led to the returned cell.

model.cell_at

model.cell_at(x: float, y: float, z: float) -> Optional[Cell]

Find the terminal cell containing the point. This is the normal point query: it follows universe fills and returns the innermost cell reached by that traversal. Returns None if no cell claims the point.

Use this for questions like "which cell/material contains this coordinate?"

model.cell_path_at

model.cell_path_at(x: float, y: float, z: float) -> List[Cell]

Return the containment path through nested universes. Results are ordered by depth, where 0 is the outermost/root-level cell. Each Cell has its depth property set.

Use this for debugging FILL/universe nesting. In a non-nested model, this usually returns either an empty list or a one-cell list.

model.contains_point

model.contains_point(x: float, y: float, z: float) -> bool

Check if point is inside any cell (not void).

model.analysis.find_overlaps

model.analysis.find_overlaps(max_pairs: int = 100) -> List[Tuple[Cell, Cell]]

Find overlapping cell pairs by statistical sampling.


Ray Tracing

model.trace

model.trace(
    origin: Tuple[float, float, float] = None,
    direction: Tuple[float, float, float] = None,
    start: Tuple[float, float, float] = None,
    end: Tuple[float, float, float] = None,
    max_distance: float = 0,       # 0 = infinite
    cell_aware: bool = False,      # Faster for large models
) -> TraceResult

Trace a ray through the geometry. Call in one of two ways:

  • Direction mode: trace(origin=(0,0,0), direction=(1,0,0))
  • Point-to-point mode: trace(start=(0,0,0), end=(100,0,0))

The direction is normalized internally. In point-to-point mode, max_distance is set automatically.

Cell-aware tracing tests only surfaces belonging to the current cell at each step, which is faster for models with many surfaces.


Cell Filtering

C-backed for performance. Return lists of cell indices (not IDs).

model.get_cells_by_material(material_id: int) -> List[int]
model.get_cells_by_universe(universe_id: int) -> List[int]
model.get_cells_filling_universe(universe_id: int) -> List[int]
model.get_cells_in_bbox(bounds: Tuple[float, float, float, float, float, float]) -> List[int]

For most use cases, prefer model.cells.by_material() etc. which return CellCollection objects with Cell iteration.


Extraction

model.extract_universe

model.extract_universe(universe_id: int) -> Model

Extract a universe and all universes it references into a new Model.

model.extract_region

model.extract_region(bounds: Tuple[float, ...]) -> Model

Extract cells whose bounding boxes intersect the given (xmin, xmax, ymin, ymax, zmin, zmax) region into a new Model.


Slice API

All slice functions take a bounds tuple of (min1, max1, min2, max2) defining the viewport in the slice plane.

Analytical Curves

model.slice.curves(axis="z", value=z, bounds=bounds) -> dict
model.slice.curves(axis="y", value=y, bounds=bounds) -> dict
model.slice.curves(axis="x", value=x, bounds=bounds) -> dict
model.slice.curves(origin=origin, normal=normal, up=up, bounds=bounds) -> dict

Return a dict with 'curves' (list of curve dicts, each with 'type', 'surface_id', and geometry-specific fields) and bounds info.

Grid Queries

model.slice.grid(axis="z", value=z, bounds=bounds, resolution=(100,100),
                 universe_depth=-1, detect_errors=False) -> dict
model.slice.grid(axis="y", value=y, bounds=bounds, ...) -> dict
model.slice.grid(axis="x", value=x, bounds=bounds, ...) -> dict
model.slice.grid(origin=origin, normal=normal, up=up, bounds=bounds, ...) -> dict

Sample cell/material IDs on a 2D pixel grid. Returns a dict with:

Key Type Description
cell_ids list[int] Cell ID at each pixel (-1 = void)
material_ids list[int] Material ID at each pixel (0 = void)
errors list[int] Error flags (only if detect_errors=True)
nx, ny (or nu, nv) int Grid dimensions
x_min, x_max, ... float Viewport bounds

universe_depth: -1 = innermost cell, 0 = root only, N = cells at depth N.

detect_errors: when True, boundary pixels are rechecked for overlaps. Error values: 0=ok, 1=overlap, 2=undefined.

Label Positioning

model.slice.labels(
    grid_result: dict,
    min_pixels: int = 100,
    by_material: bool = False,
) -> List[dict]

Find optimal label positions for regions in a grid. Returns list of {'id', 'px', 'py', 'pixel_count'}. The min_pixels parameter filters out tiny regions.

model.slice.surface_labels(
    grid_result: dict,
    margin: int = 20,
) -> List[dict]

Find label positions for surfaces on a slice plane. Returns list of {'id', 'px', 'py'}.

Overlap Checking

model.slice.check_overlaps(
    grid_result: dict,
    universe_depth: int = -1,
) -> List[int]

Comprehensive overlap detection: re-queries every non-void pixel. Returns updated error list (0=ok, 1=overlap, 2=undefined). This is O(area) — use only when thorough validation is needed.


Plotting

Plotting uses matplotlib and numpy, which are installed as regular package dependencies. Import check: ath.HAS_PLOTTING.

model.plot

model.plot(
    z=None, y=None, x=None,          # Axis-aligned slice (use one)
    origin=None, normal=None, up=None, # Arbitrary plane
    bounds=None,                       # (min1, max1, min2, max2)
    filled: bool = True,
    by_material: bool = False,
    show_colorbar: bool = False,
    show_contours: bool = True,
    detect_errors: bool = False,
    universe_depth: int = -1,
    save: str = None,                  # Save to file
    ax=None,                           # Existing matplotlib Axes
    overlay=None,                      # 2D array for tally overlay
    overlay_extent=None,
    overlay_cmap: str = 'jet',
    overlay_norm: str = None,          # 'log' for logarithmic
    overlay_alpha: float = 1.0,
    overlay_vmin=None, overlay_vmax=None,
    overlay_label: str = None,
    contour_by: str = None,            # 'cell', 'material', or None (auto)
) -> Axes

Plot geometry slice. If no axis is specified, defaults to z=0. Returns the matplotlib Axes.

When by_material=True or overlay is set, contours automatically follow material boundaries. Override with contour_by='cell'.

Also available as a module-level function:

from aleathor.plotting import plot
ax = plot(model, z=0, bounds=(-10, 10, -10, 10))

model.plot_views

model.plot_views(
    bounds=None,    # (xmin, xmax, ymin, ymax, zmin, zmax) — 6-element
    save: str = None,
    **kwargs,       # Passed to plot()
) -> Figure

Plot three orthogonal views (XY at z=0, XZ at y=0, YZ at x=0). Returns the matplotlib Figure.

Low-level plotting functions

from aleathor.plotting import (
    plot_slice_curves,     # Vector plot of analytical curves
    plot_slice_filled,     # Grid-based filled plot with contours
    plot_curve,            # Plot a single curve
    plot_ray_path,         # 1D bar chart of ray trace segments
    filter_boundary_curves,            # Filter to true cell boundaries
    filter_boundary_curves_arbitrary,  # Same for arbitrary planes
    count_surfaces,        # Count unique surfaces in curves result
    count_cells,           # Count unique cells in grid result
    count_materials,       # Count unique materials in grid result
    get_slice_stats,       # All three counts at once
)

plot_slice_curves

plot_slice_curves(
    curves_result: dict,
    ax=None,
    color: str = 'black',
    linewidth: float = 0.5,
    title: str = None,
    xlabel: str = None, ylabel: str = None,
    xlim=None, ylim=None,
) -> Axes

Plot analytical surface boundaries as vector graphics.

plot_slice_filled

plot_slice_filled(
    grid_result: dict,
    ax=None,
    cmap: str = 'tab20',
    by_material: bool = False,
    show_colorbar: bool = False,
    show_fill: bool = True,
    show_contours: bool = True,
    contour_color: str = 'black',
    contour_width: float = 0.5,
    show_errors: bool = True,
    overlap_color: str = 'red',
    undefined_color: str = 'orange',
    title: str = None,
    overlay=None,                    # 2D array for tally data
    overlay_cmap: str = 'jet',
    overlay_norm: str = None,
    overlay_alpha: float = 1.0,
    overlay_vmin=None, overlay_vmax=None,
    overlay_label: str = None,
    contour_by: str = None,
) -> Axes

Grid-based filled plot with contour lines. The recommended way to visualize geometry slices.

plot_ray_path

plot_ray_path(
    trace,  # TraceResult or list of segment dicts
    ax=None,
    show_materials: bool = True,
    t_max: float = None,
) -> Axes

Plot ray path as a 1D bar chart showing material transitions. Accepts a TraceResult from model.trace(), or a list of raw segment dicts (with keys t_enter, t_exit, cell_id, material_id).

Also available as trace.plot().


Export

model.export_mcnp

model.export_mcnp(filename: str) -> None

model.export_openmc

model.export_openmc(filename: str) -> None

model.export_serpent

model.export_serpent(filename: str) -> None

model.save

model.save(filename: str, format: str = None) -> None

Auto-detects format from extension. .xml = OpenMC, .serp/.sss/.serpent = Serpent, everything else = MCNP. Override with format='mcnp', format='openmc', or format='serpent'.

model.to_mcnp_string

model.to_mcnp_string() -> str

Generate MCNP input file contents as a string.

File-level I/O functions

ath.write_mcnp(model, filename) -> None
ath.write_openmc(model, filename) -> None
ath.write_serpent(model, filename) -> None

Mesh API

model.mesh.export

model.mesh.export(
    filename: str,
    nx: int = 10, ny: int = 10, nz: int = 10,
    bounds: Tuple[float, ...] = None,   # (xmin, xmax, ymin, ymax, zmin, zmax), None = auto
    format: str = "gmsh",                # "gmsh" or "vtk"
    void_material_id: int = 0,
    auto_pad: float = 0.01,
) -> None

Export the geometry as a structured hexahedral mesh. Each element is assigned the material ID at its center. Bounds are auto-detected from cell bounding boxes if not given.

Supported formats: - "gmsh": Gmsh .msh v2.2 ASCII — can be opened in Gmsh for visualization - "vtk": VTK legacy .vtk ASCII — can be opened in ParaView

model.mesh.sample

model.mesh.sample(
    nx: int = 10, ny: int = 10, nz: int = 10,
    bounds: Tuple[float, ...] = None,
    void_material_id: int = 0,
    auto_pad: float = 0.01,
) -> dict

Sample the geometry on a structured mesh without writing to file. Returns a dict:

Key Type Description
material_ids list[int] Material at each element (nxnynz, Z-major order)
cell_ids list[int] Cell ID at each element
x_nodes list[float] X node positions (nx+1 values)
y_nodes list[float] Y node positions (ny+1 values)
z_nodes list[float] Z node positions (nz+1 values)
nx, ny, nz int Grid dimensions

Geometry Transforms

Renumbering

model.ids.renumber_cells(start_id: int = 1) -> int
model.ids.renumber_surfaces(start_id: int = 1) -> int

Reassign IDs starting from start_id, preserving order. Returns the count.

Offsetting

model.ids.offset_cells(offset: int) -> None
model.ids.offset_surfaces(offset: int) -> None
model.ids.offset_materials(offset: int) -> None

Add a fixed offset to all IDs. Useful when merging models.

Splitting and expanding

model.repair.split_union_cells() -> int

Split cells with top-level unions into multiple simpler cells. Returns number of new cells created.

model.repair.expand_macrobodies() -> int

Expand all macrobodies to primitive surfaces. Returns number expanded.

Bounding boxes

model.repair.tighten_bboxes(tolerance: float = 1.0) -> int

Tighten all cell bounding boxes via interval arithmetic. Returns number tightened.

model.repair.tighten_cell_bbox(cell_id: int, tolerance: float = 1.0)
    -> Tuple[float, float, float, float, float, float]

Tighten a single cell's bounding box. Returns (xmin, xmax, ymin, ymax, zmin, zmax). Raises KeyError if cell not found.

model.repair.tighten_bbox_numerical(cell_id: int) -> None

Tighten a cell's bounding box using numerical sampling. This is a fallback for cells where interval arithmetic gives loose bounds (e.g., cells with complex boolean expressions). Raises KeyError if cell not found, RuntimeError on failure.

Fill mutation

Use the cell view API for fills:

cell = model.cells[10]
cell.fill = 5
cell.fill = None
cell.fill_with(universe, transform=3)

Volume Estimation

model.analysis.bounding_sphere

model.analysis.bounding_sphere(tolerance: float = 1.0)
    -> Tuple[float, float, float, float]

Compute a tight bounding sphere. Returns (cx, cy, cz, radius).

model.analysis.estimate_cell_volumes

model.analysis.estimate_cell_volumes(
    n_rays: int = 100000,
    center: Tuple[float, float, float] = None,  # Auto-computed if None
    radius: float = None,                         # Auto-computed if None
) -> dict

Estimate cell volumes using random ray tracing (Cauchy-Crofton method). Returns {'volumes': list, 'rel_errors': list} indexed by cell index.

If center or radius are not given, a bounding sphere is computed automatically.

model.analysis.estimate_instance_volumes

model.analysis.estimate_instance_volumes(n_rays: int = 100000) -> dict

Estimate volumes per cell instance (spatial-index aware). Query acceleration is prepared automatically if needed.

model.analysis.remove_cells_by_volume

model.analysis.remove_cells_by_volume(volumes: list, threshold: float) -> int

Compute a tight bounding sphere for the model.


Void Generation

model.void.generate

model.void.generate(
    bounds: Tuple[float, float, float, float, float, float] = None,
    max_depth: int = 8,
    min_size: float = 0.1,
    probes_per_axis: int = 3,
    region: Region = None,
) -> VoidResult

Find empty space in the geometry using octree decomposition. Identifies axis-aligned bounding boxes covering regions not occupied by any cell. If bounds and region are both None, uses the system's automatic bounding box.

Use bounds for an axis-aligned bbox. Use region to supply an existing finite CSG region, such as -outer_box or -outer_sphere; this lets void merging reuse that region instead of generating a new box clip.

VoidResult

Property / Method Returns Description
len(voids) int Number of void boxes
voids.box_count int Number of void boxes
voids[i] tuple Get box by index (xmin, xmax, ymin, ymax, zmin, zmax)
voids.get_box(i) tuple Get box by index
voids.get_boxes() list[tuple] All boxes
voids.merge() int Merge adjacent boxes, returns new count
voids.to_node() int Convert to CSG node (union of boxes)
voids.total_volume() float Sum of all box volumes
for box in voids tuple Iterate over boxes

Commit generated voids through the model:

added = model.void.add(voids)
model.void.add_graveyard(voids)

Spatial Indexing

Query methods (cell_at, trace, slice.grid, get_cells_in_bbox, estimate_*, plot) build their acceleration caches lazily on first use. There is no public preparation entry point — you do not need to call anything before issuing queries.

model.backend.build_spatial_index

model.backend.build_spatial_index() -> Model

Build only the spatial index over cell instances. Returns self for chaining. Rarely needed in user code; query methods handle this automatically.

model.repair.flatten_universe

model.repair.flatten_universe(universe_id: int) -> None

Expand all fills in a universe. After flattening, all cells are in the specified universe with no fills.

model.repair.simplify

model.repair.simplify() -> dict

Run full CSG simplification on all cells. Applies complement elimination, double-negation removal, idempotent/absorption reductions, subtree deduplication, and more. Returns a dict with statistics:

Key Type Meaning
nodes_before int Total CSG nodes before simplification
nodes_after int Total CSG nodes after simplification
complements_eliminated int Complement nodes removed
double_negations int Double negations eliminated
idempotent_reductions int Idempotent reductions (A & A = A)
absorption_reductions int Absorption reductions (A & universe = A)
subtrees_deduplicated int Duplicate subtrees merged
cell_complements_expanded int Cell complements expanded inline
contradictions_found int Contradictions reduced to empty
tautologies_found int Tautologies reduced to universe
empty_cells_removed int Empty cells removed
union_branches_absorbed int Union branches absorbed
union_common_factors int Common factors extracted from unions
union_branches_subsumed int Union branches subsumed

Validation

model.validate

model.validate() -> List[str]

Check for common issues: undefined materials in cells, overlapping cells, internal validation. Returns list of warning/error messages (empty = valid).


Configuration

model.backend.config

# Read
cfg = model.backend.config    # Returns dict

# Write (only provided keys are changed)
model.backend.config = {'log_level': 3, 'abs_tol': 1e-8}

model.backend.set_verbose

model.backend.set_verbose(enabled: bool) -> None

Enable/disable verbose output from the C library.


Utilities

model.print_summary() -> None
str(model)        # "Model: 45 cells, 89 surfaces, 3 universes"
repr(model)       # "Model(title='...', cells=45, surfaces=89)"

Cell

Mutable view of a cell in the C system. Returned by model.get_cell(), model.cell_at(), and iteration over model.cells.

Properties

cell.id: int              # Cell ID (MCNP cell number)
cell.material: int        # Material ID (0 for void)         [read-write]
cell.density: float       # Material density                 [read-write]
cell.density_unit: str    # "g/cm3" or "atoms/b-cm"          [read-write]
cell.universe: int        # Universe this cell belongs to
cell.fill: Optional[int]  # Fill universe (None if not filled) [read-write]
cell.name: Optional[str]  # Cell name                        [read-write]
cell.bounds: Tuple[float, float, float, float, float, float]  # Bounding box
cell.is_void: bool        # True if material == 0
cell.is_filled: bool      # True if fill is set
cell.importance: float    # Particle importance               [read-write]
cell.depth: int           # Hierarchy depth (0 = root)
cell.region               # Region or _ImportedRegion

Lattice properties

Only populated for cells that define a lattice (lat_type != 0). For non-lattice cells, these return None or 0/False.

cell.is_lattice: bool                     # True if this cell defines a lattice
cell.lattice_type: int                    # 0=none, 1=rectangular, 2=hexagonal
cell.lattice_pitch: Optional[Tuple[float, float, float]]    # Element pitch (x, y, z)
cell.lattice_fill: Optional[List[int]]    # Universe IDs filling lattice elements
cell.lattice_lower_left: Optional[Tuple[float, float, float]]  # Lower-left corner
cell.lattice_dims: Optional[Tuple[int, int, int, int, int, int]]  # (imin,imax,jmin,jmax,kmin,kmax)

Comment Properties

cell.comments: Optional[str]        # "C" comment lines before the cell (from MCNP)
cell.inline_comment: Optional[str]  # Inline "$" comment (from MCNP)

Methods

cell.contains(x: float, y: float, z: float) -> bool
cell.fill_with(universe, transform: int = 0) -> None
cell.unfill() -> None
cell.expr(style: str = "mcnp") -> str  # Get CSG expression string ("mcnp" or "openmc")

CellCollection

Collection of cells with filtering.

Basic operations

len(collection)                    # Number of cells
collection[cell_id]                # Cell by ID
for cell in collection: ...        # Iterate Cells
cell_view in collection            # Membership test

Filtering

collection.by_material(material_id: int) -> CellCollection
collection.by_universe(universe_id: int) -> CellCollection
collection.by_fill(fill_universe: int = None) -> CellCollection
collection.filter(predicate: Callable[[Cell], bool]) -> CellCollection

Filters can be chained: model.cells.by_material(1).by_universe(0).

Utility

collection.get(cell_id: int) -> Optional[Cell]  # Get by ID, None if missing
collection.ids() -> List[int]
collection.materials() -> Set[int]
collection.universes() -> Set[int]
collection.to_list() -> List[Cell]

TraceResult

Result of a ray trace through geometry.

Iteration

len(result)             # Number of segments
result[0]               # First TraceSegment
for seg in result: ...  # Iterate segments

Analysis

result.path_length(material: int = None) -> float

Total path length through a specific material, or all materials if material=None.

result.cells_hit() -> List[Optional[Cell]]
result.materials_hit() -> Set[int]

Plotting

result.plot(ax=None, show_materials=True, t_max=None) -> Axes

Plot the ray path as a 1D bar chart. Shorthand for plot_ray_path(result, ...).


TraceSegment

A segment of a ray trace.

Properties

seg.cell: Optional[Cell]  # Cell (None for void)
seg.t_enter: float             # Entry distance along ray
seg.t_exit: float              # Exit distance along ray
seg.material: int              # Material ID (0 for void)
seg.density: float             # Material density
seg.length: float              # t_exit - t_enter
seg.is_void: bool              # True if cell is None

Surface Classes

All surfaces inherit from Surface and support:

-surface    # Negative halfspace (inside)
+surface    # Positive halfspace (outside)
surface.interior()  # Same as -surface
surface.exterior()  # Same as +surface
surface.evaluate(point)  # Signed distance function

Primitives

Plane(a, b, c, d, name=None, boundary='transmissive')
XPlane(x0, ...)
YPlane(y0, ...)
ZPlane(z0, ...)

Sphere(x0, y0, z0, radius, ...)
XCylinder(y0, z0, radius, ...)
YCylinder(x0, z0, radius, ...)
ZCylinder(x0, y0, radius, ...)
XCone(x0, y0, z0, t_sq, sheet=0, ...)
YCone(x0, y0, z0, t_sq, sheet=0, ...)
ZCone(x0, y0, z0, t_sq, sheet=0, ...)
XTorus(x0, y0, z0, major_radius, minor_radius, ...)
YTorus(x0, y0, z0, major_radius, minor_radius, ...)
ZTorus(x0, y0, z0, major_radius, minor_radius, ...)
Quadric(A, B, C, D, E, F, G, H, J, K, ...)

Macrobodies

RPP(xmin, xmax, ymin, ymax, zmin, zmax, ...)
RCC(base_x, base_y, base_z, height_x, height_y, height_z, radius, ...)
TRC(base_x, base_y, base_z, height_x, height_y, height_z, base_radius, top_radius, ...)
ELL(v1_x, v1_y, v1_z, v2_x, v2_y, v2_z, major_axis_len, ...)
REC(base_x, ..., height_x, ..., axis1_x, ..., axis2_x, ..., ...)
WED(vertex_x, ..., v1_x, ..., v2_x, ..., v3_x, ..., ...)
RHP(base_x, ..., height_x, ..., r1_x, ..., r2_x, ..., r3_x, ..., ...)
Box(corner_x, ..., v1_x, ..., v2_x, ..., v3_x, ..., ...)

Region Classes

Halfspace

Halfspace(surface, positive)   # Created by -surface or +surface

Properties: surface, positive.

Intersection

region_a & region_b    # Creates Intersection([a, b])

Property: regions (list of child regions). Nested intersections are flattened.

Union

region_a | region_b    # Creates Union([a, b])

Property: regions (list). Nested unions are flattened.

Complement

~region    # Creates Complement(region)

Double negation is eliminated: ~~region returns the original region.

All Regions

(x, y, z) in region         # Point containment test
region.get_surfaces()        # Set of all referenced surfaces

Material

mat = model.add_material(1, name="Steel", density=7.8)
mat.add_element(26, 0.70)
mat.add_nuclide(26056, 0.90)
mat.expand_elements()
mat.id: int
mat.name: Optional[str]
mat.density: Optional[float]
mat.weight_fractions: bool
mat.nuclides: List[dict]
mat.elements: List[dict]

Dataclass: Universe

@dataclass
class Universe:
    id: int
    name: Optional[str] = None
    cells: list = []  # Internal cell records for programmatic universes

    def add_cell(cell) -> None

Logging

ath.enable_logging()                 # Set INFO level
ath.disable_logging()                # Silence
ath.set_log_level(ath.LOG_DEBUG)     # Specific level
ath.get_log_level() -> int

Log level constants

Constant Value Meaning
ath.LOG_NONE 0 No output
ath.LOG_ERROR 1 Errors only
ath.LOG_WARN 2 Warnings and above
ath.LOG_INFO 3 Informational
ath.LOG_DEBUG 4 Debug detail
ath.LOG_TRACE 5 Full trace

Constants

Grid/Cell identification

Constant Value Meaning
ath.CELL_VOID -1 Void pixel in grid
ath.CELL_UNDEFINED -2 Undefined region
ath.CELL_OVERLAP -3 Overlapping cells

Grid error flags

Constant Value Meaning
ath.GRID_ERROR_OK 0 No error
ath.GRID_ERROR_OVERLAP 1 Overlap detected
ath.GRID_ERROR_UNDEFINED 2 Undefined region

Module: slicing

Helpers used internally by model.slice. Available for advanced use.

from aleathor.slicing import (
    find_label_positions,
    find_surface_label_positions,
    check_grid_overlaps,
    _extract_slice_params,       # DRY helper for grid dimension dispatch
)

_extract_slice_params

_extract_slice_params(grid_result: dict)
    -> Tuple[nu, nv, origin, normal, up, u_min, u_max, v_min, v_max]

Extract unified slice parameters from any grid result dict (z, y, x, or arbitrary). Handles the dispatch logic for different grid dimension keys (nx/ny, nx/nz, ny/nz, nu/nv).