コード例 #1
0
ファイル: rfea.py プロジェクト: AquaDragon/python-lib
def IVderiv(curr, scale=1, nwindow=51, nwindow2=None, polyn=3, **kwargs):
    # Calculates the current derivative -dI/dV
    smoo1 = tbx.smooth(curr, nwindow=nwindow, polyn=polyn, **kwargs)
    grad1 = -np.gradient(smoo1)
    if nwindow2 is not None:
        smoo2 = tbx.smooth(grad1, nwindow=nwindow2, polyn=polyn, **kwargs)
        return smoo2 * scale
    else:
        return grad1 * scale
コード例 #2
0
ファイル: rfea.py プロジェクト: AquaDragon/python-lib
    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))
コード例 #3
0
ファイル: rfea.py プロジェクト: AquaDragon/python-lib
def rsmooth(data, repeat=2, nwindow=31, **kwargs):
    temp = data
    while repeat > 0:
        temp = tbx.smooth(temp, nwindow=nwindow, **kwargs)
        repeat -= 1
    return temp
コード例 #4
0
ファイル: rfea.py プロジェクト: AquaDragon/python-lib
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
コード例 #5
0
ファイル: analyzeIV.py プロジェクト: AquaDragon/python-lib
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