lstnet 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. lstnet-0.1.0/.github/workflows/publish.yml +30 -0
  2. lstnet-0.1.0/.github/workflows/release-binaries.yml +51 -0
  3. lstnet-0.1.0/.github/workflows/test.yml +30 -0
  4. lstnet-0.1.0/.gitignore +33 -0
  5. lstnet-0.1.0/AGENTS.md +1 -0
  6. lstnet-0.1.0/CITATION.cff +24 -0
  7. lstnet-0.1.0/CLAUDE.md +82 -0
  8. lstnet-0.1.0/CONTEXT.md +34 -0
  9. lstnet-0.1.0/LICENSE +21 -0
  10. lstnet-0.1.0/PKG-INFO +166 -0
  11. lstnet-0.1.0/PRD.md +99 -0
  12. lstnet-0.1.0/Pipfile +34 -0
  13. lstnet-0.1.0/README.md +142 -0
  14. lstnet-0.1.0/TIR.ico +0 -0
  15. lstnet-0.1.0/_readme.txt +3 -0
  16. lstnet-0.1.0/all.py +1352 -0
  17. lstnet-0.1.0/calculateLSTdlg.py +357 -0
  18. lstnet-0.1.0/calculateLSTdlg.ui +662 -0
  19. lstnet-0.1.0/config.py +2 -0
  20. lstnet-0.1.0/docs/adr/.gitkeep +0 -0
  21. lstnet-0.1.0/docs/adr/0001-core-library-and-validation-architecture.md +48 -0
  22. lstnet-0.1.0/docs/superpowers/plans/2026-06-19-core-domain-ground-lst.md +355 -0
  23. lstnet-0.1.0/docs/superpowers/plans/2026-06-19-modis-emissivity.md +155 -0
  24. lstnet-0.1.0/docs/superpowers/plans/2026-06-19-validation-engine.md +90 -0
  25. lstnet-0.1.0/docs/superpowers/specs/2026-06-19-lstnet-refactor-design.md +268 -0
  26. lstnet-0.1.0/help.py +41 -0
  27. lstnet-0.1.0/help.ui +47 -0
  28. lstnet-0.1.0/images/Hisite_map.png +0 -0
  29. lstnet-0.1.0/images/PKU&Hisite_map.png +0 -0
  30. lstnet-0.1.0/images/PKUsite_map.png +0 -0
  31. lstnet-0.1.0/images/SUR&Hisite_map.png +0 -0
  32. lstnet-0.1.0/images/SUR&PKUsite_map.png +0 -0
  33. lstnet-0.1.0/images/SURsite_map.png +0 -0
  34. lstnet-0.1.0/images/TIR.png +0 -0
  35. lstnet-0.1.0/images/allsite_map.png +0 -0
  36. lstnet-0.1.0/images/avatar.png +0 -0
  37. lstnet-0.1.0/images/initial_map.png +0 -0
  38. lstnet-0.1.0/lstnet-gui.spec +44 -0
  39. lstnet-0.1.0/main.py +267 -0
  40. lstnet-0.1.0/main.spec +37 -0
  41. lstnet-0.1.0/mainWindow.py +131 -0
  42. lstnet-0.1.0/mainWindow.ui +249 -0
  43. lstnet-0.1.0/methods/DayorNight.py +37 -0
  44. lstnet-0.1.0/methods/Modis_emiss.py +185 -0
  45. lstnet-0.1.0/methods/random_avatar.py +49 -0
  46. lstnet-0.1.0/methods/site_LST.py +270 -0
  47. lstnet-0.1.0/methods/site_map.py +110 -0
  48. lstnet-0.1.0/pyproject.toml +39 -0
  49. lstnet-0.1.0/requirements.txt +16 -0
  50. lstnet-0.1.0/samples/overpass_times.txt +5 -0
  51. lstnet-0.1.0/samples/retrieved_sample.csv +10 -0
  52. lstnet-0.1.0/samples/validation_template.csv +26 -0
  53. lstnet-0.1.0/src/lstnet/__init__.py +43 -0
  54. lstnet-0.1.0/src/lstnet/config.py +47 -0
  55. lstnet-0.1.0/src/lstnet/dayornight.py +23 -0
  56. lstnet-0.1.0/src/lstnet/ground_lst.py +127 -0
  57. lstnet-0.1.0/src/lstnet/gui.py +616 -0
  58. lstnet-0.1.0/src/lstnet/io/__init__.py +6 -0
  59. lstnet-0.1.0/src/lstnet/io/aster_ged.py +341 -0
  60. lstnet-0.1.0/src/lstnet/io/base.py +58 -0
  61. lstnet-0.1.0/src/lstnet/io/emissivity.py +144 -0
  62. lstnet-0.1.0/src/lstnet/io/hiwater.py +191 -0
  63. lstnet-0.1.0/src/lstnet/io/modis.py +462 -0
  64. lstnet-0.1.0/src/lstnet/io/pku.py +268 -0
  65. lstnet-0.1.0/src/lstnet/io/raster.py +36 -0
  66. lstnet-0.1.0/src/lstnet/io/surfrad.py +182 -0
  67. lstnet-0.1.0/src/lstnet/mcp_server.py +131 -0
  68. lstnet-0.1.0/src/lstnet/models.py +68 -0
  69. lstnet-0.1.0/src/lstnet/plotting.py +52 -0
  70. lstnet-0.1.0/src/lstnet/qc.py +38 -0
  71. lstnet-0.1.0/src/lstnet/sites.py +71 -0
  72. lstnet-0.1.0/src/lstnet/stats.py +68 -0
  73. lstnet-0.1.0/src/lstnet/validation.py +105 -0
  74. lstnet-0.1.0/tests/fixtures/README.md +13 -0
  75. lstnet-0.1.0/tests/fixtures/bon/2011/bon11043.dat +900 -0
  76. lstnet-0.1.0/tests/fixtures/hiwater/2018/2018/345/271/264/351/273/221/346/262/263/346/265/201/345/237/237/345/234/260/350/241/250/350/277/207/347/250/213/347/273/274/345/220/210/350/247/202/346/265/213/347/275/221/351/230/277/346/237/224/350/266/205/347/272/247/347/253/231AWS.xlsx +0 -0
  77. lstnet-0.1.0/tests/fixtures/pku-sites/Total/346/211/277/345/276/267/347/253/231CR200Series_Data-20180801-0831.dat +45 -0
  78. lstnet-0.1.0/tests/fixtures/retrieved.csv +4 -0
  79. lstnet-0.1.0/tests/test_aster_ged.py +300 -0
  80. lstnet-0.1.0/tests/test_compute_ground_lst.py +240 -0
  81. lstnet-0.1.0/tests/test_dayornight.py +36 -0
  82. lstnet-0.1.0/tests/test_emissivity.py +39 -0
  83. lstnet-0.1.0/tests/test_ground_lst.py +50 -0
  84. lstnet-0.1.0/tests/test_gui.py +439 -0
  85. lstnet-0.1.0/tests/test_hiwater.py +150 -0
  86. lstnet-0.1.0/tests/test_io_base.py +28 -0
  87. lstnet-0.1.0/tests/test_mcp.py +28 -0
  88. lstnet-0.1.0/tests/test_models.py +47 -0
  89. lstnet-0.1.0/tests/test_modis.py +386 -0
  90. lstnet-0.1.0/tests/test_pku.py +148 -0
  91. lstnet-0.1.0/tests/test_plotting.py +65 -0
  92. lstnet-0.1.0/tests/test_public_api_golden.py +66 -0
  93. lstnet-0.1.0/tests/test_qc.py +45 -0
  94. lstnet-0.1.0/tests/test_raster.py +37 -0
  95. lstnet-0.1.0/tests/test_sites.py +45 -0
  96. lstnet-0.1.0/tests/test_stats.py +72 -0
  97. lstnet-0.1.0/tests/test_surfrad.py +105 -0
  98. lstnet-0.1.0/tests/test_validation.py +136 -0
