Exemple #1
0
    def svd(self, n=5):
        """
        Plot the SVD-components of the dataset.

        Parameters
        ----------
        n : int or list of int
            Determines the plotted SVD-components. If `n` is an int, it plots
            the first n components. If `n` is a list of ints, then every
            number is a SVD-component to be plotted.
        """
        is_nm = self.freq_unit is "nm"
        if is_nm:
            ph.vis_mode()
        else:
            ph.ir_mode()
        ds = self.dataset
        x = ds.wavelengths if is_nm else ds.wavenumbers
        fig, axs = plt.subplots(3, 1, figsize=(4, 5))
        u, s, v = np.linalg.svd(ds.data)
        axs[0].stem(s)
        axs[0].set_xlim(0, 11)
        try:
            len(n)
            comps = n
        except TypeError:
            comps = range(n)

        for i in comps:
            axs[1].plot(ds.t, u.T[i], label="%d" % i)
            axs[2].plot(x, v[i])
        ph.lbl_trans(axs[1], use_symlog=True)
        self.lbl_spec(axs[2])
Exemple #2
0
    def svd(self, n=5):
        """
        Plot the SVD-components of the dataset.

        Parameters
        ----------
        n : int or list of int
            Determines the plotted SVD-components. If `n` is an int, it plots
            the first n components. If `n` is a list of ints, then every
            number is a SVD-component to be plotted.
        """
        is_nm = self.freq_unit is 'nm'
        if is_nm:
            ph.vis_mode()
        else:
            ph.ir_mode()
        ds = self.dataset
        x = ds.wavelengths if is_nm else ds.wavenumbers
        fig, axs = plt.subplots(3, 1, figsize=(4, 5))
        u, s, v = np.linalg.svd(ds.data)
        axs[0].stem(s)
        axs[0].set_xlim(0, 11)
        try:
            len(n)
            comps = n
        except TypeError:
            comps = range(n)

        for i in comps:
            axs[1].plot(ds.t, u.T[i], label='%d' % i)
            axs[2].plot(x, v[i])
        ph.lbl_trans(axs[1], use_symlog=True)
        self.lbl_spec(axs[2])
Exemple #3
0
def das(tup,  x0, from_t=0.4, uniform_fil=None, plot_result=True, fit_kws=None):
    out = namedtuple('das_result', field_names=[
                     'fitter', 'result', 'minimizer'])

    ti = dv.make_fi(tup.t)
    if uniform_fil is not None:
        tupf = filter.uniform_filter(tup, uniform_fil)
    else:
        tupf = tup
    if fit_kws is None:
        fit_kws = {}
    import numpy as np
    #ct = dv.tup(np.hstack((wl, wl)), tup.t[ti(t0):],  np.hstack((pa[ti(t0):, :], se[ti(t0):, :])))
    ct = dv.tup(tup.wl, tup.t[ti(from_t):], tupf.data[ti(from_t):, :])
    f = fitter.Fitter(ct, model_coh=0, model_disp=0)
    f.lsq_method = 'ridge'
    kws = dict(full_model=0, lower_bound=0.2, fixed_names=['w'])
    kws.update(fit_kws)
    lm = f.start_lmfit(x0, **kws)
    res = lm.leastsq()
    import lmfit
    lmfit.report_fit(res)
    if plot_result:
        plt.figure(figsize=(4, 7))
        plt.subplot(211)
        if is_montone(f.wl):
            monotone = False
            # Assume wl is repeated
            N = len(f.wl)
        else:
            monotone = True
            N = len(f.wl) // 2
        print(N)
        l = plt.plot(f.wl[:N], f.c[:N, :], lw=3)
        if monotone:
            l2 = plt.plot(f.wl[:N], f.c[N:, :], lw=1)
            for i, j in zip(l, l2):
                j.set_color(i.get_color())
        plot_helpers.lbl_spec()
        lbls = ['%.1f' % i for i in f.last_para[1:-1]] + ['const']
        plt.legend(lbls)

        plt.subplot(212)

        wi = dv.make_fi(tup.wl)
        for i in range(N)[::6]:
            l, = plt.plot(tup.t, tupf.data[:, i], '-o', lw=0.7,
                          alpha=0.5, label='%.1f cm-1' % f.wl[i], mec='None', ms=3)
            plt.plot(f.t, f.model[:, i], lw=3, c=l.get_color())

            if monotone:
                l, = plt.plot(tup.t, tupf.data[:, i+N], '-o', lw=0.7,
                              alpha=0.5, label='%.1f cm-1' % f.wl[i], mec='None', ms=3)
                plt.plot(f.t, f.model[:, i+N], lw=3, c=l.get_color())
        plt.xlim(-1)
        plt.xscale('symlog', linthreshx=1, linscalex=0.5)
        plot_helpers.lbl_trans()
        plt.legend(loc='best')

    return out(f, res, lm)
