def __init__(self, shot, i_diag, v_diag, dev_name="W7X", debug=debug, plot=1, verbose=0, params=None): self.dev = pyfusion.getDevice(dev_name) self.shot = shot self.verbose = verbose self.i_diag = i_diag self.v_diag = v_diag self.debug = debug self.plot = plot self.select = None self.t_comp = (0.1,0.2) self.params = params self.figs = [] self.suffix = '' # this gets put at the end of the fig name (title bar) self.imeasfull = self.dev.acq.getdata(shot, i_diag) self.vmeasfull = self.dev.acq.getdata(shot, v_diag) comlen = min(len(self.vmeasfull.timebase), len(self.imeasfull.timebase)) FFT_size = nice_FFT_size(comlen-2, -1) # the minus 2 is a fudge to hide small inconsistencies in reduce_time # e.g. 20160310 9 W7X_L5_LPALLI self.imeasfull = self.imeasfull.reduce_time([self.imeasfull.timebase[0], self.imeasfull.timebase[FFT_size]]) self.vmeasfull = self.vmeasfull.reduce_time([self.vmeasfull.timebase[0], self.vmeasfull.timebase[FFT_size]]) if self.params is not None: self.process_swept_Langmuir(**self.params)
def get_iprobe(self, leakage=None, t_comp=None): """ main purpose is to subtract leakage currents Will use the full data, as the t_range is meant to be plasma interval returns a copy of the measured courremt, overwritten with the corrected iprobe """ # obtain leakage estimate if t_comp is None: t_comp = self.t_comp FFT_size = nice_FFT_size(len(self.imeasfull.timebase), -1) self.iprobefull = self.imeasfull.copy() self.sweepQ = [] # will keep these for synchronous sampling input_leakage = leakage for (c, chan) in enumerate(self.imeasfull.channels): if self.select is not None and c not in self.select: continue leakage = input_leakage cname = chan.config_name sweepV = self.vcorrfull.signal[self.vlookup[self.vassoc[c]]][0:FFT_size] sweepQ = hilbert(sweepV) self.sweepQ.append(sweepQ) # save for synchronising segments (it is smoothed) # these attempts to make it accept a single channel are only partial imeas = self.imeasfull.signal[c] # len(self.imeasfull.channels) >1 else self.imeasfull.signal tb = self.imeasfull.timebase w_comp = np.where((tb>=t_comp[0]) & (tb<=t_comp[1]))[0] if len(w_comp) < 2000: raise ValueError('Not enough points {wc} t_comp - try {tt}' .format(tt=np.round([tb[0], tb[0] + t_comp[1]-t_comp[0]],3), wc=len(w_comp))) ns = len(w_comp) wind = np.blackman(ns) offset = np.mean(wind * imeas[w_comp])/np.mean(wind) sweepVFT = np.fft.fft(AC(sweepV[w_comp]) * wind) imeasFT = np.fft.fft(AC(imeas[w_comp]) * wind) ipk = np.argmax(np.abs(sweepVFT)[0:ns//2]) # avoid the upper one comp = imeasFT[ipk]/sweepVFT[ipk] #print('leakage compensation factor = {r:.2e} + j{i:.2e}' # .format(r=np.real(comp), i=np.imag(comp))) print('{u}sing computed leakage comp factor = {m:.2e} e^{p:.2f}j' .format(u = ["Not u", "U"][leakage is None], m=np.abs(comp), p=np.angle(comp))) if leakage is None: leakage = [np.real(comp), np.imag(comp)] # find the common length - assuming they start at the same time???? comlen = min(len(self.imeasfull.timebase),len(self.vmeasfull.timebase),len(sweepQ)) # put signals back into rdata (original was copied by reduce_time) # overwrite - is this OK? self.iprobefull.signal[c] = self.iprobefull.signal[c]*0. # clear it # sweepV has a DC component! beware self.iprobefull.signal[c][0:comlen] = self.imeasfull.signal[c][0:comlen]-offset \ - sweepV[0:comlen] * leakage[0] - sweepQ[0:comlen] * leakage[1] # remove DC cpt (including that from the compensation sweepV) offset = np.mean(wind * self.iprobefull.signal[c][w_comp])/np.mean(wind) self.iprobefull.signal[c][0:comlen] -= offset
print('data length is ', len(data.timebase)) if add_corruption: for sig in data.signal: # small dislocation for 0309_52 sig[100000:140000] = sig[140001: 180001] # small disloc (depends on fsw) sig[200000:201450] = sig[201450:202900] # big dislocation 1.5 cycles sig[300000:300450] = sig[300450:300900] # small 0.5 cycles fd = data # this is a workaround for clipped sweep signals, but it slows time response if fft: # in this context (data with errors), many weird FFT sizes are likely, so limit planning time if pyfusion.fft_type == 'fftw3': pyfusion.fftw3_args.update(dict(planning_timelimit=1.0)) FFT_size = nice_FFT_size(len(data.timebase) - 1, -1) # 1 less to allow rounding err in reduce time data = data.reduce_time([data.timebase[0], data.timebase[FFT_size]]) fd = data.filter_fourier_bandpass(passband=[100, 900], stopband=[50, 950]) print('filtered data length is ', len(fd.timebase)) phc = analytic_phase(data[data.keys()[0]]) - fsamp * 2 * pi * data.timebase ends = len(phc) / 10 #fsamp += np.diff(phc)[ends:-ends].mean()/np.diff(data.timebase).mean()/(2*pi) if iterate: # this correction looks just at data between 30% and 70% to avoid hiccups from shot with no plasma dfsamp = (phc[-3 * ends:-2 * ends].mean() - phc[2 * ends:3 * ends].mean()) / ( (data.timebase[-3 * ends:-2 * ends].mean() - data.timebase[2 * ends:3 * ends].mean())) / (2 * np.pi) if np.isnan(dfsamp): print(