コード例 #1
0
def loadcurrent(shot, scope='3'):
    """ helper function to read in the current"""
    data = sdr.scope_data(shot, scope)
    time = data.time
    eastcurrent = -data.ch2 * 170000  #East gun 170kA/V
    westcurrent = -data.ch4 * 190000  #West gun 190kA/V
    return time, eastcurrent, westcurrent
コード例 #2
0
def plot_voltage(shot, scope='3'):
    """ helper function to read in the current"""
    data = sdr.scope_data(shot, scope)
    time = data.time
    eastvolt = data.ch1  #East gun 170kA/V
    westvolt = data.ch3  #West gun 190kA/V
    plt.plot(time, eastvolt, label="East Voltage")
    plt.plot(time, westvolt, label="West Voltage")
    plt.legend()
    plt.show()
コード例 #3
0
def dens_calib(calib_shot, cutoff=1, scope='1'):
    """
    day - str, mmddyy, with date of the shot taken
    shot - int, shot number
    cutoff - float, cutoff frequency in MHz for lowpass filter used to improve data
    scope - str, scope


    returns:
        env - envelope, range of data for signal 1 and 2
        offset - minima of both signals
        phasediff - phase error between cos and sin, in radians

    """

    #load the data
    data = sdr.scope_data(calib_shot, scope)
    names = ['signal1', 'signal2']
    if scope == '2': channels = (1, 2)
    if scope == '1': channels = (3, 4)
    #channels = (3, 4)
    mult = (1, 1)
    data.setScopeProperties(names, channels, mult)

    cos, sin, t = data.signal1[data.time > 50], data.signal2[
        data.time > 50], data.time[data.time > 50]
    # removes first bit of the data due to occasional noise at t = 0

    cos = mytools.lowpass_gfilter(t, cos, cutoff, return_mean=True)
    sin = mytools.lowpass_gfilter(t, sin, cutoff, return_mean=True)
    #apply lowpass filter to make the fits better
    print("stage 1 completed...")
    env = [max(cos) - min(cos), max(sin) - min(sin)]
    offset = [min(cos), min(sin)]
    #find ranges for the data

    cos = (cos - offset[0]) / env[0]
    sin = (sin - offset[1]) / env[1]
    #calibrate the data

    #find the phase error
    x_ym_list = []  #array of  xvals around the ymax pt
    weights_list = []
    for i in range(len(cos)):
        if sin[i] > 0.98:
            x_ym_list.append(cos[i])
            weights_list.append(np.abs((0.98 - sin[i]) / 0.02))

    #find weighted average max pt.
    #x_ym = np.mean(x_ym_list)
    x_ym = np.dot(x_ym_list, weights_list) / sum(weights_list)
    #use cosine when sin = 1 to find phase error
    phasediff = np.arccos((x_ym - 0.5) * 2) - np.pi / 2
    print("stage 2 completed...")
    return env, offset, phasediff
コード例 #4
0
def load_smallbdot(shot, scope = '1'):
    data = sdr.scope_data(shot, scope)
    time = data.time
    X_bdot = data.ch1 #*170000#East gun 170kA/V
    Y_bdot = data.ch2 #*190000#West gun 190kA/V
    Z_bdot = data.ch3
    Bx = sp.integrate.cumtrapz(X_bdot,time)
    By = sp.integrate.cumtrapz(Y_bdot,time)
    Bz = sp.integrate.cumtrapz(Z_bdot,time)
    timeb = time[:-1]
    return timeb, Bx, By, Bz
コード例 #5
0
def sxr(run, scope='2', showPlot=False):
    """Plots the SXR data."""

    data = sdr.scope_data(run, scope)
    data.ylabel = 'mA'
    names = data.header[1:]
    channels = (1, 2, 3, 4)
    mult = (1 / 50. * 1000, ) * 4
    units = (data.ylabel, ) * 4

    data.setScopeProperties(names, channels, mult, units)

    return data
コード例 #6
0
def vuv(run, scope='1', amp=100e-6, channel=4):
    """VUV data.
    amp is in amps/volt, so 100 ua/v is 100e-6."""

    data = sdr.scope_data(run, scope)
    names = ['vuv']
    channels = [channel]

    mult = [amp]
    units = ['A']

    data.setScopeProperties(names, channels, mult, units)

    return data
コード例 #7
0
def tripleProbe(run, scope='2', smoothing=100, mult=None):
    """Reads data from triple probe and analysizes it.
    This hasn't been updated in a long time so use at your discretion.  It
    probably eneds to be tweaked."""
    data = sdr.scope_data(run, scope)

    names = ('vd2', 'vd3', 'i1', 'vfloat')
    channels = (1, 2, 3, 4)
    if not mult:
        mult = (-50, -50, 10, 200)
    units = ('V', 'V', 'A', 'V')

    data.setScopeProperties(names, channels, mult, units)

    data.temperature = data.vd2 / np.log(2)
    data.temperature2 = data.vd2 / (np.log(2) -
                                    np.log(1 + 11.3205 *
                                           (data.vd2 / data.vd3)**3.53217))

    data.temperatureSmooth = mf.smooth(data.vd2, smoothing) / np.log(2)
    data.temperature2Smooth = mf.smooth(data.vd2, smoothing) / (
        np.log(2) - np.log(1 + 11.3205 *
                           (mf.smooth(data.vd2, smoothing) /
                            mf.smooth(data.vd3, smoothing))**3.53217))

    mi = 1.6726e-27
    elecCharge = 1.6022e-19
    tconv = 1.1604e4
    area = 3.6e-6
    boltz = 1.3807e-23

    data.isat = data.i1 * (np.exp(-(data.vd2 / data.temperature))) / (
        1 - np.exp(-(data.vd2 / data.temperature)))

    data.isatSmooth = mf.smooth(data.i1, smoothing) * (
        np.exp(-(mf.smooth(data.vd2, smoothing) / data.temperature2Smooth))
    ) / (1 -
         np.exp(-(mf.smooth(data.vd2, smoothing) / data.temperature2Smooth)))

    data.density = (data.isat * np.exp(.5)) / (elecCharge * area) * sqrt(
        mi / (data.temperature * tconv * boltz)) / 1e6

    data.density2 = (data.isatSmooth *
                     np.exp(.5)) / (elecCharge * area) * sqrt(
                         mi / (data.temperature2Smooth * tconv * boltz)) / 1e6

    return data
コード例 #8
0
def gunPlots(shot, scope='3', writeFiles=False, ext='png'):
    """Plots gun data from scope 3."""
    data = sdr.scope_data(shot, scope)
    fig = figure(12, **ssxdef.f)
    fig.clear()
    a = axes()
    a.plot(data.time, data.ch2 * 170, label='East')
    a.plot(data.time, data.ch4 * 190, label='West')
    xlabel('Time (us)')
    ylabel('Gun Current (kA)')
    title(data.shotname)
    a.legend()

    fig2 = figure(13, **ssxdef.f)
    fig2.clear()
    a = axes()
    a.plot(data.time, data.ch1, label='East')
    a.plot(data.time, data.ch3, label='West')
    xlabel('Time (us)')
    ylabel('Gun voltage ()')
    title(data.shotname)
    a.legend()

    if writeFiles:
        fName = ssxutil.ssxPath('guncurrent.' + ext,
                                'output',
                                data.runYear + '/' + data.runDate + '/' +
                                data.shotname,
                                mkdir=True)
        fig.savefig(fName)
        fName2 = ssxutil.ssxPath(
            'gunvoltage.' + ext, 'output',
            data.runYear + '/' + data.runDate + '/' + data.shotname)
        fig2.savefig(fName2)
    else:
        show()

    return data
