Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 24 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@

LamellarSAXS2D reads calibrated detector frames (CBF, EDF, TIFF, NPY/NPZ, HDF5), builds physical `q`, `chi`, `qx`, and `qy` from a PONI file through pyFAI, traces observed butterfly arcs, and reports what the image actually supports:

| A typical frame reports | Only when an interior ellipse is supported |
| A typical frame reports | Only when a radial reflection or interior ellipse is supported |
| --- | --- |
| First-order `q*` and **L ring** = `2π/q*` | Apparent `a`, `b/a`, `θ` |
| Occupied sides, quality, and flags | Unpublished **Ln / Lz / L major** candidates |
| q-ring profiles, observed petal trajectories, quality, and flags | First-order `q*` and **L ring** = `2π/q*` |
| Occupied sides and supported branches | Apparent `a`, `b/a`, `θ` |
| Missing lobes/rings remain missing | Unpublished **Ln / Lz / L major** candidates |
| `ring` when the fit sits on a bound or the major axis runs away | Never a silent overwrite of user bounds or of ring L into the Ln column |

`success=True` is not scientific acceptance. Pixel-q never invents a physical period. Opposite quadrants are never fabricated.
Expand All @@ -25,11 +26,14 @@ Synthetic demonstration (pixel-q): the Wang/Grubb double ellipse drawn on a gene
## What it does

- **Butterfly arcs** (`ridge_method=butterfly_curvature`): curvature ridges, branch/side labels (QI+QIII vs QII+QIV), first-order family vs harmonics, sparse-ring fill. See the [butterfly arc guide](docs/butterfly_arcs_zh.md).
- **Annular butterfly trajectories**: the new workbench session defaults to fixed-q annuli and angular profiles `I(χ)`, connecting up to four observed lobe maxima into long butterfly petals. Each ring retains its raw profile, counts, and coverage; missing lobes/rings remain missing. See the [annular trajectory guide](docs/annular_trajectories_zh.md).
- **Independent radial diagnostics**: `radial_sector` measures fixed-χ `I(q)` profiles for a separate check. Its `q*` values are not the default butterfly trajectory or the primary ellipse input. See the [radial-sector guide](docs/sector_peaks_zh.md).
- **Honest ellipse publication**: `flat_ellipse` (editable `b/a` bounds, default `0.005–0.35`) and `very_flat_ellipse`. A cap, floor, or major axis longer than the observed first-order ridge is **ring-only** — `a`, tilt, and ellipticity stay unpublished.
- **Batch review**: independent frames, cancel/progress, checkpoints, streaming CSV/JSON/NPZ. The table shows `WARN · ring` / `WARN · ellipse`, L ring, and candidate-period tooltips. Warm-start stays quality-gated.
- **Workbench**: Identify arcs → Evaluate; bilingual UI; first-order ring overlay instead of a capped tilted ellipse; lamellar studio and 0.4 publication artboards are schematics, not a unique inversion ([studio](docs/lamellar_workbench_zh.md), [figures](docs/publication_figures_zh.md)).
- **Workbench**: Identify trajectories → Evaluate; bilingual UI; first-order ring overlay instead of a capped tilted ellipse; lamellar studio and 0.4 publication artboards are schematics, not a unique inversion ([studio](docs/lamellar_workbench_zh.md), [figures](docs/publication_figures_zh.md)).
- **Optional `full2d`**: empirical whole-pixel intensity refinement. It is a different model from the butterfly geometry measurement.
- **Measurement and fit figures**: export fixed-size SVG/PDF and high-resolution TIFF/PNG with source arrays, curve/profile CSVs, and checksums. Inspect measured data, candidate ellipses, overlays, and actual `full2d` predictions without promoting a candidate to a scientifically accepted result. See the [figure export guide](docs/butterfly_figures_zh.md).
- **Figure delivery**: choose column width and resolution in one export window, then browse the complete figure bundle offline through `index.html`. Annular/radial source CSV and technical figure checks accompany the images; formatting checks do not imply scientific acceptance.
- **Peak diagnostics**: locate the raw brightest pixel separately from supported lobe peaks; inspect measured/model peak positions, local zooms, angular/radial profiles, and clean overlays from each fit source. Peak coordinates and support flags also travel through batch exports.
- **Preflight and P3/P4 gates**: read-only package checks and evidence reports. They do not freeze science or replace named human review.

Expand Down Expand Up @@ -98,6 +102,8 @@ bsaxs preflight data/package --manifest manifest.csv \
--poni geometry.poni --mask mask.npy -o results/preflight
```

For an unattended package run, use `bsaxs batch "data/package/images/*.edf" --unattended data/package --manifest data/package/manifest.csv --poni data/package/geometry.poni --mask data/package/mask.npy -o results/unattended_001`. This performs preflight before fitting, writes a checkpoint and streams batch evidence. A red preflight blocks fitting; warnings or failed frames return a nonzero exit status. Keep the output outside the raw package and use `--resume` with the same inputs and settings after interruption.

`bsaxs analyze ... --full2d` is the optional empirical intensity fit. `bsaxs-gui` is the crash-visible desktop entry (same as `启动_LamellarSAXS2D.cmd`); `bsaxs gui` remains a supported CLI alias that opens the workbench.

Agents (and any non-interactive operator) should start with `bsaxs describe` or a bare `bsaxs`. That prints a JSON catalog of commands, exit codes, and scientific invariants. Environment checks: `bsaxs doctor --json` (same as `bsaxs-doctor`). Failed commands emit a JSON error envelope on stdout and a human `错误:` line on stderr. See [AGENTS.md](AGENTS.md).
Expand All @@ -118,6 +124,8 @@ Agents (and any non-interactive operator) should start with `bsaxs describe` or
| Agent / automation CLI contract | [AGENTS.md](AGENTS.md) |
| CLI, TOML, batch, masks, exports | [docs/user_guide_zh.md](docs/user_guide_zh.md) |
| Butterfly arcs and publication rules | [docs/butterfly_arcs_zh.md](docs/butterfly_arcs_zh.md) |
| Fixed-q annular butterfly trajectories | [docs/annular_trajectories_zh.md](docs/annular_trajectories_zh.md) |
| Fixed-χ radial sector peaks | [docs/sector_peaks_zh.md](docs/sector_peaks_zh.md) |
| Measurement / peak figures | [docs/butterfly_figures_zh.md](docs/butterfly_figures_zh.md) |
| Symbols, units, and interpretation limits | [docs/scientific_basis_zh.md](docs/scientific_basis_zh.md) |
| Architecture | [docs/architecture_zh.md](docs/architecture_zh.md) |
Expand All @@ -126,21 +134,15 @@ Agents (and any non-interactive operator) should start with `bsaxs describe` or

## Scientific scope

The double ellipse is an **empirical reciprocal-space measurement**, following the Wang/Grubb picture of a butterfly as a pair of origin-centred ellipses. One 2D pattern does not uniquely recover a 3D lamellar stack or a deformation mechanism.

- [Wang, Murthy & Grubb (2007)](https://doi.org/10.1016/j.polymer.2007.04.026)
- [Grubb, Murthy & Francescangeli (2016)](https://doi.org/10.1002/polb.23930)
- [Grubb et al. (2021)](https://doi.org/10.1016/j.polymer.2021.123566)

The papers are not redistributed here.
The double ellipse is an **empirical reciprocal-space measurement**. The current annular engineering route is documented against Murthy & Grubb (2024), especially §4.1 on z-slices, minimum-curvature peak trajectories, and the two-ellipse butterfly description: [IUCr article](https://journals.iucr.org/j/issues/2024/04/00/tu5052/). It is not claimed as a reproduction of the 2021 algorithm; the 2007 and 2021 full texts were not obtained and read for this tuning. One 2D pattern does not uniquely recover a 3D lamellar stack or a deformation mechanism.

---

## 中文说明

LamellarSAXS2D 面向取向层片的各向异性二维 SAXS 蝴蝶纹:用 PONI(pyFAI)得到物理 `q/chi/qx/qy`,识别观测弧,并只发表图像真正支持的量。
LamellarSAXS2D 面向取向层片的各向异性二维 SAXS 蝴蝶纹:用 PONI(pyFAI)得到物理 `q/chi/qx/qy`,提取固定 q 环的 `I(χ)` 花瓣轨迹,并只发表图像真正支持的量。

多数实验帧给出的是**一阶环周期**(`q*` 与 **环 L**)。只有内凹椭圆真正成立时,才显示表观 `a`、`b/a`、`θ`,以及未发表的 **Ln / Lz / 长轴 L** 候选。贴在 `flat_ellipse` 上下界、或长轴超出一阶脊线范围的解,按 **仅环** 处理,不会把求解器的倾角或环 L 写进 Ln 列。`success=True` 不是科学验收;像素 q 不能冒充物理周期;缺失象限不会被镜像补齐。
只有在径向反射峰有明确支持、单位有效且级次解释另有依据时,才把 `q*` 换算为一阶环周期 **L = 2π/q***。annular 的 `q_annulus` 只是固定 q 环采样坐标。只有内凹椭圆真正成立时,才显示表观 `a`、`b/a`、`θ`,以及未发表的 **Ln / Lz / 长轴 L** 候选。贴在 `flat_ellipse` 上下界、或长轴超出观测支持的解,按 **仅环/候选限制** 处理,不会把求解器的倾角或环 L 写进 Ln 列。`success=True` 不是科学验收;像素 q 不能冒充物理周期;缺失象限不会被镜像补齐。

### 安装与启动

Expand All @@ -158,7 +160,11 @@ py -3.13 -m venv .venv-project
.\启动_LamellarSAXS2D.cmd
```

蝴蝶页建议顺序:**识别弧 → 评估**。详见[首次启动](docs/first_run_zh.md)。
蝴蝶页建议顺序:**识别 → 评估**(曲率模式下识别步骤显示为“识别弧”)。详见[首次启动](docs/first_run_zh.md)。

新建 GUI 会话默认按固定 q 环计算角向 `I(χ)`,用 q 环上的角向峰连接四条花瓣轨迹;默认 q 环数 40、方位角分箱 72。每个 q 环最多保留四个实际支持峰,少于四个就保留少数峰,不镜像补象限;缺环造成的轨迹断点也不桥接。历史项目缺少 `trace_method` 时保持曲率路径兼容,历史 `ridge_method=butterfly_curvature` 的分支/象限 family 仍可复现。固定 χ 的 `radial_sector` 只作为独立径向诊断,不是默认主椭圆输入。详见[固定 q 环花瓣轨迹](docs/annular_trajectories_zh.md)与[径向扇区诊断](docs/sector_peaks_zh.md)。

annular 点的 `q_annulus` 是预设 q 环的采样坐标,不是径向反射峰 `q*`,不能换算成 `2π/q`。椭圆拟合使用固定参考轴的对角配对,不能逐个花瓣重新指派;外层 q 窗口边界也不能冒充真实长轴尖端。

评估后可在「叠加图层」分别检查实测谱、观测轨迹、几何候选和全像素模型椭圆;峰位表区分原始最亮点 G 与受支持峰 P,选中行即可定位。导出同时包含干净叠加图、峰位图、局部放大、剖面及 CSV/NPZ 源数据。匹配差或参数不稳定时会保留明确提示,不能仅凭曲线看起来像蝴蝶判定拟合正确。详见[测量图与峰位导出](docs/butterfly_figures_zh.md)。

Expand All @@ -171,6 +177,10 @@ bsaxs inspect data/frame_0001.edf --poni geometry/detector.poni --mask masks/det
bsaxs analyze data/frame_0001.edf --poni geometry/detector.poni --mask masks/detector.npy \
--ridge-method butterfly_curvature --ellipse-preset flat_ellipse \
--butterfly-stage evaluate --butterfly-resamples 0 -o results/frame_0001
bsaxs analyze data/frame_0001.edf --poni geometry/detector.poni --mask masks/detector.npy \
--butterfly-stage evaluate --butterfly-trace-method annular_peak \
--annular-rings 40 --annular-angles 72 --butterfly-resamples 0 \
-o results/frame_0001_annular
bsaxs batch "data/frame_*.edf" --poni geometry/detector.poni --mask masks/detector.npy \
--ridge-method butterfly_curvature --ellipse-preset flat_ellipse \
--butterfly-stage evaluate --mode independent -o results/batch
Expand Down
81 changes: 81 additions & 0 deletions docs/annular_trajectories_zh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# 固定 q 环的 `I(χ)` 花瓣轨迹

`annular_peak` 是当前 GUI 新会话的主蝴蝶路径。它把 q 窗口划成一组固定的 q 环,在每个 q 环上计算角向 profile `I(χ)`,从每个 profile 中提取实际支持的角向峰,再沿 q 方向连接成最多四条、支持充分时呈四条的长花瓣弧。这个观测定义对应用户在二维图上看到的 4 条蓝色花瓣轨迹;它不再把每个 bar 的局部最亮点直接当作主轨迹。

固定 χ 的 `radial_sector` 仍可用于独立的 `I(q)` 径向诊断,但其 `q*` 不属于默认 annular 主轨迹,也不是默认主椭圆输入。局部二维曲率 `curvature` 保留为历史项目和高级诊断路径。

## 默认采样与原始 profile

GUI 新建会话默认使用 40 个 q 环和 72 个方位角分箱。实际有效 q 像素会按 q 环和 χ 分箱;每个 q 环的原始角向强度定义为:

```text
I_raw(χₗ | qₖ) = sum(Iₚ) / count(Iₚ)
```

其中 `p` 只包括当前 mask、q 窗口和有限强度允许的像素。每个 q 环的 `raw_mean`、`raw_sum`、`counts` 和 `coverage` 都保留在结果中;`raw_sum` 不应脱离 count 单独比较。空分箱保持为空,不用零或镜像数据填充。

环积分层不额外施加探测器效率、固角、偏振或绝对强度校正,也不把输入强度重新解释为另一种 pyFAI 校正积分。输入数据已有的校正和强度单位随上下文记录。q 环中心来自 PONI 的 q 坐标;若只有 pixel-q,只能按采样坐标解释。

每个 q 环最多保留四个实际观测峰,每个参考象限最多一个 dominant 峰。少于四个时保留实际存在的峰,不补齐缺失象限;某个 q 环没有可靠峰时保留 profile 和缺环状态,不跨过缺环强行连接。当前默认最小连续轨迹长度为 3 个 q 环,短于该长度的候选不升级为连续花瓣弧。

## 峰筛选和轨迹连接

一个角向候选需要在该环上有足够 coverage、连续的角向支持、局部突出度和噪声支持,并通过有效像素贡献与热像素主导检查。相邻候选峰过于接近或强度证据不足时保留歧义/拒绝原因;程序不会为了得到四瓣而强行选峰。

轨迹只连接相邻 q 环中同一参考象限的实际峰,并限制角度跳变。mask、beam stop、探测器缝隙或低 coverage 造成的断开会原样记录。`I(χ)` profile 以及每个环的 candidates 仍可在 GUI 和离线图包中检查,即使该环最终没有进入花瓣弧。

当前真实 frame110/120 中看到的 point 数和 4 条 arc 只是某一组 q 环/角度分箱下的调校示例。它们不应写成最终验证数字、普适结构计数或科学接受结论;改变 q 窗口、mask、PONI 或分箱会改变可见支持。

## 固定对角配对与椭圆拟合

轨迹建立前先按用户给定的参考轴固定象限和 branch:

- family 0:参考轴内的 QI 与 QIII;
- family 1:参考轴内的 QII 与 QIV。

这是一种固定的对角配对。拟合接收已经分配好的 branch、side 和 arc 身份,不能在优化过程中把某一条花瓣重新指派给另一个 individual petal,也不能靠最近距离替换缺失象限。配对、缺口和支撑状态会写入结果诊断。

拟合得到的双椭圆仍是观测几何候选,不是唯一的三维结构反演。长轴、倾角和 `Ln/Lz` 只有在真实二维支持足够且参数可辨识时才可解释;求解器成功、残差较小或图形完整都不等于科学验收。

## q 环坐标和长轴边界

`q_annulus` 是预先规定的 q 环采样坐标,只说明该点来自哪个 q 环。它不是径向强度峰 `q*`,不能用 `2π/q_annulus` 换算层片间距,也不能自动命名为一阶反射。

分析 q 窗口的外边界是采样范围,不是真实长轴尖端。annular 路径已禁用共享的 `observed_tip_constraint`,避免把 q 窗口边界塞进长轴估计;用户明确给出的参数上下界仍然保留。若 q 支持不足以辨识很长的 `a`,结果应标记为不可辨识、ring-only 或候选限制状态,不强报长轴、`Ln` 或 `L`。

## GUI、CLI 与旧项目

新建 GUI 会话的识别方式是 `annular_peak`,控制栏默认显示 q 环数量 40 和方位角分箱 72。历史项目配方缺少 `trace_method` 时,继续使用历史 `curvature` 语义;历史 `ridge_method=butterfly_curvature` 的 family、象限和分支标记仍保留。需要切换到 annular 时应明确选择方法并重新识别。

CLI 的主路径写法为:

```powershell
bsaxs analyze data/frame_0001.edf `
--poni geometry/detector.poni `
--mask masks/detector.npy `
--butterfly-stage evaluate `
--butterfly-trace-method annular_peak `
--annular-rings 40 `
--annular-angles 72 `
--butterfly-resamples 0 `
-o results/frame_0001_annular
```

`--annular-rings` 是请求的 q 环数量,实际数量仍受 q 像素采样限制;`--annular-angles` 是每个 q 环的方位角分箱数。显式指定 `--butterfly-trace-method` 时,CLI 会选择蝴蝶工作流;不要与其他 `--ridge-method` 混用,除非该值也是 `butterfly_curvature`。`radial_sector` 的 `--sector-width`/`--sector-step` 只改变独立径向诊断。

## 文献边界

本路线的文献依据只采用已核读的 Murthy 与 Grubb 2024 年 Journal of Applied Crystallography 文章[《Evolution of elliptical SAXS patterns in aligned systems》](https://journals.iucr.org/j/issues/2024/04/00/tu5052/),尤其是 §4.1:先用 z slices 观察层片反射峰位,再以强度曲面的 minimum-curvature 轨迹扩展椭圆拟合;butterfly 需要两条椭圆。该文支持“峰位轨迹可以呈椭圆、蝴蝶需要两个椭圆”的物理和几何背景,不等同于本项目的 annular 工程算法。

本项目的 `annular_peak` 是固定 q 环、逐环 `I(χ)`、实际峰支持和连续轨迹连接的工程实现,不能称作对 2021 年算法的复刻。2007/2021 文献全文在本次调校中未取得并逐篇核读,因此不把它们写成已验证的实现依据。最终椭圆参数、反射级次和材料结构解释仍需独立实验与人工审查。

## 图稿和源数据

含 `annular_peaks` 的图包会新增:

- `annular_qchi.svg/pdf/png/tiff`:q–χ 原始均值和受支持角向峰;
- `annular_profiles.svg/pdf/png/tiff`:代表 q 环的原始/平滑 `I(χ)`、count 和 coverage;
- `annular_profiles.csv`、`annular_peaks.csv`、`annular_profiles.npz`:profile、候选峰、选择状态、覆盖和原始数组;
- `annular_caption.txt`、`annular_manifest.json`:方法定义、解释边界和文件哈希。

导出器只消费已完成的 annular 结果,不在图稿阶段重积分、补象限、跨缺环桥接或重新拟合椭圆。Nature 单栏/双栏尺寸和矢量输出有助于排版与复核,但图件生成成功不保证几何模型适用、参数可发表或科学验收。
Loading
Loading