Plugins / FLIMKit / Spectral Unmixing MuFLE · edit on GitHub
Spectral Unmixing (MuFLE)
flimkit-mufle unmixes multi-channel time-resolved emission, in the style of MuFLE (Adams et al., IEEE TBME 2023; Biomed. Opt. Express 17(4):2176, 2026). It fits a stack of decays, one per wavelength channel, with a small number of components, each an emission spectrum times a single-exponential lifetime, and returns the spectra and lifetimes.
Each spectrum is a smooth cubic B-spline over wavelength. The lifetimes are fitted by non-linear least squares with the IRF reconvolved, and the spectral amplitudes are solved by non-negative least squares inside each step, so spectra come out non-negative without extra constraints. Poisson weighting is used throughout.
Installing MuFLE
pip install flimkit-mufle
into the environment FLIMKit runs from. It appears under Tools > Unmixing on the next start.

Using MuFLE
Synthetic Unmixing Demo generates two components with known answers, fits them and shows the result, so you can check it works without a file:

The fitted spectra are the solid lines, the truth is dashed. It recovered 0.500 ns and 3.010 ns against a truth of 0.500 ns and 3.000 ns, with reduced χ² 1.041. The abundances are each component's share of the total signal.
Spectral-Temporal Unmixing... picks a multi-channel file, asks how many components, fits and shows the same window. It needs a file with one detection channel per wavelength band; a single-channel .ptu such as Ado_1.ptu has nothing to unmix.
From code:
from flimkit_mufle import unmixFile
result = unmixFile('scan.ptu', n_components=2)
print(result['taus'], result['chi2_reduced'])
fitMufle(data, wavelengths, tcspc_res, irf, n_components) is the core and returns taus, spectra, amplitudes, background, model, residual and chi2_reduced.
MuFLE limits
- Channel numbering follows the reader: PTU channels start at 0, Becker & Hickl at 1. Pass
channels=if the defaults pick the wrong ones. - The IRF for a real file is currently a Gaussian placeholder, not FLIMKit's machine or measured IRF.
- Wavelength calibration is not read from file metadata yet, so the channel index is used as the axis.
- It fits one summed spectrum at a time, for a whole field or an ROI. Per-pixel maps would need the GPU path.