MAXI/RBM Time Series Visualization

beginnerPythoncdflibastropymatplotlibnumpyrequestsMAXIRBMRadiation Belt Monitortime seriescharged particleelectronprotonCDF

MAXI/RBM Time Series Visualization

The Radiation Belt Monitor (RBM) counts charged particles at 1-second cadence in two perpendicular directions (horizontal: RATE_H, zenithal: RATE_Z), primarily to protect the GSC by triggering its automatic shutdown when MAXI enters high-flux regions such as the radiation belts.
It is also useful for studying relativistic electron precipitation (REP) events.
The dataset page is at DARTS.


Instrument Summary

The RBM is a PIN diode (5 mm × 5 mm, 200 μm thick) sensitive to electrons above ~150 keV and protons above ~3 MeV.
The standard operating threshold since launch is LD = 1 (50 keV), which responds to both electrons and protons.

LD Threshold Sensitive to
0 30 keV Ground testing only
1 50 keV Electrons and protons (standard)
2 200 keV Protons only (2–100 MeV)
3 1 MeV Reserved for noisy conditions

Data Files

Files are organized by year under:

https://data.darts.isas.jaxa.jp/pub/maxi/rbm/{YYYY}/

Each daily CDF file is named mx_rbm_{YYYYMMDD}.cdf and contains the following variables:

Variable Type Description
Epoch CDF_EPOCH Time (1-second cadence)
RATE_H CDF_DOUBLE Count rate, horizontal direction (cts/s)
RATE_Z CDF_DOUBLE Count rate, zenithal direction (cts/s)
Longitude CDF_DOUBLE ISS geographic longitude (deg)
Latitude CDF_DOUBLE ISS geographic latitude (deg)
Radius CDF_DOUBLE ISS distance from Earth center (km)

Visualization with Python

Requirements

pip install cdflib astropy matplotlib numpy requests

Helper functions

import re
import requests
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import cdflib
from astropy.utils.data import download_file

def list_rbm_files(year):
    url = f"https://data.darts.isas.jaxa.jp/pub/maxi/rbm/{year}/"
    resp = requests.get(url, timeout=30)
    if resp.status_code != 200:
        return []
    return [url + name for name in re.findall(r'href="(mx_rbm_\d{8}\.cdf)"', resp.text)]

def load_rbm(url):
    local = download_file(url, cache=True)
    cdf = cdflib.CDF(local)
    time = cdflib.cdfepoch.to_datetime(cdf.varget("Epoch"))
    return {
        "time":      np.array(time),
        "rate_h":    cdf.varget("RATE_H"),
        "rate_z":    cdf.varget("RATE_Z"),
        "longitude": cdf.varget("Longitude"),
        "latitude":  cdf.varget("Latitude"),
        "radius":    cdf.varget("Radius"),
    }

Example 1: Single-day time series

url = "https://data.darts.isas.jaxa.jp/pub/maxi/rbm/2015/mx_rbm_20150104.cdf"
d = load_rbm(url)

fig, axes = plt.subplots(2, 1, figsize=(12, 6), sharex=True)

axes[0].plot(d["time"], d["rate_h"], lw=0.5, color="steelblue", label="RATE_H (horizontal)")
axes[0].set_ylabel("Count rate (cts/s)")
axes[0].legend(loc="upper right")

axes[1].plot(d["time"], d["rate_z"], lw=0.5, color="tomato", label="RATE_Z (zenithal)")
axes[1].set_ylabel("Count rate (cts/s)")
axes[1].set_xlabel("Time (UTC)")
axes[1].legend(loc="upper right")

for ax in axes:
    ax.xaxis.set_major_formatter(mdates.DateFormatter("%H:%M"))

fig.suptitle("MAXI/RBM 2015-01-04")
fig.autofmt_xdate()
plt.tight_layout()
plt.savefig("maxi_rbm_20150104.png", dpi=150, bbox_inches="tight")
plt.close()

Example 2: Multi-day time series

from astropy.time import Time

t_start = Time("2015-01-01")
t_stop  = Time("2015-01-31")

keys = ["time", "rate_h", "rate_z", "longitude", "latitude"]
acc = {k: [] for k in keys}

for url in list_rbm_files(t_start.datetime.year):
    try:
        d = load_rbm(url)
        mask = (d["time"] >= t_start.datetime) & (d["time"] <= t_stop.datetime)
        for k in keys:
            acc[k].append(d[k][mask])
    except Exception:
        pass

for k in keys:
    acc[k] = np.concatenate(acc[k])

fig, ax = plt.subplots(figsize=(14, 4))
ax.plot(acc["time"], acc["rate_h"], lw=0.3, color="steelblue", label="RATE_H")
ax.plot(acc["time"], acc["rate_z"], lw=0.3, color="tomato",    label="RATE_Z")
ax.set_xlabel("Date (UTC)")
ax.set_ylabel("Count rate (cts/s)")
ax.set_title("MAXI/RBM January 2015")
ax.xaxis.set_major_formatter(mdates.DateFormatter("%m-%d"))
ax.legend()
fig.autofmt_xdate()
plt.tight_layout()
plt.savefig("maxi_rbm_2015-01.png", dpi=150, bbox_inches="tight")
plt.close()

Example 3: Geographic map of count rate

fig, ax = plt.subplots(figsize=(12, 5))
sc = ax.scatter(acc["longitude"], acc["latitude"],
                c=np.log1p(acc["rate_h"]), s=0.5, cmap="hot")
fig.colorbar(sc, ax=ax, label="log(1 + RATE_H) [cts/s]")
ax.set_xlim(0, 360)
ax.set_ylim(-90, 90)
ax.set_xlabel("Geographic Longitude (deg)")
ax.set_ylabel("Geographic Latitude (deg)")
ax.set_title("MAXI/RBM RATE_H — Geographic Distribution (2015-01)")
plt.tight_layout()
plt.savefig("maxi_rbm_2015-01_geo.png", dpi=150, bbox_inches="tight")
plt.close()

Acknowledgement

When using this data in publications, please include:

“This research has made use of MAXI data provided by RIKEN, JAXA and the MAXI team.”

and cite:

References

Related Datasets