Example #1
0
def offAngleLoop2(file,inPulse,channel,antHeight=[]):
    """
    the thing in doOffAngle that gets the waveform and processes it

    The main one was doing an fft average on top of time averaging, and I want to try without that

    -> Nope, doesn't help

    """

    inPulseF,inPulseFFT = inPulse
    inPulseX,inPulseY = tf.genTimeSeries(inPulseF,inPulseFFT)

    if len(antHeight) != 0:
        antHeightF,antHeightFFT = antHeight
        antHeightX,antHeightY = tf.genTimeSeries(antHeightF,antHeightFFT)
    

    #import all the events from that file (it is stored with a ton of events in it)
    events = importAll(file,channel=channel)
    print "doOffAngle(): ",file," has number of events:",len(events)

    avgEventX,avgEventY = tf.correlateAndAverage(events)
    avgEventX *= 1e9
    #also sampled too fast, so lets just do the FFT trick to downsample it again
    avgEventF,avgEventFFT = tf.genFFT(avgEventX,avgEventY)
    avgEventF   = avgEventF[:1001]
    avgEventFFT = avgEventFFT[:1001]
    avgEventX,avgEventY = tf.genTimeSeries(avgEventF,avgEventFFT)
    #it is also too long
    avgEventX = avgEventX[:1000]
    avgEventY = avgEventY[:1000]
    avgEventF,avgEventFFT = tf.genFFT(avgEventX,avgEventY)
    if debug:
        print "doOffAngle(): avgEvent length: ",len(avgEventX)," dT:",avgEventX[1]-avgEventX[0]
        if len(antHeight) != 0: print "doOffAngle(): antHeight length: ",len(antHeightX)," dT:",antHeightX[1]-antHeightX[0]
        print "doOffAngle(): inPulse length: ",len(inPulseX)," dT:",inPulseX[1]-inPulseX[0]
            
        print "doOffAngle(): avgEventFFT length: ",len(avgEventF),"/",len(avgEventFFT)," dF:",avgEventF[1]-avgEventF[0]
        if len(antHeight) != 0: print "doOffAngle(): antHeightFFT length: ",len(antHeightF),"/",len(antHeightFFT)," dF:",antHeightF[1]-antHeightF[0]
        print "doOffAngle(): inPulseFFT length: ",len(inPulseF),"/",len(inPulseFFT)," dF:",inPulseF[1]-inPulseF[0]
        
    #generate the transfer function
    if len(antHeight) == 0:
        transFuncF,transFuncFFT = doChamberIdenticalTF(avgEventF,avgEventFFT,inPulseFFT)
    else:
        transFuncF,transFuncFFT = doChamberRotatedTF(avgEventF,avgEventFFT,inPulseFFT,antHeightFFT)
        


    return transFuncF,transFuncFFT
Example #2
0
def addNoise(sigWaveX,sigWaveY,snr,showPlots=False):

    length = len(sigWaveX)

    sigWaveY /= np.std(sigWaveY)
    sigWaveY /= np.sqrt(length)
    sigWaveY *= snr

    noiseX = np.arange(0,length)*0.1
    noiseY = makeNoise(length) #normalized to one already

    noiseF,noiseFFT = tf.genFFT(noiseX,noiseY)
    sigF,sigFFT = tf.genFFT(sigWaveX,sigWaveY)

    convolved = sigFFT+noiseFFT

    outX,outY = tf.genTimeSeries(sigF,convolved)

    outY /= np.std(outY)
    outY /= np.sqrt(length)


    if showPlots:
        fig,ax = lab.subplots(3,2)
        ax[0][0].plot(sigWaveX,sigWaveY,color="blue",label="signal")
        ax[0][0].legend()
        ax[2][0].plot(noiseX,noiseY,color="red",label="noise")
        ax[2][0].legend()
        ax[1][0].plot(outX,outY,color="purple",label="convolution")
        ax[1][0].legend()

        ax[0][1].plot(sigF,tf.calcLogMag(sigF,sigFFT),color="blue",label="signal")
        ax[0][1].legend()
        ax[2][1].plot(noiseF,tf.calcLogMag(noiseF,noiseFFT),color="red",label="noise")
        ax[2][1].set_ylim([-30,30])
        ax[2][1].legend()
        ax[1][1].plot(sigF,tf.calcLogMag(sigF,convolved),color="purple",label="convolution")
        ax[1][1].set_ylim([-30,30])
        ax[1][1].legend()
        fig.show()
        

    return outX,outY
