Files
fmq b058e66722 feat(all): NaN 伪收敛否决与 nl_tight 能量回退、emflux 检验 4π 修正、nst 行宽与种子边界修复、gfATO 谱线表接通与网格加密 9216 点、阶段分项统计与跳板机部署
物理修复(400 失败点归因,见 docs/failed400_nan_pseudo_convergence_2026_08_17.md):
- runner: 阶段 converged 后复查 fort.7,含 NaN/Inf 即否决(fort.9 全零伪收敛,
  曾致 261 点误跳过 nl_direct 回退);否决阶段不产出种子,阻断污染传播
- runner: nl_tight 回退——仅能量边际失败时以 CHMAX 收紧 10× 从自身模型续迭代,
  残差降幅 ~10×;execute_tlusty_stage 抽取供主链与回退共用
- conv_check: fort.14 为 Eddington 通量 Hλ,积分需乘 4π 再比 σTeff⁴
  (旧版 ratio 稳定 0.0796=1/4π,全点系统性假阳性)+ 回归测试
- nst_writer: 单行超 80 字符被 TLUSTY 静默截断,IFALI/JALI/TRAD 等从未生效;
  按 75 字符自动换行
- seed_finder: Teff 容忍度改含边界 <=,相邻 5000K 档恢复互为种子 + 回归测试

谱线表与网格:
- 默认线表 gfVIS99 → gfATO(全波段 18-23000Å),TaskSpec.linelist 支持工作流
  级覆盖,节点按需下载(进程互斥锁防并发重复下载 238MB)
- sdB_cno Teff 加密至 5000K 步长,432 → 9216 点;tlusty/synspec 静态二进制更新

统计与部署:
- grid 汇总改按 tlusty_status/synspec_status 分项计数,新增 tlusty_failed/
  synspec_failed/synspec_pending,前端详情页双视图适配
- deploy/fetch_results 支持跳板机 ProxyJump 与 SSH 主连接复用,fetch 新增 --force;
- Docker 构建支持 CARGO_MIRROR/USE_MIRRORS 国内镜像参数;移除 tools/ 拷贝
- 新增 tlusty-synspec-test skill 与 6 篇根因分析/验证文档
2026-08-17 23:55:26 +08:00

79 lines
4.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SYNSPEC 输入与执行详解
参考源码:`dcts/crates/common/src/fort55_writer.rs`fort.55 生成)、`config.rs:1184` `SynspecInput`
## SYNSPEC 做什么
给定一个**收敛的 TLUSTY 大气**fort.7/fort.8),SYNSPEC 合成指定波长范围的理论光谱(emergent flux vs wavelength)。输出:连续谱 + 谱线 + 谱线标识。
## 输入文件
| 文件 | 来源 | 说明 |
|---|---|---|
| `fort.5` | SYNSPEC stdin(模型描述) | 与 TLUSTY 的 `.5` 不同;含模型 TEFF/丰度/模式开关。测试里通常从已验证输入复制 |
| `fort.55` | `fort55_writer.rs` 生成 | 控制卡,**恰好 9 行**(有回归测试) |
| `fort.8` | 收敛大气的 `.7` 复制 | 输入大气;TEFF/丰度须与 fort.5 一致 |
| `fort.19` | `assets/data/gfATO.dat` 软链 | 原子线表(全波段,1823000 Å,~238MB278 万条线) |
| `data/` | `assets/data/` 软链 | 原子数据(与 TLUSTY 共用) |
> 可见光子集线表 `assets/gfVIS99.dat`30007000 Å)用于窄段测试;全波段用 `gfATO.dat`。
## fort.55 九行控制卡(逐行)
`fort55_writer.rs:26 generate_fort55_content()`,每行 1-to-1 对应 `synspec54.f` 的一个 `READ(55,*)`
| 行 | 变量 | 默认 | 说明 / 源码行 |
|---|---|---|---|
| 1 | `IMODE IDSTD IPRIN` | `0 0 1` | `synspec54.f:253` |
| 2 | `INMOD INTRPL ICHANG ICHEMC` | `1 0 0 0` | `:254` |
| 3 | `IOPHLI nunalp nunbet nungam nunbal` | — | `:255` 氢线开关 |
| 4 | `IFREQ INLTE ICONTL INLIST IFHE2` | — | `:2146`。**注意 IFREQ 在这行第1列**,不是第1行(历史错位 bug,已加回归测试) |
| 5 | `IHYDPR IHE1PR IHE2PR` | — | `:2148` 氢/氦线详细处理开关 |
| 6 | `ALAM0 ALAST CUTOF0 CUTOFS RELOP SPACE` | `1400.0 1410.0 10 0 0.0001 0.01` | `:2149` **波长范围与采样**。ALAM0=起始 Å,ALAST=结束 Å,RELOP=相对采样步长,SPACE=绝对步长。波长用 `:.1` |
| 7 | `nmlist [iunitm...]` | `0` | `:2208`IMODE∈[-3,1] 时读)。**分子列表行**,必须独占一行,否则会吞掉下一行的 VTB |
| 8 | `VTB` | `-1.0` | `:2251` 微观湍流速度 km/s。**负值**=`-1.0` 表示"不覆盖大气自身 vturb"(来自 TLUSTY 的 2 km/s);正值会触发 `vtb²·1e10` 覆盖 |
| 9 | `NMU0 ANG0 IFLUX` | — | `:2301`IFWIN≤0 时读)角度网格 |
`SynspecInput::validate()``config.rs:1238+`)会拒绝触发不支持的条件 READ 的配置(如 `inmod>0 && intrpl>0` → DM 数组 READ`nmu0<0` → 显式角度数组 READ)。
### 常见波长范围配置(line 6)
- 窄段验证(官方测试):`1400.0 1410.0 ...`
- 可见光:`3000.0 7000.0 ...`
- 全波段:`100.0 20000.0 10 0 0.0001 0.01`SYNSPEC 可靠边界 10023000 Å)
## 输出文件(SYNSPEC 产物)
| fort.* | 复制为 | 内容 |
|---|---|---|
| `fort.7` | `.spec` | 合成光谱(emergent flux vs λ,主产物) |
| `fort.17` | `.cont` | 连续谱 |
| `fort.12` | `.iden` | 谱线标识 |
| `fort.11` | `.lindat` | 谱线数据 |
模板 `assets/run_synspec.sh`:切 `run/` → 复制 fort.5/fort.55/fort.8 + 建软链 → `timeout 1200 synspec_static < fort.5 > synspec.log 2> synspec.err` → 产物复制到 `outputs/{name}.spec/.cont/.iden/.lindat`
## NaN 修复背景(重要)
`synspec_static``-ftoplevel-reorder` 编译,破坏了 SYNSPEC COMMON 块初始化顺序,导致 **Balmer 系限 3646 Å 之后整段 NaN**73% 数据点失效)。修复版用 `-O3 -fno-toplevel-reorder`,全波段 0 NaN。
**验收 SYNSPEC 必查**:分段统计 NaNEUV 100912 / UV 9123646 / 可见 36468200 / NIR 820020000),尤其 36468200 段(旧 bug 重灾区)。详见 `docs/synspec_nan_fix_2026_08_11.md`
## SYNSPEC 校验判据
| 判据 | 工具 | 通过条件 |
|---|---|---|
| 无 NaN/Inf/坏行 | `grep -ciE 'nan\|inf\|\*{3,}' fullband.spec` | = 0 |
| 波长范围正确 | `head -1 / tail -1 fullband.spec` | 首/尾 λ ≈ ALAM0/ALAST |
| 通量物理 | 抽查关键 λ(Lyα 1216、Balmer 3646/6563 | 有限、非全零、形态符合 Teff |
| 谱形 | EUV 峰 → 长波单调下降 | 与 Teff 一致(热星 EUV 占优) |
> 注:深吸收线心可能有少量微负通量(数值残差),不是 NaN/Inf,不影响"0 NaN"结论。绘图时把负通量裁成 NaN 即可。`spec_is_valid``conv_check.rs:290`)只判 NaN/Inf/坏行。
## 官方 Runtest 结构(源码侧参考)
`tests/synspec/{hhe,bstar,kurucz,hybrid,pseudonlt,optab}/``R1` 调用 `RSynspec`
```
$TLUSTY/RSynspec hhe35nl fort.55.con data/gfATO.dat
```
`RSynspec` 做的事:`cp $1.7 fort.8`(输入大气);`ln -s $2 fort.55`(控制卡);`ln -s $3 fort.19`(线表);`synspec.exe < $1.5 > results/$1.log``cp fort.7/17/12 results/$1.spec/.cont/.iden`。Kurucz 测试还演示了不用 RSynspec 直接手动链软链 + 跑二进制的写法(见 `tests/synspec/kurucz/R1` 第二段)。