コード例 #9
0
def calibrationDTAC_david(calibInfo, probeinfo, prefunc = None):
    """Modification to calibration() for the dtac data.

    Data from the dtac units needs to be integrated before we calibrate it.
    The integrated data is used for fitting.

    probeinfo has some dtac specific data stashed in it.
    - probe is the probe name (m1).
    - filestrings is the dtac filestring names.
    - dir relates the probe coords (1,2,3) to lab coords (r,t,z).
      Specifically, you pass in ['r', 't', 'z'] in this variable (in the
      appropriate order) if the probe data has *different* names, like ['1',
      '2', '3'].  This probably will never need to be used for the dtac probes,
      but it's here in just in case.  This was originally for the colorado
      probe - look in the functions calibcolorado and calibrationCol for more
      on the implementation."""

    import hiresmag_david as hr

    nump = calibInfo['numProbes']
    numc = calibInfo['numChan']
    pretrig = calibInfo['pretrigger']

    calibData = zeros((3, nump, 4))

    # dir = c,b,a
    # dir = a,b,c
    # dir2 = r,t,z
    dir = calibInfo['dir']
    # helmholtz fields - triplet location, shot orientation, components (r,t,z)
    b = zeros((nump,3,3))
    # data from 3 calibration shots, triplet position, components (r,z,t)
    voltages = zeros((3, nump, 3))
    dir2 = probeinfo['dir']

    for i, k in enumerate(dir):
        d = dir2[i]
        print "Calculating b fields - %s" % d
        # calculate the field from the helmholtz coils as *should* be measured
        # by each probe in the right location
        b0 = calibBFields2(d, calibInfo)
        # stick it into the big b array
        b[:,i,:] = b0

    if calibInfo['coil'] == 2:
        peakrange = [25,60]
    elif calibInfo['coil'] == 1:
        peakrange = [50,130]

    for i,run in enumerate(calibInfo['runs']):
        print "using run %s" % run
        # Get the data from the scopes
        shotdata = sdr.scope_data(run, calibInfo['scope'])
        # get the calibrated current for the shot
        current = getattr(shotdata, shotdata.names[calibInfo['currentChan'] -
            1]) * 170000. #(1000./0.00541/1.025)
        # the above is our calibration for the gun current.
        # - 170 kA/V for east gun
        # - 190 kA/V for west gun
        # - 180 kA/V was the historical value

        # get the peak of the current
        currentMax = polyPeak(shotdata.time, current, range = peakrange, timebase
            = 200)

        # read in the dtac mag data and get it ready
        # hiresmag_data should be kosher to use for any dtac setup, but I'm not
        # sure.  We might have to modify this.
        magdata = hr.hiresmag_data(run, probeinfo['probe'])
        magdata.filestrings = probeinfo['filestrings']
        magdata._getData()
        magdata._makeFullData()
        magdata.removeOffsets()
        # call our preprocessing function on the data, if we need it
        if prefunc:
            prefunc(magdata)
        magdata.iFullData = np.ma.zeros(magdata.fullData.shape)
        magdata.iFullData.mask = True
        magdata.iFullData[:,1:] = sp.integrate.cumtrapz(magdata.fullData, dx =
            magdata.deltat * 1e6, axis = 1)
        print 'fullData ',magdata.fullData.shape
        print 'iFullData ',magdata.iFullData.shape

        # tmp = ma.masked_outside(magdata.fullData[:,2:100], -.50, .50).mean(1)
        # offsets = np.expand_dims(tmp, 2)
        # dat = magdata.fullData - offsets
        # magdata.iFullData = np.ma.zeros(magdata.fullData.shape)
        # magdata.iFullData.mask = True
        # magdata.iFullData[:,1:] = sp.integrate.cumtrapz(dat, dx =
        #     magdata.deltat * 1e6, axis = 1)

        # magmax = zeros(numc)
        magmax = zeros((nump, 3))

        # Outer loop is for each probe location (i.e. 16 probes)
        # Inner loop is for directions (i.e. r,t,z)
        # So the progression goes: 1r, 1t, 1z, 2r, 2t, 2z...
        for j in xrange(nump):
            for k,p in enumerate(dir):
                # first figure out the name of our probe channel - ex. m2r1
                probeNum = "%s%s%i" % (probeinfo['probe'], p, j+1)
                print "%s: i = %i, j = %i, k = %i" % (probeNum, i,
                    j, k)
                # find the peak in the mag signal
                #chan = magdata.channelNames.index(probeNum)
                chan = (16*k)+j #Dschaffner changed 5/16/2014 to convert [3,16] to [48]
                print 'Chan = ',chan
                timebase = int(1e-6 / magdata.deltat)
                # tmpmag = polyPeak(magdata.time, magdata.iFullData[chan],
                #     timebase = timebase, pretrigger = 100)
                tmpmag = polyPeak(magdata.time, magdata.iFullData[chan,:], range
                    = peakrange, timebase = timebase, pretrigger = pretrig)
                    #DSchaffner changed magdata.iFullData[chan] to magdata.iFullData[k,j]
                # print tmpmag, currentMax, tmpmag/ currentMax
                # normalize to the current
                # No longer normalize to the double turn helmholtz coil.  First
                # of all that was stupid - why not just spit that out in the
                # helmholtz function?  Secondly, we have a new coil which is
                # only one turn, so we need to be able to toggle that on and
                # off, and it seems to make the most sense to do it in the...
                # helmholtz function.
                #
                # We will still normalize the measured field here with the
                # current
                magmax[j, k] =  tmpmag / (currentMax)
        # our normalized B signals - takes into account current
        # magmax is now number of probes x number of axis long.  So for a 16
        # channel, 3 axis probe, it should be 48 channels (16,3).
        # Voltages is the same size as magmax, but with an extra dimension. The
        # extra dimension is number of calibration directions (3
        # usually).  So it would be [3,16,3].
        voltages[i] = magmax

    # Outer loop is for each probe location (i.e. 16 probes)
    # inner loops is r, t, z
    for i in xrange(nump):
        for j,d in enumerate(dir):
            # so we are going to dot the normalized voltages into the inverse
            # of the expected field.  The indices in voltages makes sure we get
            # a single coil (m2r1) for all three calibration orientations
            # (r,t,z).

            u = dot((voltages[:,i,j]), inv(b[i,:,:]))
            # all the magic is in the above line.  All we are doing is dotting
            # the measured voltages (r,t,z) into the inverse of the 3x3 array
            # of the fields we should be measuring ((r,t,z) for each of the 3
            # orientations r, t, and z (though I think the indices of b are as
            # follows:
            #   - first index is probe number
            #   - second index is calibration orientation
            #   - third index is component of field
            # dot sums over the last dimension of the first array and the 2nd
            # to last dimension of the second array.  So we are dotting the
            # calib orientation of voltages and the calib orientation of b.  At
            # this point in time, b should more or less be diagonal (ignoring
            # any error fields in the coil due to non-uniform fields in the
            # helmholtz).
            #
            # this normalizes it all
            modu = sqrt(dot(u,u))
            calibData[j,i,:3] = u/modu
            calibData[j,i,3] = modu
    # Reshape before we send it back.  This is getting written to a file so it
    # needs to be 2-D.  Note, I think the data is going to get put down in the
    # file as 1-16r, 1-16t, then 1-16z.  When we read it in later, just run
    # reshape() again, this time like reshape((3, nump, 4)) where nump is 16
    # most likely.
    #
    # This is a change of how this data used to be stored.  It used to be
    # stored in a 48x4 array, where the first three lines formed a 3x4 array
    # that consisted of 1r,1t,1z data, etc.  We also just used to parse the
    # array with a bunch of stupid indices.  Now we reshape to get our 3x16 for
    # axis x probe.  Mind you, we choose 3x16 instead of 16x3 because of the
    # way the dtac data is read in, organized and easily reshaped.  This way we
    # don't have to think about indices (dtac data is 3x16) nor do we have to
    # worry about making the 3D arrays 2D, just use reshape and things go
    # together in the correct way for unreshaping it later.
    return calibData.reshape((nump*3,4))
