Measures equilibrium step responses in LSPR sensorgrams, with an uncertainty on every value.
In a localised surface plasmon resonance (LSPR) protein quantification unit, each sample is read out by a deliberate shift in the light incidence: the response drops sharply for a few tens of seconds, then relaxes to a new equilibrium level. The difference between the level before the shift and the level it settles at afterwards is what associates a sample with its product concentration. Each read-out is followed by a regeneration step, so a record is a repeating cycle of switch → relaxation → regeneration, with one measurement per cycle.
The task is therefore not peak detection but estimation of an equilibrium level change across a switching event, in the presence of baseline drift, at an unknown number of unknown times.
Record Offline_test1_SN_7_3. Each cycle shows the narrow switch transient, the
pre-switch level extrapolated to the switch time (red), the fitted relaxation and
its asymptote (green), and the step between them with its standard uncertainty.
The deep excursions between cycles are regeneration. The last event, 13.4 pm
against steps of 150–530 pm, is a tail artefact that the defaults keep because it
is statistically real; --min-step removes it.
Detection runs on a smoothed copy of the signal; all estimation uses the raw samples.
Locating the switch. Transients are local minima selected by prominence,
which in one dimension equals topological persistence [2] — scale-free, and
unreachable by noise. The gate is
Segmenting. Regeneration excursions are told from switch transients by depth, not duration: they are thousands of picometres deep against a few hundred, while their durations overlap once an excursion is clipped by the end of a record. They partition the record into cycles, so the number of reported values is fixed by the record's structure, not by a threshold.
Estimating. The pre-switch level
fitted past a guard band out to the plateau maximum; the measurement is
Uncertainty. The relaxation carries the Gauss–Newton covariance over all of
Rejection. An event is reported only if --min-step.
Needs numpy, scipy and matplotlib.
python measure_step_response.py # ./data -> ./output
python measure_step_response.py --min-step 50 # ignore steps under 50 pmRecords are tab- or space-separated, one header line, columns time, response, extinction; a comma decimal separator is accepted.
output/csv holds one row per measurement — step_pm, u_pm, the 95 %
interval, the fitted tau_s, and diagnostics. output/plot_fit draws the
fitted model over the data, and output/plot_only the bare sensorgram. The red
and green markers are the two fitted levels, not data points that happened to
be local extrema.
All in physical units, all with defaults; --help lists them.
--detect-sigma |
3 s | detection scale; structure below it is noise |
--min-prominence |
10 | transient prominence, in noise scales |
--switch-width |
60 s | maximum width of a switch transient |
--cycle-depth |
0.40 | excursion depth bounding a cycle, as a fraction of range |
--guard |
25 s | excluded either side of the switch |
--pre-window / --post-window |
60 / 250 s | fit window lengths |
--min-snr / --min-tstat |
5 / 5 | significance floors |
--min-step |
0 pm | absolute size floor; a stated prior, off by default |
- Babaud, Witkin, Baudin & Duda. Uniqueness of the Gaussian kernel for scale-space filtering. IEEE TPAMI 8(1), 26–33 (1986).
- Edelsbrunner, Letscher & Zomorodian. Topological persistence and simplification. Discrete Comput. Geom. 28, 511–533 (2002).
- Rousseeuw & Croux. Alternatives to the median absolute deviation. JASA 88(424), 1273–1283 (1993).
- Golub & Pereyra. The differentiation of pseudo-inverses and nonlinear least squares problems whose variables separate. SIAM J. Numer. Anal. 10(2), 413–432 (1973).
- JCGM 100:2008. Guide to the expression of uncertainty in measurement (GUM), Annex G.
Written in 2022 for a fellow student's master's work and reworked around the estimator above. Suggestions welcome via LinkedIn.
