def run(self, data):
        """
        Expects a level2 file structure to be passed.
        """
        fname = data.filename.split('/')[-1]

        az = data['level1/spectrometer/pixel_pointing/pixel_az'][0, :]
        el = data['level1/spectrometer/pixel_pointing/pixel_el'][0, :]
        mjd = data['level1/spectrometer/MJD'][:]

        self.distances = {k: np.zeros(az.size) for k in ['sun', 'moon']}

        for src, v in self.distances.items():
            s_az, s_el, s_ra, s_dec = Coordinates.sourcePosition(
                src, mjd, Coordinates.comap_longitude,
                Coordinates.comap_latitude)
            self.distances[src] = Coordinates.AngularSeperation(
                az, el, s_az, s_el)

        sources = list(self.distances.keys())
        for src in sources:
            self.distances[f'{src}_mean'] = np.array(
                [np.mean(self.distances[src])])
    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
Exemple #3
0
    def create_maps(self, data, tod, filters, sel):
        """
        Bin maps into instrument frame centred on source
        """

        mjd = data['spectrometer/MJD'][:]

        # We do Jupiter in the Az/El frame but celestial in sky frame
        #if self.source.upper() == 'JUPITER':
        az = data['spectrometer/pixel_pointing/pixel_az'][:]
        el = data['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 = {
            'maps': {
                'map': np.zeros(
                    (tod.shape[0], tod.shape[1], self.Nx, self.Ny)),
                'cov': np.zeros((tod.shape[0], tod.shape[1], self.Nx, self.Ny))
            }
        }
        maps['feed_avg'] = {
            'map': np.zeros((tod.shape[0], 1, self.Nx, self.Ny)),
            'cov': np.zeros((tod.shape[0], 1, self.Nx, self.Ny))
        }
        maps['CW'] = {
            'map': np.zeros((1, 1, self.Nx, self.Ny)),
            'cov': np.zeros((1, 1, self.Nx, self.Ny))
        }
        maps['CCW'] = {
            'map': np.zeros((1, 1, self.Nx, self.Ny)),
            'cov': np.zeros((1, 1, self.Nx, self.Ny))
        }

        selections = {
            k: selection
            for k, selection in zip(maps.keys(), [
                np.ones(az.shape[-1], dtype=bool),
                np.ones(az.shape[-1], dtype=bool), cw, ccw
            ])
        }
        slices = {
            k: sl
            for k, sl in zip(maps.keys(), [
                lambda ifeed, isb: [
                    slice(ifeed, ifeed + 1),
                    slice(isb, isb + 1),
                    slice(None),
                    slice(None)
                ], lambda ifeed, isb: [
                    slice(ifeed, ifeed + 1),
                    slice(None),
                    slice(None),
                    slice(None)
                ], lambda ifeed, isb:
                [slice(None),
                 slice(None),
                 slice(None),
                 slice(None)], lambda ifeed, isb:
                [slice(None),
                 slice(None),
                 slice(None),
                 slice(None)]
            ])
        }

        self.source_positions = {
            k: a
            for k, a in zip(['az', 'el', 'ra', 'dec'],
                            Coordinates.sourcePosition(self.source, mjd,
                                                       self.lon, self.lat))
        }
        self.source_positions['mean_el'] = np.mean(self.source_positions['el'])
        self.source_positions['mean_az'] = np.mean(self.source_positions['az'])

        for ifeed in tqdm(self.feedlist,
                          desc=f'{self.name}:create_maps:{self.source}'):
            feed_tod = tod[ifeed, ...]

            pixels = self.get_pixel_positions(self.source_positions['az'],
                                              self.source_positions['el'],
                                              az[ifeed, :], el[ifeed, :])

            mask = np.ones(pixels.size, dtype=int)
            for isb in range(tod.shape[1]):
                for k in temp_maps.keys():
                    temp_maps[k][:] = 0.
                z = (feed_tod[isb, sel] - filters[ifeed, isb])
                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():
                    for mode, map_data in maps.items():
                        if ('CW' in mode) & (ifeed > 1):
                            continue
                        binFuncs.binValues(
                            temp_maps[k],
                            pixels[selections[mode]],
                            weights=weights[k][selections[mode]],
                            mask=mask[selections[mode]])
                        maps[mode][k][slices[mode](ifeed, isb)] = 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.)

        for k, v in maps.items():
            maps[k] = self.average_maps(maps[k])
            maps[k]['xygrid'] = xygrid
        return maps