## 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](https://darts.isas.jaxa.jp/datasets/darts:maxi-rbm-timeseries/).

---

### 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

```python
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

```python
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

```python
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

```python
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:

- Matsuoka, M. et al. (2009), PASJ, 61, 999. [doi:10.1093/pasj/61.5.999](https://doi.org/10.1093/pasj/61.5.999)