Exemple #4
0
 def plot_square(self,
                 probe_range,
                 pump_range=None,
                 use_symlog=True,
                 ax=None):
     if pump_range is None:
         pump_range = probe_range
     pr = inbetween(self.ds.probe_wn, min(probe_range), max(probe_range))
     reg = self.ds.spec2d[:, pr, :]
     pu = inbetween(self.ds.pump_wn, min(pump_range), max(pump_range))
     reg = reg[:, :, pu]
     s = reg.sum(1).sum(1)
     if ax is None:
         ax = plt.gca()
     l, = ax.plot(self.ds.t, s)
     plot_helpers.lbl_trans(ax, use_symlog)
     return l
Exemple #5
0
    def trans_anisotropy(self, wls, symlog=True, ax=None, freq_unit='auto'):
        """
        Plots the anisotropy over time for given frequencies.
        Parameters
        ----------
        wls : list of floats
            Which frequencies are plotted.
        symlog : bool
            Use symlog scale
        ax : plt.Axes or None
            Matplotlib Axes, if `None`, defaults to `plt.gca()`.

        Returns
        -------
        : list of Line2D
            List with the line objects.

        """
        if ax is None:
            ax = ax.gca()
        ds = self.pol_ds
        tmp = self.freq_unit if freq_unit == 'auto' else freq_unit
        is_nm = tmp == 'nm'
        x = ds.wavelengths if is_nm else ds.wavenumbers
        if is_nm:
            ph.vis_mode()
        else:
            ph.ir_mode()
        l = []
        for i in wls:
            idx = dv.fi(x, i)
            pa, pe = ds.para.data[:, idx], ds.perp.data[:, idx]
            aniso = (pa - pe) / (2 * pe + pa)
            l += ax.plot(ds.para.t,
                         aniso,
                         label=ph.time_formatter(ds.t[idx], ph.time_unit))
        ph.lbl_trans(use_symlog=symlog)
        if symlog:
            ax.set_xscale('symlog')
        ax.set_xlim(-1, )
        return l
Exemple #6
0
    def trans_anisotropy(self, wls, symlog=True, ax=None, freq_unit="auto"):
        """
        Plots the anisotropy over time for given frequencies.
        Parameters
        ----------
        wls : list of floats
            Which frequencies are plotted.
        symlog : bool
            Use symlog scale
        ax : plt.Axes or None
            Matplotlib Axes, if `None`, defaults to `plt.gca()`.

        Returns
        -------
        : list of Line2D
            List with the line objects.

        """
        if ax is None:
            ax = ax.gca()
        ds = self.pol_ds
        tmp = self.freq_unit if freq_unit == "auto" else freq_unit
        is_nm = tmp == "nm"
        x = ds.wavelengths if is_nm else ds.wavenumbers
        if is_nm:
            ph.vis_mode()
        else:
            ph.ir_mode()
        l = []
        for i in wls:
            idx = dv.fi(x, i)
            pa, pe = ds.para.data[:, idx], ds.perp.data[:, idx]
            aniso = (pa - pe) / (2 * pe + pa)
            l += ax.plot(
                ds.para.t, aniso, label=ph.time_formatter(ds.t[idx], ph.time_unit)
            )
        ph.lbl_trans(use_symlog=symlog)
        if symlog:
            ax.set_xscale("symlog")
        ax.set_xlim(-1)
        return l
Exemple #7
0
    def plot_cls(self,
                 ax=None,
                 model_style: Dict = None,
                 symlog=False,
                 **kwargs):
        if ax is None:
            ax = plt.gca()
        ec = ax.errorbar(self.wt, self.slopes, self.slope_errors, **kwargs)
        if symlog:
            ax.set_xscale('symlog', linthresh=1)
        plot_helpers.lbl_trans(ax=ax, use_symlog=symlog)

        ax.set(xlabel=plot_helpers.time_label, ylabel='Slope')
        m_line = None
        if self.exp_fit_result_:
            xu = np.linspace(min(self.wt), max(self.wt), 300)
            yu = self.exp_fit_result_.eval(x=xu)
            style = dict(c='k', zorder=1.8)
            if model_style:
                style.update(model_style)
            m_line = ax.plot(xu, yu, color='k', zorder=1.8)
        return ec, m_line