コード例 #10
0
def interferometer(run,
                   env,
                   offset,
                   phasediff,
                   linfit=True,
                   cutoff=1,
                   scope='1',
                   diam=0.155575,
                   showPlot=False,
                   writeFiles=False):
    """Interferometer analysis routine.

    Reads data from the scope data files and runs the analysis.  Inputting a
    proper diameter is necessary.

    Diameter is path length of interferometer in cm.  In oblate flux
    conservers it should be 50 cm.  For neck part of oblate conservers, it
    should be 15.5575 cm.

    run - str, mmddyy+'r'+shot number
    env - envelope output from densitycalibration, should be shot from same day
    offset - offset output from densitycalibration, should be shot from same day
    phasediff - phasediff output from densitycalibration , should be shot from same day
    linfit - whether or not to subtract a linear fit from the data. should set to false for
            calibration shots
    cutoff - float, lowpass filter cutoff frequency in MHz
    calib_shot - controls whether or not to subtract a linear fit to the density data
                 before t = 3 ms to remove phase drift. I.e. usually false for looking
                 at calibration data

    Written by Emma Suen-Lewis 2017, adapted from Tim Gray
    """
    print('Shot ' + run + ': analyzing density')
    data = sdr.scope_data(run, scope)
    names = ['signal1', 'signal2']
    channels = (3, 4)
    mult = (1, 1)

    data.setScopeProperties(names, channels, mult)
    data.runname = run  #save run name for folder naming in other functions
    data.cutoff = cutoff  # save lowpass cutoff frequency

    t = data.time

    cos = mytools.lowpass_gfilter(t, data.signal1, cutoff, return_mean=True)
    sin = mytools.lowpass_gfilter(t, data.signal2, cutoff, return_mean=True)
    #load cos/sin data and apply lowpass filter

    cos = (cos - offset[0]) / env[0]
    sin = (sin - offset[1]) / env[1]
    #calibrate data with envelope and offsets

    #change ranges from [0,1] to [-1,1]
    for i in range(len(cos)):
        cos[i] = 2 * cos[i] - 1
        sin[i] = 2 * sin[i] - 1

    data.sig1cal = cos.copy()
    data.sig2cal = sin.copy()

    for i in range(len(cos)):
        cos[i] = (cos[i] / np.cos(phasediff) + (sin[i]) * np.tan(phasediff))
    #remove effects of phase error

    #will output cosine and sine data (note that this doesn't include corrections
    #for low-frequency phase drift)
    data.cos = cos.copy()
    data.sin = sin.copy()

    phi = np.arctan(sin / cos)
    #calculate phase in radians

    #get rid of jumps due to the range of arctan
    for i in range(len(phi)):
        if i < len(phi) - 1:
            if phi[i + 1] - phi[i] > 3:
                phi[i + 1:] = phi[i + 1:] - np.pi
            if phi[i + 1] - phi[i] < -3:
                phi[i + 1:] = phi[i + 1:] + np.pi

    dphi = phi - np.mean(phi[0:10])
    #subtract out initial phase

    data.p = []
    #linear fit to data before firing
    if linfit == True:
        time_mask = t < 35
        p = np.polyfit(
            t[time_mask],
            ism.iter_smooth(dphi, loops=10, window_len=15)[time_mask], 1)
        dphi = dphi - p[1] - p[0] * t
        data.p = p
    data.dphi = dphi

    # .155575 m is the ID of the small part of the flux conserver
    # mks
    #density = (dphi * 4 * pi * (3e8)**2 * 8.854e-                                                                                                                                        12 * 9.109e-31) /
    #((1.602e-19)**2 * 632.8e-9 * .155575)

    #cgs
    #density = (dphi * (3e10)**2 * 9.109e-28) / ((4.8032e-10)**2 * 632.8e-7 *
    #    diam)
    density = 5.62e14 * dphi / diam

    data.pathlength = diam
    data.density = density

    if showPlot or writeFiles:
        fig = figure(13, **ssxdef.f)
        fig.clear()
        a = axes()
        a.plot(data.time, data.density, 'k-')
        xlabel('Time (us)')
        ylabel('Density (#/cm$^3$)')
        title(data.shotname)
        if writeFiles:
            # make output directory
            fName = ssxutil.ssxPath(
                'interferometer.png', 'output',
                data.runYear + '/' + data.runDate + '/' + run)
            dir, trash = os.path.split(fName)
            os.spawnlp(os.P_WAIT, 'mkdir', 'mkdir', '-p', dir)
            fig.savefig(fName)
        else:
            show()

    return data