def computeTF(inF, inFFT, outF, outFFT):
    """
    Generating the transfer function is always the same, so it gets its own class
    Comparable to "deconvwnr()" in matlab (nearly identical)
    
    It has a bunch of other things you can uncomment to use, but most end up being dumb
    """
    #then generate the transfer function!
    #In(f)*H(f) = Out(f) -> H(f) = Out(f)/In(f)
    tfFFT = np.divide(outFFT, inFFT)
    tfF = inF

    tfY = tf.fftw.irfft(tfFFT)

    #    print tfY

    tfX = np.arange(0, len(tfY)) * (1. / (2. * tfF[-1]))

    tfF, tfFFT = tf.genFFT(tfX, tfY)

    return tfX, tfY, tfF, tfFFT
Example #4
0
def HpolTransferFunctionAnalysis(pulse=False,respo=False,makeFigs=False):
    #import stuff
    if type(pulse)==bool and type(respo)==bool:
        print "type(pulse)"
        pulse = antChamberResponse(chamberRefPulse,channel=0)
        respo = antChamberResponse("/Volumes/BenANITA3Data/Anechoic_Chamber_New_Horn_Impulse/IdenticalAntennas/Ant2Blue_to_Ant0/HPol_Pulse/Impulse_p180Deg_t090Deg_16May2012_H.dat")

    #quickly making them have the same time steps
    pulseArgMax = np.argmax(pulse[1])
    respoArgMax = np.argmax(respo[1])
    offset = pulseArgMax - respoArgMax
    dT = (pulse[0][1] - pulse[0][0])
    pulseNewT = (np.arange(0,len(pulse[0]))-pulseArgMax)*dT
    respoNewT = (np.arange(0,len(respo[0]))-respoArgMax)*dT
    
    #make a quick plot of that
    if makeFigs==True:
        figInWaves = lab.figure(figsize=(16,8))
        axInWaves1 = figInWaves.add_subplot(111)
        axInWaves1.plot(pulseNewT,pulse[1],color="red",lw=1,alpha=0.6)
        axInWaves1.set_xlabel("Time (ns)")
        axInWaves1.set_ylabel("Input Pulse (V)",color="red")
        axInWaves1.set_title("HPol chamber input and output pulses")
        
        axInWaves2 = axInWaves1.twinx()
        axInWaves2.plot(respoNewT,respo[1],color="blue",lw=1,alpha=0.6)
        axInWaves2.set_ylabel("Recieved Pulse (V)",color="blue")
        axInWaves2.grid(b=True,which="major",color="white",linestyle="--")
        
        figInWaves.show()
        figInWaves.savefig("HpolBoresightWaveforms.png")

    #take the fourier transform
    pulseF,pulseFFT = tf.genFFT(pulseNewT,pulse)

    respoF,respoFFT = tf.genFFT(respoNewT,respo)

    #plot the log magnitude of that
    pulseLogMag = tf.calcLogMag(pulseF,pulseFFT)
    respoLogMag = tf.calcLogMag(respoF,respoFFT)

    if makeFigs == True:
        figLogMag = lab.figure(figsize=(16,8))
        axLogMag1 = figLogMag.add_subplot(111)
        axLogMag1.plot(pulseF,pulseLogMag,color="red",lw=1,alpha=0.6)
        axLogMag1.set_xlabel("Frequency (GHz)")
        axLogMag1.set_ylabel("Input Pulse (dBm)",color="red")
        axLogMag1.set_title("HPol chamber input and output spectral magnitude")
        
        axLogMag2 = axLogMag1.twinx()
        axLogMag2.plot(respoF,respoLogMag,color="blue",lw=1,alpha=0.6)
        axLogMag2.set_ylabel("Recieved Pulse (dBm)",color="blue")
        axLogMag2.grid(b=True,which="major",color="white",linestyle="--")
        
        figLogMag.show()
        figLogMag.savefig("HpolBoresightMagnitudes.png")

    #generate a transfer function
    transFFT = respoFFT/pulseFFT

    #Also cut off the top frequencies (since there isn't any power there)
    cutFraction = 4
    trans = tf.fftw.irfft(transFFT[:len(respo[0])/(cutFraction*2)+1])
    transNewT = respoNewT[::cutFraction]

    #it is phase aligned at zero and I want it to start in like 10a
    trans = np.roll(trans,len(respo[0])/10)

    if makeFigs == True:
        figTrans = lab.figure(figsize=(16,8))
        axTrans = figTrans.add_subplot(111)

        axTrans.plot(respoNewT[::4],trans)
        axTrans.set_xlabel("Time (ns)")
        axTrans.set_ylabel("Transfer Function (V)",color="black")
        axTrans.set_title("HPol Chamber Boresight Transfer Function")
        
        figTrans.show()
        figTrans.savefig("HpolBoresightTransferFunction.png")

    return transNewT,trans