Exemple #8
0
def das(tup, x0, from_t=0.4, uniform_fil=None, plot_result=True, fit_kws=None):
    out = namedtuple('das_result',
                     field_names=['fitter', 'result', 'minimizer'])

    ti = dv.make_fi(tup.t)
    if uniform_fil is not None:
        tupf = filter.uniform_filter(tup, uniform_fil)
    else:
        tupf = tup
    if fit_kws is None:
        fit_kws = {}

    #ct = dv.tup(np.hstack((wl, wl)), tup.t[ti(t0):],  np.hstack((pa[ti(t0):, :], se[ti(t0):, :])))
    ct = dv.tup(tup.wl, tup.t[ti(from_t):], tupf.data[ti(from_t):, :])
    f = fitter.Fitter(ct, model_coh=0, model_disp=0)
    f.lsq_method = 'ridge'
    kws = dict(full_model=0, lower_bound=0.2, fixed_names=['w'])
    kws.update(fit_kws)
    lm = f.start_lmfit(x0, **kws)
    res = lm.leastsq()
    import lmfit
    lmfit.report_fit(res)
    if plot_result:
        plt.figure(figsize=(4, 7))
        plt.subplot(211)
        if is_montone(f.wl):
            monotone = False
            # Assume wl is repeated
            N = len(f.wl)
        else:
            monotone = True
            N = len(f.wl) // 2
        print(N)
        l = plt.plot(f.wl[:N], f.c[:N, :], lw=3)
        if monotone:
            l2 = plt.plot(f.wl[:N], f.c[N:, :], lw=1)
            for i, j in zip(l, l2):
                j.set_color(i.get_color())
        plot_helpers.lbl_spec()
        lbls = ['%.1f' % i for i in f.last_para[1:-1]] + ['const']
        plt.legend(lbls)

        plt.subplot(212)

        wi = dv.make_fi(tup.wl)
        for i in range(N)[::6]:
            l, = plt.plot(tup.t,
                          tupf.data[:, i],
                          '-o',
                          lw=0.7,
                          alpha=0.5,
                          label='%.1f cm-1' % f.wl[i],
                          mec='None',
                          ms=3)
            plt.plot(f.t, f.model[:, i], lw=3, c=l.get_color())

            if monotone:
                l, = plt.plot(tup.t,
                              tupf.data[:, i + N],
                              '-o',
                              lw=0.7,
                              alpha=0.5,
                              label='%.1f cm-1' % f.wl[i],
                              mec='None',
                              ms=3)
                plt.plot(f.t, f.model[:, i + N], lw=3, c=l.get_color())
        plt.xlim(-1)
        plt.xscale('symlog', linthreshx=1, linscalex=0.5)
        plot_helpers.lbl_trans()
        plt.legend(loc='best')

    return out(f, res, lm)
Exemple #9
0
    def trans(self,
              wls,
              symlog=True,
              norm=False,
              ax=None,
              freq_unit='auto',
              **kwargs):
        """
        Plot the nearest transients for given frequencies.

        Parameters
        ----------
        wls : list or ndarray
            Spectral positions, should be given in the same unit as
            `self.freq_unit`.
        symlog : bool
            Determines if the x-scale is symlog.
        norm : bool or float
            If `False`, no normalization is used. If `True`, each transient
            is divided by the maximum absolute value. If `norm` is a float,
            all transient are normalized by their signal at the time `norm`.
        ax : plt.Axes or None
            Takes a matplotlib axes. If none, it uses `plt.gca()` to get the
            current axes. The lines are plotted in this axis.
        freq_unit : 'auto', 'cm' or 'nm'
            How to interpret the given frequencies. If 'auto' it defaults to
            the plotters freq_unit.

        All other kwargs are forwarded to the plot function.

        Returns
        -------
         list of Line2D
            List containing the plotted lines.
        """
        if ax is None:
            ax = plt.gca()

        tmp = self.freq_unit if freq_unit is 'auto' else freq_unit
        is_nm = tmp == 'nm'
        if is_nm:
            ph.vis_mode()
        else:
            ph.ir_mode()
        ds = self.dataset
        x = ds.wavelengths if is_nm else ds.wavenumbers

        wl, t, d = ds.wl, ds.t, ds.data
        l, plotted_vals = [], []
        for i in wls:
            idx = dv.fi(x, i)

            dat = d[:, idx]
            if norm is True:
                dat = np.sign(dat[np.argmax(abs(dat))]) * dat / abs(dat).max()
            elif norm is False:
                pass
            else:
                dat = dat / dat[dv.fi(t, norm)]
            plotted_vals.append(dat)
            l.extend(
                ax.plot(t,
                        dat,
                        label='%.1f %s' % (x[idx], ph.freq_unit),
                        **kwargs))

        if symlog:
            ax.set_xscale('symlog', linthreshx=1.)
        ph.lbl_trans(ax=ax, use_symlog=symlog)
        ax.legend(loc='best', ncol=3)
        ax.set_xlim(right=t.max())
        ax.yaxis.set_tick_params(which='minor', left=True)
        return l
