Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
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(