def setLevel1(self, datafile, source=''): """ """ self.setSource(source) self.teleLon = self.datafile['hk/antenna0/tracker/siteActual'][ 0, 0] / (60.**2 * 1000.) self.teleLat = self.datafile['hk/antenna0/tracker/siteActual'][ 0, 1] / (60.**2 * 1000.) self.datafile = datafile self.attributes = self.datafile['comap'].attrs self.tsamp = float(self.attributes['tsamp'].decode()) self.obsid = self.attributes['obsid'].decode() self.source = self.attributes['source'].decode() # load but do not read yet. self.x = self.datafile['spectrometer/pixel_pointing/pixel_ra'] self.y = self.datafile['spectrometer/pixel_pointing/pixel_dec'] self.utc = self.datafile['spectrometer/MJD'] sunra, sundec, sundist = Coordinates.getPlanetPosition('Sun', self.teleLon, self.teleLat, self.utc[:], returnall=True) sunra, sundec = Coordinates.precess(sunra, sundec, self.utc[:]) pa = Coordinates.pa(sunra, sundec, self.utc, self.teleLon, self.teleLat) for i in range(self.x.shape[0]): self.x[i, :], self.y[i, :] = Coordinates.Rotate( self.x[i, :], self.y[i, :], sunra, sundec, -pa) self.xCoordinateName = r'$\Delta$A' self.yCoordinateName = r'$\Delta$E' self.el = self.datafile['spectrometer/pixel_pointing/pixel_el'] self.tod_bavg = self.datafile['spectrometer/band_average'] self.features = self.datafile['spectrometer/features'][:] self.mask = np.ones(self.features.size).astype(int) self.mask[self.featureBits(self.features.astype(float), 13)] = 0 self.mask[self.features == 0] = 0 self.mask = self.mask.astype(int) # If we don't spe self.setCrval() self.setWCS(self.crval, self.cdelt, self.crpix, self.ctype)
def create_maps(self, data, tod, filters, sel): """ Bin maps into instrument frame centred on source """ mjd = data['level1/spectrometer/MJD'][:] # We do Jupiter in the Az/El frame but celestial in sky frame #if self.source.upper() == 'JUPITER': az = data['level1/spectrometer/pixel_pointing/pixel_az'][:] el = data['level1/spectrometer/pixel_pointing/pixel_el'][:] N = az.shape[1] // 2 * 2 daz = np.gradient(az[0, :]) * 50. daz = daz[sel] az = az[:, sel] el = el[:, sel] cw = daz > 1e-2 ccw = daz < 1e-2 mjd = mjd[sel] npix = self.Nx * self.Ny temp_maps = { 'map': np.zeros(npix, dtype=np.float64), 'cov': np.zeros(npix, dtype=np.float64) } maps = { 'map': np.zeros( (tod.shape[0], tod.shape[1], tod.shape[2], self.Nx, self.Ny)), 'cov': np.zeros( (tod.shape[0], tod.shape[1], tod.shape[2], self.Nx, self.Ny)) } feed_avg = { 'map': np.zeros((tod.shape[0], self.Nx, self.Ny)), 'cov': np.zeros((tod.shape[0], self.Nx, self.Ny)) } scan_maps = { 'CW': { 'map': np.zeros((self.Nx, self.Ny)), 'cov': np.zeros((self.Nx, self.Ny)) }, 'CCW': { 'map': np.zeros((self.Nx, self.Ny)), 'cov': np.zeros((self.Nx, self.Ny)) } } azSource, elSource, raSource, decSource = Coordinates.sourcePosition( self.source, mjd, self.lon, self.lat) self.src_el = np.mean(elSource) self.src_az = np.mean(azSource) for ifeed in tqdm(self.feedlist, desc=f'{self.name}:create_maps:{self.source}'): feed_tod = tod[ifeed, ...] #if self.source.upper() == 'JUPITER': x, y = Coordinates.Rotate(azSource, elSource, az[ifeed, :], el[ifeed, :], 0) pixels, pX, pY = self.getpixels(x, y, self.dx, self.dy, self.Nx, self.Ny) mask = np.ones(pixels.size, dtype=int) for isb in range(tod.shape[1]): for ichan in range(1, tod.shape[2] - 1): # Always skip edges for k in temp_maps.keys(): temp_maps[k][:] = 0. z = (feed_tod[isb, ichan, sel] - filters[ifeed, isb, ichan]) mask[:] = 1 mask[(pixels == -1) | np.isnan(z) | np.isinf(z)] = 0 if np.sum(np.isfinite(z)) == 0: continue rms = stats.AutoRMS(z) weights = { 'map': z.astype(np.float64) / rms**2, 'cov': np.ones(z.size) / rms**2 } for k in temp_maps.keys(): binFuncs.binValues(temp_maps[k], pixels, weights=weights[k], mask=mask) maps[k][ifeed, isb, ichan, ...] = np.reshape(temp_maps[k], (self.Ny, self.Nx)) feed_avg[k][ifeed, ...] += np.reshape(temp_maps[k], (self.Ny, self.Nx)) if (ifeed == 0): for (key, direction) in zip(['CW', 'CCW'], [cw, ccw]): for k in temp_maps.keys(): temp_maps[k][:] = 0. binFuncs.binValues( temp_maps[k], pixels[direction], weights=weights[k][direction], mask=mask[direction]) scan_maps[key][k] += np.reshape( temp_maps[k], (self.Ny, self.Nx)) xygrid = np.meshgrid( (np.arange(self.Nx) + 0.5) * self.dx - self.Nx * self.dx / 2., (np.arange(self.Ny) + 0.5) * self.dy - self.Ny * self.dy / 2.) feed_avg['xygrid'] = xygrid maps['xygrid'] = xygrid feed_avg = self.average_maps(feed_avg) for key in scan_maps.keys(): scan_maps[key] = self.average_maps(scan_maps[key]) scan_maps[key]['xygrid'] = xygrid map_axes = np.array([a for a in maps['map'].shape]) map_axes[2] = int(map_axes[2] / self.binwidth) map_axes = np.insert(map_axes, 3, self.binwidth) maps['map'] = np.nansum(np.reshape(maps['map'], map_axes), axis=3) maps['cov'] = np.nansum(np.reshape(maps['cov'], map_axes), axis=3) maps = self.average_maps(maps) self.map_freqs = np.mean(np.reshape( data[f'{self.level2}/frequency'][...], map_axes[1:4]), axis=-1) return maps, feed_avg, scan_maps
def MakeMap(self, tod, ra, dec, mjd, el): #takes a 1D tod array and makes a simple map #produce arrays for mapping npix = self.naxis[0] * self.naxis[1] pixbins = np.arange(0, npix + 1).astype(int) nHorns, nSBs, nChans, nSamples = tod.shape rms = Filtering.calcRMS(tod) maps = np.zeros((nHorns, nSBs, nChans, self.naxis[0], self.naxis[1])) for i in range(nHorns): good = (np.isnan(ra[i, :]) == False) & (np.isnan(tod[i, 0, 0]) == False) pa = Coordinates.pa(ra[i, good], dec[i, good], mjd[good], self.lon, self.lat) x, y = Coordinates.Rotate(ra[i, good], dec[i, good], self.x0, self.y0, -pa) nbins = 10 xbins = np.linspace(np.min(x), np.max(x), nbins + 1) xmids = (xbins[1:] + xbins[:-1]) / 2. xbw, _ = np.histogram(x, xbins) ybw, _ = np.histogram(y, xbins) todAvg = np.nanmean(np.nanmean(tod[i, ...], axis=0), axis=0) fitx0, fity0 = self.initialPeak(todAvg[good], x, y) r = np.sqrt((x - fitx0)**2 + (y - fity0)**2) close = (r < 6. / 60.) pix = ang2pixWCS(self.wcs, x, y).astype('int') mask = np.where((pix != -1))[0] h, b = np.histogram(pix, pixbins, weights=(pix != -1).astype(float)) self.hits = np.reshape(h, (self.naxis[0], self.naxis[1])) for j in range(nSBs): for k in range(1): #nChans): todmap = tod[i, j, k, good] if self.filtertod: txbw, _ = np.histogram(x, xbins, weights=todmap) tybw, _ = np.histogram(y, xbins, weights=todmap) fb = txbw / xbw gd = np.isfinite(fb) pmdl = np.poly1d(np.polyfit(xmids[gd], fb[gd], 1)) todmap -= pmdl(x) fb = tybw / ybw gd = np.isfinite(fb) pmdl = np.poly1d(np.polyfit(xmids[gd], fb[gd], 1)) todmap -= pmdl(y) w, b = np.histogram(pix[mask], pixbins, weights=todmap[mask]) # w, b = np.histogram(pix[:], pixbins, weights=tod[i,j,k,:]) m = np.reshape(w, (self.naxis[0], self.naxis[1])) maps[i, j, k, ...] = m / self.hits return maps
def get_pixel_positions(self, azSource, elSource, az, el): x, y = Coordinates.Rotate(azSource, elSource, az, el, 0) pixels, pX, pY = self.getpixels(x, y, self.dx, self.dy, self.Nx, self.Ny) return pixels