:py:mod:`tcspcfit` ================== .. py:module:: tcspcfit .. autoapi-nested-parse:: Module for fitting TCSPC data. The function distfluofit is based on MATLAB code by Jörg Enderlein: https://www.uni-goettingen.de/en/513325.html Bertus van Heerden and Joshua Botha, University of Pretoria Module Contents --------------- Classes ~~~~~~~ .. autoapisummary:: tcspcfit.FluoFit tcspcfit.OneExp tcspcfit.TwoExp tcspcfit.ThreeExp tcspcfit.FittingParameters tcspcfit.FittingDialog Functions ~~~~~~~~~ .. autoapisummary:: tcspcfit.moving_avg tcspcfit.max_continuous_zeros tcspcfit.makerow tcspcfit.colorshift tcspcfit.minfunc tcspcfit.ml_curve_fit Attributes ~~~~~~~~~~ .. autoapisummary:: tcspcfit.__docformat__ tcspcfit.logger tcspcfit.fitting_dialog_file tcspcfit.BACKGROUND_SECTION_LENGTH .. py:data:: __docformat__ :value: "'NumPy'" .. py:data:: logger :value: "'tcspcfit'" .. py:data:: fitting_dialog_file .. py:data:: BACKGROUND_SECTION_LENGTH :value: '50' .. py:function:: moving_avg(vector: Union[list, numpy.ndarray], window_length: int, pad_same_size: bool = True) -> numpy.ndarray Moving average filter. This function is used to smooth the decay histgram before determining a suitable fitting endpoint. :param vector: data moving average is to be applied to :type vector: 1D ndarray :param window_length: moving average window size in number of datapoints :type window_length: int :param pad_same_size: whether to pad the data with zeros before calculating moving average :type pad_same_size: bool, default True :returns: **new_vector** -- filtered data :rtype: 1D ndarray .. py:function:: max_continuous_zeros(vector: numpy.ndarray) -> int Find the maximum number of continuous zeros in data. Used by `FluoFit.estimate_bg`, this function finds the maximum number of consecutive zeros in the input data. :param vector: input data :type vector: 1D ndarray :returns: **maxzeros** -- maximum number of consecutive zeros :rtype: int .. py:function:: makerow(vector) Reshape 1D vector into a 2D row .. py:function:: colorshift(irf, shift) Shift irf left or right 'periodically'. A shift past the start or end results in those values of irf 'wrapping around'. :param irf: data to be shifted :type irf: row vector or 1D :param shift: amount to be shifted in number of channels :type shift: float :returns: **irs** -- shifted irf, as row vector :rtype: ndarray .. py:function:: minfunc(p0, fitfunc, t, measured) .. py:function:: ml_curve_fit(fitfunc, t, measured, bounds, p0, constraints=None) .. py:class:: FluoFit(irf, measured, t, channelwidth, tau=None, amp=None, shift=None, bg=None, irfbg=None, boundaries=None, ploton=False, fwhm=None, method='ls', normalize_amps=True, numexp=None) Base class for fit of a multi-exponential decay curve. This class is only used for subclassing. :param irf: Instrumental Response Function :type irf: ndarray :param measured: The measured decay data :type measured: ndarray :param channelwidth: Time width of one TCSPC channel (in nanoseconds) :type channelwidth: float :param tau: Initial guess times (in ns). This is either in the format [tau1, tau2, ...] or [[tau1, min1, max1, fix1], [tau2, ...], ...]. When the "fix" value is False, the min and max values are ignored. :type tau: array_like, optional :param amp: Initial guess amplitude. Format [amp1, amp2, ...] or [[amp1, fix1], [amp2, fix2], ...] :type amp: array_like, optional :param shift: Initial guess IRF shift. Either a float, or [shift, min, max, fix]. :type shift: array_like, optional :param bg: Background value for decay. Will be estimated if not given. :type bg: float :param irfbg: Background value for IRF. Will be estimated if not given. :type irfbg: float :param boundaries: Start and end of fitting range as well as options for automatic determination of the parameters as used by `calculate_boundaries`. :type boundaries: list :param ploton: Whether to automatically plot the irf_data. :type ploton: bool :param fwhm: Full-width at half maximum of simulated irf. IRF is not simulated if fwhm is None. :type fwhm: float = None :param normalize_amps: Whether to use normalized lifetime amplitudes. :type normalize_amps: bool = True :param method: Method for fitting - 'ls' for least-squares or 'ml' for maximum likelihood. :type method: str = 'ls' :param numexp: Number of exponential components in fit. :type numexp: int, optional .. py:attribute:: numexp :value: 'None' .. py:attribute:: normalize_amps :value: 'True' .. py:attribute:: channelwidth .. py:attribute:: ploton :value: 'False' .. py:attribute:: t .. py:attribute:: method :value: "'ls'" .. py:attribute:: tau :value: '[]' .. py:attribute:: taumin :value: '[]' .. py:attribute:: taumax :value: '[]' .. py:attribute:: amp :value: '[]' .. py:attribute:: ampmin :value: '[]' .. py:attribute:: ampmax :value: '[]' .. py:attribute:: shift :value: 'None' .. py:attribute:: shiftmin :value: 'None' .. py:attribute:: shiftmax :value: 'None' .. py:attribute:: fwhm :value: 'None' .. py:attribute:: fwhmmin :value: 'None' .. py:attribute:: fwhmmax :value: 'None' .. py:attribute:: stds :value: '[]' .. py:attribute:: settings .. py:attribute:: bg :value: 'None' .. py:attribute:: irfbg :value: 'None' .. py:attribute:: startpoint :value: 'None' .. py:attribute:: endpoint :value: 'None' .. py:attribute:: meas_bef_bg .. py:attribute:: measured_unbounded .. py:attribute:: measured_not_normalized .. py:attribute:: meas_sum .. py:attribute:: bg_n :value: 'None' .. py:attribute:: meas_std :value: 'None' .. py:attribute:: dtau :value: 'None' .. py:attribute:: chisq :value: 'None' .. py:attribute:: residuals :value: 'None' .. py:attribute:: dw :value: 'None' .. py:attribute:: dw_bound :value: 'None' .. py:attribute:: convd :value: 'None' .. py:attribute:: is_fit :value: 'False' .. py:method:: load_settings() Load configuration from settings.json file. .. py:method:: calculate_boundaries(measured, boundaries, bg, settings, channel_width, fitmethod='ls') :staticmethod: Set the start and endpoints. Sets the values to the given ones or automatically find good ones. The start value is chosen as earliest point that is at least 80% of the maximum point of the measured decay, and the end value is chosen as either the point where the decay is 1 % of maximum or 20 times the background value, whichever is highest. These values can be modified in the settings dialog. :param measured: The measured decay data. :type measured: ndarray :param boundaries: [startpoint, endpoint, autostart, autoend]. :type boundaries: list :param bg: Calculated decay background. :type bg: float :param settings: Contains config settings. :type settings: settings_dialog.Settings() object :param channel_width: Duration of a single channel. :type channel_width: float :param fitmethod: Fitting method for lifetime fit - 'ls' for least squares or 'ml' for maximum likelihood. :type fitmethod: string .. py:method:: calculate_bg(bg, irf, irf_bg, measured) Calculate decay and IRF background values If not given, the background value is estimated from the first part of the curve, before the rise. :param bg: Decay background value :type bg: float :param irf: Instrument response function :type irf: ndarray :param irfbg: IRF background value :type irfbg: float :param measured: Measured decay data :type measured: ndarray .. py:method:: estimate_bg(measured, return_bglim=False, settings=None) :staticmethod: Estimate decay background Optionally returns only the index of rise start. :param measured: measured decay data :type measured: ndarray :param return_bglim: whether to return index of rise start instead of bg :type return_bglim: bool :param settings: Contains config settings :type settings: settings_dialog.Settings() object .. py:method:: setup_params(amp, shift, tau, fwhm=None, bg=None) Setup fitting parameters. This method handles the input of initial parameters for fitting. The input system is flexible, allowing optional input of min and max values as well as choosing to fix a value. :param amp: Amplitude(s) :type amp: list or float :param shift: IRF colour shift :type shift: list or float :param tau: Lifetime(s) :type tau: list or float :param fwhm: simulated IRF fwhm :type fwhm: list or float .. py:method:: df_len(test_obj) -> int :staticmethod: Find the 'length' of an object Returns len(obj) if possible, else returns 1 iff obj is not None .. py:method:: results(tau, stds, avtaustd, shift, amp=1, fwhm=None, bg=None) Handle results after fitting After fitting, the results are processed. Chi-squared is calculated and optional plotting is done. :param tau: Fitted lifetime(s) :type tau: ndarray or float :param dtau: Error in fitted lifetimes :type dtau: ndarray or float :param shift: Fitted colourshift value :type shift: float :param amp: Fitted amplitude(s) :type amp: ndarray or float .. py:method:: makeconvd(shift, model, fwhm=None, bg=0) Makes a convolved decay using IRF and exponential model The IRF is either `self.irf` or, if `fwhm` is provided, a simulated Gaussian. :param shift: IRF colour shift :type shift: float :param model: Exponential model function :type model: ndarray :returns: **convd** -- convolution of model with shifted IRF :rtype: 1D ndarray .. py:method:: sim_irf(channelwidth, fwhm, measured) :staticmethod: Return a simulated Gaussian IRF. The IRF is shifted and scaled to have its peak lined up with the peak of the provided measured data. :param channelwidth: TCSPC channelwidth in ns :type channelwidth: float :param fwhm: full width at half maximum of Gaussian IRF :type fwhm: float :param measured: measured decay function :type measured: 1D ndarray :returns: * **irf** (*1D ndarray*) -- simulated IRF * **irft** (*1D ndarray*) -- time axis for IRF .. py:method:: durbinwatson() Calculates Durbin-Watson lower bound. Based on Turner 2020 https://doi.org/10.1080/13504851.2019.1691711 We use 0.1%, 0.3%, 1% or 5% critical bound for lower bound d_L of DW parameter. .. py:class:: OneExp(irf, measured, t, channelwidth, tau=None, amp=None, shift=None, bg=None, irfbg=None, boundaries=None, addopt=None, ploton=False, fwhm=None, method='ls') Bases: :py:obj:`FluoFit` Single exponential fit. Takes exact same arguments as `FluoFit` with the addition of addopt. :param addopt: Additional options for `curve_fit`. :type addopt: Dict = None .. py:method:: fitfunc_ls(t, tau1, a, shift, fwhm=None) Single exponential model function passed to curve_fit, to be fitted to data. .. py:method:: fitfunc_ml(t, tau1, shift, bg, fwhm=None) Single exponential model function passed to curve_fit, to be fitted to data. .. py:class:: TwoExp(irf, measured, t, channelwidth, tau=None, amp=None, shift=None, bg=None, irfbg=None, boundaries=None, addopt=None, ploton=False, fwhm=None, normalize_amps=True, method='ls') Bases: :py:obj:`FluoFit` Double exponential fit. Takes exact same arguments as `FluoFit` with the addition of addopt. :param addopt: Additional options for `curve_fit`. :type addopt: Dict = None .. py:method:: fitfunc_ls(t, tau1, tau2, a1, a2, shift, fwhm=None) Double exponential model function passed to curve_fit, to be fitted to data. .. py:method:: fitfunc_ml(t, tau1, tau2, a1, shift, bg, fwhm=None) Double exponential model function passed to curve_fit, to be fitted to data. .. py:class:: ThreeExp(irf, measured, t, channelwidth, tau=None, amp=None, shift=None, bg=None, irfbg=None, boundaries=None, addopt=None, ploton=False, fwhm=None, normalize_amps=True, method='ls') Bases: :py:obj:`FluoFit` Triple exponential fit. Takes exact same arguments as `FluoFit` with the addition of addopt. :param addopt: Additional options for `curve_fit`. :type addopt: Dict = None .. py:method:: fitfunc_ls(t, tau1, tau2, tau3, a1, a2, a3, shift, fwhm=None) Triple exponential model function passed to curve_fit, to be fitted to data .. py:method:: fitfunc_ml(t, tau1, tau2, tau3, a1, a2, shift, bg, fwhm=None) Triple exponential model function passed to curve_fit, to be fitted to data .. py:class:: FittingParameters(parent: controllers.LifetimeController) This class encapsulates lifetime fitting parameters. An instance of the class is created by `LifetimeController` to get the fitting parameters from the `FittingDialog` and a copy of this instance is passed to the fitting thread. :param parent: the parent object :type parent: controllers.LifetimeController .. py:attribute:: parent .. py:attribute:: fpd .. py:attribute:: irf :value: 'None' .. py:attribute:: tau :value: 'None' .. py:attribute:: amp :value: 'None' .. py:attribute:: shift :value: 'None' .. py:attribute:: decaybg :value: 'None' .. py:attribute:: irfbg :value: 'None' .. py:attribute:: start :value: 'None' .. py:attribute:: autostart :value: "'Manual'" .. py:attribute:: end :value: 'None' .. py:attribute:: autoend :value: 'False' .. py:attribute:: numexp :value: 'None' .. py:attribute:: addopt :value: 'None' .. py:attribute:: fwhm :value: 'None' .. py:attribute:: normalize_amps :value: 'True' .. py:attribute:: maximum_likelihood :value: 'False' .. py:method:: getfromdialog() .. py:method:: get_from_gui(guiobj) Get cleaned-up values from gui This function checks the validity of gui values in the fitting dialog and returns them to `getfromdialog`. .. py:class:: FittingDialog(mainwindow, lifetime_controller) Bases: :py:obj:`PyQt5.QtWidgets.QDialog`, :py:obj:`UI_Fitting_Dialog` Class for dialog that is used to choose lifetime fit parameters. :param mainwindow: the current mainwindow instance :type mainwindow: main.MainWindow :param lifetime_controller: the parent of this object :type lifetime_controller: controllers.LifetimeController .. py:attribute:: mainwindow .. py:attribute:: lifetime_controller .. py:attribute:: settings .. py:attribute:: tau_edits .. py:attribute:: tau_min_edits .. py:attribute:: tau_max_edits .. py:attribute:: amp_edits .. py:attribute:: amp_min_edits .. py:attribute:: amp_max_edits .. py:attribute:: bg_edits .. py:attribute:: time_edits .. py:attribute:: irf_shift_edits .. py:attribute:: _reg_exp_validator .. py:method:: load_settings() Load configuration from settings.json file. .. py:method:: enable_sim_vals(enable) Called to enable the IRF simulation parameter input widgets. .. py:method:: disable_amps(disable) Called to enable the secondary amplitudes when not normalized. .. py:method:: updateplot(*args) Update the plot using the current input values. .. py:method:: getparams() Return fit parameters from `FittingParameters` object. .. py:method:: make_model() Return multi-exponential model based on fitting parameters.