Skip to main content
Pre-release

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

PyPI - Version GitHub Release Python >= 3.12 PyPI - Python Version GUI: PyQt6 uv Code style: Ruff Tests: pytest Requires: PyMORGAN License: AGPL-3.0 CodeFactor GitHub Stars GitHub Forks GitHub Issues PyPI - Downloads

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 in pymorgan.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 where K is 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 filespr.save_fit / pr.load_fit round-trip the full result (arrays + JSON metadata) to a .prfit file. 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 modepr.preview_global evaluates 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_ta does not pay for scipy or, through PyMORGAN, matplotlib and the loader registries.
  • Logging, not prints — library messages go through the pyrate logger (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:

  1. The PyRATE-TA / PyMORGAN software paper — manuscript in preparation.
  2. 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
  3. 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.
  4. 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.
  5. 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

pyrate_ta-0.1.260814.dev1.tar.gz (759.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyrate_ta-0.1.260814.dev1-py3-none-any.whl (355.6 kB view details)

Uploaded Python 3

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

Hashes for pyrate_ta-0.1.260814.dev1.tar.gz
Algorithm Hash digest
SHA256 aee34424b881b1e8761ee7e9ed0ee998dc261052edb23f6df2f4031e230da9e7
MD5 affe416a568c5c963a25d7039f6b63af
BLAKE2b-256 5bcd5e1b0dcfc5b895f9eaead7007bc9ae1893bbabf0f66f6501a53764560cbe

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyrate_ta-0.1.260814.dev1.tar.gz:

Publisher: python-publish.yml on RJFernandezTeran/PyRATE-TA

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyrate_ta-0.1.260814.dev1-py3-none-any.whl.

File metadata

File hashes

Hashes for pyrate_ta-0.1.260814.dev1-py3-none-any.whl
Algorithm Hash digest
SHA256 d6d6236aa91ac835debea714ae89792d0faf3154a085f5c692460c57ab7f8898
MD5 0d1c2a631830111e8f0f0354efa88985
BLAKE2b-256 2af569ede3c44aba5cd6d3a2a00e0c143242aa00b6d3d4d23d083756702ed7c7

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page