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
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
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
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
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
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
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