コンテンツにスキップ

電子反射法(ER)

電子反射法(Electron Reflectometry)は、探査機で測った電子のエネルギー・ピッチ角分布から、 月面へ向かった電子がどこで跳ね返されたか(反射の障壁)を推定する手法です。 SOPRANの試作は、ピッチ角分布の「ロスコーン」の境界から磁気ミラー比\(R_m\)と電位差\(\Delta U\)を当てはめます。

解釈の限界

当てはめが数値的に収束したことは、月面の磁場を測れたことを意味しません。 \(B_\mathrm{eff} = R_m B_\mathrm{sc}\)(nT)は反射の境界を表す実効的な磁場で、地殻磁場のベクトルではありません。 \(\Delta U\)は「月面の電位 − 探査機の電位」(eV)で、月面の絶対電位でもありません。 磁場として採用するかは、下の品質フラグとプロファイル区間で判断します。

手法の選び方

推定器はfinite-binとHalekasの2つです。

用途 手法と設定
主解析 finite-bin、beta-binomialのカウント尤度(既定)。角度方向の拡散\(D_\mathrm{out}\)は必要に応じて有効にする
磁場として採用するかの判断 profile_mirror_ratioの区間とfield_flags
フラックスしか無い入力、以前の解析との比較 finite-bin、loss="huber"(0.1 dex)
固定した反射率0.1・外側1のモデルとの比較 Halekas

モデルの式、目的関数、フラグの定義はERモデルの定義にあります。

KAGUYAのデータから推定する

import sopran as spn
from sopran.experimental.kaguya.er import KaguyaErInstrument
from sopran.experimental.electron_reflection import (
    FiniteBinFitSettings, FiniteBinObservation, HalekasFitSettings,
)

er = KaguyaErInstrument(spn.Kaguya())
pitch_counts = er.pitch_angle_spectrum(spn.day("2008-04-26"))

# magnetic_field と position は同じ座標系の配列、または SopranArray
counts = er.paired_counts(
    pitch_counts, index=0, magnetic_field=magnetic_field, position=position,
)

observation = FiniteBinObservation.from_counts(
    counts, energy_edges_eV=energy_edges, pitch_edges_deg=folded_pitch_edges,
)
result = er.effective_field.fit_finite_bin(
    observation, settings=FiniteBinFitSettings(angular_transport="out"),
)
profile = er.effective_field.profile_finite_bin(observation, result)

comparison = er.effective_field.fit_halekas(counts, settings=HalekasFitSettings())

入力の準備

KaguyaErInstrumentは、ESAの読み込みと校正、余白を付けたLMAGの読み込み、SPICEの準備を2つの入口で共有します。 pitch_angle_spectra(..., align=False)はセンサーごとに元の時刻を保ったピッチ角スペクトルを返します。

paired_countsは、指定した1サンプルの0〜90度と90〜180度を対にしたElectronReflectionCounts (エネルギー×折り返したピッチ角)を作ります。

  • 月面から戻ってくる向き(反射を経た電子)の半球を「affected」、月面へ向かう向き(入射電子)を「reference」とします。 +Bが月から外向きなら低ピッチ角側をaffectedにし、それ以外は高ピッチ角側にします。 affected_side="low"または"high"で明示もできます。
  • finite-binには、校正済みの実際のビン境界をenergy_edges_eVとpitch_edges_degで渡します。中心値から境界を推定しません。
  • 露出時間は、明示した値、スペクトルの座標、等しい露出の順で決めます。明示する値は、選んだサンプルの エネルギー×ピッチ角に放送(broadcast)できる配列です。等しい露出を仮定したときは入力のメタデータに記録します。

取得・校正にはkaguya、推定にはexperimental、作図にはvizのextraを使います。

結果を読む

result.effective_field_nT       # B_eff
result.field_flags              # 磁場を決められない理由
result.field_unconstrained      # field_flags のどれかが立っていれば True
profile.interval_nT             # R_m を固定して再最適化した95%区間

フラグが立っていなくても、磁場が一意に決まったとは限りません。採用の判断にはプロファイル区間を使い、 区間が探索範囲の端に届いた(interval_bounded=False)ものや、より良い解が見つかった(improved_minimum=True)ものは 個別に確かめます。カウント損失とHuber損失で別の解に落ちる窓では、カウント損失のプロファイル区間が両方を含むことがあります。 この場合は点推定の差ではなく、区間の幅で識別できたかを判断します。

結果の保存

推定結果は手法ごとの型付きdataclassで返し、Storeへ自動では保存しません。 呼び出し側で、設定・入力・マスク・ビン・コードのハッシュと一緒に保存してください。 全期間をまとめて処理し、設定とコードを固定して保存する仕組みはER全期間バッチにあります。

モジュール構成

場所 役割
electron_reflection/common.py 共通の入力型ElectronReflectionCounts、露出の検証、境界の式mirror_boundary_sin2
electron_reflection/finite_bin.py finite-binモデル、損失、ロスコーンの検定、プロファイル
electron_reflection/halekas.py Halekasモデル
experimental/kaguya/er.py ESA1/ESA2・LMAG・SPICEの準備、ピッチ角スペクトル、paired_counts、推定器の呼び出し
experimental/kaguya/er_batch.py 全期間の日別シャード化、設定の固定、並列の当てはめ、Storeへの登録
crates/sopran-native/src/finite_bin.rs finite-binの応答・\(D_\mathrm{out}\)・損失・最適化(Rust)

廃止した推定器

paired-countのbeta-binomial推定器(カウント尤度は2026-10-10にfinite-binのlossへ統合)、binary surface、joint、 global-joint、incident・integratedの各推定器と、それら専用のwarm start・尤度スキャン・時系列・カタログ・スキーマ・評価補助は削除しました。 旧fit、fit_joint、fit_global_joint、fit_timeseries、buildの代わりにfit_finite_bin・fit_halekasを使います。 旧sopran-er-finite-binのJSONL CLIも廃止し、PyO3のAPIに一本化しました。互換の別名や旧推定器への切り替えはありません。 過去に保存したデータはStoreに残り、通常のデータセットとして読めます。

検証

対象 テスト
finite-bin、\(D_\mathrm{out}\)、損失(scipyの二項・beta-binomialと照合)、カウントの選別、ロスコーンの検定、オフセットと事前分布、プロファイル区間、欠測、固定\(B_\mathrm{eff}\) tests/test_er_finite_bin.py
Halekasのhard/probitでの回復、\(R_m<1\)、探索の一致 test_electron_reflection.py、test_electron_reflection_subunity.py、test_halekas_search.py
KAGUYAの入力、露出、幾何、読み込み test_kaguya_er.py、test_kaguya_er_geometry.py、test_kaguya_pace.py
通常APIが試作を読み込まないこと test_experimental_boundary.py