中文安装、数据导入、七步处理、结果导出与故障排查说明见 USER_GUIDE.zh-CN.md。
A self-contained desktop application for transient absorption (TA) spectroscopy data processing. Built with Electron + React/Vite on the front end and a NumPy/SciPy Python engine on the back end.
TA-processer does not depend on TA-skill at runtime. The scientific algorithms were migrated from TA-skill (commit
45bdb12) and are maintained independently here. See PROVENANCE.md for the full lineage, source hashes, and the parity verification that proves the migration preserved the numerics.
The left navigation drives each stage independently. Each stage shows its parameters, a before/after visualization, run/cancel controls, and a per-stage provenance manifest. Editing an upstream stage marks its downstream stages stale (results retained but excluded from the final report).
- Raw data & QC — load + validate the input matrix; emit the canonical standard matrix (nm, ps).
- Wavelength crop — keep an inclusive band.
- Pre-pump background — per-wavelength median subtraction over the pre-pump window.
- Chirp correction — estimate wavelength-dependent t0 from high-SNR rising edges.
- IRF extraction — Gaussian-broadened erf-step fit (or a known FWHM).
- Per-wavelength fits — 1/2/3-exponential models, with optional IRF convolution.
- SVD / global fit — IRF-forward global kinetic fit + bootstrap CIs + HTML report.
TA-processer/
├── apps/desktop/ Electron + React/Vite + Plotly desktop app
│ ├── electron/ main process, preload, backend IPC, project store
│ └── src/ React renderer (7-step UI, heatmap)
├── backend/ta_engine/ migrated scientific engine (Python, no subprocess)
│ ├── pipeline.py in-process orchestrator (one stage = one function)
│ ├── cli.py JSON-Lines dispatcher Electron spawns
│ └── {background,chirp,irf,local_exponential,svd_global_fit,...}.py
├── schemas/ shared wire protocol (messages.ts + messages.py)
├── tests/ pytest (parity + CLI contract) + vitest
└── PROVENANCE.md algorithm migration record
- Node.js ≥ 20 (for the desktop app)
- Python ≥ 3.10 with NumPy, SciPy, pandas, Matplotlib (for the engine)
# from the repo root
npm install # installs the apps/desktop workspace
npm run dev # electron-vite dev — launches the Electron windowThe Electron main process spawns python -m ta_engine.cli with PYTHONPATH
pointing at backend/, so no engine install is required in dev. Override the
interpreter with TA_PROCESSER_PYTHON=/path/to/python if needed.
# backend: numerical-parity vs TA-skill + JSON-Lines contract
python -m pytest tests/backend
# frontend: renderer logic
npm run test --workspace apps/desktop
# both
npm testpython scripts/smoke_pipeline.py # runs raw→crop→bg→chirp→irf→local on a synthetic matrixThe macOS release workflow deliberately refuses to publish an unsigned build.
Configure these GitHub Actions repository secrets before dispatching
.github/workflows/release-macos.yml:
MAC_CSC_LINK: base64-encoded Developer ID Application.p12certificate;MAC_CSC_KEY_PASSWORD: password used when exporting the.p12;APPLE_ID: Apple Developer account email;APPLE_APP_SPECIFIC_PASSWORD: app-specific Apple ID password;APPLE_TEAM_ID: 10-character Apple Developer team ID.
The workflow signs the Electron app and bundled PyInstaller backend, submits it
to Apple notarization, staples the ticket, then verifies codesign, Gatekeeper,
the stapled ticket, and the backend JSON protocol before uploading either DMG.
Do not restore identity: null or CSC_IDENTITY_AUTO_DISCOVERY=false: those
settings produce quarantined downloads that macOS may report as damaged.
The desktop app spawns one Python backend process and communicates over
JSON-Lines (one JSON object per line on stdin/stdout). Commands flow in; progress,
warnings, artifacts, and completion flow out. See
schemas/messages.ts for the full contract.
| stdin command | stdout response |
|---|---|
{"cmd":"ping"} |
{"type":"pong"} |
{"cmd":"run","id":...,"stage":"background","out_dir":...,"params":{...}} |
started → progress* → artifact* → completed | failed |
{"cmd":"quit"} |
process exits |
- One Python process, in-process stages. Unlike TA-skill (which used one
subprocess per stage),
ta_engine.pipelineimports every stage module and calls its entry function directly. A fresh run spawns a fresh process; cancel is SIGTERM at the OS level. - Atomic publishing. Each stage writes to a staging directory and commits atomically; a cancelled or failed run leaves no partially-written artifacts.
- Restricted renderer. The renderer has no
fs/node/Python access — only the methods exposed byelectron/preload.ts(window.ta). - Staleness tracking. Re-running an upstream stage marks all completed
downstream stages
stale; their old artifacts are kept but cannot enter a new final report.
This is the runnable foundation: migrated algorithms, working IPC,
7-step navigation with a Plotly heatmap, and a parity test harness. The full
per-stage scientific visualizations, PyInstaller packaging, and signed
installer builds are subsequent checkpoints (tracked in .zcode/plans/).
MIT — see LICENSE.