@@ -0,0 +1,30 @@
1
+ name: publish
2
+
3
+ # Trusted publishing (OIDC) to PyPI on GitHub Release.
4
+ # One-time setup: create the project on https://pypi.org and add a trusted
5
+ # publisher for this repo + environment `pypi` + workflow `publish.yml`.
6
+ on:
7
+ release:
8
+ types: [published]
9
+
10
+ jobs:
11
+ build:
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ - uses: actions/setup-python@v5
16
+ with: { python-version: "3.x" }
17
+ - run: pip install build
18
+ - run: python -m build
19
+ - uses: actions/upload-artifact@v4
20
+ with: { name: dist, path: dist/ }
21
+ publish:
22
+ needs: build
23
+ runs-on: ubuntu-latest
24
+ environment: pypi
25
+ permissions:
26
+ id-token: write
27
+ steps:
28
+ - uses: actions/download-artifact@v4
29
+ with: { name: dist, path: dist/ }
30
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,51 @@
1
+ name: release-binaries
2
+
3
+ # Build standalone GUI binaries (PyInstaller) for Win/macOS/Linux and attach
4
+ # them to the GitHub Release. Users download for their OS — no Python needed.
5
+ # Runs alongside the PyPI publish workflow (both trigger on release).
6
+
7
+ on:
8
+ release:
9
+ types: [published]
10
+
11
+ jobs:
12
+ build:
13
+ strategy:
14
+ fail-fast: false
15
+ matrix:
16
+ include:
17
+ - os: ubuntu-latest
18
+ artifact: lstnet-gui-linux.tar.gz
19
+ - os: macos-latest
20
+ artifact: lstnet-gui-macos.zip
21
+ - os: windows-latest
22
+ artifact: lstnet-gui-windows.zip
23
+ runs-on: ${{ matrix.os }}
24
+ steps:
25
+ - uses: actions/checkout@v4
26
+ - uses: actions/setup-python@v5
27
+ with:
28
+ python-version: "3.12"
29
+
30
+ - name: Install Qt system libs (Linux only)
31
+ if: runner.os == 'Linux'
32
+ run: sudo apt-get update && sudo apt-get install -y libxcb-cursor0 libegl1 libgl1 libxkbcommon0
33
+
34
+ - run: pip install -e ".[gui]"
35
+ - run: pip install pyinstaller
36
+
37
+ - name: Build binary
38
+ run: pyinstaller lstnet-gui.spec --noconfirm --clean
39
+
40
+ - name: Archive (Linux/macOS)
41
+ if: runner.os != 'Windows'
42
+ run: tar czf "${{ matrix.artifact }}" -C dist lstnet-gui
43
+
44
+ - name: Archive (Windows)
45
+ if: runner.os == 'Windows'
46
+ run: Compress-Archive -Path dist/lstnet-gui -DestinationPath "${{ matrix.artifact }}"
47
+
48
+ - name: Upload to release
49
+ uses: softprops/action-gh-release@v2
50
+ with:
51
+ files: ${{ matrix.artifact }}
@@ -0,0 +1,30 @@
1
+ name: tests
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ${{ matrix.os }}
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ os: [ubuntu-latest, macos-latest, windows-latest]
15
+ python-version: ["3.11", "3.12"]
16
+ env:
17
+ QT_QPA_PLATFORM: offscreen
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+ - uses: actions/setup-python@v5
21
+ with:
22
+ python-version: ${{ matrix.python-version }}
23
+ - name: Install Qt system libraries (Linux only — headless PySide6 needs libEGL etc.)
24
+ if: runner.os == 'Linux'
25
+ run: sudo apt-get update && sudo apt-get install -y libegl1 libgl1 libxkbcommon0 libdbus-1-3 libxcb-cursor0
26
+ - run: pip install --upgrade pip
27
+ - run: pip install -e .[dev]
28
+ - run: pip install PySide6 fastmcp # extras (GUI/MCP smoke tests)
29
+ # Golden tests gate on EARTHDATA creds -> skipped automatically on CI.
30
+ - run: pytest -q
@@ -0,0 +1,33 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .eggs/
6
+ *.egg
7
+
8
+ # Virtual environments
9
+ .venv/
10
+ venv/
11
+ env/
12
+
13
+ # PyInstaller build artifacts
14
+ build/
15
+ dist/
16
+
17
+ # Observation / satellite data (large; obtained separately, not version-controlled)
18
+ # Small test fixtures live in tests/fixtures/
19
+ data/
20
+
21
+ # IDE
22
+ .idea/
23
+
24
+ # OS
25
+ .DS_Store
26
+ Thumbs.db
27
+
28
+ # Secrets / personal
29
+ .env
30
+ CLAUDE.local.md
31
+
32
+ # Logs
33
+ *.log
lstnet-0.1.0/AGENTS.md ADDED
@@ -0,0 +1 @@
1
+ @CLAUDE.md
@@ -0,0 +1,24 @@
1
+ cff-version: 1.2.0
2
+ message: "If you use lstnet in your research, please cite it as below."
3
+ title: "lstnet: a pure-Python land surface temperature ground-validation library"
4
+ abstract: >-
5
+ lstnet computes ground-truth land surface temperature (LST) from in-situ
6
+ longwave radiation at SURFRAD / PKULSTNet / HiWATER sites and validates it
7
+ against retrieved LST (bias / RMSE / R + plots). GDAL-free, cross-platform.
8
+ authors:
9
+ - family-names: "Zeng"
10
+ given-names: "Hui"
11
+ email: "zenghui@pku.edu.cn"
12
+ - name: "LSTNet Contributors"
13
+ keywords:
14
+ - land surface temperature
15
+ - LST
16
+ - validation
17
+ - MODIS
18
+ - SURFRAD
19
+ - remote sensing
20
+ - broadband emissivity
21
+ license: MIT
22
+ version: 0.1.0
23
+ date-released: "2026-06-20"
24
+ repository-code: "https://github.com/veniai/lstnet"
lstnet-0.1.0/CLAUDE.md ADDED
@@ -0,0 +1,82 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## 项目概述
6
+
7
+ **lstnet**:地表面温度(LST)地面验证库。读取 SURFRAD / PKULSTNet / HiWATER(共 25 站)现场辐射数据,算出**地面真值 LST**,与**反演 LST**(用户自己的算法或卫星产品)配对验证(bias / RMSE / R + 图)。纯 Python,零系统 GDAL,跨平台(Win / macOS 含 Apple Silicon / Linux),MIT。
8
+
9
+ - 原作者:曾辉(北大遥感所热红外组),2021 PyQt5 桌面应用
10
+ - 现状:已重构为 `lstnet` 库(核心域 + 发射率源 + 验证引擎 + GUI + MCP + PyPI 就绪)。**仓库根目录的 legacy PyQt5 代码(`main.py` / `methods/` / `all.py` / `*.ui`)是退役基线,逐字节未动,勿在其上开发**——活跃代码在 `src/lstnet/`
11
+
12
+ ## 运行 / 测试 / 构建
13
+
14
+ ```bash
15
+ python3 -m pip install -e . # 装核心库(editable)
16
+ python3 -m pip install -e .[gui] # + PySide6(GUI)
17
+ python3 -m pip install -e .[mcp] # + fastmcp(MCP 服务器)
18
+ python3 -m pip install -e .[dev] # + pytest
19
+
20
+ python3 -m pytest -q # 全量(golden 测试无凭据时自动 skip)
21
+ lstnet-gui # 启动 PySide6 桌面 GUI
22
+ lstnet-mcp # 启动 MCP 服务器(AI agent 接入)
23
+ python3 -m build # 打 wheel/sdist(发 PyPI 前验证)
24
+ ```
25
+
26
+ - Earthdata 凭据(MODIS/GED 发射率源需要,`FixedEmissivity` 不需要):
27
+ `export EARTHDATA_USERNAME=... EARTHDATA_PASSWORD=...`(**绝不硬编码**)
28
+ - GUI 离屏测试:`QT_QPA_PLATFORM=offscreen`
29
+
30
+ ## 架构(`src/lstnet/`)
31
+
32
+ ```
33
+ models.py 值对象:Site / GroundLST / RetrievedLST / ValidationPair/Stats/Result
34
+ sites.py 25 站注册表(SUR7/PKU7/Hi11)
35
+ ground_lst.py 物理与编排:lst_from_radiance、compute_ground_lst、SIGMA(5.670374e-8)
36
+ qc.py decide_qc + qc_flag 枚举
37
+ dayornight.py astral 太阳高度角判昼夜
38
+ config.py package_root/project_root + earthdata_credentials(读环境变量)
39
+ io/base.py 接口:EmissivitySource / NetworkReader + Radiation 类型
40
+ io/surfrad.py SURFRAD .dat(HTTPS,非 FTP)
41
+ io/pku.py io/hiwater.py 历史本地 CSV/xlsx 读取器
42
+ io/modis.py MODIS C6.1 发射率(earthaccess + pyhdf,正弦像元查找,QC+padding 修复)
43
+ io/emissivity.py FixedEmissivity / ModisDailyEmissivity + broadband_emissivity
44
+ io/aster_ged.py AsterGEDEmissivity(CMR AG100 V003 + h5py)
45
+ io/raster.py pixel_at_lonlat(GeoTIFF 站点像元提取,rasterio)
46
+ validation.py validate()(按 site+过境时刻配对)+ TableRetrievedLST
47
+ stats.py bias / rmse / pearson_r / linear_regression
48
+ plotting.py scatter(1:1) + time_series
49
+ gui.py PySide6 GUI(lstnet-gui)
50
+ mcp_server.py FastMCP 工具服务器(lstnet-mcp)
51
+ ```
52
+
53
+ **分层**:值对象 → 数据访问接口/读取器 → 域编排 → 前端(GUI/MCP)。核心库**无 Qt 依赖**(PySide6/fastmcp 仅在 GUI/MCP)。`compute_ground_lst` 的 `emiss_src` 必须显式传入(不静默联网)。
54
+
55
+ ## 依赖
56
+
57
+ - `requires-python >=3.9`;核心 deps:`numpy pandas openpyxl requests earthaccess pyhdf astral matplotlib h5py rasterio`
58
+ - **零系统 GDAL**:MODIS HDF4 走 `pyhdf`、ASTER GED HDF5 走 `h5py`、GeoTIFF 走 `rasterio`(自带 GDAL wheel,**无需 `apt install gdal`**)。跨平台 wheel 齐全。
59
+ - extras:`gui`(PySide6) / `mcp`(fastmcp) / `dev`(pytest)。
60
+
61
+ ## 关键约束(铁律)
62
+
63
+ - **无 `eval`、无硬编码凭据、无 CWD 依赖**(数据路径走 `config.project_root()`);改代码 grep 确认。
64
+ - **MODIS C6.1**(`.061`),不是 C6(`.006` 已停用);UTC 过境时刻。
65
+ - **BBE 系数一手化**:MODIS 走 Ogawa 2004 (RSE 88);ASTER GED 默认走 Cheng & Liang 2014(开放获取一手),Ogawa 为可选 `bbe='ogawa'`。
66
+ - **旧码勿动**:`git diff --exit-code -- main.py methods/ all.py` 应 exit 0。
67
+ - `data/`(数百 MB 真实观测)gitignored;小样本在 `tests/fixtures/`。
68
+
69
+ ## 文档与决策
70
+
71
+ - 设计 spec:`docs/superpowers/specs/2026-06-19-lstnet-refactor-design.md`(§9 含 pyhdf spike 结论)
72
+ - ADR-0001:`docs/adr/0001-...`(核心库 + 薄前端 + 验证引擎)
73
+ - 实现计划:`docs/superpowers/plans/`(1a / 1b 最终版 / 1c / validation-engine)
74
+ - 领域词典:`CONTEXT.md`(地面真值 LST / 反演 LST / 验证引擎 / 过境时刻…)
75
+ - 执行进度 ledger:`.git/sdd/progress.md`(gitignored,恢复图)
76
+ - 发布:`.github/workflows/`(test 跨平台矩阵 + publish trusted-publishing)
77
+
78
+ ## 路线图
79
+
80
+ - ✅ Plan 1a 核心域 · 1b 发射率(MODIS+GED,全闭合)· 1c 验证引擎 · PyPI 脚手架 · PySide6 GUI · MCP
81
+ - 待办(用户操作,非代码):建 GitHub 仓库 → 推送 → pypi.org 配 trusted publisher → 打 Release 自动发 → `pip install lstnet` 生效
82
+ - 可选未来:CLI(自动化批处理)、neighbor-tile mosaic、按网络分组报告、raster 式反演 LST source(待用户真实格式)
@@ -0,0 +1,34 @@
1
+ # CONTEXT.md — LSTNet 领域语言
2
+
3
+ > 项目领域术语表。涉及需求/架构/跨模块讨论时用这些词,避免歧义。
4
+
5
+ ## 术语
6
+
7
+ ### 地面真值 LST (ground-truth LST)
8
+ 从地面站点(SURFRAD / PKULSTNet / HiWATER)的上下行长波辐射数据反演出的 LST,作为**验证基准**。公式:`T = ((L↑ - (1-ε)·L↓) / (ε·σ))^0.25`。
9
+ - **避免**:"site LST"(与"站点观测的 LST"歧义)
10
+
11
+ ### 反演 LST (retrieved LST)
12
+ 反演算法产出的 LST——**用户自己的算法**,或卫星产品(MYD21 / MYD11)。**被验证的对象**。
13
+ - **避免**:"satellite LST"(含混;用户验证的是自己的算法,不是 NASA 产品)
14
+
15
+ ### 验证引擎 (validation engine)
16
+ 核心库模块:按 (站点, 过境时刻) 配对**地面真值**与**反演 LST**,算 bias / RMSE / R,出散点/时序图。
17
+
18
+ ### 过境时刻 (overpass time)
19
+ 卫星过境瞬间,12 位时间戳 `YYYYMMDDHHMM`(**UTC**)。地面真值与反演 LST 的**配对键**。
20
+ - **避免**:"tiftime"(旧代码实现细节名)
21
+
22
+ ### 发射率来源 (emissivity source)
23
+ 可插拔:`Fixed`(固定值)/ `ModisDaily`(MYD21 日值)/ `AsterGED`(气候态,**默认**)。
24
+
25
+ ### BBE (宽带发射率, broadband emissivity)
26
+ 8–13.5µm 有效发射率,用于地面 LST 公式中的 ε。旧代码用的 `0.329·em29+0.572·em31+0.095` 是 Cheng & Liang (2014) **裸土专用**公式,已 deprecated。
27
+
28
+ ### 网络 (networks)
29
+ - **SURFRAD**:美国 7 站,NOAA **在线**(HTTPS),**主力**。
30
+ - **PKULSTNet**:中国 7 站,历史本地 CSV(2018-2019)。
31
+ - **HiWATER**:黑河 11 站,历史本地 xlsx(2018-2019)。
32
+
33
+ ### 反演 LST 取值 (retrieved LST extraction)
34
+ 验证时按**站点经纬度**从反演结果(栅格 GeoTIFF / 点表)取出该像元的 LST 值,与地面真值比——复用 MODIS 发射率取像元的同一模式(`findpointmodis`)。格式无关。
lstnet-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021-2026 Zeng Hui and LSTNet Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
lstnet-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,166 @@
1
+ Metadata-Version: 2.4
2
+ Name: lstnet
3
+ Version: 0.1.0
4
+ Summary: LSTNet: pure-Python land surface temperature library (ground truth LST production refactor).
5
+ Author: LSTNet Contributors
6
+ License: MIT
7
+ License-File: LICENSE
8
+ Requires-Python: >=3.9
9
+ Requires-Dist: astral
10
+ Requires-Dist: earthaccess
11
+ Requires-Dist: fastmcp
12
+ Requires-Dist: h5py
13
+ Requires-Dist: matplotlib
14
+ Requires-Dist: numpy
15
+ Requires-Dist: openpyxl
16
+ Requires-Dist: pandas
17
+ Requires-Dist: pyhdf
18
+ Requires-Dist: pyside6
19
+ Requires-Dist: rasterio
20
+ Requires-Dist: requests
21
+ Provides-Extra: dev
22
+ Requires-Dist: pytest; extra == 'dev'
23
+ Description-Content-Type: text/markdown
24
+
25
+ # lstnet
26
+
27
+ **Pure-Python land surface temperature (LST) ground-validation library + GUI.**
28
+
29
+ `lstnet` computes **ground-truth LST** from in-situ longwave radiation at
30
+ SURFRAD / PKULSTNet / HiWATER validation sites and **validates** it against
31
+ retrieved LST (your own algorithm or a satellite product) — bias / RMSE / R +
32
+ scatter and time-series plots. Zero system GDAL; cross-platform
33
+ (Windows / macOS incl. Apple Silicon / Linux); MIT-licensed.
34
+
35
+ **Networks:** **SURFRAD** (7 US sites, served online by NOAA — the default,
36
+ works out of the box) is the primary network. **PKULSTNet** (7) and **HiWATER**
37
+ (11) readers are also included for users who hold those local datasets (they
38
+ are not publicly downloadable — point the reader at your `data/` directory).
39
+
40
+ ## Install
41
+
42
+ ```bash
43
+ pip install lstnet
44
+ ```
45
+
46
+ That's it — core library, GUI (`lstnet-gui`), and MCP server (`lstnet-mcp`) are
47
+ all included.
48
+
49
+ For MODIS / ASTER GED emissivity sources, set NASA Earthdata credentials
50
+ (never hardcoded):
51
+
52
+ ```bash
53
+ export EARTHDATA_USERNAME=you@example.com
54
+ export EARTHDATA_PASSWORD=********
55
+ ```
56
+
57
+ Or enter them in the GUI: **Settings → Earthdata Login** (saved to
58
+ `~/.lstnet/earthdata.json`, chmod 600). Register at
59
+ <https://urs.earthdata.nasa.gov/users/new>.
60
+
61
+ `FixedEmissivity` needs no credentials.
62
+
63
+ ## GUI usage
64
+
65
+ ```bash
66
+ lstnet-gui # launch the PySide6 desktop application
67
+ ```
68
+
69
+ The GUI lets you:
70
+
71
+ 1. **Select sites** (multi-select, with lon/lat shown) from SURFRAD / PKULSTNet
72
+ / HiWATER.
73
+ 2. **Enter overpass times** (12-digit `YYYYMMDDHHMM`, one per line, UTC).
74
+ 3. **Pick an emissivity source** — ASTER GED (default, recommended for
75
+ validation), MODIS daily, or a manual fixed value.
76
+ 4. **Compute ground LST** — batch across all selected sites × times.
77
+ 5. **Validate** — load a retrieved-LST CSV (`site, overpass_time_utc, lst_k`),
78
+ the tool auto-computes ground truth for each row, pairs, and shows
79
+ bias / RMSE / R + an embedded scatter plot (retrieved vs ground, 1:1 line).
80
+ 6. **Export** the enriched CSV (retrieved LST + ground LST + diff + emissivity).
81
+
82
+ **Sample data** is in `samples/`:
83
+ - `retrieved_sample.csv` — 9-site multi-network demo (SURFRAD ×7 + HiWATER ×2).
84
+ - `validation_template.csv` — all 25 sites pre-filled (fill in time + your LST).
85
+
86
+ **Linux note:** the GUI needs `libxcb-cursor0`:
87
+ ```bash
88
+ sudo apt install -y libxcb-cursor0 libegl1 libgl1
89
+ ```
90
+
91
+ ## Library usage (script / notebook)
92
+
93
+ Compute ground-truth LST for one site/time:
94
+
95
+ ```python
96
+ from datetime import datetime, timezone
97
+ from lstnet import compute_ground_lst, FixedEmissivity
98
+ from lstnet.sites import get_site
99
+ from lstnet.io.surfrad import SurfradReader
100
+
101
+ site = get_site("psu")
102
+ t = datetime(2011, 2, 12, 14, 30, tzinfo=timezone.utc)
103
+ g = compute_ground_lst(site, t, FixedEmissivity(0.98), SurfradReader())
104
+ print(g.lst_k, g.qc_flag) # e.g. 270.15 OK
105
+ ```
106
+
107
+ Validate ground truth against your retrieved LST:
108
+
109
+ ```python
110
+ from lstnet import validate, TableRetrievedLST
111
+ from lstnet.plotting import scatter_plot
112
+
113
+ ground = [compute_ground_lst(s, t, FixedEmissivity(0.98), SurfradReader())
114
+ for s, t in your_site_times]
115
+ result = validate(ground, TableRetrievedLST("your_retrieval.csv"))
116
+ print(result.stats.bias, result.stats.rmse, result.stats.r)
117
+ scatter_plot(result) # retrieved-vs-ground with 1:1 line
118
+ ```
119
+
120
+ `your_retrieval.csv` columns: `site, overpass_time_utc, lst_k[, source]`
121
+ (`overpass_time_utc` = 12-digit `YYYYMMDDHHMM` or ISO 8601, UTC).
122
+
123
+ ## MCP server (AI agent integration)
124
+
125
+ ```bash
126
+ lstnet-mcp # start the FastMCP server
127
+ ```
128
+
129
+ Exposes three tools that an AI agent (Claude Desktop, etc.) can call:
130
+ `list_sites`, `compute_lst`, `validate_csv`.
131
+
132
+ ## Features
133
+
134
+ - **Ground-truth LST** from SURFRAD (NOAA, HTTPS) / PKULSTNet / HiWATER
135
+ station data, at satellite overpass times (Stefan–Boltzmann radiance inversion).
136
+ - **Emissivity sources**: `FixedEmissivity` (offline), `ModisDailyEmissivity`
137
+ (MYD21A1D/A1N C6.1, Ogawa 2004 broadband), `AsterGEDEmissivity`
138
+ (AG100 V003 climatological, Cheng & Liang 2014 broadband — recommended for
139
+ sub-K validation).
140
+ - **Validation engine**: pair ground-truth + retrieved LST by `(site, overpass
141
+ time)` within a tolerance; bias / RMSE / Pearson R / regression; scatter +
142
+ time-series plots.
143
+ - **GDAL-free**: MODIS HDF4 via `pyhdf`, ASTER GED HDF5 via `h5py`, GeoTIFF via
144
+ `rasterio` — all ship pip wheels, no system GDAL install.
145
+ - Quality control (configurable `strict`), day/night (astral), credential
146
+ externalization, CWD-independent paths.
147
+ - **Cross-platform**: tested on Windows / macOS / Linux via GitHub Actions CI.
148
+
149
+ ## Platform notes
150
+
151
+ | Platform | Status | Notes |
152
+ |----------|--------|-------|
153
+ | Linux | ✅ Full | GUI needs `libxcb-cursor0 libegl1 libgl1` (apt install) |
154
+ | macOS (Intel + Apple Silicon) | ✅ CI green | Native Qt backend; no extra libs |
155
+ | Windows | ✅ CI green | Native Qt backend; no extra libs |
156
+
157
+ All binary dependencies (pyhdf, h5py, rasterio, PySide6) ship pip wheels for
158
+ all three platforms — no compilation needed.
159
+
160
+ ## Citing
161
+
162
+ See [`CITATION.cff`](CITATION.cff).
163
+
164
+ ## License
165
+
166
+ MIT — see [`LICENSE`](LICENSE).
lstnet-0.1.0/PRD.md ADDED
@@ -0,0 +1,99 @@
1
+ # Product: LST
2
+ # Current Version: 1.0.0
3
+ # Last Updated: 2026-06-19
4
+ # Status: active
5
+
6
+ ## 0. 使用说明
7
+ > PRD 只管"造什么":产品定义、范围、功能、进度、决策。
8
+ > 技术架构/命令/规范 → `CLAUDE.md`;安装/部署/测试 → `README.md`。
9
+ >
10
+ > 更新规则:
11
+ > - 长期稳定信息:直接覆盖更新,保持"当前真实状态"
12
+ > - 短期流动信息:追加记录,保留时间线
13
+ > - 每次任务结束前,检查是否需要更新本文件
14
+
15
+ ## 1. 当前快照
16
+
17
+ - **当前阶段**: discovery
18
+ - **当前目标**:
19
+ - **下一步**:
20
+
21
+ ## 2. 当前进度
22
+ > 路线图/阶段规划只在此处维护,不在 §5 重复。
23
+
24
+ ### 2.1 In Progress
25
+ - [ ]
26
+
27
+ ### 2.2 Next Up
28
+ - [ ]
29
+
30
+ ### 2.3 Blocked
31
+ -
32
+
33
+ ## 3. 最近决策记录
34
+ > 只保留最近 5-10 条仍然影响当前工作的决策。
35
+
36
+ | Date | Decision | Why | Impact |
37
+ |------|----------|-----|--------|
38
+ | 2026-06-19 | 项目初始化 | 创建 PRD 文档 | 建立产品基线 |
39
+
40
+ ## 4. 版本历史
41
+ > 规则:新版本追加在最上方。超过 5 个版本时,最旧的压缩为一行摘要。
42
+
43
+ ### **V1.0.0 - 2026-06-19 - (Initial Release)**
44
+ - 项目初始化,创建 `PRD.md`
45
+
46
+ ## 5. 产品核心规范
47
+ > 此区域始终反映产品"当前真实状态",每次迭代直接更新。
48
+
49
+ ### 5.1 核心目标
50
+
51
+ ### 5.2 用户画像
52
+
53
+ ### 5.3 范围定义
54
+ #### In Scope
55
+ -
56
+
57
+ #### Out of Scope
58
+ -
59
+
60
+ ### 5.4 核心功能
61
+ -
62
+
63
+ ### 5.5 领域实体
64
+ > 描述业务数据模型,不绑定具体框架实现。
65
+
66
+ ### 5.6 业务用例
67
+ > 描述业务规则与流程,不写技术实现细节。
68
+
69
+ ### 5.7 ASCII UI 原型图(可选)
70
+ > 架构图和系统交互图放 `CLAUDE.md`,不放此处。
71
+
72
+ ### 5.8 技术实现规范
73
+ > 仅保留"项目技术决策与质量标准",不放 AI 代理行为规则。
74
+
75
+ ## 6. 当前风险与假设
76
+ ### 6.1 Risks
77
+ -
78
+
79
+ ### 6.2 Assumptions
80
+ -
81
+
82
+ ## 7. 工作日志
83
+ > 只保留最近 5 条。更早的删除——git log 是权威来源。
84
+ > 每条简短、事实化:背景 → 动作 → 结果 → 后续。
85
+
86
+ ### 2026-06-19 - 项目初始化
87
+ - 创建 PRD.md 文档
88
+
89
+ ## 8. 并行开发记录
90
+
91
+ > **规则**:worktree 中只能编辑当前分支名的子节;全局内容只能回 main 修改。
92
+ > 分支合并后,将结论吸收到正式章节,删除该分支子节。每个子节只记 3 项:进展、卡点、是否影响全局设计。
93
+
94
+ <!-- 活跃分支在此添加子节,格式:
95
+ ### <branch-name>
96
+ - **进展**:
97
+ - **卡点**:
98
+ - **影响全局**:是/否,说明:
99
+ -->
lstnet-0.1.0/Pipfile ADDED
@@ -0,0 +1,34 @@
1
+ [[source]]
2
+ url = "https://pypi.tuna.tsinghua.edu.cn/simple/"
3
+ verify_ssl = true
4
+ name = "pypi"
5
+
6
+ [packages]
7
+ sys = "*"
8
+ pytz = "*"
9
+ pandas = "*"
10
+ os = "*"
11
+ io = "*"
12
+ random = "*"
13
+ requests = "*"
14
+ astral = "*"
15
+ glob = "*"
16
+ urllib-request = "*"
17
+ shutil = "*"
18
+ numpy = "*"
19
+ matplotlib-pyplot = "*"
20
+ osgeo = "*"
21
+ "bs4" = "*"
22
+ DateTime = "*"
23
+ "PyQt5" = "*"
24
+ PIL = "*"
25
+ pyModis = "*"
26
+ matplotlib = "*"
27
+ gdal = {path = "C:/Users/85816/Desktop/GDAL-3.2.1-cp38-cp38-win_amd64.whl"}
28
+ lxml = "*"
29
+ openpyxl = "*"
30
+
31
+ [dev-packages]
32
+
33
+ [requires]
34
+ python_version = "3.8"