Skip to content

Releases: mbustama/Magnus

Release list

v1.2.0

Choose a tag to compare

@mbustama mbustama released this 05 Oct 10:52
ef92d24

Magνs 1.2.0.

Magνs 1.2.0 fixes three physics errors, so some results change. It also validates inputs more strictly and adds a few features.

Results that change

  • Electron density from mass density. A density in g/cm³ is now converted with the atomic mass unit, ρ N_A Y_e, as in nuSQuIDS, GLoBES, Prob3++, NuFast, OscProb, and nuCraft. Before, it was 0.8% too low. Probabilities through the Earth's core change by up to 0.065 at 1–20 GeV (#168).
  • Lorentz violation for antineutrinos. The Lorentz-violating term now changes sign for antineutrinos when n_liv is even, including the default n_liv=0. Neutrinos, and odd n_liv, are unchanged (#162).
  • average=True. It now returns the phase average over an energy spread set by the new keyword average_spread (default 0.1). Before, it kept or dropped each interference term outright (#64).

Fixed

  • Calls from several threads no longer interfere (#153).
  • A tight tolerance on the Sun no longer gives a worse answer than the default.
  • Undeclared jumps and narrow spikes in a profile no longer end the refinement on a wrong answer.

Changed

  • Arguments are checked once per call, by one set of rules, at every entry point. Values that used to be ignored or misread now raise an error that names the argument (#160).
  • The 1-3 CP phase is dCP, and the Lorentz-violating one dxiCP, at every number of flavors. The old names d13 and dxi13 still work, with a FutureWarning (#121).
  • Every Hamiltonian builder accepts an array for its varying argument (#155).

Added

  • osc_prob_pseudo_dirac_vacuum, whose phase average stays exact even for very small splittings (#165).
  • Oscillograms with non-standard interactions and Lorentz violation (#146), and nubar= on the probability plots (#145).
  • On the command line, prob is optional (#138).

Install or upgrade with pip install -U magnuspy. The full list of changes is in the changelog.

v1.0.0

Choose a tag to compare

@mbustama mbustama released this 13 Aug 09:27
f49eeff

The first public release of Magνs — a Python package for neutrino oscillation probabilities between an arbitrary number of flavors, for any Hamiltonian, time-dependent or not.

It works by the Magnus expansion: instead of integrating the Schrödinger equation step by step, it exponentiates truncated time-ordered integrals of the Hamiltonian over a chain of position slabs. Any truncation of the series lives in the Lie algebra, so the evolution operator is exactly unitary by construction — probabilities are non-negative and sum to one at machine precision, at every accuracy setting.

Install

pip install magnuspy

Python 3.10 or newer. The distribution is magnuspy; the import package is magnus.

import magnus.oscprob as oscprob
import magnus.globaldefs as gd

# Three-flavor vacuum probability at 1 GeV over 1000 km
P = oscprob.osc_prob_3nu_vacuum(1.0*gd.UNIT_GEV, 1000.0*gd.UNIT_KM)
print(P[gd.NUMU][gd.NUE])

Oscillation parameters left unset default to the current global fit, so that call is complete as it stands.

What it computes

  • Two to five flavors, in vacuum and in matter, with a dedicated named function for every combination of flavor count, environment and scenario.
  • Environments: constant density, exponential profiles, the Earth through PREM, the Sun, a tabulated model from disk, or any density profile or Hamiltonian you supply.
  • Beyond the Standard Model: non-standard interactions, Lorentz-invariance violation, sterile states (3+1 and 3+2).
  • Phase-averaged probabilities — the quantity a solar experiment actually measures — evaluated in closed form and returned directly, rather than estimated by averaging a scan over a window.
  • An accuracy, not a slab count: ask for rtol and the refinement ladder finds the resolution.
  • An adiabatic + Magnus hybrid for trajectories carrying extreme accumulated phase.
  • A command-line calculator — magnus prob ... — for one probability without writing Python.

Why you might trust it

  • 1207 tests, run on Python 3.10 through 3.13, at 93% coverage, including a clean-room install of the built wheel.
  • Unitarity is structural, not checked afterwards — a property of the truncation, at any order.
  • Measured against other codes rather than asserted: a documented comparison against NuOscProbExact and nuSQuIDS, every case refereed by a third method, with the boundary stated plainly — where a closed form exists and the accumulated phase is large, use the closed form.
  • 27 example notebooks, executed in CI so their numbers cannot drift from the code.
  • Constants are documented where they live, each with the measurement that set it.

A known limitation, stated rather than hidden

On an Earth chord with a sterile state, the matter potential's density is resolved per PREM layer, while the sterile states' entry in the projector takes a single scalar for the whole chord — no single value is right for a chord crossing iron and rock. The Earth entry points warn when the two disagree by more than 2%, naming the path-averaged ratio to pass. No number changes unless you act on the warning. The position-dependent fix is tracked as #47.

If you have been running this from a git checkout

Everything above is new to PyPI, but the repository has been usable for a while. Four changes move numbers, so results produced from an earlier checkout should be re-run:

Two wrong-answer bugs, both in published entry points:

  • Sterile states felt no matter at all on the NSI route. osc_prob_matter_nsi built the standard part of its matter Hamiltonian as a literal diag(1, 0, 0, 0), so sterile states carried zero where they carry −V_NC = (r/2)V_CC. With every coupling set to zero the route must reproduce the standard one, and did not: 5.2e-02 at four flavors, 5.1e-02 at five. Three flavors agreed throughout, which is why nothing caught it.
  • The solar LIV routes read the Sun's electron number density as a mass density, forwarding a flag that defaulted to False. Off by up to 0.69 in probability.

Two deliberate defaults that change results:

  • The Earth's electron fraction is now resolved per PREM layer — iron core 0.4656, peridotite mantle 0.4957, granitic crust 0.4952, seawater ocean 0.5551 — with the neutron-to-proton ratio derived from it. Up to a factor of four on core-crossing chords. Pass electron_fraction=0.5 to reproduce the old uniform composition.
  • The default oscillation parameters are NuFIT 6.1, derived from load_nufit_params() so the implicit values cannot drift from the loader again. 4.0e-03 in probability.

The changelog carries the full list, with the measurement behind each entry.

Links

GPL-3.0-only. Mauricio Bustamante (mbustamante@gmail.com).