Aperture
This module describes the aperture checking system (Aperture) in PASS, used to check whether particles exceed the transverse aperture boundaries of the beam pipe during particle tracking. Aperture checking is a core component of beam loss simulation, capable of identifying and recording particles lost due to transverse coordinates exceeding physical pipe limits.
The aperture module is located at PASS/utils/aperture.py and provides both CPU and GPU implementations (called via the check_aperture_cpu and check_aperture_gpu functions, respectively), automatically invoked after each element tracking. The current element’s longitudinal position \(s\) and the current turn number are passed in at call time.
Aperture checking is performed only on the transverse coordinates \((x, y)\) of particles and does not involve longitudinal coordinates. Each element can independently set its aperture type and parameters, supporting 10 aperture geometries.
Geometry construction and loss handling are both defined in this one file.
build_aperture({"Type": ..., "Value": ...}) constructs a geometry object;
mask(x, y) includes the wall, while strict_mask(x, y) excludes it.
These predicates accept NumPy or CuPy coordinate arrays and return a mask on
the same backend without modifying particles. aperture_bounds(geometry)
returns the geometric extents for initialization checks.
check_aperture_gpu supports all types below with float32 or float64 particle
coordinates and records losses on the device. It validates shape parameters
before launching a CUDA kernel, accepts integer or floating-point dimensions,
and does nothing for an empty bunch. Previously lost particles retain their
original loss position and turn; particles outside the requested bunch range
are untouched. CPU execution does not require CuPy. This GPU support concerns
the aperture module; PIC and SpaceCharge tracking remain CPU-only.
Interface Parameters
The aperture system is controlled by two parameters:
Property |
JSON key |
Type |
Description |
|---|---|---|---|
|
|
str |
Aperture type, case-insensitive; available values are listed below |
|
|
list |
Aperture parameter values; meaning varies by type |
Note
aperture_type is case-insensitive and is internally converted to lowercase before matching. The off and default types ignore aperture_value .
Lost Particle Handling
Only strict aperture interiors survive on both CPU and GPU. Particles touching any physical wall are lost, including polygon edges and vertices; rectangular loss does not require both coordinates to reach their limits.
When a particle is determined to be lost, the system performs the following operations:
tag negation : \(\text{tag} \leftarrow -|\text{tag}|\) , preserving the particle ID information and only negating the sign to mark it as lost
lost_position : records the longitudinal coordinate \(s\) of the loss location, i.e., the longitudinal position of the current element
lost_turn : records the turn number at the time of loss
Particles already lost ( \(\text{tag} < 0\) ) are skipped in subsequent aperture checks and are not marked again. Aperture checking is performed only on surviving particles ( \(\text{tag} > 0\) ).
Detailed Aperture Types
The following describes the parameter definitions and loss conditions for each of the 10 aperture types.
off (Disabled)
Parameters : none ( aperture_value is ignored)
Description : No aperture checking is performed; all particles are retained.
default (Default Rectangle)
Parameters : none ( aperture_value is ignored)
Description : Ordinary elements use the default ±1m rectangle, equivalent
to aperture_value = [1.0, 1.0]. SpaceCharge instead resolves default
to the rectangle defined by its configuration’s grid extent; see Space-Charge Effect (SpaceCharge).
Loss condition :
circle (Circular)
Parameters : aperture_value = [r] , where \(r\) is the circle radius.
Loss condition :
rectangle (Rectangular)
Parameters : aperture_value = [w, h] , where \(w\) is the half-width and \(h\) is the half-height.
Loss condition (particle is lost if either condition is met):
ellipse (Elliptical)
Parameters : aperture_value = [a, b] , where \(a\) is the semi-major axis (x direction) and \(b\) is the semi-minor axis (y direction).
Loss condition :
rectcircle (Rectangle Inscribed Circle)
Parameters : aperture_value = [w, h, r] , where \(w\) is the rectangle half-width, \(h\) is the rectangle half-height, and \(r\) is the circle radius.
The aperture region is the intersection of the rectangle and the circle (particles must be inside both the rectangle and the circle to survive).
Loss condition (particle is lost if either condition is met):
Note
The red dashed line is the rectangle boundary, and the blue solid line is the circle boundary. The aperture region is the intersection of the two.
rectellipse (Rectangle Inscribed Ellipse)
Parameters : aperture_value = [w, h, a, b] , where \(w\) is the rectangle half-width, \(h\) is the rectangle half-height, \(a\) is the ellipse semi-major axis (x direction), and \(b\) is the ellipse semi-minor axis (y direction).
The aperture region is the intersection of the rectangle and the ellipse (particles must be inside both the rectangle and the ellipse to survive).
Loss condition (particle is lost if either condition is met):
Note
The red dashed line is the rectangle boundary, and the blue solid line is the ellipse boundary. The aperture region is the intersection of the two.
racetrack (Racetrack)
Parameters : aperture_value = [w, h, a, b] , where \(w\) is the rectangle half-width, \(h\) is the rectangle half-height, \(a\) is the x-direction semi-axis of the elliptical ends, and \(b\) is the y-direction semi-axis of the elliptical ends.
The racetrack aperture consists of a central rectangle and two semi-elliptical ends. The centers of the elliptical ends are located at \((\pm w, 0)\) .
Survival condition (particle survives if either condition is met):
Strictly inside the rectangular region:
Inside the elliptical end region (when \(|x| > w\) ):
At the internal seams \(|x|=w\), a particle survives only when \(|y|<\min(h,b)\); these seams are not physical walls. All other points outside the strict regions are lost.
Note
The orange dots mark the centers of the elliptical ends at \((\pm w, 0)\) .
octagon (Octagonal)
Parameters : aperture_value = [w, h, d] , where \(w\) is the half-width, \(h\) is the half-height, and \(d\) is the half-diagonal clearance (chamfer distance).
The octagon is the shape obtained by cutting 45° corners off a rectangle. The larger \(d\) , the larger the chamfer; when \(d = 0\) , it degenerates into a rectangle.
Loss condition (particle is lost if either condition is met):
polygon (Polygon)
Parameters : aperture_value = [[x1, y1], [x2, y2], ...] , a list of vertices, automatically closed (the last vertex connects back to the first vertex).
Loss condition : The point lies on an edge or vertex, or outside the polygon. The edge check precedes ray casting; it uses a small floating-point tolerance shared by CPU and GPU.
The ray casting method is used to determine whether a point is inside the polygon: a ray is cast from the test point in the horizontal direction, and the number of intersections with the polygon edges is counted:
Odd number of intersections → the point is inside the polygon (survives)
Even number of intersections → the point is outside the polygon (lost)
Parameter Summary Table
Type |
aperture_value |
Description |
|---|---|---|
|
ignored |
No aperture checking |
|
ignored |
Default ±1m rectangular aperture |
|
|
Circular, \(r\) is the radius |
|
|
Rectangular, \(w\) is the half-width, \(h\) is the half-height |
|
|
Elliptical, \(a\) is the semi-major axis, \(b\) is the semi-minor axis |
|
|
Intersection of rectangle and circle |
|
|
Intersection of rectangle and ellipse |
|
|
Racetrack (rectangle + elliptical ends) |
|
|
Octagonal (rectangle with 45° chamfers) |
|
|
Polygon vertex list, automatically closed |
Usage Example
The following JSON snippets show the configuration of each aperture type. Aperture parameters are element properties,
placed alongside fields such as S (m) , Command , Length (m) , etc.:
Circular aperture :
"Drift1": {
"S (m)": 10.0,
"Command": "Drift",
"Length (m)": 0.5,
"Aperture Type": "circle",
"Aperture Value": [0.1]
}
Rectangular aperture :
"Drift2": {
"S (m)": 10.5,
"Command": "Drift",
"Length (m)": 0.3,
"Aperture Type": "rectangle",
"Aperture Value": [0.06, 0.04]
}
Elliptical aperture :
"Drift3": {
"S (m)": 11.0,
"Command": "Drift",
"Length (m)": 0.2,
"Aperture Type": "ellipse",
"Aperture Value": [0.06, 0.04]
}
Racetrack aperture :
"Drift4": {
"S (m)": 11.5,
"Command": "Drift",
"Length (m)": 0.4,
"Aperture Type": "racetrack",
"Aperture Value": [0.03, 0.05, 0.02, 0.05]
}
Octagonal aperture :
"Drift5": {
"S (m)": 12.0,
"Command": "Drift",
"Length (m)": 0.3,
"Aperture Type": "octagon",
"Aperture Value": [0.05, 0.03, 0.01]
}
Polygon aperture :
"Drift6": {
"S (m)": 12.5,
"Command": "Drift",
"Length (m)": 0.2,
"Aperture Type": "polygon",
"Aperture Value": [[0.05, 0.0], [0.025, 0.043], [-0.025, 0.043], [-0.05, 0.0], [-0.025, -0.043], [0.025, -0.043]]
}
Disable aperture checking :
"Drift7": {
"S (m)": 13.0,
"Command": "Drift",
"Length (m)": 0.5,
"Aperture Type": "off"
}