コード例 #11
0
def loadcurrent(shot, scope = '3'):
    data = sdr.scope_data(shot, scope)
    time = data.time
    eastcurrent = -data.ch2*170000#East gun 170kA/V
    westcurrent = -data.ch4*190000#West gun 190kA/V
    return time,eastcurrent,westcurrent
コード例 #12
0
def interferometer_mod(run,
                       calib,
                       s1=[],
                       s2=[],
                       scope='2',
                       diam=0.155575,
                       showPlot=False,
                       writeFiles=False):
    """Interferometer analysis routine.
    Reads data from the altered cosine/sine data and runs the analysis.  Inputting a
    proper diameter is necessary.
    Diameter is path length of interferometer in cm.  In oblate flux
    conservers it should be 50 cm.  For neck part of oblate conservers, it
    should be 15.5575 cm.
    calib should be a tuple/list of the maximum and minimums observed on the
    scope for each channel at the beginning of the run day."""

    data = sdr.scope_data(run, scope)
    names = ['signal1', 'signal2']
    channels = (1, 2)
    mult = (1, 1)
    units = ('arb', 'arb')

    data.setScopeProperties(names, channels, mult)
    data.calib = dict(zip(names, calib))

    if s1 == []:
        dv1 = data.signal1 - np.mean(data.signal1[0:10])
    else:
        dv1 = s1 - np.mean(s1[0:10])

    if s2 == []:
        dv2 = data.signal2 - np.mean(data.signal2[0:10])

    else:
        dv2 = s2 - np.mean(s2[0:10])

    arg = 1 - 0.5 * ((dv1 / data.calib[names[0]])**2 +
                     (dv2 / data.calib[names[1]])**2)
    #remove values outside of arccos domain
    spikes = np.where(arg < -1.0)
    arg[spikes] = -1.0

    dphi = np.arccos(arg)
    data.dphi = dphi

    # .155575 m is the ID of the small part of the flux conserver
    # mks
    #density = (dphi * 4 * pi * (3e8)**2 * 8.854e-12 * 9.109e-31) /
    #((1.602e-19)**2 * 632.8e-9 * .155575)

    #cgs
    #density = (dphi * (3e10)**2 * 9.109e-28) / ((4.8032e-10)**2 * 632.8e-7 *
    #    diam)
    density = 5.62e14 * dphi / diam

    data.pathlength = diam
    data.density = density

    if showPlot or writeFiles:
        fig = figure(13, **ssxdef.f)
        fig.clear()
        a = axes()
        a.plot(data.time, data.density, 'k-')
        xlabel('Time (us)')
        ylabel('Density (#/cm$^3$)')
        title(data.shotname)
        if writeFiles:
            # make output directory
            fName = ssxutil.ssxPath(
                'interferometer.png', 'output',
                data.runYear + '/' + data.runDate + '/' + run)
            dir, trash = os.path.split(fName)
            os.spawnlp(os.P_WAIT, 'mkdir', 'mkdir', '-p', dir)
            fig.savefig(fName)
        else:
            show()
    x1, x2 = data.signal1, data.signal2
    k1, k2 = calib[0], calib[1]
    error = (3.6 * 10**15) * 0.00627 * (x1 * (k1**-2) + x2 *
                                        (k2**-2)) / np.sqrt(4 *
                                                            ((x1 / k1)**2 +
                                                             (x2 / k2)**2) -
                                                            ((x1 / k1)**2 +
                                                             (x2 / k2)**2)**2)
    return data, error