headless / tests /download_wave_data.py
logos42's picture
Upload folder using huggingface_hub
216004d verified
Raw History Blame Contribute Delete
3.98 kB
#!/usr/bin/env python3
"""LM4 电磁波持续学习 — NASA CDAWeb (Van Allen Probes RBSP-A) 数据下载
数据源 (HAPI 2.0):
- RBSP-A_DENSITY_EMFISIS-L4 : 等离子体密度 + 磁场 + 特征频率 (6秒)
- RBSP-A_MAGNETOMETER_1SEC-GEI_EMFISIS-L3 : 三分量磁场 (1秒)
输出: 每个月一个 .npz, 含对齐后的 时间/密度/磁场/等离子体特征
用法:
python3 download_wave_data.py --start 2015-01 --months 3
"""
import os, sys, json, time, argparse, urllib.request, urllib.error
from datetime import datetime, timedelta, timezone
HAPI = "https://cdaweb.gsfc.nasa.gov/hapi/data"
OUT_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "data", "wave")
def fetch(ds, t0, t1, retries=3):
"""拉一段时间的数据 (HAPI JSON)."""
url = (f"{HAPI}?id={ds}&time.min={t0}&time.max={t1}&format=json")
for attempt in range(retries):
try:
with urllib.request.urlopen(url, timeout=120) as r:
d = json.load(r)
code = d.get("status", {}).get("code")
if code == 1201: # no data for time range
return None
if code != 1200:
raise RuntimeError(f"HAPI status {code}: {d.get('status')}")
return d
except Exception as e:
if attempt == retries - 1:
print(f" [warn] {ds} {t0[:10]} 失败: {e}", flush=True)
return None
time.sleep(3 * (attempt + 1))
return None
def download_month(ds_list, year, month, out_dir):
"""下载一个月, 逐天下载后合并."""
import numpy as np
if month == 12:
nxt = datetime(year + 1, 1, 1)
else:
nxt = datetime(year, month + 1, 1)
day = datetime(year, month, 1)
all_rows = {ds: [] for ds in ds_list}
ndays = 0
while day < nxt:
d2 = day + timedelta(days=1)
t0 = day.strftime("%Y-%m-%dT%H:%M:%SZ")
t1 = d2.strftime("%Y-%m-%dT%H:%M:%SZ")
got = False
for ds in ds_list:
d = fetch(ds, t0, t1)
if d:
all_rows[ds].extend(d["data"])
got = True
ndays += 1 if got else 0
print(f" {t0[:10]} {'ok' if got else 'no-data'}", flush=True)
day = d2
os.makedirs(out_dir, exist_ok=True)
out = os.path.join(out_dir, f"rbsp_a_{year}{month:02d}.npz")
save = {}
for ds in ds_list:
rows = all_rows[ds]
if not rows:
continue
times = [r[0] for r in rows]
vals = []
for r in rows:
row = []
for v in r[1:]:
if isinstance(v, list):
row.append(float("nan")) # 频谱类跳过 (用单独脚本)
elif v is None:
row.append(float("nan"))
else:
fv = float(v)
# CDAWeb fill value -1e31 → nan
if fv < -1e30:
fv = float("nan")
row.append(fv)
vals.append(row)
save[ds + "__time"] = np.array(times)
save[ds + "__vals"] = np.array(vals, dtype=np.float32)
np.savez_compressed(out, **save)
print(f"[save] {out} ({os.path.getsize(out)/1024:.0f} KB, {ndays} days)", flush=True)
return out
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--start", default="2015-01", help="起始月 YYYY-MM")
ap.add_argument("--months", type=int, default=3)
ap.add_argument("--out", default=OUT_DIR)
args = ap.parse_args()
y, m = map(int, args.start.split("-"))
ds_list = ["RBSP-A_DENSITY_EMFISIS-L4",
"RBSP-A_MAGNETOMETER_1SEC-GEI_EMFISIS-L3"]
for i in range(args.months):
yy, mm = y + (m - 1 + i) // 12, (m - 1 + i) % 12 + 1
print(f"=== {yy}-{mm:02d} ===", flush=True)
download_month(ds_list, yy, mm, args.out)
print("done", flush=True)
if __name__ == "__main__":
main()