Command-line calculator
Magνs installs a magnus command (also run as python -m magnus) that
computes a single oscillation probability from the shell, without writing
Python. It picks one of the osc_prob_{2,3,4,5}nu_* functions from
--flavors, --environment and --scenario, and calls it with the flags
you give. Its one subcommand, prob, is the default and may be omitted, so
magnus --flavors 3 ... and magnus prob --flavors 3 ... are the same call;
magnus --help lists every flag.
Note
The CLI computes one probability at a time, at a single energy and baseline. For scans, plots or fits, use the Python API, which runs the same code and computes a scan in one batched call (Performance).
Installation
pip install magnuspy installs the magnus command along with the package.
From a checkout, pip install -e . does the same, and python -m magnus
works 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] ...
Unlike the Python API, the command line takes physical units: --energy in
GeV, --baseline in km and --rho in g cm-3 by default, changed with
--energy-unit, --baseline-unit and --density-unit. The NSI couplings
are real on the command line; complex ones need the Python API.
--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 (see Errors are explicit rather than silent). 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 --flavors 3 --environment vacuum \
--energy 1 --energy-unit GeV --baseline 1300 --baseline-unit km
Magνs 1.2.0 -- 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 --flavors 3 --environment vacuum --energy 1 --energy-unit GeV \
--baseline 1300 --baseline-unit km --nu-i e --nu-f mu
Magνs 1.2.0 -- 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 --flavors 3 --environment earth --energy 1 --energy-unit GeV \
--costhz -0.8 --baseline 10193.6 --baseline-unit km
Magνs 1.2.0 -- osc_prob_3nu_earth
E = 1 GeV, L = 10193.6 km
nu_e nu_mu nu_tau
nu_e 0.9093 0.0900 0.0007
nu_mu 0.0666 0.6870 0.2465
nu_tau 0.0241 0.2230 0.7529
The baseline, 10 193.6 km, is the length of the chord at
\(\cos\theta_z = -0.8\), which magnus.earth.distance_traveled_inside_earth
gives in Python. That command also writes MagnusConvergenceWarning once to
standard error:
some slabs of this chord are wider than the sufficient convergence condition
allows. The warning flags a slab width, not an inaccurate result; Accuracy and diagnostics
gives its measured false-alarm rate and says what to do about it.
The Sun, from the center to the surface (\(R_\odot\) = 695 700 km), 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 --flavors 3 --environment sun --density-profile B16-GS98 \
--energy 10 --energy-unit MeV --baseline 695700 --baseline-unit km
Magνs 1.2.0 -- osc_prob_3nu_sun
E = 10 MeV, L = 695700 km, B16-GS98 solar model
nu_e nu_mu nu_tau
nu_e 0.2954 0.4392 0.2653
nu_mu 0.4349 0.5058 0.0592
nu_tau 0.2696 0.0549 0.6755
This is the instantaneous probability at one energy and distance, which oscillates
rapidly. A solar experiment measures the phase-averaged one, which needs the Python
API (average=True; Phase-averaged probabilities).
--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 --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.2.0 -- osc_prob_3nu_matter_nsi_constant_density
E = 1 GeV, L = 1000 km
nu_e nu_mu nu_tau
nu_e 0.9894 0.0096 0.0010
nu_mu 0.0097 0.9903 0.0001
nu_tau 0.0009 0.0001 0.9989
Vacuum with a (deliberately large, for illustration) Lorentz-invariance-violating term, to compare with the plain-vacuum result above at the same energy and baseline:
$ magnus --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.2.0 -- 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
Five flavors (3+2 sterile) with LIV through the Earth, as machine-readable JSON:
$ magnus --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 and the sterile LIV angles
sxi14 to sxi35 at zero (their defaults), the two sterile states stay
decoupled from the three active flavors and from each other. One of the CLI’s
regression tests (tests/test_cli.py, in a source checkout) checks this.
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. It works 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. Vacuum and constant-density environments do not
depend on position, so a non-default --strategy is rejected there.
Under auto, a smooth profile whose estimated accumulated phase is at most
1e4 rad, at a tolerance of 1e-6 or looser, goes to the Magnus ladder. Any other
request tries the hybrid strategy first and falls back to the Magnus engines if the hybrid
strategy cannot certify its result (Dispatch has the full table). You need
this flag only to keep to the Magnus engines (--strategy magnus) or to force the hybrid
strategy and be warned when it cannot certify its own result (--strategy hybrid).
--strategy magnus is rarely what you want. It resolves the oscillation phase slab by
slab. A low-energy solar neutrino accumulates a very large phase, so this route reaches a
refinement cap and issues 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
A missing required flag or an invalid flag combination produces a clear message and a non-zero exit code instead of a wrong answer or a raw traceback:
$ magnus --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 --flavors 2 --environment vacuum --energy 1 --baseline 1300
usage: magnus [-h] [-V] {prob} ...
magnus: error: --sth and --dm2 are both required for --flavors 2.
At two flavors, the table’s rows and columns are labeled 0 and 1 rather than by
flavor: a two-flavor system stands for whichever pair --sth and --dm2 describe, and
--nu-i/--nu-f take 0 or 1 accordingly.
Full flag reference
The complete magnus prob --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 --scenario std,
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.
For earth, give it with --costhz, or omit it when --detector-
depth or --source-depth is given (the baseline is then computed)
or when --loc-ini and --loc-fin are given. Must be omitted with
--detector-depth.
--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. It sets
the neutral-current potential of the sterile states, so it has
no effect at 2 or 3 flavors. Default: 1.0.
--electron-fraction ELECTRON_FRACTION
Y_e, the number of electrons per atomic mass unit of the matter,
so that n_e = rho N_A Y_e. 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) takes sines, 'sin2' squared sines
(the form global fits report), 'rad' radians and 'deg' 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 [eV^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 [eV^2]. Default: NuFIT 6.1.
--dm31 D31 Mass-squared difference Delta m^2_31 [eV^2]. 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, mass ordering (..._NO
or ..._IO) and, from release 4.0 on, inclusion (..._SK_) or
exclusion (..._NOSK_) of Super-Kamiokande atmospheric data.
OSC_PARAMS_DEFAULT is NuFIT 6.1 SK NO. The full list is
globaldefs.OSC_PARAMS_PREDEFINED; an unknown name prints it.
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 [eV^2]. 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 [eV^2]. 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 (3/4/5nu) LIV CP-violation phase of the 1-3 rotation [radian, or
degree with --angles deg].
--dxi13 DXI13 (4/5nu) Deprecated alias of --dxicp; issues a FutureWarning.
--sxi14 SXI14 (4/5nu) LIV mixing angle xi_14, per --angles.
--dxi14 DXI14 (4/5nu) LIV CP-violation phase of the 1-4 rotation [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 of the 2-4 rotation [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 of the 1-5 rotation [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 of the 3-5 rotation [radian, or
degree with --angles deg].
--b1 B1 LIV eigenvalue b1 [eV].
--b2 B2 LIV eigenvalue b2 [eV].
--b3 B3 LIV eigenvalue b3 [eV].
--b4 B4 LIV eigenvalue b4 [eV].
--b5 B5 LIV eigenvalue b5 [eV].
--liv-lambda LAMBDA LIV energy scale Lambda [eV]. 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; an even order from
2 to 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'
instead sample a uniform grid of points in each slab, starting
from 100 points per slab (the library default, which the CLI
cannot change). At a declared breakpoint, they sample each side
of a jump separately. 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 engines. 'hybrid' also tries adiabatic
transport with a Magnus patch at each non-adiabatic window and
warns if it cannot certify the result. 'auto' sends a smooth
profile whose estimated accumulated phase is at most 1e4 rad (at
a tolerance of 1e-6 or looser) to the Magnus ladder. Otherwise,
it tries hybrid and falls back to the Magnus engines without a
warning, except for an undeclared density jump. Vacuum and
constant-density environments accept only 'auto'. 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 does not reimplement any physics: it calls the matching
osc_prob_{N}nu_* wrapper with the flags you passed (see magnus.cli.main()).