Satellite Observation Package for Retrieval, Analysis, and Navigation
Project description
SOPRAN
Satellite Observation Package for Retrieval, Analysis, and Navigation.
SOPRAN は、衛星観測データの取得、読み込み、解析、可視化、座標変換を Python から
扱うためのライブラリとして作る予定のリポジトリです。まずは KAGUYA/SELENE や
ARTEMIS など、月周辺の衛星データ解析を主対象にします。
目標
- ミッションごとに異なるデータ形式や測定器を、共通した使い方で扱えるようにする。
- IDL/SPEDAS で使ってきた解析スクリプトを pure Python + Rust の実装へ移植する。
- Python から読みやすい API を提供しつつ、重い decode、binning、fit、大量 batch 処理は Rust backend へ分離する。
- 解析作業で増えた一時コードを、そのまま積み上げず、reader、product、workflow、 analysis primitive として整理する。
初期スコープ
- KAGUYA/SELENE の public data reader と product builder
- ARTEMIS の基本 reader と時系列 product
- SPEDAS/tplot に近い軽量な時系列データモデル
- dataset root / local cache / metadata の共通 resolver
- SPICE を使った時刻・座標系補助
- DEM/SVM などの天体固有 map product、投影、経度表現、region query
- DEM と太陽位置に基づく shadow / illumination product
- Rust による重い処理の backend 化
依存関係
SOPRAN は研究・解析環境でそのまま使えることを優先し、KAGUYA/ARTEMIS、SPICE、
SpacePy、MAP/DEM/SVM、Matplotlib/HoloViz 系の runtime backend を標準 dependencies に
含めます。optional-dependencies は用途別の目印と開発環境向けに残しています。
pip install sopran
pip install "sopran[full]"
pip install "sopran[dev]"
optional extras は kaguya, artemis, moon, viz, geospace, full, dev に分けますが、
runtime 系は標準 dependencies にも含めます。
Documentation
公開ドキュメントは MkDocs Material で docs/ からビルドします。GitHub Pages は
.github/workflows/docs.yml で main への push 時に build/deploy する構成です。
pip install mkdocs mkdocs-material "mkdocstrings[python]" pymdown-extensions numpy
set PYTHONPATH=src
mkdocs serve
pip install -e ".[docs]" も定義していますが、通常の runtime dependencies も解決対象になるため、
Windows で MSVC がない環境では aacgmv2 などの build に失敗することがあります。docs だけを
編集する場合は上の軽量 install を使います。
現在動く最小 API
KAGUYA ESA1 については、public PBF file discovery、ローカル raw PBF decode、
xarray/polars 変換、parquet 保存、Pipeline scan/run、最小 PlotStack までの縦切りを
実装し始めています。ARTEMIS FGM は normalized parquet が Store にある場合の load skeleton を
用意しています。
import sopran as spn
store = spn.Store("F:/sopran_data")
kg = spn.Kaguya(store=store, download="never")
time = spn.day("2008-01-01")
kg.esa1.energy_flux.info()
kg.esa1.energy_flux.plan(time)
esa1 = kg.esa1.load(time)
ds = esa1.to_xarray()
counts = esa1.to_polars("counts", reduce_look="sum")
record = esa1.write_parquet(store, variable="counts", reduce_look="sum")
pipe = (
kg.esa1.pipeline(time)
.decode()
.select_variables("counts")
.quicklook("counts")
.write("kaguya.esa1.counts", layer="normalized")
)
pipe.run() # existing shard があれば失敗
pipe.run(mode="replace") # 明示置換
pipe.run(mode="append") # catalog に shard を追加
manifest = store.dataset("kaguya.esa1.counts", layer="normalized").manifest()
manifest["provenance"]["pipeline"]["stages"]
lazy = kg.esa1.pipeline(time).from_normalized().select_variables("counts").scan()
counts_frame = lazy.collect()
stream = (
kg.esa1.pipeline(time)
.from_normalized()
.select_variables("counts")
.stream(partition="day")
)
for day_frame in stream:
pass
stack = spn.stack(
kg.esa1.counts.load(time).spectrogram(y="energy"),
kg.esa1.quality.load(time).line(),
)
fig = stack.plot(backend="matplotlib")
quicklook = stack.quicklook("esa1_counts", root="reports", backend="matplotlib")
bins = spn.time_bins(time, cadence="10s", partial="keep")
features = spn.align(
kg.esa1.quality.load(time),
grid=bins,
method="nearest",
tolerance="5s",
).to_polars()
# sza, wave_power, density, and quality_flag are loaded xarray-like products.
ml_features = (
spn.SampleTable(bins)
.add(sza, method="nearest", tolerance="5s")
.add(wave_power, method="max")
.add(density, method="median")
.collect(join="inner", quality_mask=quality_flag)
.to_polars()
)
time x component の vector product は magnetic_field_x のような wide columns に展開します。
観測量ごとに対応づけ方法を変える場合は SampleTable を使います。現在の reducer は
nearest, center, mean, max, median, first, last です。
join="outer" は全binを残し、join="inner" は欠損featureを含むbinを落とします。
fill=-1.0 のように指定すると、outer で残した欠損featureを明示値で埋められます。
quality_mask=<1D time series> はbin内でcenterに近いmask値が0/False/欠損のbinを落とします。
partial="keep" はcadenceで割り切れない末尾binを残し、partial="drop" は捨てます。
to_polars(layout="long") は time, feature, value 形式のtableを返します。
metadata() はgridやreducer条件を返し、保存時のmanifest材料にできます。
spn.align(...).write_parquet("features.parquet") または
spn.SampleTable(...).collect().write_parquet("features.parquet") で feature table を保存できます。
raw file は Store.raw_path("kaguya", "pds3") 以下に public provider path を保って置きます。
たとえば ESA1 の 2008-01-01 は次の配置を探索します。
F:/sopran_data/raw/kaguya/pds3/
sln-l-pace-3-pbf1-v3.0/20080101/data/IPACE_PBF1_080101_ESA1_V003.dat.gz
保存済み dataset は Store.datasets(refresh=True) で registry/datasets.parquet に索引化し、
layer や mission で絞り込めます。
index = store.datasets(refresh=True)
kaguya_features = store.datasets(layer="features", mission="kaguya")
kg.esa1.energy_flux は実データではなく endpoint です。属性アクセスだけでは I/O を起こさず、
実データ取得は .load(time)、計算は .compute(...)、描画は .plot(...) を実行点にします。
解析プロジェクトでは case に時間範囲や既定 frame を持たせます。
prj = spn.Project("projects/lunar_wake")
case = prj.case("wake_20080201")
counts = case.kaguya.esa1.counts.load()
artemis_b_plan = case.artemis.p1.fgm.magnetic_field.plan()
moon_dem_plan = case.moon.dem.plan(source="kaguya.tc.dem")
moon_sza_plan = case.moon.sza.plan()
stack = case.stack(
counts.spectrogram(y="energy"),
case.kaguya.esa1.quality.load().line(),
)
stack.plot()
artifact = prj.save(case.kaguya.esa1.quality.load(), "interim/kaguya_esa1_quality_wake")
月面 DEM/SVM/SZA/shadow/illumination は mission ではなく body-first API を主導線にします。
moon = spn.Moon()
region = spn.Region(lon=(120, 160), lat=(-45, -10), body="moon")
dem_plan = moon.dem.plan(source="kaguya.tc.dem", region=region, resolution="512ppd")
sza_plan = moon.sza.plan(time="2008-02-01T12:00:00", region=region)
shadow_plan = moon.shadow.plan(time="2008-02-01T12:00:00", dem=dem_plan)
ユーザー定義の database product は Store 配下に metadata と空 dataset として登録できます。
db = store.database("lunar_wake", create=True)
product = db.register_product(
name="event_table",
schema=kg.esa1.schema(),
description="hand-curated lunar wake events",
)
pipe.write(db.product("event_table", description="event table generated by pipeline"))
events = db.product("event_table").scan()
予定ディレクトリ
src/sopran/
core/
missions/
kaguya/
artemis/
bodies/
moon/
maps/
frames/
analysis/
plot/
crates/
sopran-backend/
docs/
tests/
ユーザーの解析 workspace は repository 内部の package とは分けて、projects/lunar_wake/ のように
管理します。
旧リポジトリ
以前の作業リポジトリは F:\idl\lunarsat にあります。そこには KAGUYA 解析、dataset
layout、Rust backend の試行錯誤が含まれていますが、このリポジトリでは設計を整理し直して
作り直します。
License
SOPRAN original code and documentation are licensed under Apache-2.0.
SPEDAS/PySPEDAS-derived ports must retain their upstream notices. The current
policy is documented in THIRD_PARTY_NOTICES.md: MIT-licensed SPEDAS routines
can be ported with attribution, while GPL/NASA-OSA external components should
not be copied into the Apache-2.0 core without a separate license review.
開発状況
現在は KAGUYA ESA1 の local PBF decode、xarray/polars 変換、parquet 保存、Pipeline run/scan、
PlotStack、Project/Case、Moon surface skeleton、ARTEMIS FGM normalized store load skeleton を
実装し始めています。
詳細設計は SPEC.md, STORE.md, PIPELINE.md, SURFACE.md, PLOTTING.md に分けます。
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sopran-0.0.0.tar.gz.
File metadata
- Download URL: sopran-0.0.0.tar.gz
- Upload date:
- Size: 144.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d1335dd31f81ffee138bf4e106a9dda1dfe7408c21c660241773f3a51c84c88a
|
|
| MD5 |
b0af187a498c793d93bd2781ffc347b8
|
|
| BLAKE2b-256 |
2d8940996b594949a247b0073082ae22670d9022eea27d71e57f64535b8ec496
|
Provenance
The following attestation bundles were made for sopran-0.0.0.tar.gz:
Publisher:
publish.yml on Nkzono99/sopran
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sopran-0.0.0.tar.gz -
Subject digest:
d1335dd31f81ffee138bf4e106a9dda1dfe7408c21c660241773f3a51c84c88a - Sigstore transparency entry: 2054213381
- Sigstore integration time:
-
Permalink:
Nkzono99/sopran@83ece037371cdaf82c8816caa09988315f0a3eda -
Branch / Tag:
refs/tags/v0.0.0 - Owner: https://github.com/Nkzono99
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@83ece037371cdaf82c8816caa09988315f0a3eda -
Trigger Event:
push
-
Statement type:
File details
Details for the file sopran-0.0.0-py3-none-any.whl.
File metadata
- Download URL: sopran-0.0.0-py3-none-any.whl
- Upload date:
- Size: 94.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8513fa294b3baed402eaf696626f3a51d3b30db66713b2e833d350edae403771
|
|
| MD5 |
7a346698456948aa29ac3d27333c8dba
|
|
| BLAKE2b-256 |
8b63b956879dcbea852809ebf0a2dfe2fdd8b96e9a3b85944e448976fd998955
|
Provenance
The following attestation bundles were made for sopran-0.0.0-py3-none-any.whl:
Publisher:
publish.yml on Nkzono99/sopran
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sopran-0.0.0-py3-none-any.whl -
Subject digest:
8513fa294b3baed402eaf696626f3a51d3b30db66713b2e833d350edae403771 - Sigstore transparency entry: 2054213585
- Sigstore integration time:
-
Permalink:
Nkzono99/sopran@83ece037371cdaf82c8816caa09988315f0a3eda -
Branch / Tag:
refs/tags/v0.0.0 - Owner: https://github.com/Nkzono99
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@83ece037371cdaf82c8816caa09988315f0a3eda -
Trigger Event:
push
-
Statement type: