This release is a pre-release and may not be stable for production use.
PyRATE-TA
Rate Analysis & Target-model Engine for Transient Absorption in Python
Kinetic analysis of ultrafast time-resolved spectroscopy data: multi-exponential fitting, global analysis and target analysis with rate-matrix (K-matrix) models, lifetime density analysis (LDA) with regularisation and automatic parameter selection, and the DAS / EAS / SAS spectra that come out of them.
Relationship to PyMORGAN
PyRATE-TA is the analysis half of a two-project pair.
PyMORGAN owns loading,
processing and plotting: the file-format readers (PDAT, P2DAT, MESS
directories, …), the Dataset1D / Dataset2D objects, the presentation
Settings and every Matplotlib plotter.
The dependency is one-way: PyRATE-TA imports PyMORGAN, never the reverse.
PyRATE-TA does not reimplement readers, dataset objects or standard figures. The
seam is deliberately narrow — PyMORGAN's plot_species_spectra takes plain
arrays (Sfit, Taus, TauErr, isFixTau, modelType) rather than a PyRATE-TA
object, so the arrow never has to reverse; the adapter (as_species_args) lives
on this side.
Features
- Shared data layer — datasets are loaded through PyMORGAN's pluggable
loader registry, so every format it supports (
PDAT,MESS_TRIR,Helios_TA,UniGE_fsTA, …) is available here without a second reader. New formats are contributed upstream, not forked. - Analysis-only settings — solver tolerances, iteration limits, default
component count and IRF handling, round-tripped to a commented
settings.toml. The dataclass field is the single source of truth: serialisation, type coercion and the GUI widgets are all derived from it. Presentation settings are deliberately not duplicated — style, colourmap and label conventions stay inpymorgan.Settings. - Global analysis by variable projection — for fixed lifetimes the linear
amplitudes are the least-squares solution
S = pinv(C) @ D, so only the non-linear parameters reach the optimiser. Far better conditioned than fitting amplitudes and lifetimes jointly. - Kinetic models — parallel (independent decays → DAS), sequential
(
A → B → C→ EAS) and general compartmental K-matrix models with branching (→ SAS).C(t)by eigendecomposition whereKis diagonalisable, by matrix-exponential propagation otherwise, with the near-degenerate eigenvalue case guarded. - Analytic IRF convolution — Gaussian-convolved exponentials (exponentially
modified Gaussian) rather than numerical convolution, with clipping (
t_min) as the alternative for the coherent artefact. - Coherent artefact suppression — append the IRF and its first two
derivatives to the design matrix (
coherent_artifact=True) so cross-phase modulation and Raman signals are absorbed by their own amplitudes instead of distorting the shortest lifetime. - Lifetime density analysis (LDA) — a dense regularised grid of fixed lifetimes with Tikhonov / first- or second-difference penalties. Automatic alpha selection by L-curve corner detection, GCV or the Morozov discrepancy principle. Optional non-negative constraint (NNLS), SVD pre-filtering, Monte Carlo bootstrap errors, and automatic peak centroid detection. Exports the 2D map to PDAT format.
- Ground-state bleach / absolute spectra — convert difference species spectra to absolute absorption spectra by adding back a scaled ground-state spectrum. The maximum physically allowable scale factor is computed automatically.
- Constrained amplitudes — a per-component sign mask (
sign_mask) imposes non-negative (+1) or non-positive (−1) constraints on any species spectrum without touching the lifetimes. - Reproducible results — every result carries the model identity, initial guesses, bounds, fixed/free masks, the delay and probe ranges actually used, and the solver's convergence report. A lifetime without its uncertainty and its fixed/free flag is not a result.
- Fit session files —
pr.save_fit/pr.load_fitround-trip the full result (arrays + JSON metadata) to a.prfitfile. A target fit reopens with its scheme in editable text so it can be modified without re-entering it. - Honest convergence — a fit that did not converge raises or is flagged; it is never returned as though it had. Parameters resting on a bound and near-degenerate lifetimes are reported explicitly.
- Preview mode —
pr.preview_globalevaluates a model at given lifetimes without optimising, showing what those lifetimes imply and what the residual would be, clearly marked as a guess rather than a result. - Analysis-only plots — residual matrices, concentration profiles
C(t), K-matrix diagrams, fit-monitor bars (live parameter tracking during a fit), kinetic traces with residuals panels, and spectra with residuals. Everything PyMORGAN can already draw is delegated upstream. - Headless-first fitting — every fit is reachable and testable from a plain
script with no
QApplication; the GUI is a caller, never a prerequisite. - Bundled PyQt6 GUI (
pyrate-ta-gui) — data loading, model building, global / target / LDA fitting, fit control and results inspection, reusing PyMORGAN's theme so the two applications look identical side by side. - Fast start-up — the public API is lazy (PEP 562), so
import pyrate_tadoes not pay for scipy or, through PyMORGAN, matplotlib and the loader registries. - Logging, not prints — library messages go through the
pyratelogger (pyrate.configure_logging()); a console handler is attached only when the host has not configured logging, so it does not fight PyMORGAN's. - uv-managed, ruff-linted, pytest-tested.
Installation
From PyPI (Recommended)
Install the latest release directly from PyPI:
pip install pyrate-ta
# or with uv:
uv pip install pyrate-ta
# Register bundled fonts in matplotlib:
pymorgan-install-fonts
You can also run the GUI directly without installing using uvx:
uvx --from pyrate-ta pyrate-ta-gui
From Source (Development)
Clone the repository and install in editable mode with uv:
git clone https://github.com/RJFernandezTeran/PyRATE-TA.git
cd PyRATE-TA
uv venv # create .venv (Python >= 3.12)
# Install the package (choose one):
uv pip install -e . # core workflow (includes PyQt6 GUI)
# or:
uv pip install -e ".[dev]" # + ruff and pytest
uv run pymorgan-install-fonts # register PyMORGAN's fonts in this environment
PyMORGAN is resolved from the sibling checkout (../PyMORGAN) through
[tool.uv.sources], so upstream edits are picked up without a reinstall. The
two folders must stay siblings; replace that entry with a plain version pin
once PyMORGAN is published to an index.
Console scripts installed with the package:
| Command | Purpose |
|---|---|
pyrate-ta-gui |
Launch the fitting interface |
pyrate-ta-edit-gui |
Open main_window.ui in Qt Designer |
pyrate-ta-settings |
Standalone analysis-settings editor |
Quick start
import pyrate_ta as pr
import pymorgan as pm
pm.load_settings("settings.toml") # aesthetics: profile, labels, cmap, ...
pm.apply_style()
# --- Load and process: PyMORGAN ---
data = pm.load_1D("scan.pdat", data_type="PDAT")
data.background_correct(tmin=-20, tmax=-5)
# --- Global fit: PyRATE-TA ---
fit = pr.fit_global(data, n_components=3, model_type="Sequential")
print(fit.taus, fit.tau_err) # lifetimes and 1-sigma uncertainties
# --- Preview (no optimisation) ---
prev = pr.preview_global(data, taus=[1.0, 10.0, 100.0])
# --- Target analysis ---
fit_t = pr.fit_target(data, scheme="A_eq_B_to_C", taus=[2.0, 5.0, 20.0, 200.0])
# --- Lifetime density analysis ---
from pyrate_ta.fit.lda import solve_lda
lda = solve_lda(data, n_taus=100, alpha="auto", non_negative=True)
# --- Plot the species spectra: PyMORGAN ---
data.plot_species_spectra(*fit.as_species_args())
# --- Save the result ---
pr.save_fit("scan_fit", fit) # -> scan_fit.prfit
pm.show_plots()
Analysis defaults come from pyrate.Settings (solver tolerances, component
count, IRF handling); everything about how the figures look comes from
pymorgan.Settings.
Project layout
src/pyrate_ta/
models/ kinetic models: parallel · sequential · target (K-matrix) · irf · schemes · scheme_text
fit/ solvers & engines: driver · engines · varpro · cost · lda (lifetime density)
groundstate (absolute spectra) · constrained · prepare
results/ KineticFit · GlobalFit · TargetFit · LDAResult · serialisation
plot/ analysis-only views: concentrations · scheme · matrix · monitor
traces (kinetics + residuals) · lda · style
io/ fit-session import/export (.prfit — raw formats belong upstream to PyMORGAN)
gui/ PyQt6 application (pyrate-ta-gui)
main_window.py / .ui window assembly, wiring, menus (layout lives in the .ui)
settings_app.py standalone analysis-settings editor (pyrate-ta-settings)
settings_panel.py embedded settings editor widget
scheme_dialog.py / .ui target analysis model scheme builder dialog
tabs/ per-tab mixins: data · model · fitting · lda
crosshair.py · designer.py · monitor.py · mw_common.py
icons/ application icons (pirate_ship.png)
settings.py Settings (TOML auto-merge, solver, model and LDA defaults, GUI field specs)
settings.default.toml canonical default settings template shipped with the package
cite.py academic citation registry and logger (pyrate-ta-cite)
helpers.py shared numerical and plotting helpers
log.py logger factory and console configuration
examples/ runnable example scripts (quick_fit.py, lda_fit.py)
tests/ pytest suite (headless matplotlib, offscreen Qt)
scripts/ bump_version.py · run_checks.py · run_changed_tests.py
docs/ LaTeX manual (main + boundary + models + fitting + gui + settings + extending + installation)
Testing
uv pip install -e ".[dev]"
uv run pytest # full test suite
uv run python scripts/run_checks.py # boundary, API and Qt-layout checks
Synthetic-recovery tests are the backbone of the suite: build data from known parameters, fit it, assert the parameters come back within tolerance. A fitting project without those is untested regardless of line coverage. The failure modes are tested too — non-convergence must be flagged rather than silently returned, and near-degenerate lifetimes must not produce exploding amplitudes unwarned.
Linting
Ruff handles linting and formatting
(configured in pyproject.toml):
uvx ruff@latest check src tests scripts
uvx ruff@latest format src tests
The version string in src/pyrate_ta/__about__.py follows 0.x.yymmdd.devN
(PEP 440) and is maintained by python scripts/bump_version.py (--minor for a
design bump, --check to verify it was bumped today).
Citing
If you publish results obtained with PyRATE-TA, please cite:
- The PyRATE-TA / PyMORGAN software paper — manuscript in preparation.
- R. J. Fernández-Terán, E. Sucre-Rosales, L. Echevarria, F. E. Hernández, A Sweet Introduction to the Mathematical Analysis of Time-Resolved Spectra and Complex Kinetic Mechanisms: The Chameleon Reaction Revisited, J. Chem. Educ. 2022, 99, 2327–2337. 10.1021/acs.jchemed.2c00104
- I. H. M. van Stokkum, D. S. Larsen, R. van Grondelle, Global and target analysis of time-resolved spectra, Biochim. Biophys. Acta Bioenerg. 2004, 1657, 82–104. 10.1016/j.bbabio.2004.04.011 — global/target analysis and variable projection.
- M. N. Berberan-Santos, J. M. G. Martinho, The integration of kinetic rate equations by matrix methods, J. Chem. Educ. 1990, 67, 375. 10.1021/ed067p375 — the eigenvector solution used by the propagator.
- P. C. Hansen, Analysis of discrete ill-posed problems by means of the L-curve, SIAM Review 1992, 34, 561–580. — L-curve corner detection for LDA alpha selection.
The list is printed by pyrate-ta-cite and logged when the GUI starts. Routines
that implement a published method also log their own reference when they run,
so the log of a fit records which formalism produced it.
Acknowledgements
- Development assisted by Google Antigravity, with all code, algorithms, and implementations manually verified and tested.
- PyRATE-TA builds upon and modernizes the original MATLAB implementation from the now-deprecated DataAnalysis repository, written by Dr. Ricardo J. Fernández-Terán during his PhD and validated iteratively throughout the years.
License
Released under the GNU Affero General Public License v3.0 (AGPLv3). © 2026 Dr. Ricardo J. Fernández-Terán
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyrate_ta-0.1.260814.dev1.tar.gz.
File metadata
- Download URL: pyrate_ta-0.1.260814.dev1.tar.gz
- Upload date:
- Size: 759.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aee34424b881b1e8761ee7e9ed0ee998dc261052edb23f6df2f4031e230da9e7
|
|
| MD5 |
affe416a568c5c963a25d7039f6b63af
|
|
| BLAKE2b-256 |
5bcd5e1b0dcfc5b895f9eaead7007bc9ae1893bbabf0f66f6501a53764560cbe
|
Provenance
The following attestation bundles were made for pyrate_ta-0.1.260814.dev1.tar.gz:
Publisher:
python-publish.yml on RJFernandezTeran/PyRATE-TA
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyrate_ta-0.1.260814.dev1.tar.gz -
Subject digest:
aee34424b881b1e8761ee7e9ed0ee998dc261052edb23f6df2f4031e230da9e7 - Sigstore transparency entry: 2464932953
- Sigstore integration time:
-
Permalink:
RJFernandezTeran/PyRATE-TA@5896688014a1352ae7f06852f11b3324270bba51 -
Branch / Tag:
refs/tags/v0.8.260814.dev1 - Owner: https://github.com/RJFernandezTeran
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@5896688014a1352ae7f06852f11b3324270bba51 -
Trigger Event:
release
-
Statement type:
File details
Details for the file pyrate_ta-0.1.260814.dev1-py3-none-any.whl.
File metadata
- Download URL: pyrate_ta-0.1.260814.dev1-py3-none-any.whl
- Upload date:
- Size: 355.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d6d6236aa91ac835debea714ae89792d0faf3154a085f5c692460c57ab7f8898
|
|
| MD5 |
0d1c2a631830111e8f0f0354efa88985
|
|
| BLAKE2b-256 |
2af569ede3c44aba5cd6d3a2a00e0c143242aa00b6d3d4d23d083756702ed7c7
|
Provenance
The following attestation bundles were made for pyrate_ta-0.1.260814.dev1-py3-none-any.whl:
Publisher:
python-publish.yml on RJFernandezTeran/PyRATE-TA
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyrate_ta-0.1.260814.dev1-py3-none-any.whl -
Subject digest:
d6d6236aa91ac835debea714ae89792d0faf3154a085f5c692460c57ab7f8898 - Sigstore transparency entry: 2464933021
- Sigstore integration time:
-
Permalink:
RJFernandezTeran/PyRATE-TA@5896688014a1352ae7f06852f11b3324270bba51 -
Branch / Tag:
refs/tags/v0.8.260814.dev1 - Owner: https://github.com/RJFernandezTeran
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@5896688014a1352ae7f06852f11b3324270bba51 -
Trigger Event:
release
-
Statement type: