Beispiel #1
0
def average( names):
    """
    Compute an average spectrum from a list of input file names
    """

    rs = radioastronomy.Spectrum()   # create input and average structures
    asum = radioastronomy.Spectrum()
    nsum = 0

    # now average coldest data for calibration
    for filename in names:

        rs.read_spec_ast(filename)
        rs.azel2radec()    # compute ra,dec from az,el

        if nsum == 0:
            asum = copy.deepcopy( rs)
            firstlon = rs.gallon
            asum.ydataA = rs.ydataA * rs.durationSec
            asum.gallat = rs.gallat * rs.durationSec
            asum.gallon = rs.gallon * rs.durationSec
            nsum = 1
            firstutc = rs.utc
            lastutc = rs.utc
        else:
            asum.ydataA = asum.ydataA + (rs.ydataA * rs.durationSec)
            asum.count = asum.count + rs.count
            asum.durationSec = asum.durationSec + rs.durationSec
            # fix wrap of longitudes
            if abs(rs.gallon - firstlon) > 180:
                crossZero = True
                if rs.gallon > firstlon:
                    rs.gallon = rs.gallon - 360.
                else:
                    rs.gallon = rs.gallon + 360.
            asum.gallon = asum.gallon + (rs.gallon * rs.durationSec)
            asum.gallat = asum.gallat + (rs.gallat * rs.durationSec)
            # keep track of observing time for weighted sum
            lastutc = rs.utc
            nsum = nsum + 1
    #end for all files loop

    if nsum < 1:
        print "No acceptable files in average list"
    else:
        asum.ydataA = asum.ydataA/float(asum.durationSec)
        asum.gallon = asum.gallon/float(asum.durationSec)
        asum.gallat = asum.gallat/float(asum.durationSec)
        aveutc,duration = radioastronomy.aveutcs( firstutc, lastutc)
        asum.utc = aveutc
        if (duration < 1.):
            print 'hotcold.average: very short average interval: ',duration
    return nsum, asum
Beispiel #2
0
def normalize_spec(ave_spec, nave, firstutc, lastutc):
    """
    Normaize the average after completing sum
    input/output
    ave_spec   input raw sum of observation 
               output normalized sum of observations
    nave       input number of spectra averaged, output zero
    input      first and last utcs in observation
    Note:  The count of observations is not used, rather the integration
    is weighted by durations.  This corrects for observations with 
    different integration times.
    """
    # now renormalize for total integration time
    ave_spec.ydataA = ave_spec.ydataA / float(ave_spec.durationSec)
    # compute average time from first and last utcs
    aveutc, duration = radioastronomy.aveutcs(firstutc, lastutc)
    ave_spec.utc = aveutc
    #need to re-calculate representative RA,Dec for average time
    ave_spec.azel2radec()
    #    nave = 0
    return ave_spec, nave
Beispiel #3
0
    def work(self, input_items, output_items):
        """
        Work averages all input vectors and outputs one vector for each N inputs
        """
        inn = input_items[0]
        # get the number of input vectors
        nv = len(inn)  # number of vectors in this port
        spec = inn[0]  # first input vector
        li = len(spec)  # length of first input vector
        ncp = min(li, self.vlen)  # don't copy more required (not used)
        n6 = int(ncp / 6)
        n56 = 5 * n6

        if li != self.vlen:
            print 'spectrum length changed! %d => %d' % (self.vlen, li)
            self.vlen = li
            self.obs.xdata = np.zeros(li)
            self.obs.ydataA = np.zeros(li)
            self.obs.ydataB = np.zeros(li)
            self.set_frequency(self.obs.centerfrequencyHz)
            self.set_bandwidth(self.obs.bandwidthHz)
            return 1

        # define output vectors
        out = output_items[0]
        ave = output_items[1]
        hot = output_items[2]
        cold = output_items[3]
        ref = output_items[4]

        nout = 0
        for i in range(nv):
            now = datetime.datetime.utcnow()
            # get the length of one input
            spec = inn[i]
            # deal with average state
            if self.inttype == radioastronomy.INTWAIT:
                self.ave.ydataB = spec
                self.nintegrate = 1
                self.ave.ydataA = spec
                self.startutc = now
                self.obs.utc = now
                self.obs.count = self.obs.nmedian
            else:  # else averaging and maybe writing
                self.ave.ydataB = self.ave.ydataB + spec
                self.nintegrate = self.nintegrate + 1
                oneovern = 1. / np.float(self.nintegrate)
                self.ave.ydataA = oneovern * self.ave.ydataB
                # total number of spectra averaged
                # is the number medianed times the number averaged
                self.ave.count = self.obs.nmedian * self.nintegrate
                self.ave.utc, duration = radioastronomy.aveutcs(
                    self.startutc, now)
                self.ave.durationsec = duration
                # only record aveaged spectra
                # now, if updating hot, cold or references spectra
                # if saving files, must reload any configuration changes updated by the sinks
                if (self.inttype
                        == radioastronomy.INTSAVE) and (self.nintegrate % 20
                                                        == 1):
                    if self.obstype == radioastronomy.OBSHOT:
                        self.hot.read_spec_ast(
                            self.noteName)  # read the parameters
                    elif self.obstype == radioastronomy.OBSCOLD:
                        self.cold.read_spec_ast(
                            self.noteName)  # read the parameters
                    elif self.obstype == radioastronomy.OBSREF:
                        self.ref.read_spec_ast(
                            self.noteName)  # read the parameters
                if self.obstype == radioastronomy.OBSHOT:
                    self.hot.ydataA = np.maximum(self.ave.ydataA[0:self.vlen],
                                                 self.epsilons[0:self.vlen])
                    self.hot.nave = self.nintegrate
                    self.hot.count = self.ave.count
                    self.hot.utc = self.ave.utc
                    self.hot.durationsec = self.ave.durationsec
                    self.hot.ydataA[0:1] = self.hot.ydataA[2]
                elif self.obstype == radioastronomy.OBSCOLD:
                    self.cold.ydataA = np.maximum(self.ave.ydataA[0:self.vlen],
                                                  self.epsilons[0:self.vlen])
                    self.cold.nave = self.nintegrate
                    self.cold.count = self.ave.count
                    self.cold.utc = self.ave.utc
                    self.cold.durationsec = self.ave.durationsec
                    self.cold.ydataA[0:1] = self.cold.ydataA[2]
                elif self.obstype == radioastronomy.OBSREF:
                    self.ref.ydataA = np.maximum(self.ave.ydataA[0:self.vlen],
                                                 self.epsilons[0:self.vlen])
                    self.ref.nave = self.nintegrate
                    self.ref.count = self.ave.count
                    self.ref.utc = self.ave.utc
                    self.ref.durationsec = self.ave.durationsec
                    self.ref.ydataA[0:1] = self.ref.ydataA[2]
                # if writing files, reduce write rate
                if (self.inttype
                        == radioastronomy.INTSAVE) and (self.nintegrate % 20
                                                        == 1):
                    if self.obstype == radioastronomy.OBSHOT:
                        self.hot.write_ascii_file("./", HOTFILE)
                    elif self.obstype == radioastronomy.OBSCOLD:
                        self.cold.write_ascii_file("./", COLDFILE)
                    elif self.obstype == radioastronomy.OBSREF:
                        self.ref.write_ascii_file("./", REFFILE)
            # after flip, the first couple channels are anomoulusly large
            spec[0:1] = spec[2]
            self.ave.ydataA[0:1] = self.ave.ydataA[2]
            self.ave.nave = self.nintegrate
            # since the data rate should be low, nout will usually be 0
            # have all spectra, decide plot format
            if self.units == radioastronomy.UNITCOUNTS:
                out[nout] = spec
                ave[nout] = self.ave.ydataA
                hot[nout] = self.hot.ydataA
                cold[nout] = self.cold.ydataA
                ref[nout] = self.ref.ydataA
            elif self.units == radioastronomy.UNITDB:
                spec = np.maximum(spec, self.epsilons)
                self.ave.ydataA = np.maximum(self.ave.ydataA, self.epsilons)
                out[nout] = 10. * np.log10(spec)
                ave[nout] = 10. * np.log10(self.ave.ydataA)
                hot[nout] = 10. * np.log10(self.hot.ydataA)
                cold[nout] = 10. * np.log10(self.cold.ydataA)
                ref[nout] = 10. * np.log10(self.ref.ydataA)
            else:  # else need Kelvins
                hv = self.hot.ydataA[0:self.vlen]
                hv = np.maximum(hv, self.epsilons[0:self.vlen])
                cv = self.cold.ydataA[0:self.vlen]
                cv = np.maximum(cv, self.epsilons[0:self.vlen])
                yv = self.ave.ydataA[0:self.vlen]
                yv = np.maximum(yv, self.epsilons[0:self.vlen])
                # compute Kelvings per count factor
                tsys, trx = self.compute_thotcold(yv, hv, cv, self.thot,
                                                  self.tcold)
                TSYS = trx + self.thot
                # now compute center scalar value
                oneoverhot = np.full(self.vlen, 1.)
                oneoverhot = oneoverhot / hv
                # compute short term Tsys value
                outs = TSYS * spec * oneoverhot
                aves = tsys
                hot[nout] = np.full(self.vlen, TSYS + self.thot)
                colds = TSYS * self.cold.ydataA * oneoverhot
                cold[nout] = TSYS * self.cold.ydataA * oneoverhot
                refs = TSYS * self.ref.ydataA * oneoverhot
                if self.units == radioastronomy.UNITBASELINE:  # if subtracting a baseline
                    # select the channels at the edges
                    self.yfit = outs[self.xfit]
                    thefit = np.polyfit(self.xfit, self.yfit, 1)
                    outs = outs - ((self.xindex * thefit[0]) + thefit[1])
                    # now subtract fit from average
                    self.yfit = aves[self.xfit]
                    thefit = np.polyfit(self.xfit, self.yfit, 1)
                    aves = aves - ((self.xindex * thefit[0]) + thefit[1])
                    # now subtract fit from cold
                    self.yfit = colds[self.xfit]
                    thefit = np.polyfit(self.xfit, self.yfit, 1)
                    colds = colds - ((self.xindex * thefit[0]) + thefit[1])
                    # if subtracting fit, change reference role to
                    # short duration average; must recalculate
                    if self.nshort <= 0:
                        self.shortave = spec
                        self.nshort = 1
                    else:
                        self.shortave = self.shortave + spec
                        self.nshort = self.nshort + 1
                    if self.nshort >= self.maxshort:
                        self.shortlast = self.oneovermax * self.shortave
                        self.shortlast = TSYS * self.shortlast * oneoverhot
                        self.yfit = self.shortlast[self.xfit]
                        thefit = np.polyfit(self.xfit, self.yfit, 1)
                        temps = self.shortlast - (
                            (self.xindex * thefit[0]) + thefit[1])
                        # hanning smooth
                        refs = 2. * temps
                        refs[1:self.vlen - 1] += (temps[0:self.vlen - 2] +
                                                  temps[2:self.vlen])
                        refs = 0.25 * refs
                        # will keep showing last short reference until next is ready
                        self.shortlast = refs
                        self.nshort = 0  # restart sum on next cycle
                        print ""
                        print "New Ref"
                        print ""
                    else:
                        refs = self.shortlast
                    # end if subtracting baseline
                out[nout] = outs
                ave[nout] = aves
                ref[nout] = refs
                cold[nout] = colds
            # completed calibration, update count of output vectors
            nout = nout + 1

            self.stoputc = now
            dt = now - self.printutc
            # if time to print
            if dt.total_seconds() > self.printinterval:

                strnow = now.isoformat()
                datestr = strnow.split('.')
                daypart = datestr[0]
                yymmdd = daypart[2:19]
                avespec = ave[0]
                avespec = avespec[n6:n56]
                vmin = min(avespec)
                vmax = max(avespec)
                vmed = np.median(avespec)

                label = radioastronomy.unitlabels[self.units]
                if self.units == 0:
                    print "%s Max %9.3f Min: %9.3f Median: %9.3f %s " % (
                        yymmdd, vmax, vmin, vmed, label)
                elif self.units == 1:
                    print "%s Max %9.3f Min: %9.3f Median: %9.3f %s " % (
                        yymmdd, vmax, vmin, vmed, label)
                else:
                    print "%s Max %9.1f Min: %9.1f Median: %9.1f %s " % (
                        yymmdd, vmax, vmin, vmed, label)
                sys.stdout.write("\033[F")
                self.printutc = now
        # end for all input vectors
        return nout
Beispiel #4
0
        xmin = min(xv[xa:xb])
        xmax = max(xv[xa:xb])
        xallmin = min(xmin, xallmin)
        xallmax = max(xmax, xallmax)
        count = cold.count
        note = cold.noteA

        ncolor = min(nmax-1, nplot)  # select color for this spectrum
        tsky = compute_tsky_hotcold( yv, gain, velcorr, minvel, maxvel)
            
        ymin = min(tsky[xa:xb])
        ymax = max(tsky[xa:xb])
        yallmin = min(ymin,yallmin)
        yallmax = max(ymax,yallmax)
        # compute average time from first and last utcs
        aveutc,duration = radioastronomy.aveutcs( firstutc, lastutc)
        if doDebug and (firstutc == lastutc):
            print("first and last utcs are the same: ", firstutc)
        # keep the average time, but use the duration from the integration times.
        cold.utc = aveutc 
            # pull out coordinates for labeling
        az = cold.telaz
        el = cold.telel
        cold.azel2radec()    # compute ra,dec from az,el and average utc
        gallon = cold.gallon
        gallat = cold.gallat

        tSys = np.median(tsky[xa:xb])
        tStdA = np.std(tsky[(xa-nFit):xa])
        tStdB = np.std(tsky[xb:(xb+nFit)])
        tStd = (tStdA+tStdB)/.2
Beispiel #5
0
    def work(self, input_items, output_items):
        """
        Work averages all input vectors and outputs one vector for each N inputs
        """
        inn = input_items[0]

        # get the number of input vectors
        nv = len(inn)  # number of vectors in this port
        spec = inn[0]  # first input vector
        li = len(spec)  # length of first input vector
        ncp = min(li, self.vlen)  # don't copy more required (not used)
        t = 0

        if li != self.vlen:
            print 'spectrum length changed! %d => %d' % (self.vlen, li)
            self.vlen = li
            self.obs.xdata = np.zeros(li)
            self.obs.ydataA = np.zeros(li)
            self.obs.ydataB = np.zeros(li)
            self.set_frequency(self.obs.centerfrequencyHz)
            self.set_bandwidth(self.obs.bandwidthHz)
            return 1

        noutports = len(output_items)
        if noutports != 1:
            print '!!!!!!! Unexpected number of output ports: ', noutports
        out = output_items[0]  # all vectors in PORT 0

        iout = 0  # count the number of output vectors
        for i in range(nv):
            # get the length of one input
            spec = inn[i]
            # if just starting a sum
            if self.avecount == 0:
                self.sum = spec
                self.average_done = self.dt
            else:
                # else add to sum
                self.average_done = self.average_done + self.dt
                self.sum = self.sum + spec
#            print 'Done: ', self.average_done
            self.avecount = self.avecount + 1
            # if still averaging, continue
            if self.avecount < self.nave:
                continue
            # else average is complete
            now = datetime.datetime.utcnow()
            self.stoputc = now
            middle, duration = radioastronomy.aveutcs(self.startutc,
                                                      self.stoputc)
            self.obs.utc = middle
            self.obs.durationSec = duration
            # this removes component due non-gain part of spectrum
            self.obs.ydataA[0:ncp] = self.sum[0:ncp]
            self.obs.azel2radec()
            strnow = middle.isoformat()
            datestr = strnow.split('.')
            daypart = datestr[0]
            yymmdd = daypart[2:19]
            if self.record != radioastronomy.INTWAIT:
                print 'Record Duration  : %7.2fs (Expected %7.2fs)' % (
                    duration, self.average_sec)
                if duration < .8 * self.average_sec:
                    print 'Duration too short, not saving'
                    self.startutc = now
                    self.avecount = 0
                    continue
                # distinguish hot load and regular observations
                if self.obstype == radioastronomy.OBSREF:
                    outname = yymmdd + '.ref'
                else:
                    if self.obs.telel > 0:
                        outname = yymmdd + '.ast'
                    else:
                        outname = yymmdd + '.hot'
                #remove : from time
                outname = outname.replace(":", "")

                self.obs.writecount = self.obs.writecount + 1
                # need to keep track of total number of spectra averaged
                tempcount = self.obs.count
                self.obs.count = self.obs.count * self.nave
                self.obs.write_ascii_file(self.obs.datadir, outname)
                print('\a')  # ring the terminal bell
                # must restore the count for possible changes in nave
                self.obs.count = tempcount
            else:
                # else not recording, plenty of time to compute data statistics
                n6 = int(ncp / 6)
                n56 = 5 * n6
                vmin = min(spec[n6:n56])
                vmax = max(spec[n6:n56])
                vmed = np.median(spec[n6:n56])
                print "%s:  Max %9.3f Min: %9.3f Median: %9.3f      " % (
                    yymmdd, vmax, vmin, vmed)
                # move backwards to replace previous message
                sys.stdout.write("\033[F")
                self.obs.writecount = 0
            # if here data written, restart sum
            self.avecount = 0
            self.startutc = now

        out[:] = self.average_sec - self.average_done
        iout = iout + 1

        # end for all input vectors
        if (nv != iout):
            print 'Accumulation error:  ', nv, iout
        return iout
Beispiel #6
0
def findzero( names, gain, vel, azoffset, eloffset, avetimesec):
    lastgain = 0.
    global nprint
    # flag start of search for a latitude zero crossing
    ncrossings = -1
    crossingsum = 0.
    lastgallat = -100.
    lastsum = 0.

    nData = len(vel)
    minGlat = +90.
    maxGlat = -90.
    nhot = 0         # number of obs with el < 0
    ncold = 0
    nhigh = 0        # highest galactic latitude
    lastfreq = 0.
    lastbw = 0.
    lastgain = 0.
    lastel = 0.
    lastaz = 0.
    firstrun = True

    avetime = datetime.timedelta(seconds=avetimesec)
    firstgallon = -1.
    ncrossings = 0

    nread = 0        
# now read through all data and average cold sky obs
    for filename in names:

        parts = filename.split('/')
        nparts = len(parts)
        aname = parts[nparts-1]
        parts = aname.split('.')
        aname = parts[0]
        extension = parts[1]
        parts = aname.split('T')
        date = parts[0]
        time = parts[1]
        time = time.replace('_', ':')  # put time back in normal hh:mm:ss format

# exclude hot load data for averaging
        if extension == 'hot':
            continue

        rs = radioastronomy.Spectrum()
#  print filename
        rs.read_spec_ast(filename)
        rs.telaz = rs.telaz + azoffset
        rs.telel = rs.telel + eloffset
        rs.azel2radec()    # compute ra,dec from az,el

# if a sky observation and close to galactic plane
        if rs.telel > 0. and (rs.gallat > -5.0 and rs.gallat < 5.0) :

# if first time reading data, set obs parameters
            if lastfreq == 0.:
                lastfreq = rs.centerFreqHz 
                lastbw = rs.bandwidthHz
                lastgain = rs.gains[0]
                lastaz = rs.telaz
                lastel = rs.telel
                cold = copy.deepcopy( rs)
                ncold = 0
                timesum = 0.
                firstutc = cold.utc
                lastutc = cold.utc

            newAzEl = (lastaz != rs.telaz) or (lastel != rs.telel)
            if newAzEl and nprint < 5:
                print 'Must keep az,el constant to find pointing offsets!'
                print 'Last %7.2f,%7.2f; New: %7.2f,%7.2f' % (lastaz, lastel, rs.telaz, rs.telel)
                lastaz = rs.telaz
                lastel = rs.telel
                nprint = nprint + 1
                break

            if ncold > 1:
            # time difference is between mid-points of integrations
                dt = rs.utc - cold.utc 
            # add the time since midpoint of latests
                dt = dt + datetime.timedelta(seconds=rs.durationSec)
                lastutc = rs.utc

           # if time to average (or end of all files)
                if (dt > avetime) or (filename == sys.argv[nargs-1]):
                    cold.ydataA = cold.ydataA/float(timesum)
                # have complicated steps to simple get the average time.
                    deltatime = endtime - starttime
                    aveutc,duration = radioastronomy.aveutcs( firstutc, lastutc)
                    cold.utc = aveutc
                    cold.azel2radec() # recompute coordinates for average time
                    ra = cold.ra
                    dec = cold.dec
                    gallat = cold.gallat
                    gallon = cold.gallon

                    if ncrossings < 0:
                        lastgallat = gallat
                        ncrossings = 0
                        crossingsum = 0.
                        
                    xv = cold.xdata * 1.E-6
                    yv = cold.ydataA * scalefactor
                    yv = interpolate.lines( linelist, linewidth, xv, yv) # interpolate rfi
                    xmin = min(xv)
                    xmax = max(xv)
                    count = cold.count
                    note = cold.noteA
                    #print('%s' % note)
                    ncolor = min(nmax-1, nplot) 
                
                    tsky  = np.zeros(nData)    # initialize arrays
                    for jjj in range (0, nData):
                        tsky[jjj] = yv[jjj]/gain[jjj]
                        
                    imin, imax = velocity_to_indicies( vel, minvel, maxvel)
                    
                    ymed = np.median(tsky[imin:imax])
                    ya = np.median(tsky[(imin-10):(imin+10)])
                    yb = np.median(tsky[(imax-10):(imax+10)])
                    slope = (yb-ya)/(imax-imin)
                    nFit = 20
                    baseline = fit_baseline( vel, tsky, imin, imax, nFit)
                    tsky = tsky - baseline

                    ymin = min(tsky[imin:imax])
                    ymax = max(tsky[imin:imax])
                    thesum = compute_sum( minvel, maxvel, ra, dec, gallon, gallat, vel, tsky, ncold)
                    
                # finallly if this is a latitude crossing sum.
                    if ((lastgallat < 0. and gallat > 0.) or (lastgallat > 0. and gallat < 0.)) and lastgallat > -100.:
                        if abs(gallat) < 5.:
                    # if first crossing, init sum
                            if ncrossings == 0:
                                ncrossings = 1
                                crossingsum = thesum 
#                                print 'Zero Latitude: %7.1f %7.1f: %10.0f, %10.0f' % (lastgallat, gallat, lastsum, thesum)
                            else:
                                # else average crossings
                                ncrossings = ncrossings + 1
                                crossingsum = crossingsum + thesum 
                        if abs(lastgallat) < 5.:
                            if ncrossings == 0:
                                ncrossings = 1
                                crossingsum = lastsum
#                                print 'Zero Latitude: %7.1f %7.1f: %10.0f, %10.0f' % (lastgallat, gallat, lastsum, thesum)
                            else:
                                # else average crossings
                                ncrossings = ncrossings + 1
                                crossingsum = crossingsum + lastsum 

                    lastgallat = gallat
                    lastsum = thesum
                    # computation done, start sum over gain
                    ncold = 0

# if this was a new obs; restart the sums
            if ncold == 0:
                cold = copy.deepcopy(rs)  # initial spectrum is one just read
                starttime = cold.utc
                endtime = starttime
                ncold = 1
            # sums are weighted by durations
                crossZero = False
                crossZeroLat = False
                crossZeroRa = False
                firstlon = rs.gallon # try to keep track of crossing zero in angular coordinates
                firstra = rs.ra #
                cold.ydataA = rs.ydataA * cold.durationSec
            # keep track of observing time for weighted sum
                timesum = rs.durationSec
            else: # else not enough time yet, average cold data
                # fix wrap of longitudes
                cold.count = cold.count + rs.count
                ncold = ncold + 1
                cold.ydataA = cold.ydataA + (rs.ydataA * rs.durationSec)
                cold.ra = cold.ra + (rs.ra * cold.durationSec)
                cold.dec = cold.dec + (rs.dec * cold.durationSec)
                cold.gallon = cold.gallon + (rs.gallon * rs.durationSec)
                cold.gallat = cold.gallat + (rs.gallat * rs.durationSec)
            # keep track of observing time for weighted sum
                endtime = rs.utc
                timesum = timesum + rs.durationSec
            # end if not a enough time
        # end if a cold file
    #end for all files to sum

    if ncrossings > 0:
        crossingsum = crossingsum/float(ncrossings)
    return crossingsum
Beispiel #7
0
    def work(self, input_items, output_items):
        """
        Work averages all input vectors and outputs one vector for each N inputs
        """
        inn = input_items[0]
        # get the number of input vectors
        nv = len(inn)  # number of vectors in this port
        spec = inn[0]  # first input vector
        li = len(spec)  # length of first input vector
        ncp = min(li, self.vlen)  # don't copy more required (not used)
        n6 = int(ncp / 6)
        n56 = 5 * n6

        if li != self.vlen:
            print 'spectrum length changed! %d => %d' % (self.vlen, li)
            self.vlen = li
            self.obs.xdata = np.zeros(li)
            self.obs.ydataA = np.zeros(li)
            self.obs.ydataB = np.zeros(li)
            self.set_frequency(self.obs.centerfrequencyHz)
            self.set_bandwidth(self.obs.bandwidthHz)
            return 1

        noutports = len(output_items)
        if noutports != NSPEC:
            print '!!!!!!! Unexpected number of output ports: ', noutports

        # define output vectors
        out = output_items[0]
        ave = output_items[1]
        hot = output_items[2]
        cold = output_items[3]
        ref = output_items[4]

        nout = 0
        li2 = 2
        li20 = int(li / 20)
        li1920 = 19 * li20
        linm2 = li - li2
        for i in range(nv):
            now = datetime.datetime.utcnow()
            # get the length of one input
            spec = inn[i]
            #           attempt to remove DC bias, but seems to be more due to insufficient gain
            #            beginvalue = np.min(spec[li2:li20])
            #            endvalue = np.min(spec[li1920:linm2])
            #            minvalue = (beginvalue+endvalue)*.5
            # now subtract the DC bias
            #            spec = spec - np.full(self.vlen, minvalue)
            # deal with average state
            if self.inttype == radioastronomy.INTWAIT:
                self.ave.ydataB = spec
                self.nintegrate = 1
                self.ave.ydataA = spec
                self.startutc = now
                self.obs.utc = now
                self.obs.count = self.obs.nmedian
            else:  # else averaging and maybe writing
                self.ave.ydataB = self.ave.ydataB + spec
                self.nintegrate = self.nintegrate + 1
                oneovern = 1. / np.float(self.nintegrate)
                self.ave.ydataA = oneovern * self.ave.ydataB
                # total number of spectra averaged
                # is the number medianed times the number averaged
                self.ave.count = self.obs.nmedian * self.nintegrate
                self.ave.utc, duration = radioastronomy.aveutcs(
                    self.startutc, now)
                self.ave.durationsec = duration
                # only record aveaged spectra
                # now, if updating hot, cold or references spectra
                # if saving files, must reload any configuration changes updated by the sinks
                if (self.inttype
                        == radioastronomy.INTSAVE) and (self.nintegrate % 20
                                                        == 1):
                    if self.obstype == radioastronomy.OBSHOT:
                        self.hot.read_spec_ast(
                            self.noteName)  # read the parameters
                    elif self.obstype == radioastronomy.OBSCOLD:
                        self.cold.read_spec_ast(
                            self.noteName)  # read the parameters
                    elif self.obstype == radioastronomy.OBSREF:
                        self.ref.read_spec_ast(
                            self.noteName)  # read the parameters
                if self.obstype == radioastronomy.OBSHOT:
                    self.hot.ydataA = np.maximum(self.ave.ydataA[0:self.vlen],
                                                 self.epsilons[0:self.vlen])
                    self.hot.nave = self.nintegrate
                    self.hot.count = self.ave.count
                    self.hot.utc = self.ave.utc
                    self.hot.durationsec = self.ave.durationsec
                elif self.obstype == radioastronomy.OBSCOLD:
                    self.cold.ydataA = np.maximum(self.ave.ydataA[0:self.vlen],
                                                  self.epsilons[0:self.vlen])
                    self.cold.nave = self.nintegrate
                    self.cold.count = self.ave.count
                    self.cold.utc = self.ave.utc
                    self.cold.durationsec = self.ave.durationsec
                elif self.obstype == radioastronomy.OBSREF:
                    self.ref.ydataA = np.maximum(self.ave.ydataA[0:self.vlen],
                                                 self.epsilons[0:self.vlen])
                    self.ref.nave = self.nintegrate
                    self.ref.count = self.ave.count
                    self.ref.utc = self.ave.utc
                    self.ref.durationsec = self.ave.durationsec
                # if writing files, reduce write rate
                if (self.inttype
                        == radioastronomy.INTSAVE) and (self.nintegrate % 20
                                                        == 1):
                    if self.obstype == radioastronomy.OBSHOT:
                        self.hot.write_ascii_file("./", HOTFILE)
                    elif self.obstype == radioastronomy.OBSCOLD:
                        self.cold.write_ascii_file("./", COLDFILE)
                    elif self.obstype == radioastronomy.OBSREF:
                        self.ref.write_ascii_file("./", REFFILE)
#                    else:
#                        self.ave.write_ascii_file( "./", AVEFILE)
# after flip, the first couple channels are anomoulusly large
            spec[0:1] = spec[2]
            self.ave.ydataA[0:1] = self.ave.ydataA[2]
            self.hot.ydataA[0:1] = self.hot.ydataA[2]
            self.cold.ydataA[0:1] = self.cold.ydataA[2]
            self.ref.ydataA[0:1] = self.ref.ydataA[2]
            self.ave.nave = self.nintegrate
            # since the data rate should be low, nout will usually be 0
            # now have all spectra, decide plot format
            if self.units == radioastronomy.UNITCOUNTS:
                out[nout] = spec
                ave[nout] = self.ave.ydataA
                hot[nout] = self.hot.ydataA
                cold[nout] = self.cold.ydataA
                ref[nout] = self.ref.ydataA
            elif self.units == radioastronomy.UNITDB:
                spec = np.maximum(spec, self.epsilons)
                self.ave.ydataA = np.maximum(self.ave.ydataA, self.epsilons)
                out[nout] = 10. * np.log10(spec)
                ave[nout] = 10. * np.log10(self.ave.ydataA)
                hot[nout] = 10. * np.log10(self.hot.ydataA)
                cold[nout] = 10. * np.log10(self.cold.ydataA)
                ref[nout] = 10. * np.log10(self.ref.ydataA)
            elif self.units == radioastronomy.UNITKELVIN:
                hv = self.hot.ydataA[0:self.vlen]
                hv = np.maximum(hv, self.epsilons[0:self.vlen])
                cv = self.cold.ydataA[0:self.vlen]
                cv = np.maximum(cv, self.epsilons[0:self.vlen])
                yv = self.ave.ydataA[0:self.vlen]
                yv = np.maximum(yv, self.epsilons[0:self.vlen])
                tsys, trx = self.compute_thotcold(yv, hv, cv, self.thot,
                                                  self.tcold)
                TSYS = trx + self.thot
                # now compute center scalar value
                oneoverhot = np.full(self.vlen, 1.)
                oneoverhot = oneoverhot / hv
                out[nout] = TSYS * spec * oneoverhot
                ave[nout] = tsys
                hot[nout] = np.full(self.vlen, TSYS + self.thot)
                cold[nout] = TSYS * self.cold.ydataA * oneoverhot
                ref[nout] = TSYS * self.ref.ydataA * oneoverhot

            # completed calibration, update count of output vectors
            nout = nout + 1

            # update length to copy
            self.stoputc = now
            strnow = now.isoformat()
            datestr = strnow.split('.')
            daypart = datestr[0]
            yymmdd = daypart[2:19]
            avespec = ave[0]
            avespec = avespec[n6:n56]
            vmin = min(avespec)
            vmax = max(avespec)
            vmed = np.median(avespec)

            label = radioastronomy.unitlabels[self.units]
            dt = now - self.printutc
            if dt.total_seconds() > self.printinterval:

                if self.units == 0:
                    print "%s Max %9.3f Min: %9.3f Median: %9.3f %s " % (
                        yymmdd, vmax, vmin, vmed, label)
                elif self.units == 1:
                    print "%s Max %9.3f Min: %9.3f Median: %9.3f %s " % (
                        yymmdd, vmax, vmin, vmed, label)
                else:
                    print "%s Max %9.1f Min: %9.1f Median: %9.1f %s " % (
                        yymmdd, vmax, vmin, vmed, label)
                sys.stdout.write("\033[F")
                self.printutc = now
        # end for all input vectors
        return nout
    def work(self, input_items, output_items):
        """
        Work averages all input vectors and outputs one vector for each N inputs
        """
        inn = input_items[0]
        
        # get the number of input vectors
        n = len( input_items)  # number of input PORTS (only 1)
        nv = len(inn)          # number of vectors in this port
        spec = inn[0]          # first input vector
        li = len(spec)          # length of first input vector
        ncp = min( li, self.vlen)  # don't copy more required (not used)

        if (li != self.vlen):
            print 'spectrum length changed! %d => %d' % ( self.vlen, li)
            self.vlen = li
            self.xdata = np.zeros(li)
            self.ydataA = np.zeros(li)
            self.ydataB = np.zeros(li)
            self.set_frequency( self.obs.centerfrequencyHz)
            self.set_bandwidth( self.obs.bandwidthHz)
            return 1

        noutports = len( output_items)
        if noutports != 0:
            print '!!!!!!! Unexpected number of output ports: ', noutports

        iout = 0 # nmedian the number of output vectors
        for i in range(nv):
            # get the length of one input
            spec = inn[i]
            endvalue = np.median( spec[(ncp-7):(ncp-1)])
            # remove dc bias, measured at end of spectrum
            spec = spec - np.full( self.vlen, endvalue)
            # if just starting a sum
            if self.avecount == 0:
                self.sum = spec
            else:
                # else add to sum
                self.sum = self.sum + spec
            self.avecount = self.avecount + 1
            # if still averaging, continue
            if self.avecount < self.nave:
                continue
            # else average is complete
            now = datetime.datetime.utcnow()
            self.stoputc = now
            middle, duration = radioastronomy.aveutcs( self.startutc, self.stoputc)
            self.obs.utc = middle
            self.obs.durationSec = duration
            tsamples = self.obs.count * self.nave * float(self.obs.nChan) / self.obs.bandwidthHz
            # this removes component due non-gain part of spectrum
            self.obs.ydataA[0:ncp] = self.sum[0:ncp]
            self.obs.azel2radec()
            strnow = middle.isoformat()
            datestr = strnow.split('.')
            daypart = datestr[0]
            yymmdd = daypart[2:19]
            if self.record != radioastronomy.INTWAIT: 
                print 'Record Duration  : %7.2fs (Expected %7.2fs)' % (duration, tsamples)
                if duration < .8 * tsamples:
                    print 'Duration too short, not saving'
                    self.startutc = now
                    self.avecount = 0
                    continue
                # distinguish hot load and regular observations
                if self.obstype == radioastronomy.OBSREF:
                    outname = yymmdd + '.ref'
                else:
                    if self.obs.telel > 0:
                        outname = yymmdd + '.ast'
                    else:
                        outname = yymmdd + '.hot'
                #remove : from time
                outname = outname.replace(":", "")
                
                self.obs.writecount = self.obs.writecount + 1
                # need to keep track of total number of spectra averaged
                tempcount = self.obs.count
                self.obs.count = self.obs.count * self.nave
                self.obs.write_ascii_file( self.obs.datadir, outname)
                # must restore the count for possible changes in nave
                self.obs.count = tempcount
            else:
                # else not recording, plenty of time to compute data statistics
                n6 = int(ncp/6)
                n56 = 5*n6
                vmin = min ( spec[n6:n56])
                vmax = max ( spec[n6:n56])
                vmed = np.median( spec[n6:n56])
                print "%s:  Max %9.3f Min: %9.3f Median: %9.3f " % (yymmdd, vmax, vmin, vmed)
                self.obs.writecount = 0 
            # if here data written, restart sum
            self.avecount = 0
            self.startutc = now
              
        # end for all input vectors
        return 1