gammapbh.cli

GammaPBHPlotter — interactive CLI to analyze and visualize Hawking-radiation gamma-ray spectra of primordial black holes (PBHs).

This module provides:
  • Monochromatic spectra visualization for selected PBH masses.

  • Distributed spectra from physically motivated mass PDFs:
    • Gaussian collapse (Press–Schechter–like).

    • Non-Gaussian collapse (Biagetti et al. formulation).

    • Log-normal mass function.

  • A custom-equation mass PDF tool that lets users enter f(m) directly.

  • A viewer for previously saved runs (with spectrum overlays and per-selection mass histograms, including analytic/KDE overlays).

All user-facing plotting is log–log with stable zero-flooring in linear space to avoid numerical warnings. Interpolations are performed in (logM, logE) space with linear/cubic bivariate splines, and inflight-annihilation tails are sanity-trimmed to prevent staircase artifacts in the rightmost bins.

Conventions

  • Masses are in grams [g].

  • Energies are in MeV.

  • Spectra are per energy [MeV^-1 s^-1].

  • “E² dN/dE” overlays are used for SED-style views.

Functions

custom_equation_pdf_tool()

Build a PBH mass PDF from a user-entered equation f(m, params...), normalize it per gram, sample N masses, accumulate ONLY the TOTAL spectrum, then show:

delta_l(mass_ratio, kappa, delta_c, gamma)

Convert mass ratio to the linear threshold δ_l used in collapse models.

discover_mass_folders(data_dir)

Discover valid mass folders within data_dir that contain all required files.

distributed_spectrum(distribution_method)

Generate distributed spectra using one of the supported PBH mass distributions.

err(msg)

Print an error (red) line.

generate_monochromatic_for_mass(target_mass, ...)

Generate (or more precisely, assemble) a monochromatic spectrum file for the nearest available pre-rendered mass to target_mass.

info(msg)

Print an informational (cyan) line.

list_saved_runs(base_dir)

List child directories beneath base_dir.

load_data(filepath[, skip_header])

A thin wrapper around numpy.genfromtxt with explicit header skipping.

load_spectra_components(directory)

Load and align spectral components for a given mass-directory.

load_xy_lenient(filepath[, skip_header, ...])

Robustly load at least two numeric columns from a whitespace/CSV-like text file, skipping blank lines, comment lines, and any lines with fewer than min_cols tokens.

main()

Entry point for the interactive CLI loop.

mass_function(delta_l_val, sigma_x, delta_c, ...)

Gaussian-collapse proxy mass function in δ_l-space.

mass_function_exact(delta_l_val, sigma_X, ...)