Exemple #10
0
    def trans(self, wls, symlog=True, norm=False, ax=None, freq_unit="auto", **kwargs):
        """
        Plot the nearest transients for given frequencies.

        Parameters
        ----------
        wls : list or ndarray
            Spectral positions, should be given in the same unit as
            `self.freq_unit`.
        symlog : bool
            Determines if the x-scale is symlog.
        norm : bool or float
            If `False`, no normalization is used. If `True`, each transient
            is divided by the maximum absolute value. If `norm` is a float,
            all transient are normalized by their signal at the time `norm`.
        ax : plt.Axes or None
            Takes a matplotlib axes. If none, it uses `plt.gca()` to get the
            current axes. The lines are plotted in this axis.
        freq_unit : 'auto', 'cm' or 'nm'
            How to interpret the given frequencies. If 'auto' it defaults to
            the plotters freq_unit.

        All other kwargs are forwarded to the plot function.

        Returns
        -------
         list of Line2D
            List containing the plotted lines.
        """
        if ax is None:
            ax = plt.gca()

        tmp = self.freq_unit if freq_unit is "auto" else freq_unit
        is_nm = tmp == "nm"
        if is_nm:
            ph.vis_mode()
        else:
            ph.ir_mode()
        ds = self.dataset
        x = ds.wavelengths if is_nm else ds.wavenumbers

        wl, t, d = ds.wl, ds.t, ds.data
        l, plotted_vals = [], []
        for i in wls:
            idx = dv.fi(x, i)

            dat = d[:, idx]
            if norm is True:
                dat = np.sign(dat[np.argmax(abs(dat))]) * dat / abs(dat).max()
            elif norm is False:
                pass
            else:
                dat = dat / dat[dv.fi(t, norm)]
            plotted_vals.append(dat)
            l.extend(
                ax.plot(t, dat, label="%.1f %s" % (x[idx], ph.freq_unit), **kwargs)
            )

        if symlog:
            ax.set_xscale("symlog", linthreshx=1.0)
        ph.lbl_trans(ax=ax, use_symlog=symlog)
        ax.legend(loc="best", ncol=3)
        ax.set_xlim(right=t.max())
        ax.yaxis.set_tick_params(which="minor", left=True)
        return l
ax[0].set_title('DAS')
plot_helpers.lbl_spec(ax[0])

sas = A_inv @ das.T
edas = np.cumsum(das, axis=1)
ax[1].plot(dsb.wn, sas.T)
ax[1].set_title('SAS')
plot_helpers.lbl_spec(ax[1])
# %%
# As we can see, we sucessfully get the SAS, which in this case are just EDAS.
# Let's also look at the concentrations.

fig, ax = plt.subplots(2, figsize=(3, 4))
ax[0].plot(dsb.t, fr.fitter.x_vec[:, :2])
ax[0].set_title('DAS')
plot_helpers.lbl_trans(ax[0], use_symlog=False)
ct = fr.fitter.x_vec[:, :2] @ A
ax[1].plot(dsb.t, ct)
ax[1].set_title('SAS')
plot_helpers.lbl_trans(ax[1], use_symlog=False)
# %%
# So why does it work?  The dataset is given by the outer product of the
# concentrations and the spectrum

C = fr.fitter.x_vec[:, :2]
S = das[:, :2]

fit = C @ S.T
fit - fr.fitter.model

# %%
Exemple #12
0
# All these function offer a number of options. More information can be found in
# their docstrings.
#
# Exponential fitting
# -------------------
# Fitting a decay-associated spectra (DAS) is a one-liner in skultrafast. If the
# dataset is dispersion corrected, only a starting guess is necessary. Please
# look at the docstring to see how the starting guess is structured.
# _Note_, the the fitting interface may change in the future.

fit_res = new_ds.fit_exp([-0.0, 0.05, 0.2, 2, 20, 10000],
                          model_coh=True, fix_sigma=False, fix_t0=False)
fit_res.lmfit_res.params

# %%
# Lets plot the DAS
new_ds.plot.das()

# %%
# We can always work with the results directly to make plots manually. Here,
# the `t_idx`, `wl_idx` and `wn_idx` methods of the dataset are very useful:
for wl in [500, 580, 620]:
    t0 = fit_res.lmfit_res.params['p0'].value
    idx = new_ds.wl_idx(wl)
    plt.plot(new_ds.t - t0, fit_res.fitter.data[:, idx], 'o', color='k', ms=4,
             alpha=0.4)
    plt.plot(new_ds.t - t0, fit_res.fitter.model[:, idx], lw=2, label='%d nm' % wl)
plt.xlim(-1, 10)
plot_helpers.lbl_trans(use_symlog=False)
plt.legend(loc='best', ncol=1)