Command-Line Calculator
In addition to the Python API (Quick Start Guide), Magνs installs a
magnus command (equivalently, python -m magnus) for computing a
single oscillation probability directly from the shell, with no Python
required. It wraps the same osc_prob_{2,3,4,5}nu_* functions used by
the Python API: magnus prob picks the right one from
--flavors/--environment/--scenario and calls it with the flags
you give (see Code Architecture for how those functions themselves are
organized).
Note
The CLI computes one probability at a time (a single energy and baseline). For scans, plots, or fitting, use the Python API – it is the same underlying code, just called in a loop or with array arguments (which Magνs evaluates in a single batched, vectorized pass; see Methodology).
Installation
git clone https://github.com/mbustama/Magnus.git
cd Magnus
pip install -e .
This installs the magnus console script. If you would rather not
install the package, python -m magnus works identically from the
repository root once src/ is on PYTHONPATH.
magnus --version (or -V) prints the installed version and exits;
it reports the same number as magnus.__version__, which is read
from the version field of pyproject.toml.
Usage pattern
magnus prob --flavors {2,3,4,5} --environment {vacuum,matter,earth,sun}
--scenario {std,nsi,liv} [environment- and scenario-specific flags]
--energy ENERGY [--energy-unit UNIT] [--baseline BASELINE] ...
--environment selects the propagation medium; --scenario selects
the physics on top of it. Not every combination exists: --scenario nsi
requires a matter potential to modify, so it is not available with
--environment vacuum (the CLI rejects this combination with a clear
error rather than silently ignoring the epsilon flags). The full dispatch
table:
|
|
|
Function called (per |
|---|---|---|---|
vacuum |
std |
– |
|
vacuum |
liv |
– |
|
matter |
std |
constant / exp |
|
matter |
nsi |
constant / exp |
|
matter |
liv |
constant / exp |
|
earth |
std / nsi / liv |
– |
|
sun |
std / nsi / liv |
exp / a solar model |
|
Examples
Three-flavor vacuum oscillation, full probability matrix (output captured from this version):
$ magnus prob --flavors 3 --environment vacuum \
--energy 1 --energy-unit GeV --baseline 1300 --baseline-unit km
Magνs 1.1.1 -- osc_prob_3nu_vacuum
E = 1 GeV, L = 1300 km
nu_e nu_mu nu_tau
nu_e 0.9289 0.0085 0.0625
nu_mu 0.0313 0.3923 0.5764
nu_tau 0.0398 0.5992 0.3611
The same calculation, one channel only:
$ magnus prob --flavors 3 --environment vacuum --energy 1 --energy-unit GeV \
--baseline 1300 --baseline-unit km --nu-i e --nu-f mu
Magνs 1.1.1 -- osc_prob_3nu_vacuum
E = 1 GeV, L = 1300 km
P = 0.0085
Earth crossing from the cosine of the zenith angle (equivalently, from two
named locations – see --loc-ini/--loc-fin below):
$ magnus prob --flavors 3 --environment earth --energy 1 --energy-unit GeV \
--costhz -0.8 --baseline 10193.6 --baseline-unit km
Magνs 1.1.1 -- osc_prob_3nu_earth
E = 1 GeV, L = 10193.6 km
nu_e nu_mu nu_tau
nu_e 0.9129 0.0861 0.0010
nu_mu 0.0638 0.6912 0.2449
nu_tau 0.0233 0.2227 0.7540
That command also writes MagnusConvergenceWarning twice to standard error:
some slabs of this chord are wider than the sufficient condition for the series
to converge. It reports a slab width rather than an error; Accuracy and diagnostics
gives its measured false-alarm rate and says what to do about it.
The Sun, through a tabulated standard solar model rather than the exponential
fit (Standard solar models lists the twelve, and --density-profile takes
their names in any case):
$ magnus prob --flavors 3 --environment sun --density-profile B16-GS98 \
--energy 10 --energy-unit MeV --baseline 300000 --baseline-unit km
Magνs 1.1.1 -- osc_prob_3nu_sun
E = 10 MeV, L = 300000 km, B16-GS98 solar model
nu_e nu_mu nu_tau
nu_e 0.5739 0.1825 0.2436
nu_mu 0.1588 0.6341 0.2071
nu_tau 0.2673 0.1834 0.5493
--stop-at-table-edge returns nan, with a warning, for a baseline that
ends past the model’s last tabulated radius, instead of continuing the profile
beyond it.
Constant-density matter with non-standard interactions:
$ magnus prob --flavors 3 --environment matter --scenario nsi --rho 2.7 \
--eps-ee 0.06 --eps-em -0.06 \
--energy 1 --energy-unit GeV --baseline 1000 --baseline-unit km
Magνs 1.1.1 -- osc_prob_3nu_matter_nsi_constant_density
E = 1 GeV, L = 1000 km
nu_e nu_mu nu_tau
nu_e 0.9895 0.0095 0.0010
nu_mu 0.0096 0.9903 0.0001
nu_tau 0.0009 0.0002 0.9989
Vacuum with a (deliberately large, for illustration) Lorentz-invariance-violating term – compare to the plain-vacuum result above at the same energy and baseline:
$ magnus prob --flavors 3 --environment vacuum --scenario liv \
--sxi12 0.3 --b1 6e-13 --b2 1.2e-12 --liv-lambda 1e9 --n-liv 1 \
--energy 1 --energy-unit GeV --baseline 1300 --baseline-unit km
Magνs 1.1.1 -- osc_prob_3nu_vacuum_liv
E = 1 GeV, L = 1300 km
nu_e nu_mu nu_tau
nu_e 0.4956 0.0510 0.4535
nu_mu 0.1349 0.7013 0.1639
nu_tau 0.3696 0.2477 0.3827
A 3+2 sterile scenario (5 flavors), machine-readable output:
$ magnus prob --flavors 5 --environment earth --scenario liv \
--costhz -0.8 --baseline 10193.6 --sxi12 0.2 --b1 1e-13 --liv-lambda 1e9 \
--energy 1 --energy-unit GeV --json
{
"function": "osc_prob_5nu_earth_liv",
"flavors": 5,
"environment": "earth",
"scenario": "liv",
"nubar": false,
"energy_eV": 1000000000.0,
"baseline_eV-1": ...,
"probability": [[...], [...], [...], [...], [...]]
}
With s14 = s15 = s24 = s25 = s34 = s35 = 0 (their defaults), the two
sterile states stay perfectly decoupled from the three active flavors and
from each other, as expected – this exact check is one of the CLI’s
regression tests (tests/test_cli.py).
Choosing a propagation strategy
For a position-dependent Hamiltonian – --environment sun,
--environment earth, or --environment matter --density-profile exp –
--strategy selects how the evolution operator is propagated, exactly as the
strategy keyword does in the Python API (see Adiabatic + Magnus Hybrid Strategy for
the full description of the three values). It defaults to auto and is
ignored for vacuum and constant-density environments, whose Hamiltonians do not
depend on position at all.
Since auto is the default, you need this flag only to opt out of the
hybrid strategy (--strategy magnus, which reproduces the behavior of
releases before the adiabatic strategy existed) or to force it and be warned
when it cannot certify its own result (--strategy hybrid).
Opting out is rarely what you want. magnus resolves the oscillation phase
slab by slab, and a low-energy solar neutrino accumulates an extreme amount of
it, so that is the route that runs into a refinement cap and raises
ToleranceNotAchievedWarning. Notebook 12
times all three against solve_ivp from two to five flavors, with and
without NSI, printing the error beside each time.
Errors are explicit rather than silent
Missing a required flag, or an invalid combination, produces a clear message and a non-zero exit code instead of a wrong answer or a raw traceback:
$ magnus prob --flavors 3 --environment vacuum --scenario nsi --energy 1 --baseline 1300
magnus prob: --scenario nsi is not available with --environment vacuum (NSI couplings
scale the matter potential, which vacuum has none of); use --environment matter/earth/sun
instead.
$ magnus prob --flavors 2 --environment vacuum --energy 1 --baseline 1300
usage: magnus [-h] [-V] {prob} ...
magnus: error: --sth and --dm2 are both required for --flavors 2.
Full flag reference
The complete, current --help output (every flag is grouped by what it
configures):
usage: magnus prob [-h] [--flavors {2,3,4,5}] [--environment {vacuum,matter,earth,sun}]
[--scenario {std,nsi,liv}] [--density-profile PROFILE] [--nubar]
--energy ENERGY [--energy-unit {eV,keV,MeV,GeV,TeV,PeV}]
[--baseline BASELINE] [--l0 L0] [--baseline-unit {eV-1,km,cm}]
[--rho RHO] [--rho-central RHO_CENTRAL] [--l-scale L_SCALE]
[--density-unit {g/cm3,natural}] [--ratio-n-to-p RATIO_N_TO_P]
[--electron-fraction ELECTRON_FRACTION] [--costhz COSTHZ]
[--loc-ini LOC_INI] [--loc-fin LOC_FIN]
[--detector-depth DETECTOR_DEPTH] [--source-depth SOURCE_DEPTH]
[--stop-at-table-edge] [--angles {sin,sin2,rad,deg}] [--sth STH]
[--dm2 DM2] [--s12 S12] [--s23 S23] [--s13 S13] [--dcp DCP]
[--dm21 D21] [--dm31 D31] [--osc-params-set NAME] [--s14 S14]
[--d14 D14] [--s24 S24] [--d24 D24] [--s34 S34] [--dm41 D41]
[--s15 S15] [--d15 D15] [--s25 S25] [--s35 S35] [--d35 D35]
[--dm51 D51] [--eps-aa EPS_AA] [--eps-ab EPS_AB] [--eps-ee EPS_EE]
[--eps-em EPS_EM] [--eps-et EPS_ET] [--eps-mm EPS_MM]
[--eps-mt EPS_MT] [--eps-tt EPS_TT] [--eps-es EPS_ES]
[--eps-ms EPS_MS] [--eps-ts EPS_TS] [--eps-ss EPS_SS]
[--eps-es1 EPS_ES1] [--eps-es2 EPS_ES2] [--eps-ms1 EPS_MS1]
[--eps-ms2 EPS_MS2] [--eps-ts1 EPS_TS1] [--eps-ts2 EPS_TS2]
[--eps-s1s1 EPS_S1S1] [--eps-s1s2 EPS_S1S2] [--eps-s2s2 EPS_S2S2]
[--sxi SXI] [--sxi12 SXI12] [--sxi23 SXI23] [--sxi13 SXI13]
[--dxicp DXICP] [--dxi13 DXI13] [--sxi14 SXI14] [--dxi14 DXI14]
[--sxi24 SXI24] [--dxi24 DXI24] [--sxi34 SXI34] [--sxi15 SXI15]
[--dxi15 DXI15] [--sxi25 SXI25] [--sxi35 SXI35] [--dxi35 DXI35]
[--b1 B1] [--b2 B2] [--b3 B3] [--b4 B4] [--b5 B5]
[--liv-lambda LAMBDA] [--n-liv N_LIV] [--nu-i NU_I] [--nu-f NU_F]
[--magnus-exp-order MAGNUS_EXP_ORDER]
[--integration-method {gl,trapezoid,simpson}] [--rtol RTOL]
[--atol ATOL] [--n-jobs N_JOBS] [--strategy {auto,hybrid,magnus}]
[--verbose {0,1,2}] [--json] [--precision PRECISION]
options:
-h, --help show this help message and exit
Environment:
--flavors {2,3,4,5} Number of neutrino flavors (default: 3).
--environment {vacuum,matter,earth,sun}
Propagation environment (default: vacuum).
--scenario {std,nsi,liv}
Physics scenario on top of the environment: 'std' (Standard
Model), 'nsi' (non-standard interactions), or 'liv' (Lorentz-
invariance violation). 'nsi' is not available with --environment
vacuum. Default: std.
--density-profile PROFILE
Matter density profile. With --environment matter: 'constant'
(the default; requires --rho) or 'exp' (requires --rho-central
and --l-scale). With --environment sun: 'exp' (the default) or a
tabulated standard solar model, named in any case: BP2000, BP04,
BS05-OP, BS05-AGS-OP, B16-GS98, B16-AGSS09met, B23-GS98,
B23-AGSS09, B23-C11, B23-AAG21, B23-MB22m, B23-MB22p.
--nubar Compute the probability for antineutrinos instead of neutrinos.
No effect with --flavors 2 --environment vacuum, where there is
no CP phase and no matter, so the two probabilities are equal.
Energy and baseline:
--energy ENERGY Neutrino energy.
--energy-unit {eV,keV,MeV,GeV,TeV,PeV}
Unit of --energy (default: GeV).
--baseline BASELINE Baseline / final position. Required for vacuum, matter, and sun,
and for earth when using --costhz, unless --source-depth or
--detector-depth is given, which computes it. Computed
automatically for earth when both --loc-ini and --loc-fin are
given instead. --detector-depth requires it to be omitted.
--l0 L0 Initial position (used by --environment sun and --density-
profile exp). Default: 0.0.
--baseline-unit {eV-1,km,cm}
Unit of --baseline, --l0, --l-scale, --source-depth and
--detector-depth (default: km).
Matter (--environment matter):
--rho RHO Matter density (constant profile).
--rho-central RHO_CENTRAL
Matter density at the center of the profile, l=0 (exponential
profile).
--l-scale L_SCALE Length scale of the exponential density decrease (exponential
profile).
--density-unit {g/cm3,natural}
Unit of --rho/--rho-central: g/cm3 (converted internally) or
natural units (eV^4). Default: g/cm3.
--ratio-n-to-p RATIO_N_TO_P
Ratio of the number of neutrons to protons in matter. Default:
1.0.
--electron-fraction ELECTRON_FRACTION
Electron fraction of matter. Default: 0.5.
Earth (--environment earth):
--costhz COSTHZ Cosine of the neutrino zenith angle.
--loc-ini LOC_INI Initial location name (e.g. fermilab); see
magnus.earth.loc_coords_dms. Must be given together with --loc-
fin, as an alternative to --costhz.
--loc-fin LOC_FIN Final location name; see --loc-ini.
--detector-depth DETECTOR_DEPTH
Depth of the detector below the surface, in --baseline-unit. The
zenith angle is measured at the detector, so a buried one also
sees downward-going neutrinos (--costhz > 0) through its
overburden. Computes the baseline, so --baseline must be
omitted. Default: 0 (a detector on the surface).
--source-depth SOURCE_DEPTH
Depth of the neutrino's entry point below the surface, in
--baseline-unit. Default: 0 (entry at the surface).
Sun (--environment sun):
--stop-at-table-edge With a tabulated solar model, do not extrapolate past its last
row: a baseline that ends beyond it returns nan, with a warning.
Without it, the density continues the last row's logarithmic
slope. Not available with 'exp', which has no table.
Standard oscillation parameters (2-flavor):
--angles {sin,sin2,rad,deg}
Convention for every mixing angle below (--sth, --s12..,
--sxi..): sin (default) their sines, sin2 their sines squared --
the form global fits report -- rad the angles in radians, deg in
degrees. Under deg the CP phases (--dcp, --d14, ...) are read as
degrees too; otherwise they stay in radians.
--sth STH Mixing angle theta, in the convention set by --angles (required
for --flavors 2).
--dm2 DM2 Mass-squared difference Delta m^2 (required for --flavors 2).
Standard oscillation parameters (3+ flavors):
--s12 S12 Mixing angle theta_12, per --angles. Default: NuFIT 6.1.
--s23 S23 Mixing angle theta_23, per --angles. Default: NuFIT 6.1.
--s13 S13 Mixing angle theta_13, per --angles. Default: NuFIT 6.1.
--dcp DCP delta_CP [radian, or degree with --angles deg]. Default: NuFIT
6.1.
--dm21 D21 Mass-squared difference Delta m^2_21. Default: NuFIT 6.1.
--dm31 D31 Mass-squared difference Delta m^2_31. Default: NuFIT 6.1.
--osc-params-set NAME
Predefined set used to fill in any of s12/s23/s13/dCP/D21/D31
left unspecified: one per NuFIT release, in normal ordering
(..._NO) or inverted (..._IO), and for releases from 4.0 on with
(..._SK_) or without (..._NOSK_) Super-Kamiokande atmospheric
data. OSC_PARAMS_DEFAULT is NuFIT 6.1 SK NO. Pass an unknown
name to see the full list. Taken from
globaldefs.OSC_PARAMS_PREDEFINED rather than listed here,
because a hand-written list went stale: it offered only the 6.0
sets, so asking for inverted ordering silently dropped a release
behind the default.
Additional sterile mixing (4+ flavors):
--s14 S14 Mixing angle theta_14, per --angles. Default: 0.0.
--d14 D14 delta_14 [radian, or degree with --angles deg]. Default: 0.0.
--s24 S24 Mixing angle theta_24, per --angles. Default: 0.0.
--d24 D24 delta_24 [radian, or degree with --angles deg]. Default: 0.0.
--s34 S34 Mixing angle theta_34, per --angles. Default: 0.0.
--dm41 D41 Mass-squared difference Delta m^2_41. Default: 0.0.
Additional sterile mixing (5 flavors):
--s15 S15 Mixing angle theta_15, per --angles. Default: 0.0.
--d15 D15 delta_15 [radian, or degree with --angles deg]. Default: 0.0.
--s25 S25 Mixing angle theta_25, per --angles. Default: 0.0.
--s35 S35 Mixing angle theta_35, per --angles. Default: 0.0.
--d35 D35 delta_35 [radian, or degree with --angles deg]. Default: 0.0.
--dm51 D51 Mass-squared difference Delta m^2_51. Default: 0.0.
NSI parameters (--scenario nsi):
--eps-aa EPS_AA 2-flavor diagonal NSI coupling.
--eps-ab EPS_AB 2-flavor off-diagonal NSI coupling.
--eps-ee EPS_EE Diagonal NSI coupling of nu_e.
--eps-em EPS_EM Off-diagonal (e-mu) NSI coupling.
--eps-et EPS_ET Off-diagonal (e-tau) NSI coupling.
--eps-mm EPS_MM Diagonal NSI coupling of nu_mu.
--eps-mt EPS_MT Off-diagonal (mu-tau) NSI coupling.
--eps-tt EPS_TT Diagonal NSI coupling of nu_tau.
--eps-es EPS_ES (4nu) Off-diagonal (e-s) NSI coupling.
--eps-ms EPS_MS (4nu) Off-diagonal (mu-s) NSI coupling.
--eps-ts EPS_TS (4nu) Off-diagonal (tau-s) NSI coupling.
--eps-ss EPS_SS (4nu) Diagonal NSI coupling of nu_s.
--eps-es1 EPS_ES1 (5nu) Off-diagonal (e-s1) NSI coupling.
--eps-es2 EPS_ES2 (5nu) Off-diagonal (e-s2) NSI coupling.
--eps-ms1 EPS_MS1 (5nu) Off-diagonal (mu-s1) NSI coupling.
--eps-ms2 EPS_MS2 (5nu) Off-diagonal (mu-s2) NSI coupling.
--eps-ts1 EPS_TS1 (5nu) Off-diagonal (tau-s1) NSI coupling.
--eps-ts2 EPS_TS2 (5nu) Off-diagonal (tau-s2) NSI coupling.
--eps-s1s1 EPS_S1S1 (5nu) Diagonal NSI coupling of nu_s1.
--eps-s1s2 EPS_S1S2 (5nu) Off-diagonal (s1-s2) NSI coupling.
--eps-s2s2 EPS_S2S2 (5nu) Diagonal NSI coupling of nu_s2.
LIV parameters (--scenario liv):
--sxi SXI 2-flavor LIV mixing angle xi, per --angles.
--sxi12 SXI12 LIV mixing angle xi_12, per --angles.
--sxi23 SXI23 LIV mixing angle xi_23, per --angles.
--sxi13 SXI13 LIV mixing angle xi_13, per --angles.
--dxicp DXICP (3nu) LIV CP-violation phase [radian, or degree with --angles
deg].
--dxi13 DXI13 (4/5nu) LIV CP-violation phase [radian, or degree with --angles
deg] (replaces --dxicp).
--sxi14 SXI14 (4/5nu) LIV mixing angle xi_14, per --angles.
--dxi14 DXI14 (4/5nu) LIV CP-violation phase [radian, or degree with --angles
deg].
--sxi24 SXI24 (4/5nu) LIV mixing angle xi_24, per --angles.
--dxi24 DXI24 (4/5nu) LIV CP-violation phase [radian, or degree with --angles
deg].
--sxi34 SXI34 (4/5nu) LIV mixing angle xi_34, per --angles.
--sxi15 SXI15 (5nu) LIV mixing angle xi_15, per --angles.
--dxi15 DXI15 (5nu) LIV CP-violation phase [radian, or degree with --angles
deg].
--sxi25 SXI25 (5nu) LIV mixing angle xi_25, per --angles.
--sxi35 SXI35 (5nu) LIV mixing angle xi_35, per --angles.
--dxi35 DXI35 (5nu) LIV CP-violation phase [radian, or degree with --angles
deg].
--b1 B1 LIV eigenvalue b1.
--b2 B2 LIV eigenvalue b2.
--b3 B3 LIV eigenvalue b3.
--b4 B4 LIV eigenvalue b4.
--b5 B5 LIV eigenvalue b5.
--liv-lambda LAMBDA LIV energy scale Lambda. Default: 1.0.
--n-liv N_LIV Power of the energy dependence of the LIV operator. Default: 0.
Channel selection:
--nu-i NU_I Initial flavor (index or name: e, mu, tau, s, s1, s2). If given
with --nu-f, prints a single probability instead of the full
matrix.
--nu-f NU_F Final flavor; see --nu-i.
Advanced numerics:
--magnus-exp-order MAGNUS_EXP_ORDER
Highest order of the Magnus expansion (1-10; 1-8 with the
default --integration-method gl). Default: 4.
--integration-method {gl,trapezoid,simpson}
Quadrature method. 'gl' (Gauss-Legendre collocation) needs only
1-4 Hamiltonian evaluations per slab and matches its quadrature
order to the expansion order, so it is both the fastest and the
most accurate for a smooth Hamiltonian. 'trapezoid'/'simpson'
sample a uniform grid of 100 points per slab instead (the
library default; the CLI does not expose it), and are the safer
choice if the Hamiltonian is not smooth within a slab. Default:
gl.
--rtol RTOL Relative tolerance on the agreement between successive
refinement levels -- a stopping rule, not a guaranteed accuracy.
Default: 1e-3.
--atol ATOL Absolute tolerance on the same agreement; see --rtol. Default:
1e-3.
--n-jobs N_JOBS Number of parallel joblib workers. Default: 1.
--strategy {auto,hybrid,magnus}
How to propagate a position-dependent Hamiltonian: 'magnus' uses
only the Magnus-expansion machinery; 'hybrid' also tries
adiabatic transport with a Magnus patch at each non-adiabatic
window, warning if it cannot certify the result; 'auto' tries
hybrid and falls back to magnus silently. Ignored for vacuum and
constant-density environments. Default: auto.
--verbose {0,1,2} Verbosity level. Default: 0.
Output:
--json Print the result as JSON instead of a table.
--precision PRECISION
Decimal digits shown in the table and in the single-channel
value; ignored with --json. Default: 4.
Implementation notes
magnus prob does not reimplement any physics: it builds a keyword-argument
dictionary from the flags you passed and calls straight into the matching
osc_prob_{N}nu_* function (see magnus.cli.main() and
_wrapper_name). Physics keyword arguments that a given
function does not explicitly accept (for example, default_osc_params_set_name
is not defined on every LIV wrapper) are filtered out via
inspect.signature() before the call, rather than being silently
forwarded through **kwargs to a layer that does not expect them – see
_call.