Non-Gaussian mass function (Biagetti et al., Eq.

mass_function_lognormal(x, mu, sigma)

Standard log-normal PDF in variable x.

monochromatic_spectra()

Interactive tool to plot one or more monochromatic spectra.

parse_float_list_verbose(s, *[, name, ...])

Parse a comma-separated list of floats with verbose validation.

pause([msg])

show_start_screen()

Print the program banner and helpful usage hints.

snap_to_available(mval, available[, tol])

If mval is essentially equal (in log space) to one of available masses, return that available mass.

user_input(prompt, *[, allow_back, ...])

Wrapper around input() that also understands navigation and, optionally, ignores comment-style lines.

view_previous_spectra()

View previously saved spectra with a queue:

warn(msg)

Print a warning (yellow) line.

Exceptions

BackRequested

Raised when the user enters 'b' or 'back' to return to the prior screen.

exception gammapbh.cli.BackRequested[source]

Bases: Exception

Raised when the user enters ‘b’ or ‘back’ to return to the prior screen.

gammapbh.cli.custom_equation_pdf_tool() None[source]

Build a PBH mass PDF from a user-entered equation f(m, params…), normalize it per gram, sample N masses, accumulate ONLY the TOTAL spectrum, then show:

  1. total dN/dE,

  2. total E^2 dN/dE,

  3. mass histogram (counts) with analytic PDF scaled to counts (log bins).

Saved outputs (if requested)

  • equation.txt : The expression and any variable values (commented).

  • samples_sorted.txt : Sorted sampled masses (g).

  • distributed_spectrum.txt : Columns: E_gamma(MeV), TotalSpectrum

Notes

  • The expression must be a right-hand-side function of m (no “f(m)=” prefix needed).

  • Allowed functions: subset from numpy (log/exp/sqrt/sin/cos/tan/arctan/abs/clip/min/max/erf).

  • Variables unknown to the safe namespace will be auto-detected and prompted for.

gammapbh.cli.delta_l(mass_ratio: ndarray, kappa: float, delta_c: float, gamma: float) ndarray[source]

Convert mass ratio to the linear threshold δ_l used in collapse models.

Parameters:
  • mass_ratio (ndarray) – Dimensionless M/M_peak (or equivalent model-specific scaling).

  • kappa (float)

  • delta_c (float)

  • gamma (float)

Returns:

δ_l(mass_ratio) with the analytic mapping and a safe clip for the sqrt argument.

Return type:

ndarray

gammapbh.cli.discover_mass_folders(data_dir: str) tuple[list[float], list[str]][source]

Discover valid mass folders within data_dir that contain all required files.

Parameters:

data_dir (str) – Absolute or relative path to the BlackHawk data directory.

Returns:

A pair (masses, names) sorted by mass, where masses[i] corresponds to directory name names[i].

Return type:

(list[float], list[str])

Notes

  • Folders are expected to be named as a float mass in grams (e.g., “1.00e+16”).

  • Only folders containing the full REQUIRED_FILES set are returned.

gammapbh.cli.distributed_spectrum(distribution_method: str) None[source]

Generate distributed spectra using one of the supported PBH mass distributions.

Parameters:
  • distribution_method (str) –

    One of:
    • GAUSSIAN_METHOD (“Gaussian collapse”)

    • NON_GAUSSIAN_METHOD (“Non-Gaussian Collapse”)

    • LOGNORMAL_METHOD (“Log-Normal Distribution”)

  • Flow (Interactive)

  • ----------------

  • grid). (1) Prompt for one or more peak masses (must lie within available pre-rendered)

  • N. (2) Prompt for target sample size)

  • ln-space). (3) Prompt for distribution-specific width parameter(s) (σ / σ_X / σ in)

  • masses (4) Sample)

  • guards). (accumulate average spectra via log–log splines (with IFA tail)

  • sets. (5) Plot dN/dE and E² dN/dE overlays across all chosen parameter)

  • set (6) For each)

  • overlay. (plot its mass histogram with a counts-scaled analytic PDF)

  • root. (7) Offer to save results into a unique directory under the method-specific results)

Notes

  • For Non-Gaussian, we enforce 0.04 ≤ σ_X ≤ 0.16 and set σ_Y/σ_X = 0.75 (typical choice).

  • For Log-Normal, we interpret the user’s σ as the ln-space standard deviation and choose μ such that the mode equals the requested peak (μ_eff = ln(peak) + σ²).

  • All interpolation occurs in (logM, logE) space; inflight annihilation tails are trimmed.

gammapbh.cli.err(msg: str) None[source]

Print an error (red) line.

gammapbh.cli.generate_monochromatic_for_mass(target_mass: float, data_dir: str, out_dir: str) str[source]

Generate (or more precisely, assemble) a monochromatic spectrum file for the nearest available pre-rendered mass to target_mass.

Parameters:
  • target_mass (float) – Desired PBH mass [g].

  • data_dir (str) – Directory containing the BlackHawk mass folders.

  • out_dir (str) – Directory to write the output TXT file.

Returns:

Path to the saved monochromatic spectrum file. Columns:

E_gamma(MeV), TotalSpectrum(MeV^-1 s^-1)

Return type:

str

Notes

  • We re-compute the total as Direct + Secondary + IFA + FSR aligned onto the primary energy grid for consistency with plotting routines.

  • The output file name encodes the requested mass, not the snapped mass, to reflect the user’s intention; the data inside reflects the snapped folder.

gammapbh.cli.info(msg: str) None[source]

Print an informational (cyan) line.

gammapbh.cli.list_saved_runs(base_dir: str) list[str][source]

List child directories beneath base_dir.

Parameters:

base_dir (str) – Root directory containing saved runs.

Returns:

Sorted child directory names (no files).

Return type:

list[str]

gammapbh.cli.load_data(filepath: str, skip_header: int = 0) ndarray[source]

