IMP logo
IMP Reference Guide  develop.7400db2aee,2024/11/23
The Integrative Modeling Platform
DecayRoutines.h
Go to the documentation of this file.
1 /**
2  * \file IMP/bff/DecayRoutines.h
3  * \brief Decay routines (e.g. convolution, scaling, and lamp shift routines)
4  *
5  * \authors Thomas-Otavio Peulen
6  * Copyright 2007-2023 IMP Inventors. All rights reserved.
7  *
8  */
9 
10 #ifndef IMPBFF_DECAYROUTINES_H
11 #define IMPBFF_DECAYROUTINES_H
12 
13 #include <IMP/bff/bff_config.h>
14 
15 #include <cmath> /* std::ceil */
16 #include <numeric> /* std::accumulate */
17 #include <iostream>
18 #include <vector>
19 #include <algorithm> /* std::max */
20 #include <string.h> /* strcmp */
21 
22 #if defined(__AVX__)
23  #if defined(_MSC_VER)
24  /* Microsoft C/C++-compatible compiler */
25  #include <intrin.h>
26  #include <immintrin.h>
27  #endif
28  #if (defined(__GNUC__) || defined(__clang__))
29  #include <immintrin.h>
30  #endif
31  #if !defined(__FMA__)
32  #define __FMA__ 1
33  #endif
34 #endif //__AVX__
35 
36 IMPBFF_BEGIN_NAMESPACE
37 
38 /**
39  * \brief Compute the modulo of a number with respect to a positive integer.
40  *
41  * This function computes the modulo of a number 'a' with respect to a positive
42  * integer 'n'. The result is always in the range from -1 to n - 1.
43  *
44  * -1 -> n - 1, -2 -> n - 2,
45  * \param a The number to compute the modulo for.
46  * \param n The positive integer to compute the modulo with respect to.
47  * \return The modulo of 'a' with respect to 'n'.
48  */inline int mod_p(int a, int n){
49  return (n + (a % n)) % n;
50 }
51 
52 /**
53  * \brief Scale model function to the data (old version).
54  *
55  * This function rescales the model function (fit) to the data by counting the
56  * number of photons between a start and a stop micro time counting channel.
57  * The model function is scaled to match the data by area. This rescaling
58  * function does not consider the noise in the data.
59  *
60  * \param fit The model function that is scaled (modified in-place).
61  * \param decay The experimental data to which the model function is scaled.
62  * \param scale The scaling parameter (the factor) by which the model function
63  * is multiplied.
64  * \param start The start micro time channel.
65  * \param stop The stop micro time channel.
66  */
67 IMPBFFEXPORT void decay_rescale(double *fit, double *decay, double *scale, int start, int stop);
68 
69 
70 /**
71  * \brief Scale model function to the data (with weights).
72  *
73  * This function rescales the model function (fit) to the data by counting the
74  * number of photons between a start and a stop micro time counting channel.
75  * The model function is scaled to match the data by area, considering the noise
76  * of the data. The scaling factor is computed by:
77  *
78  * \f[
79  * \text{scale} = \frac{\sum \left(\frac{{\text{fit}} \cdot \text{decay}}}{{w^2}}\right)}{\sum \left(\frac{{\text{fit}}^2}}{{w^2}}\right)}
80  * \f]
81  *
82  * \param fit The model function that is scaled (modified in-place).
83  * \param decay The experimental data to which the model function is scaled.
84  * \param w_sq The squared weights of the data.
85  * \param scale The scaling parameter (the factor) by which the model function
86  * is multiplied.
87  * \param start The start micro time channel.
88  * \param stop The stop micro time channel.
89  */
90 IMPBFFEXPORT void decay_rescale_w(double *fit, double *decay, double *w_sq, double *scale, int start, int stop);
91 
92 /**
93  * @brief Scale model function to the data (with weights and background)
94  *
95  * This function scales the model function (fit) to the data by the number
96  * of photons between a start and a stop micro time counting channel. The number
97  * of photons between start and stop are counted and the model function is scaled
98  * to match the data by area considering the noise of the data and a constant
99  * offset of the data.
100  *
101  * scale = sum(fit*(decay-bg)/w^2)/sum(fit^2/w^2)
102  *
103  * @param fit[in,out] model function that is scaled (modified in-place)
104  * @param decay[in] the experimental data to which the model function is scaled
105  * @param w_sq[in] squared weights of the data.
106  * @param bg[in] constant background of the data
107  * @param scale[out] the scaling parameter (the factor) by which the model
108  * function is multiplied.
109  * @param start[in] The start micro time channel
110  * @param stop[in] The stop micro time channel
111  */
112 IMPBFFEXPORT void decay_rescale_w_bg(double *fit, double *decay, double *e_sq, double bg, double *scale, int start, int stop);
113 
114 
115 /**
116  * @brief Convolve lifetime spectrum with instrument response (fast convolution, low repetition rate)
117  *
118  * This function computes the convolution of a lifetime spectrum (a set of
119  * lifetimes with corresponding amplitudes) with an instrument response function
120  * (irf). This function does not consider periodic excitation and is suited for
121  * experiments at low repetition rate.
122  *
123  * @param fit[out] model function. The convoluted decay is written to this array
124  * @param x[in] lifetime spectrum (amplitude1, lifetime1, amplitude2, lifetime2, ...)
125  * @param lamp[in] instrument response function
126  * @param numexp[in] number of fluorescence lifetimes
127  * @param start[in] start micro time index for convolution (not used)
128  * @param stop[in] stop micro time index for convolution.
129  * @param dt[in] time difference between two micro time channels
130  */
131 IMPBFFEXPORT void decay_fconv(double *fit, double *x, double *lamp, int numexp, int start, int stop, double dt=0.05);
132 
133 /**
134  * @brief Convolve lifetime spectrum with instrument response (fast convolution, AVX optimized for large lifetime spectra)
135  *
136  * This function is a modification of fconv for large lifetime spectra. The lifetime spectrum is processed by AVX intrinsics.
137  * Four lifetimes are convolved at once. Spectra with lifetimes that are not multiple of four are zero padded.
138  *
139  * @param fit[out] model function. The convoluted decay is written to this array
140  * @param x[in] lifetime spectrum (amplitude1, lifetime1, amplitude2, lifetime2, ...)
141  * @param lamp[in] instrument response function
142  * @param numexp[in] number of fluorescence lifetimes
143  * @param start[in] start micro time index for convolution (not used)
144  * @param stop[in] stop micro time index for convolution.
145  * @param n_points[in] number of points in the lifetime spectrum
146  * @param dt[in] time difference between two micro time channels
147  */
148 IMPBFFEXPORT void decay_fconv_avx(double *fit, double *x, double *lamp, int numexp, int start, int stop, double dt=0.05);
149 
150 /**
151  * @brief Convolve lifetime spectrum with instrument response (fast convolution, high repetition rate)
152  *
153  * This function computes the convolution of a lifetime spectrum (a set of lifetimes with corresponding amplitudes)
154  * with an instrument response function (irf). This function considers periodic excitation and is suited for experiments
155  * at high repetition rate.
156  *
157  * @param fit[out] model function. The convoluted decay is written to this array
158  * @param x[in] lifetime spectrum (amplitude1, lifetime1, amplitude2, lifetime2, ...)
159  * @param lamp[in] instrument response function
160  * @param numexp[in] number of fluorescence lifetimes
161  * @param start[in] start micro time index for convolution (not used)
162  * @param stop[in] stop micro time index for convolution.
163  * @param n_points number of points in the model function.
164  * @param period excitation period in units of the fluorescence lifetimes (typically nanoseconds)
165  * @param dt[in] time difference between two micro time channels
166  */
167 IMPBFFEXPORT void decay_fconv_per(
168  double *fit, double *x, double *lamp, int numexp, int start, int stop,
169  int n_points, double period, double dt=0.05
170 );
171 
172 /**
173  * @brief Convolve lifetime spectrum with instrument response (fast convolution, high repetition rate), AVX optimized version
174  *
175  * This function computes the convolution of a lifetime spectrum (a set of lifetimes with corresponding amplitudes)
176  * with an instrument response function (irf). This function considers periodic excitation and is suited for experiments
177  * at high repetition rate. It is an AVX optimized version.
178  *
179  * @param fit[out] model function. The convoluted decay is written to this array
180  * @param x[in] lifetime spectrum (amplitude1, lifetime1, amplitude2, lifetime2, ...)
181  * @param lamp[in] instrument response function
182  * @param numexp[in] number of fluorescence lifetimes
183  * @param start[in] start micro time index for convolution (not used)
184  * @param stop[in] stop micro time index for convolution.
185  * @param n_points number of points in the model function.
186  * @param period excitation period in units of the fluorescence lifetimes (typically nanoseconds)
187  * @param dt[in] time difference between two micro time channels
188  */
189 IMPBFFEXPORT void decay_fconv_per_avx(
190  double *fit, double *x, double *lamp, int numexp, int start, int stop,
191  int n_points, double period, double dt=0.05
192 );
193 
194 /**
195  * @brief Convolve lifetime spectrum - fast convolution, high repetition rate, with convolution stop
196  *
197  * This function performs fast convolution of a lifetime spectrum with an instrument response function.
198  * The convolution is stopped at a specified micro time index.
199  *
200  * @param fit[out] Model function. The convoluted decay is written to this array.
201  * @param x[in] Lifetime spectrum (amplitude1, lifetime1, amplitude2, lifetime2, ...).
202  * @param lamp[in] Instrument response function.
203  * @param numexp[in] Number of fluorescence lifetimes.
204  * @param stop[in] Stop micro time index for convolution.
205  * @param n_points Number of points in the model function.
206  * @param period Excitation period in units of the fluorescence lifetimes (typically nanoseconds).
207  * @param conv_stop Convolution stop micro channel number.
208  * @param dt[in] Time difference between two micro time channels.
209  */
210 IMPBFFEXPORT void decay_fconv_per_cs(double *fit, double *x, double *lamp, int numexp, int stop,
211  int n_points, double period, int conv_stop, double dt);
212 
213 /**
214  * @brief Convolve lifetime spectrum - fast convolution with reference compound decay.
215  *
216  * This function convolves a set of fluorescence lifetimes and associated amplitudes with an instrument response function.
217  * The provided amplitudes are scaled prior to the convolution by area using a reference fluorescence
218  * lifetime. The amplitudes are computed as:
219  *
220  * amplitude_corrected = a * (1 / tauref - 1 / tau)
221  *
222  * where a and tau are the provided amplitudes.
223  *
224  * @param fit[out] Model function. The convoluted decay is written to this array.
225  * @param x[in] Lifetime spectrum (amplitude1, lifetime1, amplitude2, lifetime2, ...).
226  * @param lamp[in] Instrument response function.
227  * @param numexp[in] Number of fluorescence lifetimes.
228  * @param start[in] Start micro time index for convolution (not used).
229  * @param stop[in] Stop micro time index for convolution.
230  * @param tauref A reference lifetime used to rescale the amplitudes of the fluorescence lifetime spectrum.
231  * @param dt[in] Time difference between two micro time channels.
232  */
233 IMPBFFEXPORT void decay_fconv_ref(double *fit, double *x, double *lamp, int numexp, int start, int stop, double tauref, double dt=0.05);
234 
235 /*!
236  * @brief Convolve fluorescence decay curve with irf
237  *
238  * This function computes a convolved model function for a fluorescence decay
239  * curve.
240  *
241  * @param fit convolved model function
242  * @param p model function before convolution - fluorescence decay curve
243  * @param lamp instrument response function
244  * @param start start index of the convolution
245  * @param stop stop index of the convolution
246  */
247 IMPBFFEXPORT void decay_sconv(double *fit, double *p, double *lamp, int start, int stop);
248 
249 /*!
250  * @brief shift instrument response function
251  *
252  * @param lampsh
253  * @param lamp
254  * @param ts
255  * @param n_points
256  * @param out_value the value of the shifted response function outside of the
257  * valid indices
258  */
259 IMPBFFEXPORT void decay_shift_lamp(double *lampsh, double *lamp, double ts, int n_points, double out_value=0.0);
260 
261 /*!
262  * @brief Add a pile-up distortion to the model function
263  *
264  * This function adds a pile up distortion to a model fluorescence decay. The
265  * model used to compute the pile-up distortion follows the description of Coates
266  * (1968, eq. 2 and eq. 4)
267  *
268  * Reference:
269  * Coates, P.: The correction for photonpile-up in the measurement of radiative
270  * lifetimes. J. Phys. E: Sci. Instrum. 1(8), 878–879 (1968)
271  *
272  * @param model[in,out] The array containing the model function
273  * @param n_model[in] Number of elements in the model array
274  * @param data[in] The array containing the experimental decay
275  * @param n_data[in] number of elements in experimental decay
276  * @param repetition_rate[in] The repetition-rate (excitation rate) in MHz
277  * @param instrument_dead_time[in] The overall dead-time of the detection system in nanoseconds
278  * @param measurement_time[in] The measurement time in seconds
279  * @param pile_up_model[in] The model used to compute the pile up distortion.
280  * @param start Start index for pile up
281  * @param stop Stop index for pile up
282  * (default "coates")
283  */
284 IMPBFFEXPORT void decay_add_pile_up_to_model(
285  double* model, int n_model,
286  double* data, int n_data,
287  double repetition_rate,
288  double instrument_dead_time,
289  double measurement_time,
290  std::string pile_up_model = "coates",
291  int start = 0,
292  int stop = -1
293 );
294 
295 /*!
296  * Threshold amplitudes
297  *
298  * Amplitudes with absolute values smaller than the specified threshold are
299  * set to zero.
300  *
301  * @param lifetime_spectrum interleaved lifetime spectrum (amplitude, lifetime)
302  * @param n_lifetime_spectrum number of elements in lifetime spectrum
303  * @param amplitude_threshold
304  */
305 IMPBFFEXPORT void discriminate_small_amplitudes(
306  double* lifetime_spectrum, int n_lifetime_spectrum,
307  double amplitude_threshold
308 );
309 
310 /*!
311 * Compute the fluorescence decay for a lifetime spectrum and an instrument
312 * response function considering periodic excitation.
313 *
314 * Fills the pre-allocated output array `output_decay` with a fluorescence
315 * intensity decay defined by a set of fluorescence lifetimes defined by the
316 * parameter `lifetime_handler`. The fluorescence decay will be convolved
317 * (non-periodically) with an instrumental response function that is defined
318 * by `instrument_response_function`.
319 *
320 * This function calculates a fluorescence intensity model_decay that is
321 * convolved with an instrument response function (IRF). The fluorescence
322 * intensity model_decay is specified by its fluorescence lifetime spectrum,
323 * i.e., an interleaved array containing fluorescence lifetimes with
324 * corresponding amplitudes.
325 *
326 * This convolution only works with evenly linear spaced time axes.
327 *
328 * @param inplace_output[in,out] Inplace output array that is filled with the values
329 * of the computed fluorescence intensity decay model
330 * @param n_output[in] Number of elements in the output array
331 * @param time_axis[in] the time-axis of the model_decay
332 * @param n_time_axis[in] length of the time axis
333 * @param irf[in] the instrument response function array
334 * @param n_irf[in] length of the instrument response function array
335 * @param lifetime_spectrum[in] Interleaved array of amplitudes and fluorescence
336 * lifetimes of the form (amplitude, lifetime, amplitude, lifetime, ...)
337 * @param n_lifetime_spectrum[in] number of elements in the lifetime spectrum
338 * @param convolution_start[in] Start channel of convolution (position in array of IRF)
339 * @param convolution_stop[in] convolution stop channel (the index on the time-axis)
340 * @param period Period of repetition in units of the lifetime (usually,
341 * nano-seconds)
342 */
343 IMPBFFEXPORT void decay_fconv_per_cs_time_axis(
344  double *model, int n_model,
345  double *time_axis, int n_time_axis,
346  double *irf, int n_irf,
347  double *lifetime_spectrum, int n_lifetime_spectrum,
348  int convolution_start = 0,
349  int convolution_stop = -1,
350  double period = 100.0
351 );
352 
353 /*!
354 * Compute the fluorescence decay for a lifetime spectrum and a instrument
355 * response function.
356 *
357 * Fills the pre-allocated output array `output_decay` with a fluorescence
358 * intensity decay defined by a set of fluorescence lifetimes defined by the
359 * parameter `lifetime_handler`. The fluorescence decay will be convolved
360 * (non-periodically) with an instrumental response function that is defined
361 * by `instrument_response_function`.
362 *
363 * This function calculates a fluorescence intensity model_decay that is
364 * convolved with an instrument response function (IRF). The fluorescence
365 * intensity model_decay is specified by its fluorescence lifetime spectrum,
366 * i.e., an interleaved array containing fluorescence lifetimes with
367 * corresponding amplitudes.
368 *
369 * This convolution works also with uneven spaced time axes.
370 *
371 * @param inplace_output[in,out] Inplace output array that is filled with the
372 * values of the computed fluorescence intensity decay model
373 * @param n_output[in] Number of elements in the output array
374 * @param time_axis[in] the time-axis of the model_decay
375 * @param n_time_axis[in] length of the time axis
376 * @param irf[in] the instrument response function array
377 * @param n_irf[in] length of the instrument response function array
378 * @param lifetime_spectrum[in] Interleaved array of amplitudes and fluorescence
379 * lifetimes of the form (amplitude, lifetime, amplitude, lifetime, ...)
380 * @param n_lifetime_spectrum[in] number of elements in the lifetime spectrum
381 * @param convolution_start[in] Start channel of convolution (position in array
382 * of IRF)
383 * @param convolution_stop[in] convolution stop channel (the index on the time-axis)
384 * @param use_amplitude_threshold[in] If this value is True (default False)
385 * fluorescence lifetimes in the lifetime spectrum which have an amplitude
386 * with an absolute value of that is smaller than `amplitude_threshold` are
387 * not omitted in the convolution.
388 * @param amplitude_threshold[in] Threshold value for the amplitudes
389 */
390 IMPBFFEXPORT void decay_fconv_cs_time_axis(
391  double *inplace_output, int n_output,
392  double *time_axis, int n_time_axis,
393  double *irf, int n_irf,
394  double *lifetime_spectrum, int n_lifetime_spectrum,
395  int convolution_start = 0,
396  int convolution_stop = -1
397 );
398 
399 
400 IMPBFF_END_NAMESPACE
401 
402 #endif //IMPBFF_DECAYROUTINES_H
void decay_fconv_per_cs(double *fit, double *x, double *lamp, int numexp, int stop, int n_points, double period, int conv_stop, double dt)
Convolve lifetime spectrum - fast convolution, high repetition rate, with convolution stop...
void decay_fconv_avx(double *fit, double *x, double *lamp, int numexp, int start, int stop, double dt=0.05)
Convolve lifetime spectrum with instrument response (fast convolution, AVX optimized for large lifeti...
void decay_rescale_w_bg(double *fit, double *decay, double *e_sq, double bg, double *scale, int start, int stop)
Scale model function to the data (with weights and background)
void decay_fconv_cs_time_axis(double *inplace_output, int n_output, double *time_axis, int n_time_axis, double *irf, int n_irf, double *lifetime_spectrum, int n_lifetime_spectrum, int convolution_start=0, int convolution_stop=-1)
void decay_rescale_w(double *fit, double *decay, double *w_sq, double *scale, int start, int stop)
Scale model function to the data (with weights).
void decay_add_pile_up_to_model(double *model, int n_model, double *data, int n_data, double repetition_rate, double instrument_dead_time, double measurement_time, std::string pile_up_model="coates", int start=0, int stop=-1)
Add a pile-up distortion to the model function.
void decay_rescale(double *fit, double *decay, double *scale, int start, int stop)
Scale model function to the data (old version).
void decay_fconv(double *fit, double *x, double *lamp, int numexp, int start, int stop, double dt=0.05)
Convolve lifetime spectrum with instrument response (fast convolution, low repetition rate) ...
void decay_fconv_per(double *fit, double *x, double *lamp, int numexp, int start, int stop, int n_points, double period, double dt=0.05)
Convolve lifetime spectrum with instrument response (fast convolution, high repetition rate) ...
void decay_shift_lamp(double *lampsh, double *lamp, double ts, int n_points, double out_value=0.0)
shift instrument response function
void decay_sconv(double *fit, double *p, double *lamp, int start, int stop)
Convolve fluorescence decay curve with irf.
void decay_fconv_per_cs_time_axis(double *model, int n_model, double *time_axis, int n_time_axis, double *irf, int n_irf, double *lifetime_spectrum, int n_lifetime_spectrum, int convolution_start=0, int convolution_stop=-1, double period=100.0)
void decay_fconv_ref(double *fit, double *x, double *lamp, int numexp, int start, int stop, double tauref, double dt=0.05)
Convolve lifetime spectrum - fast convolution with reference compound decay.
void decay_fconv_per_avx(double *fit, double *x, double *lamp, int numexp, int start, int stop, int n_points, double period, double dt=0.05)
Convolve lifetime spectrum with instrument response (fast convolution, high repetition rate)...
void discriminate_small_amplitudes(double *lifetime_spectrum, int n_lifetime_spectrum, double amplitude_threshold)
int mod_p(int a, int n)
Compute the modulo of a number with respect to a positive integer.
Definition: DecayRoutines.h:48