def make_beam(lats,lons,alts,spec_raw,lat0=0.0,lon0=0.0, nsides=8,volts=False,normalize=False,freq_chan=0): # Convert lat/lon to x/y x,y = latlon2xy(lats,lons,lat0,lon0) # Obtain spherical coordinates for x, y, and alt rs,thetas,phis = to_spherical(x,y,alts) #freq_chan = np.argmax(spec_raw[0,:]) # Only extract information from appropriate column (index = 10) if len(spec_raw.shape)>1: z = spec_raw[:,freq_chan].copy() else: z=spec_raw.copy() if volts: # Distance normalization r0 = 100 # reference position for distance normalization (unit: meters) z = 10*np.log10((2*z**2)*(rs/r0)**2) if normalize: z -= z.max() # Scaled on [-infty,0] # Set binsize (used in function grid_data) # Affects the apparent size of the pixels on the plot created below. binsize=5 # Obtain gridded data grid,bins,rmsBins,binloc,xg,yg,gcounts,grms = grid_data(x,y,z,binsize=binsize) # Healpix things nPixels = hp.nside2npix(nsides) hpx_beam = np.zeros(nPixels) hpx_counts = np.zeros(nPixels) hpx_rms = np.zeros(nPixels) # Find pixel # for a given theta and phi pixInd = hp.ang2pix(nsides,thetas,phis,nest=False) # Set pixel values at pixInd to power values hpx_beam[pixInd] = z hpx_counts[pixInd] = gcounts hpx_rms[pixInd] = grms # Grey out pixels with no measurements hpx_beam[hpx_beam == 0] = np.nan hpx_counts[hpx_counts == 0] = np.nan hpx_rms[hpx_rms == 0] = np.nan return np.ma.masked_invalid(hpx_beam),\ np.ma.masked_invalid(hpx_counts),\ np.ma.masked_invalid(hpx_rms)
def grid_to_healpix(lats,lons,alts,rx,lat0,lon0,nside=8): """ input: lats (deg) lons (deg) alts (m) (relative) rx: power in dB lat0: lat of rx ant (deg) lon0: lon of rx ant nside: of healpix map """ # Convert lat/lon to x/y x,y = latlon2xy(lats,lons,lat0,lon0) # Obtain spherical coordinates for x, y, and alt rs,thetas,phis = to_spherical(x,y,alts) pixes = hp.ang2pix(nside,thetas,phis) beam = np.zeros(hp.nside2npix(nside)) rms = np.zeros(hp.nside2npix(nside)) counts = np.zeros(hp.nside2npix(nside)) for i,pix in enumerate(pixes): beam[pix] += rx[i] rms[pix] += rx[i]**2 counts[pix] += 1 beam[counts>0] /= counts[counts>0] rms[counts>0] /= counts[counts>0] rms -= beam**2 rms = np.sqrt(rms) beam[counts==0] = hp.UNSEEN counts[counts==0] = hp.UNSEEN rms[counts==0] = hp.UNSEEN #the standard deviation is uncertain for small counts #the the error in the standard deviation goes as 1/sqrt(2(N-1)) #lets inflate the reported error to report the worst case upper limit #print 'Inflating error bars for low number counts' rms *= (1+1./np.sqrt(2*(counts-1))) return beam,rms,counts