A thin wrapper around numpy.genfromtxt with explicit header skipping.

Parameters:
  • filepath (str) – Path to file.

  • skip_header (int) – Number of header lines to skip.

Returns:

Parsed numeric array.

Return type:

ndarray

Raises:
  • FileNotFoundError – If file does not exist.

  • ValueError – If genfromtxt fails due to column inconsistency.

gammapbh.cli.load_spectra_components(directory: str) dict[str, ndarray][source]

Load and align spectral components for a given mass-directory.

Files expected in directory

instantaneous_primary_spectra.txt

Columns: E(GeV) dN/dE (GeV^-1 s^-1) [we later convert E to MeV and flux to MeV^-1 s^-1]

instantaneous_secondary_spectra.txt

Columns: E(MeV) dN/dE (MeV^-1 s^-1)

inflight_annihilation_prim.txt

Typically two columns (E(MeV), rate) but may contain a spurious single-number line first.

inflight_annihilation_sec.txt

Same caveat as above.

final_state_radiation_prim.txt

Typically two columns, sometimes with one header line to skip.

final_state_radiation_sec.txt

Typically two columns, sometimes with one header line to skip.

returns:
Keys:

energy_primary, energy_secondary, direct_gamma_primary, direct_gamma_secondary, IFA_primary, IFA_secondary, FSR_primary, FSR_secondary

rtype:

dict[str, ndarray]

Notes

  • This function now uses load_xy_lenient for IFA/FSR files to survive files with leading single-value rows.

gammapbh.cli.load_xy_lenient(filepath: str, skip_header: int = 0, min_cols: int = 2) ndarray[source]

Robustly load at least two numeric columns from a whitespace/CSV-like text file, skipping blank lines, comment lines, and any lines with fewer than min_cols tokens.

This specifically fixes files where the first data row contains a single integer (e.g., a length or counter), followed by proper 2-column numeric rows; vanilla genfromtxt would lock onto the one-column width and then error.

Parameters:
  • filepath (str) – Path to the file to read.

  • skip_header (int, optional) – Number of initial lines to skip unconditionally.

  • min_cols (int, optional) – Minimum number of numeric columns required to accept a line (default 2).

Returns:

Array of shape (N, >=min_cols). Only the first min_cols columns are guaranteed.

Return type:

ndarray

Raises:
  • FileNotFoundError – If the file does not exist.

  • ValueError – If no usable numeric rows are found.

Notes

  • Treats lines starting with ‘#’ as comments.

  • Replaces commas with spaces to tolerate CSV-ish files.

  • Silently skips lines that fail float conversion or are too short.

gammapbh.cli.main() None[source]

Entry point for the interactive CLI loop.

gammapbh.cli.mass_function(delta_l_val: ndarray, sigma_x: float, delta_c: float, gamma: float) ndarray[source]

Gaussian-collapse proxy mass function in δ_l-space.

Parameters:
  • delta_l_val (ndarray) – δ_l grid.

  • sigma_x (float) – Collapse dispersion parameter.

  • delta_c (float) – Critical collapse threshold.

  • gamma (float) – Shape parameter.

Returns:

Unnormalized mass function (shape same as input).

Return type:

ndarray

gammapbh.cli.mass_function_exact(delta_l_val: ndarray, sigma_X: float, sigma_Y: float, delta_c: float, gamma: float) ndarray[source]

Non-Gaussian mass function (Biagetti et al., Eq. 20 shape—up to constants), mapped into δ_l with a Jacobian consistent with the collapse mapping used above.

Parameters:
  • delta_l_val (ndarray) – δ_l grid.

  • sigma_X (float) – Dispersion along X-direction.

  • sigma_Y (float) – Dispersion along Y-direction (often tied to sigma_X via ratio).

  • delta_c (float) – Critical threshold.

  • gamma (float) – Shape parameter for the mapping.

Returns:

Unnormalized mass function (shape same as input).

Return type:

ndarray

gammapbh.cli.mass_function_lognormal(x: ndarray, mu: float, sigma: float) ndarray[source]

Standard log-normal PDF in variable x.

Parameters:
  • x (ndarray) – Positive support (will be clipped below to avoid divide-by-zero).

  • mu (float) – Mean in ln-space.

  • sigma (float) – Std. dev. in ln-space (must be > 0).