Example #5
0
def ANITA3_chamberResponse(files=-1,rotate="phi",channel=1,eventAvgs=50):
    #imports and generates some arrays for angle, frequency, and spectral magnitude of
    # correlated and averaged waveforms in a series of chamber data

    #the defaults are for HPol rotating in phi, but you can do others.
    # channel==0 is Vpol and channel==1 is Hpol (I think)

    if files==-1:
        files = localFileList_ANITA3chamberHPol()

    freqs = []
    allFreqs = []
    mags = []
    allMags = []
    angles = []

    #params
    numFreqs = 25
    stop = 100 #~1GHz
    start = 2
    step = stop/float(numFreqs)

    sns.set_palette(sns.color_palette("husl",numFreqs))

    inPulse =  antChamberResponse(chamberRefPulse,channel=0)

    for file in files:
        events = importAll(file,channel=channel)
        print len(events)
        fftAvgs = len(events)/eventAvgs
        for fftAvgNum in range(0,fftAvgs):
            avgEvent = tf.correlateAndAverage(events[eventAvgs*fftAvgNum:eventAvgs*(fftAvgNum+1)])
            peak = np.argmax(np.abs(avgEvent[1])) + 500
            print "I'M CRAB V.v.V"
            procAvgEvent = processAllEvents([avgEvent],totalWidth=2000,peak=peak)[0]
            transFunc = HpolTransferFunctionAnalysis(pulse=inPulse,respo=procAvgEvent)
            #friis equation transforms to S21!  (Gr*Gt)/(4*pi*R/lambda)**2
            R=5.9
            f,fft = tf.genFFT(transFunc[0],transFunc[1])
            friis = (fft**2)/(4.*np.pi*R*f*3e8)**2
            logMag = tf.calcLogMag(f,friis*1000)
            if freqs == []:
                freqs = np.ceil(f[start:stop:step]/1e6)
                allFreqs = np.ceil(f[start:stop]/1e6)
            if fftAvgNum == 0:
                logMagAvg = logMag/fftAvgs
            else:
                logMagAvg += logMag/fftAvgs

        mags.append(logMagAvg[start:stop:step])
        allMags.append(logMagAvg[start:stop])

        if rotate=="phi":
            angles.append(file.split("/")[-1].split("_")[1][1:4])
        if rotate=="theta":
            angles.append(file.split("/")[-1].split("_")[2][1:4])

        print(len(freqs))

    lab.close("all")
    fig = lab.figure()
    ax = fig.add_subplot(111)
    for freqNum in range(0,numFreqs):
        curve = []
        for angleNum in range(0,len(angles)):
            curve.append(mags[angleNum][freqNum])
        curve = np.array(curve)-np.max(curve)
        ax.plot(angles,curve,label=freqs[freqNum])
        
    ax.legend()
    fig.show()

    return angles,allFreqs,allMags
Example #6
0
def offAngleLoop(file,inPulse,channel,antHeight=[]):

    """
    Theres a loop in doOffAngle that I want to split out

    antHeightFFT: boresight complex antenna height
    for identical antennas dont set this parameter and it will treat them as identical
    for rotated antennas, set this to the boresight complex antenna height and it will determine the rotated height

    """


    inPulseF,inPulseFFT = inPulse
    inPulseX,inPulseY = tf.genTimeSeries(inPulseF,inPulseFFT)

    if len(antHeight) != 0:
        antHeightF,antHeightFFT = antHeight
        antHeightX,antHeightY = tf.genTimeSeries(antHeightF,antHeightFFT)
    

    #import all the events from that file (it is stored with a ton of events in it)
    events = importAll(file,channel=channel)
    print "doOffAngle(): ",file," has number of events:",len(events)
    fftAvgs = len(events)/eventAvgs
    print "doOffAngle(): doing ",fftAvgs," fft averages"
    #so first I average together a bunch of events, then I average the FFTs of the transfer functions together?
    for fftAvgNum in range(0,fftAvgs):
        #get the averaged waveform
        avgEventX,avgEventY = tf.correlateAndAverage(events[eventAvgs*fftAvgNum:eventAvgs*(fftAvgNum+1)])
        avgEventX *= 1e9
        #also sampled too fast, so lets just do the FFT trick to downsample it again
        avgEventF,avgEventFFT = tf.genFFT(avgEventX,avgEventY)
        avgEventF   = avgEventF[:1001]
        avgEventFFT = avgEventFFT[:1001]
        avgEventX,avgEventY = tf.genTimeSeries(avgEventF,avgEventFFT)
        #it is also too long
        avgEventX = avgEventX[:1000]
        avgEventY = avgEventY[:1000]
        print len(avgEventX),len(avgEventY)
        avgEventF,avgEventFFT = tf.genFFT(avgEventX,avgEventY)
        print len(avgEventF),len(avgEventFFT)
        if debug:
            print "doOffAngle(): avgEvent length: ",len(avgEventX)," dT:",avgEventX[1]-avgEventX[0]
            if len(antHeight) != 0: print "doOffAngle(): antHeight length: ",len(antHeightX)," dT:",antHeightX[1]-antHeightX[0]
            print "doOffAngle(): inPulse length: ",len(inPulseX)," dT:",inPulseX[1]-inPulseX[0]
            
            print "doOffAngle(): avgEventFFT length: ",len(avgEventF),"/",len(avgEventFFT)," dF:",avgEventF[1]-avgEventF[0]
            if len(antHeight) != 0: print "doOffAngle(): antHeightFFT length: ",len(antHeightF),"/",len(antHeightFFT)," dF:",antHeightF[1]-antHeightF[0]
            print "doOffAngle(): inPulseFFT length: ",len(inPulseF),"/",len(inPulseFFT)," dF:",inPulseF[1]-inPulseF[0]
        #find its peak (with some offset for some reason)
        peak = np.argmax(np.abs(avgEventY[1])) + 500
        print "I'M CRAB V.v.V ",fftAvgNum #for fun

        #generate the transfer function
        if len(antHeight) == 0:
            transFuncF,transFuncFFT = doChamberIdenticalTF(avgEventF,avgEventFFT,inPulseFFT)
        else:
            transFuncF,transFuncFFT = doChamberRotatedTF(avgEventF,avgEventFFT,inPulseFFT,antHeightFFT)
        

        if fftAvgNum == 0:
            fftAvg = transFuncFFT/fftAvgs
        else:
            fftAvg += transFuncFFT/fftAvgs

    return transFuncF,fftAvg
