tsamps
v0.1.0
Published
Pure TypeScript port of pyAMPS — the Average Magnetic field and Polar current System (AMPS) empirical model of high-latitude ionospheric electrodynamics
Maintainers
Readme
tsAMPS
Pure TypeScript port of pyAMPS — the Average Magnetic field and Polar current System (AMPS), an empirical spherical-harmonic model of high-latitude ionospheric electrodynamics fit to Swarm and CHAMP magnetometer data (Laundal et al., 2018).
Given solar-wind / IMF / dipole-tilt / F10.7 drivers, AMPS produces — over the polar caps — field-aligned (Birkeland) currents, horizontal currents, equivalent current functions, and ground/space magnetic perturbations. Because it is empirical (no field-line tracing or PDE solve at evaluation time), per-frame evaluation is fast enough for live manipulation of input parameters.
tsAMPS is framework-pure: it exports the model math only. The Timeline Viewer
ModelPlugin wrapping lives in the viewer, not here.
Status: v0.1.0 (pre-release). All pyAMPS runtime products are ported and validated against pyAMPS — scalar fields (toroidal/poloidal scalars, current functions and potentials, FAC), the horizontal current vectors, the QD ground-perturbation field, and the AE indices — together with the precomputed {@link GridEvaluator} live-slider fast path. The optional
tsamps/geoadapter adds the geodetic-frame products: space magnetic perturbations (getBSpace) and apex-frame horizontal currents (getJHoriz), validated against pyAMPS to ~0.1 nT / mA/m (the residual is the apexcoords-vs-apexpy coordinate difference). Only the matplotlib plotting layer is intentionally omitted. See Status below.
Install
npm install tsampsThe core tsamps entry has no runtime dependencies — it is a QD-only model
(QD-latitude + magnetic-local-time in, magnetic-frame values out). Only the
optional tsamps/geo adapter needs
apexcoords ^1.1 (declared as an
optional peer dependency); install it alongside tsamps if you use the geodetic
products:
npm install tsamps apexcoordsUsage
import { loadCoefficients, AMPSModel, compute } from 'tsamps';
const coeffs = await loadCoefficients();
// One-shot point evaluation:
const { upwardCurrent, toroidalScalar } = compute(
coeffs,
{ v: 350, by: 10, bz: -4, tilt: 20, f107: 80 }, // drivers
[70, 75, 80], // magnetic latitude, deg
[6, 9, 12], // magnetic local time, h
);
// Live manipulation (sliders): build once, then updateInputs per tick.
const model = new AMPSModel(coeffs, { v: 350, by: 10, bz: -4, tilt: 20, f107: 80 });
model.updateInputs({ v: 600, by: -8, bz: -10, tilt: 20, f107: 120 });
const fac = model.getUpwardCurrent([70, 75, 80], [6, 9, 12]); // microA/m^2In the browser, pass a fetch-able URL to loadCoefficients(url) or supply the
parsed table directly to new AMPSModel(table, inputs).
Geodetic products (tsamps/geo)
For space magnetic-field perturbations in the geodetic frame (e.g. to compare
against Swarm/CHAMP), use the optional adapter with an apexcoords converter
built at the model epoch (pyAMPS defaults: epoch 2015, reference height 110 km):
import { loadCoefficients } from 'tsamps';
import { getBSpace } from 'tsamps/geo';
import { createApex } from 'apexcoords';
const coeffs = await loadCoefficients();
const apex = await createApex({ epoch: 2015, refh: 110, coeffUrl: '/apex_coeffs_1980_2030.bin' });
const { be, bn, bu } = getBSpace(
apex,
coeffs,
{ glat: [70, 75], glon: [0, 45], height: 350 }, // geodetic, km
new Date('2020-06-21T12:00:00Z'),
{ v: 350, by: 10, bz: -4, tilt: 20, f107: 80 },
); // nT, geodetic east / north / upThe Timeline Viewer does not use this adapter — it consumes the QD-only core directly and handles coordinate conversion (and QD→geodetic vector rotation) with its own apexcoords integration, keeping a single coordinate source of truth.
Status
| Product | pyAMPS source | tsAMPS |
| --- | --- | --- |
| legendre (Schmidt-normalized ALF) | sh_utils.legendre | ✅ ported, validated |
| 19-parameter Newell expansion | model_utils.get_model_vectors | ✅ ported, validated |
| Toroidal scalar | AMPS.get_toroidal_scalar | ✅ ported, validated |
| Upward (Birkeland) current — FAC | AMPS.get_upward_current | ✅ ported, validated |
| Curl-free current potential | AMPS.get_curl_free_current_potential | ✅ ported, validated |
| Poloidal scalar | AMPS.get_poloidal_scalar | ✅ ported, validated |
| Divergence-free current function (equivalent current) | AMPS.get_divergence_free_current_function | ✅ ported, validated |
| Horizontal currents (curl-free / div-free / total) | AMPS.get_*_current | ✅ ported, validated |
| Ground perturbation (QD east/north) | AMPS.get_ground_perturbation | ✅ ported, validated |
| AE indices (AL/AU) | AMPS.get_AE_indices | ✅ ported, validated |
| Precomputed grid evaluator (computeGrid, scalar products) | AMPS.calculate_matrices | ✅ ported (GridEvaluator) |
| Space magnetic perturbation, geodetic Be/Bn/Bu (tsamps/geo) | get_B_space | ✅ ported, validated (~0.1 nT) |
| Horizontal current, apex-frame Je/Jn (tsamps/geo) | get_J_horiz | ✅ ported, validated (~0.1 mA/m) |
Development
npm run build # tsc -> dist/
npm test # vitest, validated against pyAMPS fixtures
npm run convert-coeffs # rebuild data/ asset from a pyAMPS coefficient .txt
npm run gen-fixtures # regenerate test/fixtures/ from a working pyAMPS installThe coefficient table (data/amps_coeffs_0105.json) is built from the official
Swarm L2 product SW_OPER_MIO_SHA_2E_..._0105.txt shipped in pyAMPS, pinned to
MODEL_COEFF_LATEST, by scripts/convert_coeffs.py. Test fixtures are
ground-truth values emitted from pyAMPS itself by scripts/gen_reference.py, so
the port is validated independently of any downstream application.
References & attribution
tsAMPS is a port of pyAMPS (MIT, © 2017 Karl M. Laundal). The AMPS model:
Laundal, K. M., Finlay, C. C., Olsen, N., & Reistad, J. P. (2018). Solar wind and seasonal influence on ionospheric currents from Swarm and CHAMP measurements. Journal of Geophysical Research: Space Physics, 123, 4402–4429. https://doi.org/10.1029/2018JA025387
MIT licensed. See LICENSE.
