API reference
This section documents the public Python API of barc4beams.
Most users will interact primarily with the barc4beams.beam.Beam
container and a few high-level helper functions, but all modules are
listed for completeness.
Beam container
beam.py — unified interface classes for standardized beams.
- Beam
Single standardized photon beam.
- BeamEnsemble
Collection of comparable beam realizations, typically repeated seeds/runs of the same simulation setup, used for ensemble statistics.
- class barc4beams.beam.Beam(obj: Any, code: str | None = None)
Bases:
objectHigh-level container for one standardized photon beam.
Wraps a validated beam DataFrame and exposes core analysis, propagation, sampling, saving, and visualization methods.
- apply_wavefront(*, wavefront: dict, energy: float | None = None, wavelength: float | None = None, threshold: float | None = None, verbose: bool = False) Beam
Returns a new Beam instance with updated intensity, slopes, and lost-ray flags.
- caustic(*, n_points: int = 501, start: float = -0.5, finish: float = 0.5) dict
Compute the free-space caustic of this Beam.
See propagation.caustic.
- property df: DataFrame
Standardized beam DataFrame.
- classmethod from_intensity(*, far_field: dict, near_field: dict | None = None, n_rays: int, energy: float | None = None, wavelength: float | None = None, jitter: bool = True, threshold: float | None = None, seed: int | None = 42, z0: float = 0.0, polarization_degree: float = 1.0) Beam
Build a Beam by sampling 2D intensity maps.
See sampling.beam_from_intensity.
- classmethod from_wavefront(*, wavefront: dict, n_rays: int, energy: float | None = None, wavelength: float | None = None, jitter: bool = True, threshold: float | None = None, seed: int | None = 42, z0: float = 0.0, polarization_degree: float = 1.0) Beam
Build a Beam by sampling a spatial wavefront map.
See sampling.beam_from_wavefront.
- plot_beam(*, mode: str = 'scatter', aspect_ratio: bool = True, color: int = 1, x_range: tuple[float | None, float | None] | None = None, y_range: tuple[float | None, float | None] | None = None, bins: int | Tuple[int, int] | None = None, bin_width: float | None = None, bin_method: int = 0, dpi: int = 100, path: str | None = None, showXhist: bool = True, showYhist: bool = True, envelope: bool = False, envelope_method: str = 'edgeworth', apply_style: bool = True, k: float = 1.0, z_offset: float = 0.0, scatter_weight_mode: str = 'auto', plot: bool = True)
Plot the spatial footprint X vs Y with optional propagation offset.
- plot_caustic(*, which: Literal['x', 'y', 'both'] = 'both', aspect_ratio: bool = False, color: int | None = 5, z_range: tuple[float | None, float | None] | None = None, xy_range: tuple[float | None, float | None] | None = None, bins: int | tuple[int | None, int] | None = None, bin_width: float | None = None, dpi: int = 100, path: str | None = None, apply_style: bool = True, k: float = 1.0, top_stat: str | None = None, n_points: int = 501, start: float = -0.5, finish: float = 0.5, plot: bool = True)
Plot the caustic map computed from self.caustic().
- plot_divergence(*, mode: str = 'scatter', aspect_ratio: bool = False, color: int = 2, x_range: tuple[float | None, float | None] | None = None, y_range: tuple[float | None, float | None] | None = None, bins: int | tuple[int, int] | None = None, bin_width: float | None = None, bin_method: int = 0, dpi: int = 100, path: str | None = None, showXhist: bool = True, showYhist: bool = True, envelope: bool = False, envelope_method: str = 'edgeworth', apply_style: bool = True, k: float = 1.0, scatter_weight_mode: str = 'auto', plot: bool = True)
Plot the angular distribution dX vs dY.
- plot_energy(*, bins: int | tuple[int, int] | None = None, bin_width: float | None = None, bin_method: int = 0, dpi: int = 100, path: str | None = None, apply_style: bool = True, k: float = 1.0, plot: bool = True)
Plot the energy distribution of the beam.
- plot_energy_vs_intensity(*, mode: str = 'scatter', aspect_ratio: bool = False, color: int | None = 3, x_range: tuple[float | None, float | None] | None = None, y_range: tuple[float | None, float | None] | None = None, bins: int | tuple[int, int] | None = None, bin_width: float | None = None, bin_method: int = 0, dpi: int = 100, path: str | None = None, showXhist: bool = True, showYhist: bool = True, envelope_method: str = 'edgeworth', apply_style: bool = True, k: float = 1.0, scatter_weight_mode: str = 'auto', plot: bool = True)
Plot beam intensity as a function of photon energy.
- plot_intensity(*, bins: int | tuple[int, int] | None = None, bin_width: float | None = None, bin_method: int = 0, dpi: int = 100, path: str | None = None, apply_style: bool = True, k: float = 1.0, plot: bool = True)
Plot the intensity distribution of the beam.
- plot_phase_space(*, direction: str = 'both', mode: str = 'scatter', aspect_ratio: bool = False, color: int = 3, x_range: tuple[float | None, float | None] | None = None, y_range: tuple[float | None, float | None] | None = None, bins: int | tuple[int, int] | None = None, bin_width: float | None = None, bin_method: int = 0, dpi: int = 100, path: str | None = None, showXhist: bool = True, showYhist: bool = True, envelope: bool = False, envelope_method: str = 'edgeworth', apply_style: bool = True, k: float = 1.0, z_offset: float = 0.0, scatter_weight_mode: str = 'auto', plot: bool = True)
Plot phase-space diagrams X vs dX and/or Y vs dY.
- propagate(z_offset: float, *, verbose: bool = False) Beam
Return a new Beam propagated through free space by z_offset [m].
- save(path: str, *, meta: dict[str, Any] | None = None) None
Save beam to HDF5 and stats to JSON.
The HDF5 file contains the beam. A sibling JSON file with the same base name contains the statistics.
- save_beam(path: str) None
Save the beam only to HDF5.
- save_stats(path: str, *, meta: dict[str, Any] | None = None) None
Save statistics only to JSON.
- stats(*, verbose: bool = False) dict
Compute descriptive beam statistics.
See stats.get_statistics.
- class barc4beams.beam.BeamEnsemble(beams: Sequence[Beam | DataFrame | Any], code: str | None = None)
Bases:
objectContainer for comparable standardized beam realizations.
This is intended for repeated runs/seeds of the same beamline setup. It owns ensemble-level statistics, saving, and merging. Single-beam operations such as plotting, propagation, and caustic calculation remain on Beam.
- classmethod from_dfs(beams: Sequence[DataFrame]) BeamEnsemble
Create a BeamEnsemble directly from standard DataFrames.
- classmethod from_h5(path: str) BeamEnsemble
Load a BeamEnsemble from an HDF5 file written by io.save_beam_ensemble.
- property n_runs: int
Number of beam realizations in the ensemble.
- property runs: Sequence[DataFrame]
Standardized beam DataFrames.
- save(path: str, *, meta: dict[str, Any] | None = None) None
Save ensemble beams to HDF5 and ensemble stats to JSON.
The HDF5 file contains all runs. A sibling JSON file with the same base name contains ensemble statistics.
- save_beams(path: str) None
Save ensemble beams only to HDF5.
- save_stats(path: str, *, meta: dict[str, Any] | None = None) None
Save ensemble statistics only to JSON.
- stats(*, verbose: bool = False) dict
Compute ensemble statistics over all runs.
See stats.get_statistics.
Propagation
propagation.py - free space ray tracing.
- barc4beams.propagation.caustic(beam: DataFrame, *, n_points: int = 501, start: float = -0.5, finish: float = 0.5) dict
Compute free-space caustics for a standard beam.
Ray positions are propagated in free space. Ray intensity weights are not modified by propagation and are used for all per-plane statistics.
- barc4beams.propagation.propagate(beam: DataFrame, z_offset: float) DataFrame
Compute free-space propagation for a standard beam
- Performs:
X <- X + z_offset * dX Y <- Y + z_offset * dY
- Parameters:
beam (pandas.DataFrame) – Standardized beam. Validated via schema.validate_beam(beam).
z_offset (float) – Propagation distance in meters (positive downstream).
- Returns:
Standard beam at the propagated plane.
- Return type:
pandas.DataFrame
Sampling
sampling.py — generate a standardized beam by sampling 2D intensity maps.
- barc4beams.sampling.apply_wavefront(*, standard_beam: DataFrame, wavefront: dict, energy: float | None = None, wavelength: float | None = None, threshold: float | None = None) DataFrame
Apply a spatial wavefront map to an existing standard beam.
The input beam is copied. Ray positions are preserved. The wavefront intensity is interpolated at each ray position and applied as a multiplicative transmission factor. The wavefront phase gradient is interpolated at each ray position and applied as an angular kick:
dX_out = dX_in + (1 / k) * dphi/dx dY_out = dY_in + (1 / k) * dphi/dy
with k = 2*pi / wavelength.
Rays outside the wavefront grid, rays landing on zero/invalid transmission, and rays landing where the phase-gradient support is invalid are marked as lost and assigned zero intensity.
- Parameters:
standard_beam (pandas.DataFrame) – Standard beam DataFrame.
wavefront (dict) –
- Flat dict with keys:
”intensity”: 2D array I[y, x].
”phase”: 2D array of unwrapped phase in radians.
”x_axis”: 1D array of x in meters.
”y_axis”: 1D array of y in meters.
energy (float, optional) – Exactly one must be provided. The other is computed using misc.energy_wavelength(…). If ‘energy’ is given, wavelength is computed in meters; if ‘wavelength’ is given, energy is computed in eV.
wavelength (float, optional) – Exactly one must be provided. The other is computed using misc.energy_wavelength(…). If ‘energy’ is given, wavelength is computed in meters; if ‘wavelength’ is given, energy is computed in eV.
threshold (float or None, optional) – Relative cutoff in [0, 1]. Pixels below threshold * max(intensity) are treated as invalid support.
- Returns:
New standard beam DataFrame with updated intensity, slopes, and lost-ray flags.
- Return type:
pandas.DataFrame
- Raises:
ValueError – If the input beam or wavefront is invalid.
- barc4beams.sampling.beam_from_intensity(*, far_field: dict, near_field: dict | None = None, n_rays: int, energy: float | None = None, wavelength: float | None = None, jitter: bool = True, threshold: float | None = None, seed: int | None = 42, z0: float = 0.0, polarization_degree: float = 1.0) DataFrame
Build a standard beam by sampling intensity maps (SI units only).
- Parameters:
far_field (dict) – Flat dict with keys: {“intensity”, “x_axis”, “y_axis”}. - “intensity”: 2D array Iff[y, x] (already per pixel; no unit conversion here) - “x_axis”: 1D array of xp in radians (strictly monotonic) - “y_axis”: 1D array of yp in radians (strictly monotonic) This is REQUIRED and defines (dX, dY).
near_field (dict or None, optional) – Flat dict with keys: {“intensity”, “x_axis”, “y_axis”}. - “intensity”: 2D array Inf[y, x] (already per pixel) - “x_axis”: 1D array of x in meters (strictly monotonic) - “y_axis”: 1D array of y in meters (strictly monotonic) If provided, defines (X, Y); otherwise X=Y=0 (point source at z0).
n_rays (int) – Number of rays to sample.
energy (float, optional) – Exactly one must be provided. The other is computed using misc.energy_wavelength(…). If ‘energy’ is given, wavelength is computed in meters; if ‘wavelength’ is given, energy is computed in eV.
wavelength (float, optional) – Exactly one must be provided. The other is computed using misc.energy_wavelength(…). If ‘energy’ is given, wavelength is computed in meters; if ‘wavelength’ is given, energy is computed in eV.
jitter (bool, optional) – Sub-pixel jitter for both FF and NF maps (if NF present).
threshold (float or None, optional) – Relative cutoff in [0, 1] applied independently to each map.
seed (int | None, optional) – RNG seed. If both FF and NF are sampled, NF uses (seed+1) for decorrelation.
z0 (float, default 0.0) – Source plane position assigned to all rays (Z=z0, dZ=0).
polarization_degree (float, default 1.0) – Value in [0,1] is the s-polarization fraction: Is = pdeg, Ip = 1-pdeg
- Returns:
Standard beam DataFrame ready for plotting/propagation/caustic.
- Return type:
pandas.DataFrame
Notes
The sampling algorithm implemented here follows the strategy described in Rebuffi et al., J. Synchrotron Rad. 27, 1108–1120 (2020).
- barc4beams.sampling.beam_from_wavefront(*, wavefront: dict, n_rays: int, energy: float | None = None, wavelength: float | None = None, jitter: bool = True, threshold: float | None = None, seed: int | None = 42, z0: float = 0.0, polarization_degree: float = 1.0) DataFrame
Build a standard beam by sampling a spatial wavefront map (SI units only).
The ray positions (X, Y) are sampled from the wavefront intensity map. The local ray angles (dX, dY) are obtained from the phase gradient:
dX = (1 / k) * dphi/dx dY = (1 / k) * dphi/dy
with k = 2*pi / wavelength.
- Parameters:
wavefront (dict) –
- Flat dict with keys:
”intensity”: 2D array I[y, x].
”phase”: 2D array of unwrapped phase in radians.
”x_axis”: 1D array of x in meters.
”y_axis”: 1D array of y in meters.
n_rays (int) – Number of rays to sample.
energy (float, optional) – Exactly one must be provided. The other is computed using misc.energy_wavelength(…). If ‘energy’ is given, wavelength is computed in meters; if ‘wavelength’ is given, energy is computed in eV.
wavelength (float, optional) – Exactly one must be provided. The other is computed using misc.energy_wavelength(…). If ‘energy’ is given, wavelength is computed in meters; if ‘wavelength’ is given, energy is computed in eV.
jitter (bool, optional) – Sub-pixel jitter for the sampled (X, Y) coordinates.
threshold (float or None, optional) – Relative cutoff in [0, 1]. Pixels below threshold * max(intensity) are excluded both from position sampling and from phase-gradient support.
seed (int | None, optional) – RNG seed for reproducibility. Use an int for deterministic draws; use None for non-deterministic sampling.
z0 (float, default 0.0) – Source plane position assigned to all rays (Z=z0, dZ=0).
polarization_degree (float, default 1.0) – Value in [0, 1] is the s-polarization fraction: Is = pdeg, Ip = 1-pdeg.
- Returns:
Standard beam DataFrame ready for plotting/propagation/caustic.
- Return type:
pandas.DataFrame
Notes
This function samples ray positions from a spatial intensity map and assigns local propagation angles from the phase gradient.
Low-intensity or invalid pixels are masked internally before gradient evaluation. This avoids differentiating noisy finite phase values outside the useful wavefront support.
Statistics
stats.py - beam statistics and 1D profile metrics.
- barc4beams.stats.calc_centroid_from_particle_distribution(profile: ndarray, weights: ndarray | None = None) float
Compute the centroid (center of mass) of a 1D particle-position distribution.
This treats profile as Monte Carlo samples of positions (each sample has equal weight by default). If weights are provided (e.g., per-ray intensities), a weighted centroid is computed.
- Parameters:
profile (np.ndarray) – 1D array of particle positions (e.g., X or Y).
weights (np.ndarray, optional) – Non-negative weights for each sample (same shape as profile). If None, all samples are equally weighted.
- Returns:
Centroid in the same units as profile, or np.nan if it cannot be computed (e.g., empty or all-nonfinite inputs, or zero total weight).
- Return type:
float
- barc4beams.stats.calc_envelope_from_moments(mean: float, std: float, skewness: float, kurtosis_excess: float, axis: ndarray, method: str = 'edgeworth', clip_negative: bool = True, maxent_iters: int = 2000, maxent_lr: float = 0.001, seed: int | None = None) Dict
Construct an approximate 1D PDF envelope consistent with the first four moments.
- Parameters:
mean (float) – Mean (μ) of the target distribution.
std (float) – Standard deviation (σ > 0).
skewness (float) – Standardized 3rd moment γ1.
kurtosis_excess (float) – Excess kurtosis γ2 (kurtosis − 3).
axis (np.ndarray) – 1D grid where the envelope is evaluated.
method ({'edgeworth', 'pearson', 'maxent'}, default 'edgeworth') –
‘edgeworth’: Gram–Charlier/Edgeworth expansion around N(μ, σ²) up to H6.
’pearson’ : Pearson Type III (Gamma) matched to γ1; reflect for γ1<0.
- ’maxent’Discrete maximum-entropy pdf ~ exp(a0 + a1 x + … + a4 x^4)
fitted so moments up to order 4 match on the given axis.
clip_negative (bool, default True) – If True, clip negative pdf values to 0 and renormalize (useful for ‘edgeworth’).
maxent_iters (int, default 2000) – Iterations for the ‘maxent’ solver.
maxent_lr (float, default 1e-3) – Learning rate for the ‘maxent’ solver.
seed (int or None) – RNG seed (used only by ‘maxent’ initialization).
- Returns:
{‘envelope’: pdf_vals, ‘axis’: axis}
- Return type:
dict
Notes
Edgeworth (default) is fastest and smooth for |skew|≲1 and |excess kurtosis|≲2. Negative lobes can appear when moments are large; keep clip_negative=True to force a valid PDF.
Pearson Type III guarantees positivity and matches mean/σ/skewness exactly. The implied excess kurtosis is γ₂ = 1.5·γ₁²; the supplied kurtosis is ignored if inconsistent.
Maximum entropy finds the least-assumptive distribution subject to the moment constraints. It needs a wide, dense axis (e.g. μ±6σ) and is slower; increase maxent_iters or reduce maxent_lr if convergence is poor.
The four moments do not uniquely define a distribution. The returned envelope is only one of many possible PDFs consistent with them.
- barc4beams.stats.calc_focal_distance_from_particle_distribution(position: ndarray, divergence: ndarray, weights: ndarray | None = None, *, eps: float = 1e-16, ridge: float = 0.0, huge_m: float = 1e+26) float
Compute the signed focal distance minimizing the weighted variance of
position + x * divergence.If
weightsis None, all particles are assigned unit weight.- Parameters:
position (np.ndarray) – 1D array of transverse positions, e.g. X or Y [m].
divergence (np.ndarray) – 1D array of corresponding angular components, e.g. dX or dY [rad].
weights (np.ndarray, optional) – 1D array of statistical ray weights. If None, unit weights are used.
eps (float, optional) – Numerical floor for denominator stability.
ridge (float, optional) – Extra ridge term added to the divergence variance.
huge_m (float, optional) – Finite surrogate distance for an effectively infinite focus.
- Returns:
Signed focal distance in meters.
- Return type:
float
- barc4beams.stats.calc_fwhm_from_particle_distribution(profile: ndarray, weights: ndarray | None = None, bins: int | None = None) float
Calculate the FWHM of a 1D particle distribution.
If
weightsis None, all particles are assigned unit weight. If weights are provided, the FWHM is computed from a weighted histogram.- Parameters:
profile (np.ndarray) – 1D array representing particle positions, divergences, or energies.
weights (np.ndarray, optional) – 1D array of statistical ray weights. If None, unit weights are used.
bins (int or None, optional) – Number of histogram bins. If None, an adaptive rule is used.
- Returns:
FWHM value in the same units as
profile. Returns -1.0 if computation fails.- Return type:
float
- barc4beams.stats.calc_moments_from_particle_distribution(profile: ndarray, weights: ndarray | None = None) Tuple[float, float, float, float]
Return (mean, std, skewness, kurtosis_excess) using population definitions.
If
weightsis None, all particles are assigned unit weight. If weights are provided, the moments are intensity-weighted.- Parameters:
profile (np.ndarray) – 1D array representing particle positions, divergences, or energies.
weights (np.ndarray, optional) – 1D array of statistical ray weights. If None, unit weights are used.
- Returns:
Mean, standard deviation, skewness, and excess kurtosis.
- Return type:
tuple[float, float, float, float]
- barc4beams.stats.get_focal_distance(beam: DataFrame, verbose: bool = False, direction: str = 'both', eps: float = 1e-16, ridge: float = 0.0, huge_m: float = 1e+23) Dict[str, float]
Calculate the intensity-weighted focal distance along X and Y.
Lost rays are removed via
lost_ray_flag == 0before computing the focal distance. If theintensitycolumn is present, it is used as the ray weight. Otherwise, all rays are assigned unit weight.Uses the closed-form weighted least-squares expression:
x* = -Cov_w(axis, d_axis) / (Var_w(d_axis) + ridge)
- Parameters:
beam (pandas.DataFrame) – Beam dataframe containing X/dX and/or Y/dY columns.
verbose (bool, optional) – If True, prints diagnostic information.
direction ({'x', 'y', 'both'}, optional) – Direction to optimize.
eps (float, optional) – Numerical floor for denominator stability.
ridge (float, optional) – Extra ridge term added to the divergence variance.
huge_m (float, optional) – Finite surrogate distance for an effectively infinite focus.
- Returns:
Dictionary with keys
'fx'and'fy'.- Return type:
dict
- barc4beams.stats.get_statistics(beams: DataFrame | List[DataFrame], *, verbose: bool = False) dict
Compute intensity-weighted beam statistics for X/Y, dX/dY, and energy.
Lost rays are removed via
lost_ray_flag == 0before computing stats. All statistical observables are weighted by theintensitycolumn.With unit intensities, the weighted formulas reduce to the unweighted case.
Inputs
- beamspd.DataFrame or list[pd.DataFrame]
One or multiple barc4beams beam DataFrames.
- keyword verbose:
If True, print a human-readable summary.
- kwtype verbose:
bool, optional
- returns:
- {
- “meta”: {
“n_rays”: int, “n_repetitions”: int, “good_rays”: [mean, std], “transmission”: [mean%, std%],
}, “energy”: {“mean”:[val,std], “std”:[val,std], “fwhm”:[val,std]}, “X”: {“mean”:[val,std], “std”:[val,std],
“fwhm”:[val,std], “skewness”:[val,std], “kurtosis”:[val,std]},
“Y”: { … same keys as X … }, “dX”: { … same keys as X … }, “dY”: { … same keys as X … }, “fx”: [val,std], “fy”: [val,std],
}
Only keys for columns actually present in the input are included.
- rtype:
dict
I/O utilities
io.py - saving and loading of standardised beams and stats.
- barc4beams.io.read_beam(path: str) DataFrame
Read a standardized beam from an HDF5 file.
- Parameters:
path (str) – Input HDF5 file path.
- Returns:
Beam as a DataFrame.
- Return type:
pandas.DataFrame
- Raises:
KeyError – If the ‘beam’ group or required datasets are missing.
ValueError – If the reconstructed DataFrame fails validation.
- barc4beams.io.read_beam_ensemble(path: str) list[DataFrame]
Read an ensemble of standardized beams from an HDF5 file.
- Parameters:
path (str) – Input HDF5 file path.
- Returns:
List of standardized beams, one DataFrame per run.
- Return type:
list[pandas.DataFrame]
- Raises:
KeyError – If the ensemble groups or beam datasets are missing.
ValueError – If any reconstructed beam fails validation.
- barc4beams.io.read_json_stats(path: str) Dict[str, Any]
Load a JSON file saved by save_json_stats.
- Returns:
Record with keys: created_utc, meta, stats
- Return type:
dict
- barc4beams.io.save_beam(obj: Any, path: str, *, code: str | None = None, overwrite: bool = True, chunks: bool = True) None
Save a standardized beam to an HDF5 file.
- Parameters:
obj (Any) – Beam-like object. If a pandas.DataFrame, it is assumed to be already standardized. Otherwise it is converted via
adapters.to_standard_beam(obj, code=code).path (str) – Output HDF5 file path.
code (str, optional) – Backend hint for conversion (passed to
to_standard_beam).overwrite (bool, optional) – If False and path exists, raise an error. Default is True.
chunks (bool, optional) – Enable chunked datasets (recommended). Default True.
- Raises:
ValueError – If standardization/validation fails or no numeric columns found.
FileExistsError – If overwrite is False and file already exists.
- barc4beams.io.save_beam_ensemble(objs: list[Any], path: str, *, code: str | None = None, overwrite: bool = True, chunks: bool = True) None
Save an ensemble of standardized beams to an HDF5 file.
- Parameters:
objs (list[Any]) – Beam-like objects. Each item may be a standardized pandas.DataFrame or any object accepted by
adapters.to_standard_beam(obj, code=code).path (str) – Output HDF5 file path.
code (str, optional) – Backend hint for conversion, passed to
to_standard_beamfor non-DataFrame objects.overwrite (bool, optional) – If False and path exists, raise an error. Default is True.
chunks (bool, optional) – Enable chunked datasets. Default True.
- Raises:
ValueError – If the ensemble is empty, standardization/validation fails, or a beam has no numeric columns.
FileExistsError – If overwrite is False and file already exists.
- barc4beams.io.save_json_stats(stats: Dict[str, Any], path: str, *, meta: Dict[str, Any] | None = None) str
Save a get_statistics() dictionary to JSON.
- Parameters:
stats (dict) – The dictionary returned by get_statistics(…).
path (str) – Target JSON file path.
meta (dict, optional) – Extra metadata to embed (e.g., n_seeds, n_rays, code_sha, settings).
- Returns:
The path written.
- Return type:
str
Visualization
viz.py - plotting routines for beams and beamline layouts.
- barc4beams.viz.plot() None
Show all pending figures.
- barc4beams.viz.plot_beam(df: DataFrame, *, mode: str = 'scatter', aspect_ratio: bool = True, color=1, x_range=None, y_range=None, bins=None, bin_width=None, bin_method=0, dpi: int = 100, path: str | None = None, showXhist=True, showYhist=True, envelope=False, envelope_method='edgeworth', weight_by_intensity: bool = True, apply_style: bool = True, k: float = 1.0, plot: bool = True, z_offset: float = 0.0, scatter_weight_mode: Literal['auto', 'none', 'resample', 'color', 'alpha', 'threshold'] | str = 'auto', scatter_sample_size: int | None = None, scatter_seed: int | None = 12345, scatter_threshold: float = 0.0)
Plot the spatial footprint of a standardized beam (X vs Y), with optional marginals and moment-matched envelope overlays.
- Parameters:
df (pandas.DataFrame) – Standardized beam with columns: ‘X’,’Y’,’dX’,’dY’,’lost_ray_flag’ (0=alive). Units expected in meters (pos) and radians (angles). This function scales to µm/µrad.
mode ({'scatter','histo2d', ...}, default 'scatter') – Plot style. Aliases like ‘s’/’h’ are accepted and normalized.
aspect_ratio (bool, default True) – If True, main axes uses equal aspect.
color (int or None, default 1) – Legacy color scheme index. 0/None → monochrome points; 1..4 → colormaps.
x_range ((min, max) or None) – Data limits. If None/partial, auto-detected with a small padding.
y_range ((min, max) or None) – Data limits. If None/partial, auto-detected with a small padding.
bins (int or (x_bins, y_bins) or None) – Histogram binning for the marginals and hist2d. Auto if None.
bin_width (float or None) – If given, overrides bin count as ceil(range/bin_width).
bin_method (int, default 0) – Auto-binning rule: 0=sqrt, 1=Sturges, 2=Rice, 3=Doane.
dpi (int, default 300)
path (str or None) – If provided, the figure is saved.
showXhist (bool, default True) – Whether to show X/Y marginals.
showYhist (bool, default True) – Whether to show X/Y marginals.
envelope (bool, default True) – Overlay envelope curve on the 1D marginals using moments from the data.
envelope_method ({'edgeworth','pearson','maxent'}, default 'edgeworth') – Reconstruction method passed to stats.calc_envelope_from_moments.
apply_style (bool, default True) – Call start_plotting(k) before plotting.
k (float, default 1.0) – Global style scale factor.
- Returns:
The Matplotlib figure and axes.
- Return type:
fig, (ax_image, ax_histx, ax_histy)
- barc4beams.viz.plot_caustic(caustic: dict, *, which: Literal['x', 'y', 'both'] = 'both', aspect_ratio: bool = False, color: int | None = 5, z_range: Tuple[int | float | None, int | float | None] | None = None, xy_range: Tuple[int | float | None, int | float | None] | None = None, bins: int | Tuple[int, int] | None = None, bin_width: int | float | None = None, dpi: int = 100, path: str | None = None, apply_style: bool = True, k: float = 1.0, plot: bool = True, top_stat: str | None = None)
Plane-centered 2D histogram caustic (no other modes allowed).
Z is binned with one contiguous column per plane (no gaps).
X/Y use fixed bin width (if bin_width) or a fixed number of bins (bins).
Optional top panel shows FWHM or sigma (STD) vs z.
Notes
Units: position on the map is in µm (input arrays in meters are scaled by 1e6).
Large beams are safe: uses numpy.histogram2d + pcolormesh (no KDE, no scatter).
- barc4beams.viz.plot_divergence(df: DataFrame, *, mode: str = 'scatter', aspect_ratio: bool = False, color=2, x_range=None, y_range=None, bins=None, bin_width=None, bin_method=0, dpi: int = 100, path: str | None = None, showXhist=True, showYhist=True, envelope=False, envelope_method='edgeworth', weight_by_intensity: bool = True, apply_style: bool = True, k: float = 1.0, plot: bool = True, z_offset: float = 0.0, scatter_weight_mode: Literal['auto', 'none', 'resample', 'color', 'alpha', 'threshold'] | str = 'auto', scatter_sample_size: int | None = None, scatter_seed: int | None = 12345, scatter_threshold: float = 0.0)
Plot the beam divergence (dX vs dY) in µrad with optional marginals and envelopes. (See plot_beam for parameter semantics.)
- Return type:
fig, (ax_image, ax_histx, ax_histy)
- barc4beams.viz.plot_energy(df: DataFrame, *, bins: int | Tuple[int, int] | None = None, bin_width: int | float | None = None, bin_method: int = 0, dpi: int = 100, path: str | None = None, weight_by_intensity: bool = True, apply_style: bool = True, k: float = 1.0, plot: bool = True) Tuple[Figure, Axes]
Energy distribution vs E (eV), optionally intensity-weighted.
- barc4beams.viz.plot_energy_vs_intensity(df: DataFrame, *, mode: str = 'scatter', aspect_ratio: bool = False, color: int | None = 3, x_range: Tuple[int | float | None, int | float | None] | None = None, y_range: Tuple[int | float | None, int | float | None] | None = None, bins: int | Tuple[int, int] | None = None, bin_width: int | float | None = None, bin_method: int = 0, dpi: int = 100, path: str | None = None, showXhist: bool = True, showYhist: bool = True, envelope_method: str = 'edgeworth', weight_by_intensity: bool = True, apply_style: bool = True, k: float = 1.0, plot: bool = True, scatter_weight_mode: Literal['auto', 'none', 'resample', 'color', 'alpha', 'threshold'] | str = 'auto', scatter_sample_size: int | None = None, scatter_seed: int | None = 12345, scatter_threshold: float = 0.0) Tuple[Figure, Tuple[Axes, Axes | None, Axes | None]]
2D plot with X=energy [eV], Y=Intensity [arb], with optional marginals/envelopes; never silently shows.
- barc4beams.viz.plot_intensity(df: DataFrame, *, bins: int | Tuple[int, int] | None = None, bin_width: int | float | None = None, bin_method: int = 0, dpi: int = 100, path: str | None = None, weight_by_intensity: bool = False, apply_style: bool = True, k: float = 1.0, plot: bool = True) Tuple[Figure, Axes]
Intensity distribution vs I, optionally intensity-weighted.
- barc4beams.viz.plot_phase_space(df: DataFrame, *, direction: str = 'both', mode: str = 'scatter', aspect_ratio: bool = False, color=3, x_range=None, y_range=None, bins=None, bin_width=None, bin_method=0, dpi: int = 100, path: str | None = None, showXhist=True, showYhist=True, envelope=False, envelope_method='edgeworth', weight_by_intensity: bool = True, apply_style: bool = True, k: float = 1.0, plot: bool = True, z_offset: float = 0.0, scatter_weight_mode: Literal['auto', 'none', 'resample', 'color', 'alpha', 'threshold'] | str = 'auto', scatter_sample_size: int | None = None, scatter_seed: int | None = 12345, scatter_threshold: float = 0.0)
Plot phase space for one or both planes: (X vs dX) and/or (Y vs dY), in µm/µrad.
- Returns:
(fig_x, axes_x), (fig_y, axes_y) if direction=’both’
or
fig, (ax_image, ax_histx, ax_histy)
- barc4beams.viz.plotting_style(k: float = 1.0)
Temporary plotting style (restores previous rcParams on exit).
Examples
>>> with plotting_style(1.2): ... plot_beam(df)
- barc4beams.viz.start_plotting(k: float = 1.0) None
Set global Matplotlib plot parameters scaled by factor k.
- Parameters:
k (float, optional) – Scaling factor for font sizes (1.0 = baseline).
Adapters
adapters.py - conversion of external beam data (PyOptiX, SHADOW3, SHADOW4) into the standard beam schema.
- barc4beams.adapters.merge_standard_beams(beams: List[DataFrame]) DataFrame
Merge multiple standard photon beams (pandas DataFrames) into a single combined beam. Each input beam should already be standardized via to_standard_beam, The merge is performed by simple row-wise concatenation of all beams.
- Args:
beams (list of pd.DataFrame): List of DataFrames to merge.
- Returns:
- pd.DataFrame: A single DataFrame containing all rows from the input beams.
Columns are the union of all input columns;
- barc4beams.adapters.to_standard_beam(beam, code: str | None = None) DataFrame
Convert an external beam representation into the standard schema.
Supported inputs
PyOptiX beam (pd.DataFrame): typically from: OpticalElement.get_diagram(…) OpticalElement.get_impacts(…).
- Shadow3 beam (code in {‘shadow3’,’s3’}):
- Uses beam.getshcol([…]) with indices:
[11, 1, 3, 2, 4, 6, 5, 19, 23, 10, 24, 25]
- and returns a DataFrame with columns:
- [“energy”,”X”,”Y”,”Z”,”dX”,”dY”,”dZ”,”wavelength”,
“intensity”,”lost_ray_flag”,”intensity_s-pol”,”intensity_p-pol”]
- Shadow4 beam (code in {‘shadow4’,’s4’,’shadow’}):
- Uses beam.get_columns([…]) with indices:
[26, 1, 3, 2, 4, 6, 5, 19, 23, 10, 24, 25]
with the same output columns and clipping as Shadow3.
- param beam:
PyOptiX DataFrame OR Shadow3/4 beam object.
- type beam:
object
- param code:
Explicit backend. If None, auto-detect.
- type code:
{“pyoptix”, “shadow3”, “shadow4”, “s3”, “s4”}, optional
- rtype:
pandas.DataFrame
Schema
schema.py - definition and validation of the standard beam format.
- barc4beams.schema.validate_beam(df: DataFrame) None
Validate a standardized beam DataFrame.
- Parameters:
df (pandas.DataFrame) – Beam after to_standard_beam(…). Columns may appear in any order.
- Raises:
ValueError – If required columns are missing, intensity columns are out of [0, 1], lost-ray flags are not {0, 1}, or a lost ray has nonzero intensity.
Miscellaneous helpers
misc.py - optical design and other auxiliary functions.
- barc4beams.misc.energy_wavelength(value: float, unit: str) float
Converts energy to wavelength and vice versa.
- Parameters:
value (float or array-like): The value of either energy or wavelength. unity (str): {‘eV’,’meV’,’keV’,’m’, ‘um’,’µm’, ‘nm’,’A’,’Å’,’Angstrom’,} (case-insensitive)
- Returns:
float: Converted value in meters if the input is energy, or in eV if the input is wavelength.
- Raises:
ValueError: If an invalid unit is provided.