Example #7
0
def doOffAngle(pol="H"):
    """
    April 2017

    Its been awhile since I worked with this, so I'm going to write a new function so I know it is right
    and I don't mess up any of the old stuff just in case

    This uses the complex antenna height generated with doPalAnt in transferFunctionFinal, as only one antenna
    was rotated, so they cannot be treated as identical and a single antenna needs to be deconvolved

    """


    #get a list of the files, which should be all the angles
    if pol=="H":
        files = localFileList_ANITA3chamberHPol()
        rotate="phi"
        channel = 1
    if pol=="V":
        files = localFileList_ANITA3chamberVPol()
        rotate="theta"
        channel = 0


    freqs = []
    allFreqs = []
    mags = []
    allMags = []
    angles = []

    #params for making contour plot
    numFreqs = 25
    stop = 100 #~1GHz
    start = 2
    step = stop/float(numFreqs)

    sns.set_palette(sns.color_palette("husl",numFreqs))


    #get the input pulse
    inPulseX,inPulseY =  antChamberResponse(chamberRefPulse,channel=0)
    #I'm doing things in nanoseconds so lets keep doing that
    inPulseX *= 1e9
    #also it is sampled too fast, so lets just do the FFT trick to downsample it
    inPulseF,inPulseFFT = tf.genFFT(inPulseX,inPulseY)
    inPulseF = inPulseF[:501]
    inPulseFFT = inPulseFFT[:501]
    inPulseX,inPulseY = tf.genTimeSeries(inPulseF,inPulseFFT)


    #get the complex antenna height from tff.doPalAnt's results
    #also note that I am cutting the end off so it is only 1000 points long
    # -> This doesn't work because the chamber measurements are shitty at low end so it messes the whole thing up
    palAntHeightX,palAntHeightY = np.loadtxt("/Users/brotter/benCode/impulseResponse/integratedTF/transferFunctions/antHeight_avg.txt")[:1000].T
    palAntHeightF,palAntHeightFFT = tf.genFFT(palAntHeightX,palAntHeightY)


    #grab the CHAMBER boresight and use that I guess
    boresight = files[4]
    antHeightF,antHeightFFT = offAngleLoop2(boresight,[inPulseF,inPulseFFT],channel)


    if debug:
        fig,ax = lab.subplots()
        ax.plot(antHeightF,tf.calcAntGain(antHeightF,antHeightFFT),label="chamber",color="red")
        ax.plot(palAntHeightF,tf.calcAntGain(palAntHeightF,palAntHeightFFT),label="palestine",color="blue")
        ax.set_xlabel("Frequency (GHz)")
        ax.set_ylabel("Antenna Gain (dBi)")
        ax.legend()
        fig.show()


    #loop over all the files
    for file in files:

        transFuncF,transFuncFFT = offAngleLoop2(file,[inPulseF,inPulseFFT],channel,antHeight=[antHeightF,antHeightFFT])

        logMagAvg = tf.calcAntGain(transFuncF,transFuncFFT)
        

        mags.append(logMagAvg)
        allMags.append(logMagAvg)


        if rotate=="phi":
            angles.append(file.split("/")[-1].split("_")[1][1:4])
        if rotate=="theta":
            angles.append(file.split("/")[-1].split("_")[2][1:4])




    return angles,transFuncF,allMags,tf.calcAntGain(antHeightF,antHeightFFT)