def plot_ints(tup, wls, factors=None, symlog=True, norm=False, is_wavelength=True, ax=None, **kwargs): if ax is None: ax = plt.gca() wl, t, d = tup.wl, tup.t, tup.data lines = [] plotted_vals = [] for i in wls: dat = dv.spec_int(tup, i, is_wavelength) 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) idx1, idx2 = dv.fi(wl, i) label = 'From {0: .1f} - {1: .1f} {2}'.format(wl[idx1], wl[idx2], freq_unit) lines += ax.plot(t, dat, label=label, **kwargs) lbl_trans(ax) ax.set_xlim(-.5, ) if symlog: ax.set_xscale('symlog') ax.axvline(1, c='k', lw=0.5, zorder=1.9) symticks(ax) ax.axhline(0, color='k', lw=0.5, zorder=1.9) ax.legend(loc='best', ncol=1) return lines
def mean_spec(wl, t, p, t_range, ax=None, pos=(0.1, 0.1), markers = ['o', '^']): if ax is None: ax = plt.gca() if not isinstance(p, list): p = [p] if not isinstance(t_range, list): t_range = [t_range] l = [] for j, (x, y) in enumerate(t_range): for i, d in enumerate(p): t0, t1 = dv.fi(t, x), dv.fi(t, y) pd = np.mean(d[t0:t1, :], 0) lw = 2 if i == 0 else 1 l+= ax.plot(wl, pd, color='C%d'%j, marker=markers[i], lw=lw, mec='none', ms=3) ax.text(pos[0], pos[1]+j*0.07,'%.1f - %.1f ps'%(t[t0], t[t1]), color='C%d'%j, transform=ax.transAxes) lbl_spec(ax) if len(t_range) == 1: print(len(p)) ax.set_title('mean signal from {0:.1f} to {1:.1f} ps'.format(t[t0], t[t1])) return l
def make_angle_plot2(wl, t, para, senk, t_range): p = para s = senk t0, t1 = dv.fi(t, t_range[0]), dv.fi(t, t_range[1]) pd = p[t0:t1, :].mean(0) sd = s[t0:t1, :].mean(0) ax = plt.subplot(111) ax.plot(wl, pd) ax.plot(wl, sd) ax.plot([], [], 's-', color='k') ax.axhline(0, c='k', zorder=1.9) ax.invert_xaxis() #ax.xaxis.tick_top() ax.set_ylabel(sig_label) ax.xaxis.set_label_position('top') ax.text(0.05, 0.05, 'Signal average\nfor %.1f...%.1f ps'%t_range, transform=ax.transAxes) ax.legend(['parallel', 'perpendicular', 'angle'], columnspacing=0.3, ncol=3, frameon=0) #horizontalalignment='center') ax2 = plt.twinx(ax) d = pd/sd ang = np.arccos(np.sqrt((2*d-1)/(d+2)))/np.pi*180 ax2.plot(wl, ang, 's-', color='k') for i in np.arange(10, 90, 10): ax2.axhline(i, c='gray', linestyle='-.', zorder=1.8, lw=.5, alpha=0.5) ax2.set_ylim(0, 90) ax2.set_ylabel('angle / degrees')
def mean_spec(wl, t, p, t_range, ax=None, pos=(0.1, 0.1), markers=['o', '^']): if ax is None: ax = plt.gca() if not isinstance(p, list): p = [p] if not isinstance(t_range, list): t_range = [t_range] l = [] for j, (x, y) in enumerate(t_range): for i, d in enumerate(p): t0, t1 = dv.fi(t, x), dv.fi(t, y) pd = np.mean(d[t0:t1, :], 0) lw = 2 if i == 0 else 1 l += ax.plot(wl, pd, color='C%d' % j, marker=markers[i], lw=lw, mec='none', ms=3) ax.text(pos[0], pos[1] + j * 0.07, '%.1f - %.1f ps' % (t[t0], t[t1]), color='C%d' % j, transform=ax.transAxes) lbl_spec(ax) if len(t_range) == 1: print(len(p)) ax.set_title('mean signal from {0:.1f} to {1:.1f} ps'.format( t[t0], t[t1])) return l
def fit_semiconductor(t, data, sav_n=11, sav_deg=4, mode='sav', tr=0.4): from scipy.signal import savgol_filter from scipy.ndimage import gaussian_filter1d from scipy.optimize import leastsq ger = data[..., -1].sum(2).squeeze() plt.subplot(121) plt.title('Germanium sum') plt.plot(t, ger[:, 0]) plt.plot(t, ger[:, 1]) if mode =='sav': plt.plot(t, savgol_filter(ger[:, 0], sav_n, sav_deg, 0)) plt.plot(t, savgol_filter(ger[:, 1], sav_n, sav_deg, 0)) plt.xlim(-1, 3) plt.subplot(122) plt.title('First dervitate') if mode == 'sav': derv0 = savgol_filter(ger[:, 0], sav_n, sav_deg, 1) derv1 = savgol_filter(ger[:, 1], sav_n, sav_deg, 1) elif mode == 'gauss': derv0 = gaussian_filter1d(ger[:, 0], sav_n, order=1) derv1 = gaussian_filter1d(ger[:, 1], sav_n, order=1) plt.plot(t , derv0) plt.plot(t , derv1) plt.xlim(-.8, .8) plt.ylim(0, 700) plt.minorticks_on() plt.grid(1) def gaussian(p, ch, res=True): i, j = dv.fi(t, -tr), dv.fi(t, tr) w = p[0] A = p[1] x0 = p[2] fit = A*np.exp(-(t[i:j]-x0)**2/(2*w**2)) if res: return fit-ch[i:j] else: return fit x0 = leastsq(gaussian, [.2, max(derv0), 0], derv0) plt.plot(t[dv.fi(t, -tr):dv.fi(t, tr)], gaussian(x0[0], 0, 0), '--k', ) plt.text(0.05, 0.9, 'x$_0$ = %.2f\nFWHM = %.2f\nA = %.1f\n'%(x0[0][2],2.35*x0[0][0], x0[0][1]), transform=plt.gca().transAxes, va='top') x0 = leastsq(gaussian, [.2, max(derv1), 0], derv1) plt.plot(t[dv.fi(t, -tr):dv.fi(t, tr)], gaussian(x0[0], 1, 0), '--b', ) plt.xlim(-.8, .8) plt.minorticks_on() plt.grid(0) plt.tight_layout() plt.text(0.5, 0.9, 'x$_0$ = %.2f\nFWHM = %.2f\nA = %.1f\n'%(x0[0][2],2.35*x0[0][0], x0[0][1]), transform=plt.gca().transAxes, va='top')
def gaussian(p, ch, res=True): i, j = dv.fi(t, -tr), dv.fi(t, tr) w = p[0] A = p[1] x0 = p[2] fit = A * np.exp(-(t[i:j] - x0)**2 / (2 * w**2)) if res: return fit - ch[i:j] else: return fit
def gaussian(p, ch, res=True): i, j = dv.fi(t, -tr), dv.fi(t, tr) w = p[0] A = p[1] x0 = p[2] fit = A*np.exp(-(t[i:j]-x0)**2/(2*w**2)) if res: return fit-ch[i:j] else: return fit
def make_angle_plot(wl, t, para, senk, t_range): p = para s = senk t0, t1 = dv.fi(t, t_range[0]), dv.fi(t, t_range[1]) pd = p[t0:t1, :].mean(0) sd = s[t0:t1, :].mean(0) ax = plt.subplot(211) ax.plot(wl, pd) ax.plot(wl, sd) ax.axhline(0, c='k') ax.legend(['Parallel', 'Perpendicular'], columnspacing=0.3, ncol=2, frameon=0) ax.xaxis.tick_top() ax.set_ylabel(sig_label) ax.xaxis.set_label_position('top') ax.text(0.05, 0.1, 'Signal average\nfor %.1f...%.0f ps' % t_range, transform=ax.transAxes) #horizontalalignment='center') ax2 = plt.subplot(212, sharex=ax) d = pd / sd ang = np.arccos(np.sqrt((2 * d - 1) / (d + 2))) / np.pi * 180 ax2.plot(wl, ang, 'o-') ax2.set_ylim(0, 90) ax2.set_ylabel('Angle / Degrees') ax3 = plt.twinx() ax3.plot(wl, ang, lw=0) ax2.invert_xaxis() f = lambda x: "%.1f" % (to_dichro(float(x) / 180. * np.pi)) ax2.set_ylim(0, 90) def to_angle(d): return np.arccos(np.sqrt((2 * d - 1) / (d + 2))) / np.pi * 180 def to_dichro(x): return (1 + 2 * np.cos(x)**2) / (2 - np.cos(x)**2) n_ticks = ax2.yaxis.get_ticklocs() ratio_ticks = np.array([0.5, 0.7, 1., 1.5, 2., 2.5, 3.]) ax3.yaxis.set_ticks(to_angle(ratio_ticks)) ax3.yaxis.set_ticklabels([i for i in ratio_ticks]) ax3.set_ylabel('$A_\\parallel / A_\\perp$') ax2.set_title('Angle calculated from dichroic ratio', fontsize='x-small') plt.tight_layout(rect=[0, 0, 1, 1], h_pad=0) return ax, ax2, ax3
def plot_trans(tup, wls, symlog=True, norm=False, marker=None, ax=None, **kwargs): if ax is None: ax = plt.gca() wl, t, d = tup.wl, tup.t, tup.data ulim = -np.inf llim = np.inf plotted_vals = [] l = [] for i in wls: idx = dv.fi(wl, 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' % (wl[idx], freq_unit), marker=marker, **kwargs)) ulim = np.percentile(plotted_vals, 99.) + 0.5 llim = np.percentile(plotted_vals, 1.) - 0.5 ax.set_xlabel(time_label) ax.set_ylabel(sig_label) #plt.ylim(llim, ulim) if symlog: ax.set_xscale('symlog', linthreshx=1) ax.axvline(1, c='k', lw=0.5, zorder=1.9) symticks(ax) ax.axhline(0, color='k', lw=0.5, zorder=1.9) ax.set_xlim(-.5, ) ax.legend(loc='best', ncol=2, title='Wavelength') return l
def make_angle_plot(wl, t, para, senk, t_range): p = para s = senk t0, t1 = dv.fi(t, t_range[0]), dv.fi(t, t_range[1]) pd = p[t0:t1, :].mean(0) sd = s[t0:t1, :].mean(0) ax = plt.subplot(211) ax.plot(wl, pd) ax.plot(wl, sd) ax.axhline(0, c='k') ax.legend(['Parallel', 'Perpendicular'], columnspacing=0.3, ncol=2, frameon=0) ax.xaxis.tick_top() ax.set_ylabel(sig_label) ax.xaxis.set_label_position('top') ax.text(0.05, 0.1, 'Signal average\nfor %.1f...%.0f ps'%t_range, transform=ax.transAxes) #horizontalalignment='center') ax2 = plt.subplot(212, sharex=ax) d = pd/sd ang = np.arccos(np.sqrt((2*d-1)/(d+2)))/np.pi*180 ax2.plot(wl, ang, 'o-') ax2.set_ylim(0, 90) ax2.set_ylabel('Angle / Degrees') ax3 = plt.twinx() ax3.plot(wl, ang, lw=0) ax2.invert_xaxis() f = lambda x: "%.1f"%(to_dichro(float(x)/180.*np.pi)) ax2.set_ylim(0, 90) def to_angle(d): return np.arccos(np.sqrt((2*d-1)/(d+2)))/np.pi*180 def to_dichro(x): return (1+2*np.cos(x)**2)/(2-np.cos(x)**2) n_ticks = ax2.yaxis.get_ticklocs() ratio_ticks = np.array([0.5, 0.7, 1., 1.5, 2., 2.5, 3.]) ax3.yaxis.set_ticks(to_angle(ratio_ticks)) ax3.yaxis.set_ticklabels([i for i in ratio_ticks]) ax3.set_ylabel('$A_\\parallel / A_\\perp$') ax2.set_title('Angle calculated from dichroic ratio', fontsize='x-small') plt.tight_layout(rect=[0, 0, 1, 1], h_pad=0) return ax, ax2, ax3
def nice_lft_map(tup, taus, coefs, show_sums=False, **kwargs): cmap = kwargs.pop('cmap', 'seismic') plt.figure(1, figsize=(6, 4)) ax = plt.subplot(111) #norm = SymLogNorm(linthresh=0.3) norm = kwargs.pop('norm', MidPointNorm(0)) m = np.abs(coefs[:, :]).max() c = ax.pcolormesh(tup.wl, taus[:], coefs[:, :], cmap=cmap, vmin=-m, vmax=m, norm=norm, **kwargs) cb = plt.colorbar(c, pad=0.01) cb.set_label('Amplitude') ax.set_yscale('log') plt.autoscale(1, 'both', 'tight') #ax.set_ylim(None, 60) plt.minorticks_on() ax.set_xlabel(freq_label) ax.set_ylabel('Decay constant [ps]') if inv_freq: ax.invert_xaxis() divider = make_axes_locatable(ax) if show_sums: axt = divider.append_axes("left", size=.5, sharey=ax, pad=0.05) pos = np.where(coefs > 0, coefs, 0).sum(1) neg = np.where(coefs < 0, coefs, 0).sum(1) axt.plot(pos[:len(taus)], taus, 'r', label='pos.') axt.plot(-neg[:len(taus)], taus, 'b', label='neg.') axt.plot(abs(coefs).sum(1)[:len(taus)], taus, 'k', label='abs.') axt.legend(frameon=False, loc='best') axt.invert_xaxis() #axt.plot(out[0].T[:, wi(1513):].sum(1), taus) #axt.plot(3*out[0].T[:, :wi(1513)].sum(1), taus) #plt.autoscale(1, 'y', 'tight') axt.set_ylabel('Decay constant [ps]') axt.xaxis.set_minor_locator(plt.NullLocator()) axt.xaxis.set_major_locator(plt.MaxNLocator(3)) ax.tick_params(labelleft=0) else: ax.set_ylabel('Decay constant [ps]') if 0: axt = divider.append_axes("top", size=1, sharex=ax, pad=0.1) axt.plot(tup.wl, out[0].T[:dv.fi(taus, 0.2), :].sum(0)) axt.plot(tup.wl, out[0].T[dv.fi(taus, 0.3):dv.fi(taus, 1), :].sum(0)) axt.plot(tup.wl, out[0].T[dv.fi(taus, 1):dv.fi(taus, 5), :].sum(0)) axt.plot(tup.wl, out[0].T[dv.fi(taus, 5):dv.fi(taus, 10), :].sum(0)) axt.xaxis.tick_top() axt.axhline(0, c='k', zorder=1.9) plt.autoscale(1, 'both', 'tight')
def spec(self, t_list, norm=False, ax=None, n_average=0, **kwargs): """ Plot spectra at given times. Parameters ---------- t_list : list or ndarray List of the times where the spectra are plotted. norm : bool If true, each spectral will be normalized. ax : plt.Axis or None. Axis where the spectra are plotted. If none, the current axis will be used. n_average : int For noisy data it may be preferred to average multiple spectra together. This function plots the average of `n_average` spectra around the specific time-points. Returns ------- list of `Lines2D` List containing the Line2D objects belonging to the spectra. """ if ax is None: ax = plt.gca() is_nm = self.freq_unit == 'nm' if is_nm: ph.vis_mode() else: ph.ir_mode() ds = self.dataset x = ds.wavelengths if is_nm else ds.wavenumbers li = [] for i in t_list: idx = dv.fi(ds.t, i) if n_average > 0: dat = uniform_filter(ds, (2 * n_average + 1, 1)).data[idx, :] elif n_average == 0: dat = ds.data[idx, :] else: raise ValueError('n_average must be an Integer >= 0.') if norm: dat = dat / abs(dat).max() li += ax.plot(x, dat, label=ph.time_formatter(ds.t[idx], ph.time_unit), **kwargs) self.lbl_spec(ax) if not is_nm: ax.set_xlim(x.max(), x.min()) return li
def spec(self, t_list, norm=False, ax=None, n_average=0, **kwargs): """ Plot spectra at given times. Parameters ---------- t_list : list or ndarray List of the times where the spectra are plotted. norm : bool If true, each spectral will be normalized. ax : plt.Axis or None. Axis where the spectra are plotted. If none, the current axis will be used. n_average : int For noisy data it may be preferred to average multiple spectra together. This function plots the average of `n_average` spectra around the specific time-points. Returns ------- list of `Lines2D` List containing the Line2D objects belonging to the spectra. """ if ax is None: ax = plt.gca() is_nm = self.freq_unit == "nm" if is_nm: ph.vis_mode() else: ph.ir_mode() ds = self.dataset x = ds.wavelengths if is_nm else ds.wavenumbers li = [] for i in t_list: idx = dv.fi(ds.t, i) if n_average > 0: dat = uniform_filter(ds, (2 * n_average + 1, 1)).data[idx, :] elif n_average == 0: dat = ds.data[idx, :] else: raise ValueError("n_average must be an Integer >= 0.") if norm: dat = dat / abs(dat).max() li += ax.plot( x, dat, label=ph.time_formatter(ds.t[idx], ph.time_unit), **kwargs ) self.lbl_spec(ax) if not is_nm: ax.set_xlim(x.max(), x.min()) return li
def nice_lft_map(tup, taus, coefs, show_sums=False, **kwargs): cmap = kwargs.pop('cmap', 'seismic') plt.figure(1, figsize=(6, 4)) ax = plt.subplot(111) #norm = SymLogNorm(linthresh=0.3) norm = kwargs.pop('norm', MidPointNorm(0)) m = np.abs(coefs[:, :]).max() c = ax.pcolormesh(tup.wl, taus[:], coefs[:, :], cmap=cmap, vmin=-m, vmax=m, norm=norm, **kwargs) cb = plt.colorbar(c, pad=0.01) cb.set_label('Amplitude') ax.set_yscale('log') plt.autoscale(1, 'both', 'tight') #ax.set_ylim(None, 60) plt.minorticks_on() ax.set_xlabel(freq_label) ax.set_ylabel('Decay constant [ps]') if inv_freq: ax.invert_xaxis() divider = make_axes_locatable(ax) if show_sums: axt = divider.append_axes("left", size=.5, sharey=ax, pad=0.05) pos = np.where(coefs>0, coefs, 0).sum(1) neg = np.where(coefs<0, coefs, 0).sum(1) axt.plot(pos[:len(taus)], taus, 'r', label='pos.') axt.plot(-neg[:len(taus)], taus, 'b', label='neg.') axt.plot(abs(coefs).sum(1)[:len(taus)], taus, 'k', label='abs.') axt.legend(frameon=False, loc='best') axt.invert_xaxis() #axt.plot(out[0].T[:, wi(1513):].sum(1), taus) #axt.plot(3*out[0].T[:, :wi(1513)].sum(1), taus) #plt.autoscale(1, 'y', 'tight') axt.set_ylabel('Decay constant [ps]') axt.xaxis.set_minor_locator(plt.NullLocator()) axt.xaxis.set_major_locator(plt.MaxNLocator(3)) ax.tick_params(labelleft=0) else: ax.set_ylabel('Decay constant [ps]') if 0: axt = divider.append_axes("top", size=1, sharex=ax, pad=0.1) axt.plot(tup.wl, out[0].T[:dv.fi(taus, 0.2), :].sum(0)) axt.plot(tup.wl, out[0].T[dv.fi(taus, 0.3):dv.fi(taus, 1), :].sum(0)) axt.plot(tup.wl, out[0].T[dv.fi(taus, 1):dv.fi(taus, 5), :].sum(0)) axt.plot(tup.wl, out[0].T[dv.fi(taus, 5):dv.fi(taus, 10), :].sum(0)) axt.xaxis.tick_top() axt.axhline(0, c='k', zorder=1.9) plt.autoscale(1, 'both', 'tight')
def plot_trans(tup, wls, symlog=True, norm=False, marker=None, ax=None, **kwargs): if ax is None: ax = plt.gca() wl, t, d = tup.wl, tup.t, tup.data ulim = -np.inf llim = np.inf plotted_vals = [] l = [] for i in wls: idx = dv.fi(wl, 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'%(wl[idx], freq_unit), marker=marker, **kwargs)) ulim = np.percentile(plotted_vals, 99.) + 0.5 llim = np.percentile(plotted_vals, 1.) - 0.5 ax.set_xlabel(time_label) ax.set_ylabel(sig_label) #plt.ylim(llim, ulim) if symlog: ax.set_xscale('symlog', linthreshx=1) ax.axvline(1, c='k', lw=0.5, zorder=1.9) symticks(ax) ax.axhline(0, color='k', lw=0.5, zorder=1.9) ax.set_xlim(-.5,) ax.legend(loc='best', ncol=2, title='Wavelength') return l
def make_angle_plot2(wl, t, para, senk, t_range): p = para s = senk t0, t1 = dv.fi(t, t_range[0]), dv.fi(t, t_range[1]) pd = p[t0:t1, :].mean(0) sd = s[t0:t1, :].mean(0) ax = plt.subplot(111) ax.plot(wl, pd) ax.plot(wl, sd) ax.plot([], [], 's-', color='k') ax.axhline(0, c='k', zorder=1.9) ax.invert_xaxis() #ax.xaxis.tick_top() ax.set_ylabel(sig_label) ax.xaxis.set_label_position('top') ax.text(0.05, 0.05, 'Signal average\nfor %.1f...%.1f ps' % t_range, transform=ax.transAxes) ax.legend(['parallel', 'perpendicular', 'angle'], columnspacing=0.3, ncol=3, frameon=0) #horizontalalignment='center') ax2 = plt.twinx(ax) d = pd / sd ang = np.arccos(np.sqrt((2 * d - 1) / (d + 2))) / np.pi * 180 ax2.plot(wl, ang, 's-', color='k') for i in np.arange(10, 90, 10): ax2.axhline(i, c='gray', linestyle='-.', zorder=1.8, lw=.5, alpha=0.5) ax2.set_ylim(0, 90) ax2.set_ylabel('angle / degrees')
def plot_spec(tup, t_list, ax=None, norm=False, **kwargs): if ax is None: ax = plt.gca() wl, t, d = tup.wl, tup.t, tup.data li = [] for i in t_list: idx = dv.fi(t, i) dat = d[idx, :] if norm: dat = dat / abs(dat).max() li += ax.plot(wl, dat, label=time_formatter(t[idx], time_unit), **kwargs) #ulim = np.percentile(plotted_vals, 98.) + 0.1 #llim = np.percentile(plotted_vals, 2.) - 0.1 ax.set_xlabel(freq_label) ax.set_ylabel(sig_label) ax.autoscale(1, 'x', 1) ax.axhline(0, color='k', lw=0.5, zorder=1.9) ax.legend(loc='best', ncol=2, title='Delay time') return li
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
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
def plot_spec(tup, t_list, ax=None, norm=False, **kwargs): if ax is None: ax = plt.gca() wl, t, d = tup.wl, tup.t, tup.data li = [] for i in t_list: idx = dv.fi(t, i) dat = d[idx, :] if norm: dat = dat/abs(dat).max() li+= ax.plot(wl, dat, label=time_formatter(t[idx], time_unit), **kwargs) #ulim = np.percentile(plotted_vals, 98.) + 0.1 #llim = np.percentile(plotted_vals, 2.) - 0.1 ax.set_xlabel(freq_label) ax.set_ylabel(sig_label) ax.autoscale(1, 'x', 1) ax.axhline(0, color='k', lw=0.5, zorder=1.9) ax.legend(loc='best', ncol=2, title='Delay time') return li
def plot_svd_components(tup, n=4, from_t=None): wl, t, d = tup.wl, tup.t, tup.data if from_t: idx = dv.fi(t, from_t) t = t[idx:] d = d[idx:, :] u, s, v = np.linalg.svd(d) ax1: plt.Axes = plt.subplot(311) ax1.set_xlim(-1, t.max()) lbl_trans() plt.minorticks_off() ax1.set_xscale('symlog') ax2 = plt.subplot(312) lbl_spec() plt.ylabel('') for i in range(n): ax1.plot(t, u.T[i], label=str(i)) ax2.plot(wl, v[i]) ax1.legend() plt.subplot(313) plot_singular_values(d) plt.tight_layout()
def plot_svd_components(tup, n=4, from_t = None): wl, t, d = tup.wl, tup.t, tup.data if from_t: idx = dv.fi(t, from_t) t = t[idx:] d = d[idx:, :] u, s, v = np.linalg.svd(d) ax1: plt.Axes = plt.subplot(311) ax1.set_xlim(-1, t.max()) lbl_trans() plt.minorticks_off() ax1.set_xscale('symlog') ax2 = plt.subplot(312) lbl_spec() plt.ylabel('') for i in range(n): ax1.plot(t,u.T[i], label=str(i) ) ax2.plot(wl,v[i] ) ax1.legend() plt.subplot(313) plot_singular_values(d) plt.tight_layout()
def data_preparation(wl, t, d, wiener=3, trunc_back=0.05, trunc_scans=0, start_det0_is_para=True, do_scan_correction=True, do_iso_correction=True, plot=1, n=10): d = d.copy() #d[..., 0, :]= shift_linear_part(d[..., 0, :]) #d[..., 1, :] = shift_linear_part(d[..., 1, :], 1, t) if wiener == 'svd': for i in range(d.shape[-1]): d[:, :, 0, i] = dv.svd_filter(d[:, :, 0, i], 3) d[:, :, 1, i] = dv.svd_filter(d[:, :, 1, i], 3) elif wiener > 1: d = sig.wiener(d, (wiener, 3, 1, 1)) elif wiener < 0: d = nd.uniform_filter1d(d, -wiener, 0, mode='nearest') #d, back0 = back_correction(d, use_robust=1) #back1 = back0 if do_scan_correction: d = scan_correction(d, dv.fi(t, 0.5)) import astropy.stats as stats def fi(x, ax=0): return stats.sigma_clip(x, sigma=trunc_back, iters=3, axis=ax).mean(ax) back0 = fi(d[:n, ..., 0, :], ax=0) back1 = fi(d[:n, ..., 1, :], ax=0) back = 0.5 * (back0 + back1).mean(-1) d[..., 0, :] -= back.reshape(1, 32, -1) d[..., 1, :] -= back.reshape(1, 32, -1) if do_scan_correction: d = scan_correction(d, dv.fi(t, 0)) # gr -> vert -> parallel zum 0. scan #fi = lambda x, ax=-1: np.median(x, ax) fi = lambda x, ax=- \ 1: stats.sigma_clip(x, sigma=trunc_scans, iters=2, axis=ax).mean(ax) if start_det0_is_para: para_0 = fi(d[..., 0, ::2]) senk_0 = fi(d[..., 0, 1::2]) para_1 = fi(d[..., 1, 1::2]) senk_1 = fi(d[..., 1, 0::2]) else: para_0 = fi(d[..., 0, 1::2]) senk_0 = fi(d[..., 0, 0::2]) para_1 = fi(d[..., 1, 0::2]) senk_1 = fi(d[..., 1, 1::2]) iso_0 = (para_0 + 2 * senk_0) / 3. iso_1 = (para_1 + 2 * senk_1) / 3. if do_iso_correction: iso_factor = calc_fac(iso_0, iso_1, dv.fi(t, 1)) else: iso_factor = 1 senk = 0.5 * senk_0 + 0.5 * (iso_factor * senk_1) senk -= senk[:10, :].mean(0) para = 0.5 * para_0 + 0.5 * (iso_factor * para_1) para -= para[:10, :].mean(0) iso = (2 * senk + para) / 3 if plot: import matplotlib.pyplot as plt from skultrafast.plot_helpers import lbl_spec, mean_spec plt.figure(figsize=(12, 4)) plt.subplot(121) plt.plot(wl, iso[:10, :].mean(0)) plt.plot(wl, back0) plt.plot(wl, back1) lbl_spec() plt.legend(['iso_rest', 'back0', 'back1']) plt.subplot(122) mean_spec(wl, t, [iso_0, iso_factor * iso_1], (1, 100)) mean_spec(wl, t, [para, senk], (1, 100), color='r') plt.legend(['iso_0', 'iso_1 * %.2f' % iso_factor]) return iso, para, senk
def shift_linear_part(p, steps, t): "Shift the linear part of the array by steps" lp = dv.fi(t, -1), dv.fi(t, 3) p = p.copy() p[lp[0] + steps:lp[1], ...] = p[lp[0]:lp[1] - steps, ...] return p
def fit_semiconductor(t, data, sav_n=11, sav_deg=4, mode='sav', tr=0.4): from scipy.signal import savgol_filter from scipy.ndimage import gaussian_filter1d from scipy.optimize import leastsq ger = data[..., -1].sum(2).squeeze() plt.subplot(121) plt.title('Germanium sum') plt.plot(t, ger[:, 0]) plt.plot(t, ger[:, 1]) if mode == 'sav': plt.plot(t, savgol_filter(ger[:, 0], sav_n, sav_deg, 0)) plt.plot(t, savgol_filter(ger[:, 1], sav_n, sav_deg, 0)) plt.xlim(-1, 3) plt.subplot(122) plt.title('First dervitate') if mode == 'sav': derv0 = savgol_filter(ger[:, 0], sav_n, sav_deg, 1) derv1 = savgol_filter(ger[:, 1], sav_n, sav_deg, 1) elif mode == 'gauss': derv0 = gaussian_filter1d(ger[:, 0], sav_n, order=1) derv1 = gaussian_filter1d(ger[:, 1], sav_n, order=1) plt.plot(t, derv0) plt.plot(t, derv1) plt.xlim(-.8, .8) plt.ylim(0, 700) plt.minorticks_on() plt.grid(1) def gaussian(p, ch, res=True): i, j = dv.fi(t, -tr), dv.fi(t, tr) w = p[0] A = p[1] x0 = p[2] fit = A * np.exp(-(t[i:j] - x0)**2 / (2 * w**2)) if res: return fit - ch[i:j] else: return fit x0 = leastsq(gaussian, [.2, max(derv0), 0], derv0) plt.plot( t[dv.fi(t, -tr):dv.fi(t, tr)], gaussian(x0[0], 0, 0), '--k', ) plt.text(0.05, 0.9, 'x$_0$ = %.2f\nFWHM = %.2f\nA = %.1f\n' % (x0[0][2], 2.35 * x0[0][0], x0[0][1]), transform=plt.gca().transAxes, va='top') x0 = leastsq(gaussian, [.2, max(derv1), 0], derv1) plt.plot( t[dv.fi(t, -tr):dv.fi(t, tr)], gaussian(x0[0], 1, 0), '--b', ) plt.xlim(-.8, .8) plt.minorticks_on() plt.grid(0) plt.tight_layout() plt.text(0.5, 0.9, 'x$_0$ = %.2f\nFWHM = %.2f\nA = %.1f\n' % (x0[0][2], 2.35 * x0[0][0], x0[0][1]), transform=plt.gca().transAxes, va='top')
def mean_tup(tup, time): wl, t, d = tup.wl, tup.t, tup.data new_dat = tup.data / tup.data[dv.fi(t, time), :] return dv.tup(wl, t, new_dat)
def shift_linear_part(p, steps, t): "Shift the linear part of the array by steps" lp = dv.fi(t, -1), dv.fi(t, 3) p = p.copy() p[lp[0]+steps:lp[1], ...] = p[lp[0]:lp[1]-steps, ...] return p
def plot_diff(tup, t0, t_list, **kwargs): diff = tup.data - tup.data[dv.fi(tup.t, t0), :] plot_spec(dv.tup(tup.wl, tup.t, diff), t_list, **kwargs)
def data_preparation(wl, t, d, wiener=3, trunc_back=0.05, trunc_scans=0, start_det0_is_para=True, do_scan_correction=True, do_iso_correction=True, plot=1, n=10): d = d.copy() #d[..., 0, :]= shift_linear_part(d[..., 0, :]) #d[..., 1, :] = shift_linear_part(d[..., 1, :], 1, t) if wiener == 'svd': for i in range(d.shape[-1]): d[:, :, 0, i] = dv.svd_filter(d[:, :, 0, i], 3) d[:, :, 1, i] = dv.svd_filter(d[:, :, 1, i], 3) elif wiener > 1: d = sig.wiener(d, (wiener, 3, 1, 1)) elif wiener < 0: d = nd.uniform_filter1d(d, -wiener, 0, mode='nearest') #d, back0 = back_correction(d, use_robust=1) #back1 = back0 if do_scan_correction: d = scan_correction(d, dv.fi(t, 0.5)) import astropy.stats as stats def fi(x, ax=0): return stats.sigma_clip( x, sigma=trunc_back, iters=3, axis=ax).mean(ax) back0 = fi(d[:n, ..., 0, :], ax=0) back1 = fi(d[:n, ..., 1, :], ax=0) back = 0.5*(back0+back1).mean(-1) d[..., 0, :] -= back.reshape(1, 32, -1) d[..., 1, :] -= back.reshape(1, 32, -1) if do_scan_correction: d = scan_correction(d, dv.fi(t, 0)) # gr -> vert -> parallel zum 0. scan #fi = lambda x, ax=-1: np.median(x, ax) fi = lambda x, ax=- \ 1: stats.sigma_clip(x, sigma=trunc_scans, iters=2, axis=ax).mean(ax) if start_det0_is_para: para_0 = fi(d[..., 0, ::2]) senk_0 = fi(d[..., 0, 1::2]) para_1 = fi(d[..., 1, 1::2]) senk_1 = fi(d[..., 1, 0::2]) else: para_0 = fi(d[..., 0, 1::2]) senk_0 = fi(d[..., 0, 0::2]) para_1 = fi(d[..., 1, 0::2]) senk_1 = fi(d[..., 1, 1::2]) iso_0 = (para_0 + 2*senk_0) / 3. iso_1 = (para_1 + 2*senk_1) / 3. if do_iso_correction: iso_factor = calc_fac(iso_0, iso_1, dv.fi(t, 1)) else: iso_factor = 1 senk = 0.5*senk_0 + 0.5 * (iso_factor*senk_1) senk -= senk[:10, :].mean(0) para = 0.5*para_0 + 0.5 * (iso_factor*para_1) para -= para[:10, :].mean(0) iso = (2*senk + para)/3 if plot: import matplotlib.pyplot as plt from skultrafast.plot_helpers import lbl_spec, mean_spec plt.figure(figsize=(12, 4)) plt.subplot(121) plt.plot(wl, iso[:10, :].mean(0)) plt.plot(wl, back0) plt.plot(wl, back1) lbl_spec() plt.legend(['iso_rest', 'back0', 'back1']) plt.subplot(122) mean_spec(wl, t, [iso_0, iso_factor*iso_1], (1, 100)) mean_spec(wl, t, [para, senk], (1, 100), color='r') plt.legend(['iso_0', 'iso_1 * %.2f' % iso_factor]) return iso, para, senk
def t_idx(self, t: Union[float, Iterable[float]]) -> int: """Return nearest idx to nearest time value""" return dv.fi(self.t, t)
def pump_idx(self, wn: Union[float, Iterable[float]]) -> int: """Return nearest idx to nearest pump_wn value""" return dv.fi(self.pump_wn, wn)
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
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