Returns:

Log-normal PDF values at x.

Return type:

ndarray

gammapbh.cli.monochromatic_spectra() None[source]

Interactive tool to plot one or more monochromatic spectra.

Flow

  1. Discover available pre-rendered masses.

  2. Ask user to enter a comma-separated list of target masses.

  3. Build logM–logE splines across the full mass grid to allow interpolation for off-grid masses as needed.

  4. For each requested mass, plot component curves and total; then offer to save selected spectra into the monochromatic results folder.

gammapbh.cli.parse_float_list_verbose(s: str, *, name: str = 'value', bounds: tuple[float | None, float | None] | None = None, allow_empty: bool = False, positive_only: bool = False, strict_gt: bool = False, strict_lt: bool = False) list[float][source]

Parse a comma-separated list of floats with verbose validation.

Parameters:
  • s (str) – Input string, e.g. “1e15, 2e15”.

  • name (str) – Friendly name used in warning messages.

  • bounds ((float|None, float|None) or None) – Inclusive (lo, hi) bounds if provided.

  • allow_empty (bool) – If False and parsing yields nothing, a warning is printed.

  • positive_only (bool) – If True, keep only values > 0.

  • strict_gt (bool) – If True and bounds[0] not None: enforce v > lo; else v ≥ lo.

  • strict_lt (bool) – If True and bounds[1] not None: enforce v < hi; else v ≤ hi.

Returns:

Validated, de-duplicated floats (first occurrence kept).

Return type:

list[float]

gammapbh.cli.pause(msg='Press Enter to continue…')[source]
gammapbh.cli.show_start_screen() None[source]

Print the program banner and helpful usage hints.

gammapbh.cli.snap_to_available(mval: float, available: list[float], tol: float = 1e-12) float | None[source]

If mval is essentially equal (in log space) to one of available masses, return that available mass. Otherwise return None.

Parameters:
  • mval (float) – Desired mass value [g].

  • available (list[float]) – Pre-rendered masses available.

  • tol (float) – Allowed absolute difference in ln-space for a snap.

Return type:

float or None

gammapbh.cli.user_input(prompt: str, *, allow_back: bool = False, allow_exit: bool = True, allow_comment: bool = True) str[source]

Wrapper around input() that also understands navigation and, optionally, ignores comment-style lines.

Parameters:
  • prompt (str) – Text to display when requesting input from the user.

  • allow_back (bool, optional) – If True, the special commands "b" or "back" (case-insensitive) will not be returned as normal input. Instead, a BackRequested exception is raised, allowing the caller to return to a previous menu.

  • allow_exit (bool, optional) – If True, the special commands "q" or "exit" (case-insensitive) cause the program to terminate immediately via sys.exit(). This is used for global “quit” shortcuts in the interactive CLI.

  • allow_comment (bool, optional) –

    If True (default), any line whose first non-whitespace character is '#' is treated as a comment and ignored. This is specifically to make copy–pasted transcripts from the documentation or README work smoothly: users can paste sequences like:

    gammapbh
    # Example A — Monochromatic spectra
    # 1) Select "Monochromatic spectra"
    1
    # 2) Enter PBH masses (g)
    3.14e15, 1.4e14
    

    and all '# …' lines will be skipped until a non-comment line is read.

Returns:

The raw user input (with leading/trailing whitespace stripped) that is not a navigation/exit command and is not suppressed as a comment.

Return type:

str

Raises:
  • BackRequested – If the user enters "b" or "back" and allow_back is True.

  • SystemExit – If the user enters "q" or "exit" and allow_exit is True. This is the normal way to terminate the top-level CLI loop.

Notes

  • All comparisons for navigation/exit/comment detection are done on the raw line before it is returned to the caller.

  • The function loops until it encounters a line that is not treated as a comment or navigation/exit command, so callers always receive a meaningful payload string.

gammapbh.cli.view_previous_spectra() None[source]
View previously saved spectra with a queue:
  • Selecting items adds them to the queue only.

  • Press ‘0’ to plot ALL queued items: spectra first (dN/dE, E^2 dN/dE), then histograms.

  • Queue auto-clears after plotting.

gammapbh.cli.warn(msg: str) None[source]

Print a warning (yellow) line.