def plot_IV(self, volt, curr, times=None): if times is None: times = [15000, 17500, 20000, 25000, 30000] # IV response tbx.prefig(xlabel='Peak pulse voltage [V]', ylabel='Current [$\mu$A]') for tt in times: plt.plot(volt, curr[tt, :], label='{0:.2f} ms'.format(self.mstime(tt, start=5))) plt.legend(fontsize=20) plt.title( 'Average IV response, NO conditional averaging, {0} shots'.format( self.obj.nshots), fontsize=20) tbx.savefig('./img/{0}-average-IV-response.png'.format(self.obj.fid)) # IV derivative tbx.prefig(xlabel='Peak pulse voltage [V]', ylabel='-dI/dV') for tt in times: deriv = IVderiv(curr[tt, :], nwindow=51) plt.plot(volt, deriv, label='{0:.2f} ms'.format(self.mstime(tt, start=5))) plt.legend(fontsize=20) plt.title( 'Average IV-deriv, NO conditional averaging, {0} shots'.format( self.obj.nshots), fontsize=20) tbx.savefig('./img/{0}-average-IV-deriv.png'.format(self.obj.fid))
def browse_data(data, x=None, y=None, step=0, shot=0, chan=0, trange=None): # Browses the data and returns the selected trange # Set default trange if trange is None: trange = [0, -1] t1 = trange[0] t2 = np.min([data.shape[0], trange[1]]) tbx.prefig(xlabel='time [px]', ylabel='magnitude') if (x is None) and (y is None): temp = data[:, step, shot, chan] plt.title("step = {0}, shot = {1}, chan = {2}, trange = [{3}," " {4}]".format(step, shot, chan, trange[0], trange[1]), fontsize=20) else: temp = data[:, x, y, step, shot, chan] plt.title('(x, y) = ({0:.2f}, {1:.2f}), step = {2}, shot = {3}, ' ' chan = {4}, trange = [{5}, {6}]'.format( x, y, step, shot, chan, trange[0], trange[1]), fontsize=20) plt.plot(temp) plt.plot([t1, t1], [np.min(temp), np.max(temp)], 'orange') plt.plot([t2, t2], [np.min(temp), np.max(temp)], 'orange') return t1, t2
def plot_bint_shift(self, bint, curr=None, step=0, shot=0, ref=None): if ref is None: ref = [0, 0] # Plots the reference bint/current with a test shot bref = bint[self.obj.bt1:self.obj.bt2, ref[0], ref[1]] bdata = bint[self.obj.bt1:self.obj.bt2, step, shot] xlag = fmp.lagtime(bref, bdata)['xlag'] if xlag is not None: tbx.prefig() plt.title('integrated B signals', fontsize=25) plt.plot(bref, label='reference') plt.plot(bdata, label='original') plt.plot(np.roll(bdata, -xlag), label='shift') plt.legend(fontsize=20) if curr is not None: curr0 = self.obj.curr[self.obj.bt1:self.obj.bt2, ref[0], ref[1]] curr1 = self.obj.curr[self.obj.bt1:self.obj.bt2, step, shot] tbx.prefig() plt.title('current signals', fontsize=25) plt.plot(curr0, label='reference') plt.plot(np.roll(curr1, -xlag), label='shift') plt.legend(fontsize=20) else: print("** curr = None, current not plotted")
def plot_TiVp(self, Ti, Vp, ca=0, limTi=20): tt = np.array([self.mstime(tt) for tt in self.obj.tarr]) temp = np.where(Ti < limTi) text = 'conditional average, exponential fit' if ca == 1: text = 'YES ' + text svname = 'yes-condavg' else: text = 'NO ' + text svname = 'no-condavg' tbx.prefig(xlabel='time [ms]', ylabel='$T_i$ [eV]') plt.title('{0} $T_i$ vs time, {1} (all times)'.format( self.obj.fid, text), fontsize=25) plt.plot(tt[temp], tbx.smooth(Ti, nwindow=51)[temp]) tbx.savefig('./img/{0}-{1}-Ti-vs-time.png'.format( self.obj.fid, svname)) tbx.prefig(xlabel='time [ms]', ylabel='$V_p$ [V]') plt.title('{0} $V_p$ vs time, {1} (all times)'.format( self.obj.fid, text), fontsize=25) plt.plot(tt, Vp) tbx.savefig('./img/{0}-{1}-Vp-vs-time.png'.format( self.obj.fid, svname))
def plot_enint(self, limTi=100): tbx.prefig(xlabel='time [ms]', ylabel='average $E$ [eV]') plt.title('{0} average energy (combined distribution ' 'function)'.format(self.fid), fontsize=20) test = np.where(self.arrTi < limTi) plt.plot(self.arrTT[test], self.arrTi[test]) tbx.savefig('./img/{0}-Ti-distfunc.png'.format(self.fid))
def hist8pi(wavelength, hist_arr, date='2021-05-xx', port='41B'): # Expecting wavelength in units of angstrom tbx.prefig(xlabel='wavelength [nm]', ylabel='counts') plt.title('{0} monochromator port {1}'.format(date, port), fontsize=20) for ii in range(8): plt.plot(wavelength / 10, hist_arr[:, ii], label='{0:.2f}$\pi$'.format(ii / 4)) plt.legend(fontsize=20, loc='upper left') tbx.savefig('./img/{0}-mc-plot-8pi.png'.format(date))
def plot_radial_eigen(x, y, eigen_arr, save=1): # Display radial eigenfunction contour plot tbx.prefig(figsize=(6, 6), xlabel='x [cm]', ylabel='y [cm]') plt.title('radial eigenfunction', fontsize=20) plt.xticks(np.arange(min(x), max(x) + 1, 5)) plt.yticks(np.arange(min(y), max(y) + 1, 5)) plt.contourf(x, y, np.transpose(eigen_arr), 100) if save == 1: print('plot_radial_eigen image saved.') plt.savefig('./img/potential_radial-eigen_contour.png', bbox_inches="tight")
def onoff(wavelength, hist_arr, date='2021-05-xx', port='41B'): # Expecting wavelength in units of angstrom tbx.prefig(figsize=(16, 7), xlabel='wavelength [nm]', ylabel='counts') # plt.title('{0} monochromator port {1}'.format(date, port), fontsize=20) plt.title('{0}, port {1} ($z=3.8$ m)'.format(date, port), fontsize=20) print('change z in code if not at port 41B') labels = [ 'background (0-9ms)', 'rope on (9-15ms)', 'afterglow (15-20ms)' ] for ii in range(3): plt.step(wavelength / 10, hist_arr[:, ii], label=labels[ii]) plt.legend(fontsize=20, loc='upper left') tbx.savefig('./img/{0}_mc-plot-onoff-{1}.png'.format(date, port))
def plot_potential_eigen(x, y, pot_L, Lmode=1, save=1): pot_arr = np.real(pot_L) # Display electric potential of a single azimuthal mode tbx.prefig(figsize=[6, 6], xlabel='x [cm]', ylabel='y [cm]') plt.title('electric potential for azimuthal mode L={0}'.format(Lmode), fontsize=20, y=1.02) plt.title('L={0}'.format(Lmode), fontsize=40, y=1.02) plt.xticks(np.arange(min(x), max(x) + 1, 5)) plt.yticks(np.arange(min(y), max(y) + 1, 5)) plt.contourf(x, y, np.transpose(pot_arr), 100) if save == 1: print('plot_potential_eigen image saved.') plt.savefig('./img/potential_eigen_L{0}.png'.format(Lmode), bbox_inches="tight")
def plot_bint_range(self, bint, step=0, shot=0): # Plot function to show the bounded region of integrated B used for # conditional averaging # INPUTS: bdata = 1D data array if bint is None: print("** Running method: integrate_bdot...") self.obj.integrate_bdot() bdata = bint[:, step, shot] tbx.prefig(xlabel='time [px]', ylabel='B-int') plt.plot(bdata) bt1 = self.obj.bt1 or 0 bt2 = self.obj.bt2 or len(bdata) plt.plot([bt1, bt1], [np.min(bdata), np.max(bdata)], 'orange') plt.plot([bt2, bt2], [np.min(bdata), np.max(bdata)], 'orange') plt.title('integrated B, step={0}, shot={1}'.format(step, shot), fontsize=20) tbx.savefig('./img/{0}-condavg-range.png'.format(self.obj.fid))
def gauss(wavelength, hist_arr, ind=1, title=None): # Input wavelength in nm xx = wavelength yy = hist_arr[:, ind] iimin = np.argmin(yy) iimax = np.argmax(yy) def twogauss_func(x, x1, a1, b1, x2, a2, b2, c): return a1 * np.exp(-((x - x1) / b1)**2) + a2 * np.exp(-( (x - x2) / b2)**2) +c def twolorenz_func(x, x1, a1, b1, x2, a2, b2, c): return a1 / (1 + ((x - x1) / b1)**2) + a2 / (1 + ((x - x2) / b2)**2) + c tbx.prefig(xlabel='wavelength [nm]', ylabel='count') plt.step(xx, yy) if title is not None: plt.title(title, fontsize=20) # Initial guess guess = [ 320.3325, yy[iimax] - yy[iimin], 0.02, 320.32, yy[iimax] - yy[iimin], 0.01, yy[iimin] ] # Set boundaries bounds = [(320.325, 0, 0, 320.30, 0, 0, -np.inf), (320.35, +np.inf, 0.2, 320.32, +np.inf, 0.2, +np.inf)] try: poptg, pcovg = scipy.optimize.curve_fit(twogauss_func, xx, yy, p0=guess, bounds=bounds) poptl, pcovl = scipy.optimize.curve_fit(twolorenz_func, xx, yy, p0=guess, bounds=bounds) # print(ind, 'g L1={0:.3f}, a1={1:.1f}, b1={2:.3f}, L2={3:.3f}, ' # 'a2={4:.1f}, b2={5:.3f}, c={6:.1f}'.format(*poptg)) # print(ind, 'L L1={0:.3f}, a1={1:.1f}, b1={2:.3f}, L2={3:.3f}, ' # 'a2={4:.1f}, b2={5:.3f}, c={6:.1f}'.format(*poptl)) # print('--') plabel = 'x1={0:.3f}, a1={1:.1f}, b1={2:.3f}, x2={3:.3f}, '\ 'a2={4:.1f}, b2={5:.3f}, c={6:.1f}'.format(*poptg) plt.plot(xx, twogauss_func(xx, *poptg), label=plabel) perr = np.sqrt(np.diag(pcovg)) t1err = np.sqrt((2 * poptg[2] / poptg[0]**2 * perr[2])**2 + (2 * poptg[2]**2 / poptg[0]**3 * perr[0])**2) * \ ti(1, 1) t2err = np.sqrt((2 * poptg[5]/poptg[3]**2 * perr[5])**2 + (2 * poptg[5]**2/poptg[3]**3 * perr[3])**2) * \ ti(1, 1) print('Ti_1 ({0:.3f} nm) = {1:.3f} +/- {2:.3f} eV, ' 'Ti_2 ({3:.3f} nm) = {4:.3f} +/- {5:.3f} eV'.format( poptg[0], ti(poptg[2], poptg[0]), t1err, poptg[3], ti(poptg[5], poptg[3]), t2err)) # plt.plot(xx, twogauss_func(xx, *poptg), label='gaussian') # plt.plot(xx, twolorenz_func(xx, *poptl), label='lorentzian') plt.legend(fontsize=15, loc='upper left') ylim = plt.gca().get_ylim() plt.ylim(ylim[0], ylim[1] * 1.2) except RuntimeError: pass
def plot_volt(volt): tbx.prefig(xlabel='step', ylabel='voltage [V]') plt.plot(volt)
def find_Ti_exp(volt, curr, startpx=100, endpx=100, plot=0, mstime=0, fid=None, save=0): ''' # Finds Ti from an exponential plot; The curve starts from some max # value then decays exponentially. startpx = number of pixels to count at the start to determine max value endpx = number of pixels to count at the end to determine min value ''' # Smooth the curve temp = tbx.smooth(curr, nwindow=11) # Take gradient to find peak of dI/dV, thats where to cut the exp fit off gradient = np.gradient(tbx.smooth(temp, nwindow=51)) argmin = np.argmin(gradient) # Determine start and end values of the curve vstart = np.mean(temp[:startpx]) vend = np.mean(temp[-endpx:]) def exp_func(x, a, b, c, x0): return a * np.exp(-(x - x0) / b) + c guess = [vstart - vend, 2, vend, volt[argmin]] bound_down = [0.1 * (vstart - vend), 0, vend - vstart, volt[0]] bound_up = [+np.inf, 50, vstart, volt[-1]] try: popt, pcov = curve_fit(exp_func, volt[argmin:], temp[argmin:], p0=guess, bounds=(bound_down, bound_up)) except: return None, None, None Vp = volt[np.argmin(abs([vstart for ii in volt] - exp_func(volt, *popt)))] Ti = popt[1] Ti_err = np.sqrt(np.diag(pcov))[1] if plot != 0: tbx.prefig(xlabel='Discriminator grid voltage [V]', ylabel='Current [$\mu$A]') plt.plot(volt, temp, color='#0e10e6') # ,label='{0} ms'.format(mstime) plt.title('exponential fit, t = {0:.2f} ms'.format(mstime), fontsize=20) # plt.plot(volt[argmin:], temp[argmin:], color='#9208e7') plt.plot(volt, [vstart for ii in volt], '--', color='#5cd05b') plt.plot(volt, [vend for ii in volt], '--', color='#5cd05b') plt.plot(volt[argmin - 20:], exp_func(volt[argmin - 20:], *popt), '--', label='$T_i$ = {0:.2f} eV'.format(Ti), color='#ff4900', linewidth=2) plt.ylim(np.min(temp) * 0.96, np.max(temp) * 1.04) plt.legend(fontsize=20, loc='upper right') if save == 1: tbx.savefig('./img/{0}-IV-expfit-{1:.2f}ms.png'.format( fid, mstime)) return Vp, Ti, Ti_err
def analyzeIV(voltage, current, res=1, area=1, gain_curr=1, gain_volt=1, lim=None, noplot=0, quiet=0, nwindow=351): # Set default values if lim is None: lim = [0.25, 0.75, 0.8] # Constants amu = const.physical_constants['atomic mass constant'][0] # Program parameters sm = 500 # isat index flag_flip = 0 # indicator to check if current was flipped # Get values of voltage and current isat0 = np.mean(current[:sm]) volt = gain_volt * tbx.smooth(voltage, nwindow=nwindow, polyn=2) curr = gain_curr / res * tbx.smooth( current - isat0, nwindow=nwindow, polyn=2) isat = gain_curr / res * isat0 # Checks if current was flipped (set electron current positive) if np.mean(curr[:100]) > np.mean(curr[-100:]): if quiet == 0: print('!!! Current input was flipped') flag_flip = 1 curr = [-ii for ii in curr] if noplot == 0: tbx.prefig(figsize=(16, 4.5), xlabel='Potential [V]', ylabel='Current [A]') plt.plot(volt, curr, linewidth=2) # Define points on the IV curve for analysis cmin, cmax = np.amin(curr), np.amax(curr) y25 = lim[0] * (cmax - cmin) + cmin # 25% of range (not percentile) y75 = lim[1] * (cmax - cmin) + cmin # 75% of range (not percentile) y95 = lim[2] * (cmax - cmin) + cmin arg25 = tbx.value_locate_arg(curr, y25) arg75 = tbx.value_locate_arg(curr, y75) arg95 = tbx.value_locate_arg(curr, y95) # Analysis: transition region ------------------------------------------- x1 = np.arange(arg25, arg75) y1 = curr[arg25:arg75] try: poly_arg1 = np.polyfit(x1, y1, 2) poly1 = np.poly1d(poly_arg1) except: return reject(volt, curr, reason='unable to fit polynomial to ' ' transition region', quiet=quiet) newx1 = np.arange(arg25, arg95) out1 = poly1(newx1) if noplot == 0: plt.plot(volt[newx1], out1, '--', color='orange', label='transition') # Analysis: exponential region ------------------------------------------ folding = 1 while folding < 4: yfold = y25 / (np.exp(folding)) # value # folding lengths below y25 argfold = tbx.value_locate_arg(curr, yfold) x2 = np.arange(argfold, arg75) y2 = curr[argfold:arg75] try: # Derivative of poly1 poly_der1 = np.poly1d([poly_arg1[1], poly_arg1[2] * 2]) etest = y75 / poly_der1(arg75) popt, pcov = curve_fit(f_exp, x2, y2, p0=(y75, etest / x2[-1], 0)) out2 = f_exp(x2, *popt) if noplot == 0: plt.plot(volt[x2], out2, '--', color='red', label='exponential') break except: folding += 1 if quiet == 0: print('\rextending folding length to {0}...'.format(folding), end='') else: return reject(volt, curr, reason='exponential region failed to ' ' converge', quiet=quiet) # Estimate the electron temperature, popt is in indices need to convert index_Te = int(1 / popt[1]) if index_Te + arg25 >= len(volt) or index_Te < 0: return reject(volt, curr, reason='garbage electron temperature', quiet=quiet) plasma_Te = volt[index_Te + arg25] - volt[arg25] v_thermal = 4.19e7 * np.sqrt(abs(plasma_Te)) # [cm/s] if quiet == 0: print('electron Temp = {0:.2f} [eV]'.format(plasma_Te)) # Analysis: electron saturation region ----------------------------------- x3 = np.arange(arg95, len(volt)) y3 = curr[arg95:] poly_arg3 = np.polyfit(x3, y3, 1) poly3 = np.poly1d(poly_arg3) newx3 = np.arange(arg75, len(volt)) # extrapolate backwards out3 = poly3(newx3) if noplot == 0: plt.plot(volt[newx3], out3, '--', color='green', label='electron saturation') # The intersection of out1 and out3 is the plasma potential coeff = poly_arg1 - np.append(0, poly_arg3) roots = np.roots(coeff) plasma_pot = None # Should only have one root that satisfy this for ii in np.unique(np.real(roots)): # Note: if root is imaginary, the real root is the point of closest # approach if (ii < len(curr)) & (ii > 0): if volt[int(ii)] > 0: plasma_pot = volt[int(ii)] plasma_den = curr[int(ii)] / (const.e * area * v_thermal) plasma_iden = isat / (const.e * area * v_thermal * np.sqrt(const.m_e / (amu * 4.0026))) if quiet == 0: print( 'Plasma potential = {0:.3f} [V]'.format(plasma_pot)) print( 'Plasma density = {0:.3e} [cm-3]'.format(plasma_den)) print('Plasma density(i)= {0:.3e} [cm-3]'.format( plasma_iden)) if plasma_pot is None: # Check if convergent solution/root exists return reject(volt, curr, reason='no plasma potential found', quiet=quiet) # The last entry is a parameter to indicate if a curve was rejected, # 0 = no, 1 = yes params = [plasma_Te, plasma_pot, plasma_den, plasma_iden, 0] # plot output if noplot == 0: plt.legend(fontsize=20) plt.ylim(cmin - 0.1 * abs(cmax - cmin), cmax + 0.1 * abs(cmax - cmin)) return volt, curr, params
def plot_CH_plane(dim=5, blank=0): Hmin, Cmin, Hmax, Cmax = minmax_CH_plot(dim=dim, npoints=100) fig = tbx.prefig(figsize=(16, 9), xlabel='BP entropy $H$', ylabel='JS complexity $C_{JS}$') plt.title('Complexity$-$Entropy causality plane ($d=${0})'.format(dim), fontsize=30) plt.plot(Hmin, Cmin, 'c', linewidth=2) plt.plot(Hmax, Cmax, 'c', linewidth=2) if blank != 0: print('\r Calculating CH for Hénon map... ', end='') C_henon, H_henon = henon_map(10000, dim=dim) plt.plot(H_henon, C_henon, 'D', markersize=12, fillstyle='none', label='Hénon map') print('\r Calculating CH for Logistic map... ', end='') C_logis, H_logis = logistic_map(10000, dim=dim) plt.plot(H_logis, C_logis, '^', markersize=15, fillstyle='none', label='Logistic map') print('\r Calculating CH for Ricker population map...', end='') C_ricker, H_ricker = ricker_map(10000, dim=dim) plt.plot(H_ricker, C_ricker, 's', markersize=15, fillstyle='none', label='Ricker population map') print('\r Calculating CH for Gingerbreadman map... ', end='') C_gbman, H_gbman = gbman_map(10000, dim=dim) plt.plot(H_gbman, C_gbman, '+', markersize=15, fillstyle='none', label='Gingerbreadman map') print('\r Calculating CH for sine wave... ', end='') C_sine, H_sine = sine_wave(10000, dim=dim) plt.plot(H_sine, C_sine, 'x', markersize=15, fillstyle='none', label='Sine wave') print('\r Calculating CH for Lorenz attractor... ', end='') C_lorenz, H_lorenz = lorenz_attractor(sigma=10, beta=8 / 3, rho=28, dim=dim) plt.plot(H_lorenz, C_lorenz, '8', markersize=15, fillstyle='none', label='Lorenz attractor') print('\r Calculating CH for double pendulum... ', end='') C_dbpd, H_dbpd = double_pendulum(m=1, l=1, g=10, dim=dim) plt.plot(H_dbpd, C_dbpd, '*', markersize=15, fillstyle='none', label='Double pendulum') C_fBm, H_fBm = fBm_gen(dim=dim) plt.plot(H_fBm, C_fBm, '.', label='fractional Brownian motion (fBm)') plt.legend(fontsize=15) return fig