Real-time LPW 项目交接与上下文恢复报告
用途:在新的 Codex/ChatGPT 会话中,先完整阅读本文件,再修改本项目。
最近整理:2026-11-01(Asia/Shanghai) 整理时分支:main
整理前基准提交:e95bb886104bca17aad2561601a1f71ec3b905e6
1. 新会话快速恢复清单
- 阅读本文件和
lpw/pipeline/README.md。 - 查看
git status --short,不得覆盖或还原用户已有修改。 - 根据任务只检查相关文件,不要重新设计整个页面。
- 修改网页 JavaScript 后递增
lpw/index.html中assets/lpw.js?v=...的缓存版本。 - 修改 CSS 后递增对应的 CSS 缓存版本。
-
至少执行:
node --check lpw/assets/lpw.js python -m unittest -v test_lpw_model.py git diff --check模型测试命令需在
lpw/pipeline目录运行。 - 涉及交互和布局时启动本地静态服务器并进行浏览器验证。
- 除非用户明确要求,不要自动提交、推送、删除历史数据或运行云端工作流。
- 完成修改后更新本报告中的“当前实现”“已知限制”和“修改记录”。
2. 项目身份与路径
- 项目:实时分层可降水量(Layered Precipitable Water, LPW)监测平台。
- 线上地址:
https://wuyuhao.top/lpw/ - GitHub Pages 原始域名:
https://wyhgnss.github.io/lpw/ - GitHub 仓库:
https://github.com/wyhgnss/wyhgnss.github.io - 本地仓库:
C:\Users\Administrator\Documents\GitHub\wyhgnss.github.io - 默认分支:
main - 个人主页顶部菜单配置:
_data/navigation.yml - LPW 页面入口:
lpw/index.html - 页面语言:英文。
- 视觉主题:暗色、半透明信息卡、真实地球和卫星背景。
3. 科学模型定义
3.1 层结定义
- Low layer:surface–900 hPa。
- Middle layer:900–700 hPa。
- High layer:700–300 hPa。
页面中所有标题、图例和三维层名必须保持以上定义。
3.2 MATLAB 原始逻辑
原 MATLAB 核心调用:
[pl, pm, ph] = getP(LAT2, LON2, DOY2, PSHAX_COEFF);
[LPW_Low, LPW_Mid, LPW_High] = getLPW(pl, pm, ph, LAT2, LON2, H2, DOY2, TPW2);
getP:根据周期函数系数和年积日计算三层比例。getLPW:用 XGBoost 对三层初始 LPW 进行残差修正。- MIMIC 网格的经纬度和 DEM 固定。
- 初始层值为
p × TPW,最终层值为p × TPW + residual。 - XGBoost 输入顺序固定为:
latitude, longitude, elevation, day_of_year, TPW。 - XGBoost 输出顺序固定为:
low, middle, high三个残差。
Python 实现在 lpw/pipeline/lpw_model.py:
- 周期项为
[1, cos(phase), sin(phase), cos(2 phase), sin(2 phase)]。 phase = DOY / 365.25 × 2π。- 输出中的无效 TPW 保持为
NaN。
4. 模型文件与更新规则
4.1 用户原始模型位置
- 周期系数:
H:\LPW模型\MIMIC\PSHAX_COEFF.mat - XGBoost 模型:
H:\LPW模型\MIMIC\xgb-gpu.pkl - 原 MATLAB 案例目录:
H:\LPW模型\MIMIC
4.2 网站使用的转换后模型
目录:lpw/pipeline/model/
| 文件 | 用途 | 2026-10-29 SHA-256 |
|---|---|---|
pshax_coefficients.npz |
Low/Middle/High 的 5 项周期系数 | c1bf8774bf3eb183ef7a57fa57f24a49327fd84d332217a49d0240f6d697c4e0 |
residual_model.ubj |
可在 GitHub Actions CPU 环境运行的 XGBoost Booster | 421f1f89bee8e8790a547acd0d19713ef3bcb2e37fe4395b695c67a59175a7db |
mimic_grid.npz |
固定纬度、经度和高程网格 | 271f9256d5a6521a334649f4cf4add10c060665e2e7a083338a867fbafcf7ee5 |
当前三个文件总计约 84.6 MB。仓库是公开仓库,因此这些模型资产也是公开的。
4.3 更新模型时必须遵守
- 不要把
.mat或 GPU pickle 直接用于 GitHub Actions。 - 将 MATLAB 系数转换为
float32NPZ,并确认 Low/Middle/High 三组数组维度和方向正确。原始系数网格为 0.25°,单层典型形状为(5, 721, 1440)。 - 将 pickle 中的 XGBoost Booster 导出为 UBJ,并明确配置为 CPU 可推理版本。
- 保持五个输入特征的顺序和三个输出残差的顺序不变。
- 对代表性样本比较原模型与 UBJ 模型预测;此前转换验证为逐点一致。
- 运行
test_lpw_model.py。测试包括 MATLAB 参考点的getP对比和 CPU 网格推理。 update_data.py会根据三个模型文件计算model_version指纹。模型指纹变化后,下一次工作流会清空旧模型帧的逻辑基础并重新计算 72 小时滚动档案;首次运行可能显著变慢。- 当前转换过程没有独立脚本保存在仓库中。下次更新模型时,应优先补充可重复的转换脚本,并保留新旧模型一致性验证。
当前 manifest.json 中的模型版本指纹为:8ef88f351066a8de。
5. 数据管线
5.1 数据源
- MIMIC-TPW 根目录:
https://bin.ssec.wisc.edu/pub/mtpw2/data/ - 文件形式:按月份目录组织的 NetCDF,例如
compYYYYMMDD.HH0000.nc。 - 源数据分辨率:0.25°。
- 页面发布分辨率:1°,由
stride=4采样得到。
5.2 Python 文件
lpw/pipeline/update_data.py:查找、下载、计算、压缩并发布最近 72 小时数据。lpw/pipeline/lpw_model.py:MATLABgetP/getLPW的 Python 实现。lpw/pipeline/test_lpw_model.py:模型一致性和 CPU 推理测试。lpw/pipeline/requirements.txt:固定依赖版本。
当前依赖:
h5py==3.12.1
numpy==2.1.3
requests==2.32.3
xgboost==3.4.1
5.3 浏览器数据格式
- 清单:
lpw/data/manifest.json - 帧目录:
lpw/data/frames/ - 档案长度:最近 72 个小时。
- 单帧:gzip 压缩的 little-endian
int16。 - 数组顺序:layer-major,依次为 Low、Middle、High。
- 当前显示网格:181 × 360。
- 比例:
0.01 mm。 - 缺测值:
-32768。 - 文件名:
YYYYMMDDTHHMMSSZ.bin.gz。
5.4 网络健壮性
- MIMIC 请求使用重试机制,覆盖
429/500/502/503/504。 - 根目录和月份目录超时为 30 秒,NetCDF 下载超时为 120 秒。
- 页面数据读取也会重试。
- 时间序列以 4 个并发 worker 加载 72 帧;单个帧失败时保留空缺,不让整张时间序列失败。
6. 前端当前实现
6.1 主要文件
lpw/index.html:页面结构和英文文案。lpw/assets/lpw.css:暗色主题、响应式布局和组件样式。lpw/assets/lpw.js:数据加载、地图、三维图、播放和时间序列。lpw/assets/coastlines.json:本地海岸线。lpw/assets/hero-earth-satellite.png:顶部真实地球和卫星背景。lpw/assets/team-logo.png:INSIGHT Team 标志。lpw/assets/wuhan-university-logo.png:武汉大学校徽。
6.2 品牌与文案
- 左上品牌:
PSHX / LPW,为普通div,点击不会跳转主页。 - 主标题:
Layered precipitable water from surface to sky,无结尾标点。 - 团队名:
INSIGHT Team。 - 学校组件:
Wuhan University/School of Geodesy and Geomatics。 - 顶部四个组件顺序:
- 左上:Wuhan University。
- 右上:Research group。
- 左下:Analysis time。
- 右下:Selected point。
- 四个组件使用暗黑半透明背景。
- Analysis time 同时显示 UTC 和 Beijing
(UTC+8);北京时间为蓝绿色、小号、正常字重并尽量不换行。
6.3 平铺视图
- 使用原生 Canvas 直接绘制三个全球 LPW 栅格。
- 不使用在线底图,不实现缩放和平移。
- 叠加本地海岸线。
- 地图内部不显示经纬网文字。
- 色标固定为 0–40 mm。
- 点击任意层地图选择最近网格点,并在下方加载 72 小时时间序列。
- 当前播放间隔:
80 ms,约 12.5 帧/秒。
6.4 三维叠放视图
- 使用 Plotly 三个
surface图层。 - Low/Middle/High 的高度间隔由
layerGap = 4控制。 - 三维图支持 Plotly 自带旋转、缩放。
- 悬停记录经纬度,点击三维表面后加载相同的 72 小时时间序列。
6.5 时间序列
- 三条线分别代表 Low、Middle、High。
- 悬浮标签只显示数值和
mm,不显示日期时间,也不在数值旁重复显示 Low/Middle/High。 - 日期时间通过横坐标读取。
- 图例仍保留层名,便于识别三条线。
6.6 历史 GNSS LPW 查询模块
- 模块位于页面底部、MIMIC 三日时间序列之后。
- 原始数据:
H:\LPW模型\GNSSLPW.mat。 - 原数据时间范围:2015-01-01 至 2025-12-08;
TIME2未设置时区,因此页面明确标注为 dataset time,不擅自解释为 UTC。 - 原始观测 803,855 条;去除 56 组数值完全一致的重复时刻—站点记录后,发布 803,799 条。
- 包含 20,721 个时刻和 211 个站点元数据,历史观测实际覆盖 186 个站。
- 浏览器数据位于
lpw/data/gnss/:manifest.json:时刻、时刻偏移和站点名称/编号/经纬度。observations.bin.gz:约 4.06 MB 的稀疏压缩观测。
- 二进制按
time_index (uint16)、station_index (uint8)、Low/Middle/High (int16) 分数组保存;比例为 0.01 mm。 lpw/pipeline/export_gnss_history.m可从原 MAT 文件重新生成数据。lpw/pipeline/test_gnss_export.py验证压缩文件长度、索引范围、时刻偏移和记录计数。- 页面脚本:
lpw/assets/gnss.js。 - 日期控件选择日期,时刻下拉框列出该日实际存在的全部观测时间;前后按钮逐观测时刻移动。
- 平铺视图使用三个 Plotly 全球散点地图,共用 0–40 mm 色标和海岸线。
- 三维视图使用三个分层
scatter3d站点层,并在各层叠加海岸线。 - 某时刻没有数据的站点不绘制、不补值,也不会导致页面报错。
- 点击平铺或三维站点后,下方只使用该站真实存在的时刻绘制完整 Low/Middle/High 折线;不再把该站铺到全部全局时刻后插入大量
null,因此零散缺站不会把折线切碎。
7. GitHub Actions
7.1 LPW 工作流
文件:.github/workflows/update-lpw.yml
- 名称:
Update real-time LPW。 actions/checkout@v5和actions/setup-python@v6,避免旧 Node.js 20 Action 警告。- 运行环境:Ubuntu + Python 3.12。
- 超时:180 分钟。
- 权限:
contents: write、pages: write。 - 并发组:
update-lpw,cancel-in-progress: false。 - 完整更新命令:
python update_data.py --hours 72 --max-new 8。 - 成功后由
github-actions[bot]提交lpw/data,随后请求 Pages 重建。
7.2 当前定时可靠性方案
GitHub 官方说明 schedule 可能延迟,负载高时甚至丢弃排队任务。项目曾在一天内只于约 03:34、08:00、13:47 自动成功,分别一次补入 5、4、6 个小时的数据。
当前补偿方案:
schedule:
- cron: "13,43 * * * *"
- 每小时第 13 和 43 分钟各尝试一次,避开整点高负载。
- 工作流首先拉取默认分支最新内容。
- 若
manifest.updated_at距当前不足 45 分钟,备用运行快速跳过所有安装、测试和模型计算。 - 若第一个触发被丢弃或失败,第二个触发可补跑。
workflow_dispatch手动触发始终执行完整更新,不受 45 分钟门限影响。- 这能提高可靠性,但 GitHub cron 仍不提供严格 SLA。若未来必须保证每小时执行,应增加外部调度服务通过 GitHub API 触发
workflow_dispatch。
7.3 另一个独立工作流
.github/workflows/download_TPW_gif.yml 是旧的 TPW PNG/GIF 下载任务,与 LPW 模型更新是两套独立流程。修改 LPW 时不要误删或混用。
8. 部署流程
- 在本地仓库修改并验证。
- 用户通常通过 GitHub Desktop 提交并推送到
main。 - GitHub Pages 使用自定义域名,
CNAME文件必须保留。 _config.yml排除了lpw/pipeline,因此计算代码和模型不是页面运行时资源;Actions 仍可在仓库检出后使用它们。lpw/data必须纳入发布内容,否则静态页面无法读取 LPW 数据。- 每次前端资源更新后检查浏览器缓存版本参数。
本地预览:
python -m http.server 8768 --bind 127.0.0.1
然后访问:http://127.0.0.1:8768/lpw/。
9. 验证命令
9.1 前端
node --check lpw/assets/lpw.js
git diff --check
浏览器人工检查:
- 页面无控制台错误。
- 三张平铺图、海岸线和 0–40 mm 色标正常。
- Play/Pause、前后帧和时间滑块正常。
- 点击平铺图能显示所选点和三条时间序列。
- 时间序列悬浮标签没有日期时间和层名重复框。
- 切换 3D 后三层间隔明显,点击后也能显示时间序列。
- Analysis time 的 UTC 与北京时间相差 8 小时。
- 手机和桌面宽度下卡片不溢出。
9.2 模型
在 lpw/pipeline:
python -m pip install -r requirements.txt
python -m unittest -v test_lpw_model.py
必要时本地更新数据:
python update_data.py --hours 72 --max-new 2
注意:此命令会修改 lpw/data,运行前先确认用户是否希望更新本地档案。
GNSS 数据导出后验证:
python -m unittest -v test_gnss_export.py
GNSS 浏览器人工检查:
- 默认显示最新可用 GNSS 时刻。
- 修改日期后,时刻下拉框只出现该日的有效时刻。
- 站点计数随时刻改变;缺站时仍正常绘制。
- Flat maps 和 3D stack 均能显示三层站点散点及 0–40 mm colorbar。
- 点击任一站点后显示站名、站号、坐标和三层完整历史折线。
9.3 Workflow
- 验证 YAML 可解析。
- 检查
schedule是否仍位于默认分支。 - 检查 Actions 是否处于启用状态。
- 区分“工作流触发时间”“开始执行时间”“完成/提交时间”;并发排队和 GitHub 延迟会使它们不同。
- 查看失败日志时重点检查:MIMIC 502、下载超时、模型测试、超时、
git pull --rebase冲突和 push 权限。
10. 已知限制与风险
- GitHub
schedule不能绝对保证准点或不丢任务;当前双时段方案只是提高成功率。 - MIMIC 服务器偶尔返回 502;前后端均有重试,但连续故障仍会失败。
- 72 帧点选历史需要下载大量小文件,首次加载取决于网络和 GitHub Pages CDN。
- 平铺图刻意不提供底图、缩放和平移,以保持稳定的栅格对齐。
- 模型和系数在公开仓库中可被下载。
- 模型转换尚未脚本化,是未来最值得补齐的可重复性环节。
- 模型指纹变化后的首次 72 小时重算可能接近或超过普通小时任务耗时。
- 浏览器需要支持
DecompressionStream;页面已对旧浏览器给出错误提示。 - GNSS 原始
TIME2没有时区元数据;除非获得用户确认,不应改标为 UTC 或北京时间。 - GNSS 历史数据约 4.9 MB(清单加压缩观测),首次访问需额外下载;之后可由浏览器缓存。
11. 修改原则
- 保持平台英文界面,不随意更改品牌、层定义和科学术语。
- 不恢复在线底图或平移缩放,除非用户明确重新提出。
- 不改变模型输入/输出顺序。
- 不对 0.25° 系数、1°发布网格和经纬度行列方向做未经验证的转置。
- 不把 GPU-only 模型放入 Ubuntu CPU Actions。
- 不把三个图层分别归一化;共用固定 0–40 mm 色标才能跨层、跨时次比较。
- 不因为某个历史帧失败而让整条时间序列报错。
- 不在未确认的情况下提交或推送。
12. 建议的新会话开场提示
可直接向新会话发送:
请先完整阅读仓库根目录的
LPW_PROJECT_HANDOFF.md和lpw/pipeline/README.md,再检查git status。本次只修改我接下来指定的内容,保留现有模型、数据格式、品牌、层定义和 Actions 补偿策略。修改后执行报告中的相应验证,并更新交接报告;不要自动提交或推送。
13. 修改记录
- 2026-10-29:建立本交接报告。
- 2026-10-29:当前平铺播放速度为 80 ms/帧;时间序列悬浮只显示数值和单位。
- 2026-10-29:LPW Action 改为每小时第 13/43 分钟双触发,并增加 45 分钟新鲜度门限。
- 2026-10-31:加入历史 GNSS LPW 查询模块、MATLAB 可重复导出脚本、稀疏压缩数据和导出测试。
- 2026-11-01:修复 GNSS 单站历史折线被全局缺测时刻大量切断的问题,改为按该站实际观测时刻连续绘制。